public void Can_read_hashes_only() { Account account = new Account(100).WithChangedCodeHash(TestItem.KeccakA).WithChangedStorageRoot(TestItem.KeccakB); AccountDecoder decoder = new AccountDecoder(); Rlp rlp = decoder.Encode(account); (Keccak codeHash, Keccak storageRoot) = decoder.DecodeHashesOnly(new RlpStream(rlp.Bytes)); Assert.AreEqual(codeHash, TestItem.KeccakA); Assert.AreEqual(storageRoot, TestItem.KeccakB); }
public async Task Can_read_dependent_items_from_state_db_while_waiting_for_dependencies() { StateDb codeDb = new StateDb(); StateDb stateDB = new StateDb(); MemDb tempDb = new MemDb(); SyncConfig syncConfig = new SyncConfig(); syncConfig.FastSync = true; IBlockTree blockTree = Substitute.For <IBlockTree>(); ISyncPeerPool pool = Substitute.For <ISyncPeerPool>(); SyncProgressResolver syncProgressResolver = new SyncProgressResolver(blockTree, NullReceiptStorage.Instance, stateDB, new MemDb(), syncConfig, LimboLogs.Instance); ISyncModeSelector syncModeSelector = new MultiSyncModeSelector(syncProgressResolver, pool, syncConfig, LimboLogs.Instance); StateSyncFeed stateSyncFeed = new StateSyncFeed(codeDb, stateDB, tempDb, syncModeSelector, blockTree, LimboLogs.Instance); // so we want to setup a trie in a structure of -> branch into two leaves // so we can respond with the branch node and with leaves missing // and we can prove that we can read the branch from the temp DB while it is still missing from the State DB AccountDecoder accountDecoder = new AccountDecoder(); TrieNode leaf = TrieNodeFactory.CreateLeaf(new HexPrefix(true, new byte[] { 1, 2, 3 }), accountDecoder.Encode(Account.TotallyEmpty).Bytes); TrieNode branch = TrieNodeFactory.CreateBranch(); branch.SetChild(1, leaf); branch.ResolveKey(true); // PatriciaTree tree = new PatriciaTree(); // tree = new PatriciaTree(); // tree.Set(branch.Keccak.Bytes, branch.Value); stateSyncFeed.ResetStateRoot(0, branch.Keccak); var request = await stateSyncFeed.PrepareRequest(); BuildRequestAndHandleResponse(branch, request, stateSyncFeed); byte[] value = tempDb.Get(branch.Keccak); value.Should().BeEquivalentTo(branch.FullRlp); byte[] valueFromState = stateDB.Get(branch.Keccak); valueFromState.Should().BeNull(); request = await stateSyncFeed.PrepareRequest(); BuildRequestAndHandleResponse(leaf, request, stateSyncFeed); value = tempDb.Get(branch.Keccak); value.Should().BeNull(); valueFromState = stateDB.Get(branch.Keccak); valueFromState.Should().BeEquivalentTo(branch.FullRlp); }
public void Leaf_with_contract_without_storage_and_empty_code_can_accept_visitors() { ITreeVisitor visitor = Substitute.For <ITreeVisitor>(); TrieVisitContext context = new TrieVisitContext(); Account account = new Account(1, 100, Keccak.EmptyTreeHash, Keccak.OfAnEmptyString); AccountDecoder decoder = new AccountDecoder(); TrieNode node = TrieNodeFactory.CreateLeaf(HexPrefix.Leaf("aa"), decoder.Encode(account).Bytes); node.Accept(visitor, NullTrieNodeResolver.Instance, context); visitor.Received().VisitLeaf(node, context, node.Value); }
public void Leaf_with_simple_account_can_accept_visitors() { ITreeVisitor visitor = Substitute.For <ITreeVisitor>(); TrieVisitContext context = new TrieVisitContext(); Account account = new Account(100); AccountDecoder decoder = new AccountDecoder(); TrieNode node = TrieNodeFactory.CreateLeaf(HexPrefix.Leaf("aa"), decoder.Encode(account).Bytes); node.Accept(visitor, NullTrieNodeResolver.Instance, context); visitor.Received().VisitLeaf(node, context, node.Value); }
public void Roundtrip_test() { Account account = new Account(100).WithChangedCodeHash(TestItem.KeccakA).WithChangedStorageRoot(TestItem.KeccakB); AccountDecoder decoder = new AccountDecoder(); Rlp rlp = decoder.Encode(account); Account decoded = decoder.Decode(new RlpStream(rlp.Bytes)); Assert.AreEqual((int)decoded.Balance, 100); Assert.AreEqual((int)decoded.Nonce, 0); Assert.AreEqual(decoded.CodeHash, TestItem.KeccakA); Assert.AreEqual(decoded.StorageRoot, TestItem.KeccakB); }
public void Leaf_with_contract_without_storage_and_empty_code_can_accept_visitors() { ITreeVisitor visitor = Substitute.For <ITreeVisitor>(); TrieVisitContext context = new TrieVisitContext(); PatriciaTree tree = new PatriciaTree(); Account account = new Account(1, 100, Keccak.EmptyTreeHash, Keccak.OfAnEmptyString); AccountDecoder decoder = new AccountDecoder(); TrieNode node = new TrieNode(NodeType.Leaf); node.Value = decoder.Encode(account).Bytes; node.Accept(visitor, tree, context); visitor.Received().VisitLeaf(node, context, node.Value); }
public void Leaf_with_simple_account_can_accept_visitors() { ITreeVisitor visitor = Substitute.For <ITreeVisitor>(); TrieVisitContext context = new TrieVisitContext(); PatriciaTree tree = new PatriciaTree(); Account account = new Account(100); AccountDecoder decoder = new AccountDecoder(); TrieNode node = new TrieNode(NodeType.Leaf); node.Value = decoder.Encode(account).Bytes; node.Accept(visitor, tree, context); visitor.Received().VisitLeaf(node, context, node.Value); }
public void Setup() { _tiniestLeaf = new TrieNode(NodeType.Leaf); _tiniestLeaf.Key = new HexPrefix(true, 5); _tiniestLeaf.Value = new byte[] { 10 }; _heavyLeaf = new TrieNode(NodeType.Leaf); _heavyLeaf.Key = new HexPrefix(true, new byte[20]); _heavyLeaf.Value = Keccak.EmptyTreeHash.Bytes.Concat(Keccak.EmptyTreeHash.Bytes).ToArray(); Account account = new Account(100); AccountDecoder decoder = new AccountDecoder(); _accountLeaf = new TrieNode(NodeType.Leaf); _accountLeaf.Value = decoder.Encode(account).Bytes; }
public void VisitLeaf(TrieNode node, TrieVisitContext trieVisitContext, byte[] value = null) { _nodesVisited++; if (trieVisitContext.IsStorage) { return; } AccountDecoder accountDecoder = new AccountDecoder(); Account account = accountDecoder.Decode(node.Value.AsRlpStream()); _balance += account.Balance; _accountsVisited++; _logger.Info($"Balance after visiting {_accountsVisited} accounts and {_nodesVisited} nodes: {_balance}"); }
public Context() { TiniestLeaf = new TrieNode(NodeType.Leaf); TiniestLeaf.Key = new HexPrefix(true, 5); TiniestLeaf.Value = new byte[] { 10 }; HeavyLeaf = new TrieNode(NodeType.Leaf); HeavyLeaf.Key = new HexPrefix(true, new byte[20]); HeavyLeaf.Value = Keccak.EmptyTreeHash.Bytes.Concat(Keccak.EmptyTreeHash.Bytes).ToArray(); Account account = new Account(100); AccountDecoder decoder = new AccountDecoder(); AccountLeaf = TrieNodeFactory.CreateLeaf( HexPrefix.Leaf("bbb"), decoder.Encode(account).Bytes); }
private void TestCallWithStorageAndCode(byte[] code, UInt256 gasPrice, Address from = null) { StateProvider stateProvider = CreateInitialState(code); StorageProvider storageProvider = new StorageProvider(new TrieStore(_dbProvider.StateDb, LimboLogs.Instance), stateProvider, LimboLogs.Instance); for (int i = 0; i < 10000; i++) { storageProvider.Set(new StorageCell(TestItem.AddressB, (UInt256)i), i.ToBigEndianByteArray()); } storageProvider.Commit(); storageProvider.CommitTrees(0); stateProvider.Commit(MainnetSpecProvider.Instance.GenesisSpec, null); stateProvider.CommitTree(0); Keccak root = stateProvider.StateRoot; Block block = Build.A.Block.WithParent(_blockTree.Head).WithStateRoot(root).TestObject; BlockTreeBuilder.AddBlock(_blockTree, block); Block blockOnTop = Build.A.Block.WithParent(block).WithStateRoot(root).TestObject; BlockTreeBuilder.AddBlock(_blockTree, blockOnTop); // would need to setup state root somehow... TransactionForRpc tx = new TransactionForRpc { // we are testing system transaction here when From is null From = from, To = TestItem.AddressB, GasPrice = gasPrice, Nonce = 1000 }; CallResultWithProof callResultWithProof = _proofModule.proof_call(tx, new BlockParameter(blockOnTop.Number)).Data; Assert.Greater(callResultWithProof.Accounts.Length, 0); // just the keys for debugging Span <byte> span = stackalloc byte[32]; new UInt256(0).ToBigEndian(span); Keccak k0 = Keccak.Compute(span); // just the keys for debugging new UInt256(1).ToBigEndian(span); Keccak k1 = Keccak.Compute(span); // just the keys for debugging new UInt256(2).ToBigEndian(span); Keccak k2 = Keccak.Compute(span); foreach (AccountProof accountProof in callResultWithProof.Accounts) { // this is here for diagnostics - so you can read what happens in the test // generally the account here should be consistent with the values inside the proof // the exception will be thrown if the account did not exist before the call Account account; try { account = new AccountDecoder().Decode(new RlpStream(ProofVerifier.Verify(accountProof.Proof, block.StateRoot))); } catch (Exception) { // ignored } foreach (StorageProof storageProof in accountProof.StorageProofs) { // we read the values here just to allow easier debugging so you can confirm that the value is same as the one in the proof and in the trie byte[] value = ProofVerifier.Verify(storageProof.Proof, accountProof.StorageRoot); } } EthereumJsonSerializer serializer = new EthereumJsonSerializer(); string response = RpcTest.TestSerializedRequest(_proofModule, "proof_call", $"{serializer.Serialize(tx)}", $"{blockOnTop.Number}"); Assert.True(response.Contains("\"result\"")); }