Skip to content

Commit

Permalink
Merge pull request #20 from aboutcircles/contracts-v0.3.6
Browse files Browse the repository at this point in the history
Contracts v0.3.6
  • Loading branch information
jaensen authored Sep 2, 2024
2 parents d8b45b3 + 82eaaec commit c51614b
Show file tree
Hide file tree
Showing 11 changed files with 145 additions and 40 deletions.
7 changes: 6 additions & 1 deletion Circles.Index.CirclesV1/LogParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,12 @@ public class LogParser(Address v1HubAddress) : ILogParser
private readonly Hash256 _hubTransferTopic = new(DatabaseSchema.HubTransfer.Topic);
private readonly Hash256 _trustTopic = new(DatabaseSchema.Trust.Topic);

public IEnumerable<IIndexEvent> ParseLog(Block block, TxReceipt receipt, LogEntry log, int logIndex)
public IEnumerable<IIndexEvent> ParseTransaction(Block block, int transactionIndex, Transaction transaction)
{
return Enumerable.Empty<IIndexEvent>();
}

public IEnumerable<IIndexEvent> ParseLog(Block block, Transaction transaction, TxReceipt receipt, LogEntry log, int logIndex)
{
List<IIndexEvent> events = new();
if (log.Topics.Length == 0)
Expand Down
7 changes: 6 additions & 1 deletion Circles.Index.CirclesV2.NameRegistry/LogParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,12 @@ public class LogParser(Address nameRegistryAddress) : ILogParser
private readonly Hash256 _updateMetadataDigestTopic = new(DatabaseSchema.UpdateMetadataDigest.Topic);
private readonly Hash256 _cidV0Topic = new(DatabaseSchema.CidV0.Topic);

public IEnumerable<IIndexEvent> ParseLog(Block block, TxReceipt receipt, LogEntry log, int logIndex)
public IEnumerable<IIndexEvent> ParseTransaction(Block block, int transactionIndex, Transaction transaction)
{
return Enumerable.Empty<IIndexEvent>();
}

public IEnumerable<IIndexEvent> ParseLog(Block block, Transaction transaction, TxReceipt receipt, LogEntry log, int logIndex)
{
if (log.Topics.Length == 0)
{
Expand Down
7 changes: 6 additions & 1 deletion Circles.Index.CirclesV2.StandardTreasury/LogParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,12 @@ public class LogParser(Address standardTreasuryAddress) : ILogParser
private readonly Hash256 _groupRedeemCollateralReturnTopic = new(DatabaseSchema.GroupRedeemCollateralReturn.Topic);
private readonly Hash256 _groupRedeemCollateralBurnTopic = new(DatabaseSchema.GroupRedeemCollateralBurn.Topic);

public IEnumerable<IIndexEvent> ParseLog(Block block, TxReceipt receipt, LogEntry log, int logIndex)
public IEnumerable<IIndexEvent> ParseTransaction(Block block, int transactionIndex, Transaction transaction)
{
return Enumerable.Empty<IIndexEvent>();
}

public IEnumerable<IIndexEvent> ParseLog(Block block, Transaction transaction, TxReceipt receipt, LogEntry log, int logIndex)
{
if (log.Topics.Length == 0)
{
Expand Down
89 changes: 65 additions & 24 deletions Circles.Index.CirclesV2/LogParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@ namespace Circles.Index.CirclesV2;
public class LogParser(Address v2HubAddress) : ILogParser
{
private readonly Hash256 _stoppedTopic = new(DatabaseSchema.Stopped.Topic);

private readonly Hash256 _trustTopic = new(DatabaseSchema.Trust.Topic);
private readonly Hash256 _inviteHumanTopic = new(DatabaseSchema.InviteHuman.Topic);

// private readonly Hash256 _inviteHumanTopic = new(DatabaseSchema.InviteHuman.Topic);
private readonly Hash256 _personalMintTopic = new(DatabaseSchema.PersonalMint.Topic);
private readonly Hash256 _registerHumanTopic = new(DatabaseSchema.RegisterHuman.Topic);
private readonly Hash256 _registerGroupTopic = new(DatabaseSchema.RegisterGroup.Topic);
Expand All @@ -32,7 +34,68 @@ public class LogParser(Address v2HubAddress) : ILogParser

public static readonly ConcurrentDictionary<Address, object?> Erc20WrapperAddresses = new();

public IEnumerable<IIndexEvent> ParseLog(Block block, TxReceipt receipt, LogEntry log, int logIndex)
private readonly byte[] _registerHumanFunctionSignature =
Keccak.Compute("registerHuman(address,bytes32)").Bytes[..4].ToArray();

public IEnumerable<IIndexEvent> ParseTransaction(Block block, int transactionIndex, Transaction transaction)
{
if (transaction.To != v2HubAddress)
{
yield break;
}

if (transaction.Data == null || transaction.Data.Value.Length < 68)
{
// 68 is the size of a complete registerHuman call with arguments
yield break;
}

// Parse the whole call data for a `registerHuman` call to get the inviter address and
// create a InviteHuman event from it.
// TODO: This is only for v0.3.6 and will be replace with an additional parameter on the InviteHuman event in the next version
// Because we cannot know how the contract was called (e.g. via a safe), we simply search for the function signature.
int callLength = 4;
for (int i = 0; i < transaction.Data.Value.Length - callLength; i++)
{
if (!transaction.Data.Value[i..(i + 4)].Span.SequenceEqual(_registerHumanFunctionSignature))
{
continue;
}

// The next 12 bytes must be zero padding.
if (!transaction.Data.Value[(i + callLength)..(i + callLength + 12)].Span.SequenceEqual(new byte[12]))
{
continue;
}

// Extract the bytes for the following call signature:
// function registerHuman(address _inviter, bytes32 _metadataDigest) external
var inviterAddressOffset = i + callLength;
var inviterAddressWithoutPaddingOffset = inviterAddressOffset + 12;
var inviterAddress = new Address(transaction.Data.Value[inviterAddressWithoutPaddingOffset..
(inviterAddressWithoutPaddingOffset + 20)].ToArray());

// TODO: Usually the sender is the invitee, but this will fail e.g. in case of relayers
var invitee = transaction.SenderAddress!;

// Console.WriteLine(
// $"Found `InviteHuman` call in tx {transaction.Hash}. Inviter: {inviterAddress}, Invitee: {invitee}");

if (inviterAddress == Address.Zero)
{
break;
}

yield return new InviteHuman(block.Number, (long)block.Timestamp, transactionIndex, -1,
transaction.Hash!.ToString(),
inviterAddress.ToString(), invitee.ToString());

break;
}
}

public IEnumerable<IIndexEvent> ParseLog(Block block, Transaction transaction, TxReceipt receipt, LogEntry log,
int logIndex)
{
if (log.Topics.Length == 0)
{
Expand All @@ -53,11 +116,6 @@ public IEnumerable<IIndexEvent> ParseLog(Block block, TxReceipt receipt, LogEntr
yield return CrcV2Trust(block, receipt, log, logIndex);
}

if (topic == _inviteHumanTopic)
{
yield return CrcV2InviteHuman(block, receipt, log, logIndex);
}

if (topic == _personalMintTopic)
{
yield return CrcV2PersonalMint(block, receipt, log, logIndex);
Expand Down Expand Up @@ -317,23 +375,6 @@ private PersonalMint CrcV2PersonalMint(Block block, TxReceipt receipt, LogEntry
endPeriod);
}

private InviteHuman CrcV2InviteHuman(Block block, TxReceipt receipt, LogEntry log, int logIndex)
{
string inviterAddress =
"0x" + log.Topics[1].ToString().Substring(Consts.AddressEmptyBytesPrefixLength);
string inviteeAddress =
"0x" + log.Topics[2].ToString().Substring(Consts.AddressEmptyBytesPrefixLength);

return new InviteHuman(
block.Number,
(long)block.Timestamp,
receipt.Index,
logIndex,
receipt.TxHash!.ToString(),
inviterAddress,
inviteeAddress);
}

private Trust CrcV2Trust(Block block, TxReceipt receipt, LogEntry log, int logIndex)
{
string userAddress = "0x" + log.Topics[1].ToString().Substring(Consts.AddressEmptyBytesPrefixLength);
Expand Down
5 changes: 4 additions & 1 deletion Circles.Index.Common/ILogParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,8 @@ namespace Circles.Index.Common;

public interface ILogParser
{
IEnumerable<IIndexEvent> ParseLog(Block block, TxReceipt receipt, LogEntry log, int logIndex);
IEnumerable<IIndexEvent> ParseTransaction(Block block, int transactionIndex, Transaction transaction);

IEnumerable<IIndexEvent> ParseLog(Block block, Transaction transaction, TxReceipt receipt, LogEntry log,
int logIndex);
}
6 changes: 4 additions & 2 deletions Circles.Index.Query/FilterPredicate.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ public ParameterizedSql ToSql(IDatabaseUtils database)
FilterType.NotIn => ConvertToEnumerable(Value)?.Any() ?? false
? $"{database.QuoteIdentifier(Column)} NOT IN ({FormatArrayParameter(Value, parameterName)})"
: "1=0 /* empty 'not in' filter */",
FilterType.IsNotNull => $"{database.QuoteIdentifier(Column)} IS NOT NULL",
FilterType.IsNull => $"{database.QuoteIdentifier(Column)} IS NULL",
_ => throw new NotImplementedException()
};

Expand Down Expand Up @@ -65,7 +67,7 @@ private IEnumerable<object> ConvertToEnumerable(object? value)
private IEnumerable<IDbDataParameter> CreateParameters(IDatabaseUtils database, string parameterName, object? value)
{
var values = ConvertToEnumerable(value).ToArray();

return values.Select((v, index) => database.CreateParameter($"{parameterName}_{index}", v)).ToList();
}
}
}
8 changes: 7 additions & 1 deletion Circles.Index.Query/FilterType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,11 @@ public enum FilterType
In,

[JsonConverter(typeof(JsonStringEnumConverter))]
NotIn
NotIn,

[JsonConverter(typeof(JsonStringEnumConverter))]
IsNotNull,

[JsonConverter(typeof(JsonStringEnumConverter))]
IsNull
}
40 changes: 39 additions & 1 deletion Circles.Index/BlockIndexer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using Nethermind.Blockchain;
using Nethermind.Blockchain.Receipts;
using Nethermind.Core;
using Nethermind.Core.Crypto;

namespace Circles.Index;

Expand Down Expand Up @@ -96,6 +97,19 @@ private async Task Sink((BlockWithReceipts, IEnumerable<IIndexEvent>) data)
TransformBlock<BlockWithReceipts, (BlockWithReceipts, IEnumerable<IIndexEvent>)> parserBlock = new(
blockWithReceipts =>
{
Dictionary<Hash256, Transaction> transactionsByHash = new();
Dictionary<Hash256, int> transactionIndexByHash = new();

for (var i = 0; i < blockWithReceipts.Block.Transactions.Length; i++)
{
var tx = blockWithReceipts.Block.Transactions[i];
if (tx.Hash != null)
{
transactionsByHash[tx.Hash] = tx;
transactionIndexByHash[tx.Hash] = i;
}
}

List<IIndexEvent> events = [];
foreach (var receipt in blockWithReceipts.Receipts)
{
Expand All @@ -105,14 +119,38 @@ private async Task Sink((BlockWithReceipts, IEnumerable<IIndexEvent>) data)
return (blockWithReceipts, events);
}

var transaction = transactionsByHash[receipt.TxHash!];
var transactionIndex = transactionIndexByHash[receipt.TxHash!];
try
{
foreach (var parser in context.LogParsers)
{
var parsedEvents = parser.ParseTransaction(blockWithReceipts.Block,
transactionIndex, transaction);

events.AddRange(parsedEvents);
}
}
catch (Exception e)
{
context.Logger.Error($"Error parsing transaction {transaction}");
context.Logger.Error($"Block: {blockWithReceipts.Block.Number}");
context.Logger.Error($"Receipt.TxHash: {receipt.TxHash}");
context.Logger.Error(e.Message);
context.Logger.Error(e.StackTrace);
throw;
}

for (int i = 0; i < receipt.Logs?.Length; i++)
{
LogEntry log = receipt.Logs[i];
foreach (var parser in context.LogParsers)
{
try
{
var parsedEvents = parser.ParseLog(blockWithReceipts.Block, receipt, log, i);
var parsedEvents = parser.ParseLog(blockWithReceipts.Block,
transaction, receipt, log, i);

events.AddRange(parsedEvents);
}
catch (Exception e)
Expand Down
4 changes: 2 additions & 2 deletions Circles.Index/Circles.Index.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
<Authors>Daniel Janz (Gnosis Service GmbH)</Authors>
<Copyright>Gnosis Service GmbH</Copyright>
<Product>Circles</Product>
<AssemblyVersion>1.6.4</AssemblyVersion>
<FileVersion>1.6.4</FileVersion>
<AssemblyVersion>1.7.0</AssemblyVersion>
<FileVersion>1.7.0</FileVersion>
</PropertyGroup>


Expand Down
6 changes: 3 additions & 3 deletions docker-compose.chiado.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,9 @@ services:
- .env
environment:
- V1_HUB_ADDRESS=0xdbf22d4e8962db3b2f1d9ff55be728a887e47710
- V2_HUB_ADDRESS=0xEddc960D3c78692BF38577054cb0a35114AE35e0
- V2_NAME_REGISTRY_ADDRESS=0x5525cbF9ad01a4E805ed1b40723D6377b336eCcf
- V2_STANDARD_TREASURY_ADDRESS=0x66A024F2055fa84b40f27c2f3Eb68A848276A641
- V2_HUB_ADDRESS=0xb80feeDfEce647dDc709777D5094fACD157BA001
- V2_NAME_REGISTRY_ADDRESS=0x24b3fDCdD9fef844fB3094ef43c0A6Ac23a6dF9E
- V2_STANDARD_TREASURY_ADDRESS=0xC06ADED7950429FdF2023e139B076f6BaFf9Fe1C
- POSTGRES_CONNECTION_STRING=Server=postgres-chiado;Port=5432;Database=postgres;User Id=${POSTGRES_USER};Password=${POSTGRES_PASSWORD};

postgres-chiado:
Expand Down
6 changes: 3 additions & 3 deletions docker-compose.gnosis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@ services:
- .env
environment:
- V1_HUB_ADDRESS=0x29b9a7fBb8995b2423a71cC17cf9810798F6C543
- V2_HUB_ADDRESS=0x7bC1F123089Bc1f384b6379d0587968d1CD5830a
- V2_NAME_REGISTRY_ADDRESS=0xb95eF3f3E693531d9588815bcA954dC8dce30937
- V2_STANDARD_TREASURY_ADDRESS=0x2434151eB40Af648AbcF73a6C9F1711FfF0F498B
- V2_HUB_ADDRESS=0xa5c7ADAE2fd3844f12D52266Cb7926f8649869Da
- V2_NAME_REGISTRY_ADDRESS=0x738fFee24770d0DE1f912adf2B48b0194780E9AD
- V2_STANDARD_TREASURY_ADDRESS=0xbb76CF35ec106c5c7a447246257dcfCB7244cA04
- POSTGRES_CONNECTION_STRING=Server=postgres-gnosis;Port=5432;Database=postgres;User Id=${POSTGRES_USER};Password=${POSTGRES_PASSWORD};
- START_BLOCK=12000000

Expand Down

0 comments on commit c51614b

Please sign in to comment.