Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Contracts v0.3.6 #20

Merged
merged 5 commits into from
Sep 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading