public class SupplyVerifier : ITreeVisitor
private readonly ILogger _logger;
private HashSet<Keccak> _ignoreThisOne = new HashSet<Keccak>();
private int _accountsVisited;
private int _nodesVisited;
public SupplyVerifier(ILogger logger)
public UInt256 Balance { get; set; } = UInt256.Zero;
public bool ShouldVisit(Keccak nextNode)
if (_ignoreThisOne.Count > 16)
_logger.Warn(quot;Ignore count leak -> {_ignoreThisOne.Count}");
if (_ignoreThisOne.Contains(nextNode))
_ignoreThisOne.Remove(nextNode);
public void VisitTree(Keccak rootHash, TrieVisitContext trieVisitContext)
public void VisitMissingNode(Keccak nodeHash, TrieVisitContext trieVisitContext)
_logger.Warn(quot;Missing node {nodeHash}");
public void VisitBranch(TrieNode node, TrieVisitContext trieVisitContext)
_logger.Info(quot;Balance after visiting {_accountsVisited} accounts and {_nodesVisited} nodes: {Balance}");
if (trieVisitContext.IsStorage)
for (int i = 0; i < 16; i++)
Keccak childHash = node.GetChildHash(i);
_ignoreThisOne.Add(childHash);
public void VisitExtension(TrieNode node, TrieVisitContext trieVisitContext)
if (trieVisitContext.IsStorage)
_ignoreThisOne.Add(node.GetChildHash(0));
public void VisitLeaf(TrieNode node, TrieVisitContext trieVisitContext, byte[] value = null)
if (trieVisitContext.IsStorage)
AccountDecoder accountDecoder = new AccountDecoder();
Account account = accountDecoder.Decode(node.Value.AsRlpStream());
Balance += account.Balance;
_logger.Info(quot;Balance after visiting {_accountsVisited} accounts and {_nodesVisited} nodes: {Balance}");
public void VisitCode(Keccak codeHash, TrieVisitContext trieVisitContext)