public void Storage_proofs_have_keys_set()
        {
            IDb         memDb       = new MemDb();
            ITrieStore  trieStore   = new TrieStore(memDb, LimboLogs.Instance);
            StateTree   tree        = new StateTree(trieStore, LimboLogs.Instance);
            StorageTree storageTree = new StorageTree(trieStore, Keccak.EmptyTreeHash, LimboLogs.Instance);

            storageTree.Set(UInt256.Zero, Bytes.FromHexString("0xab12000000000000000000000000000000000000000000000000000000000000000000000000000000"));
            storageTree.Set(UInt256.One, Bytes.FromHexString("0xab34000000000000000000000000000000000000000000000000000000000000000000000000000000"));
            storageTree.Commit(0);

            byte[]  code     = new byte[] { 1, 2, 3 };
            Account account1 = Build.An.Account.WithBalance(1).WithStorageRoot(storageTree.RootHash).TestObject;
            Account account2 = Build.An.Account.WithBalance(2).TestObject;

            tree.Set(TestItem.AddressA, account1);
            tree.Set(TestItem.AddressB, account2);
            tree.Commit(0);

            AccountProofCollector accountProofCollector = new AccountProofCollector(TestItem.AddressA, new[] { Bytes.FromHexString("0x0000000000000000000000000000000000000000000000000000000000000000"), Bytes.FromHexString("0x0000000000000000000000000000000000000000000000000000000000000001") });

            tree.Accept(accountProofCollector, tree.RootHash, true);
            AccountProof proof = accountProofCollector.BuildResult();

            Assert.AreEqual("0x0000000000000000000000000000000000000000000000000000000000000000", proof.StorageProofs[0].Key.ToHexString(true));
            Assert.AreEqual("0x0000000000000000000000000000000000000000000000000000000000000001", proof.StorageProofs[1].Key.ToHexString(true));
        }
        public void Shows_empty_values_when_account_is_missing()
        {
            IDb       memDb = new MemDb();
            StateTree tree  = new StateTree(new TrieStore(memDb, LimboLogs.Instance), LimboLogs.Instance);

            byte[]  code     = new byte[] { 1, 2, 3 };
            Account account2 = Build.An.Account.WithBalance(2).TestObject;

            tree.Set(TestItem.AddressB, account2);
            tree.Commit(0);

            TreeDumper dumper = new TreeDumper();

            tree.Accept(dumper, tree.RootHash, true);
            Console.WriteLine(dumper.ToString());

            AccountProofCollector accountProofCollector = new AccountProofCollector(TestItem.AddressA);

            tree.Accept(accountProofCollector, tree.RootHash, true);
            AccountProof proof = accountProofCollector.BuildResult();

            Assert.AreEqual((UInt256)0, proof.Balance);
            Assert.AreEqual(UInt256.Zero, proof.Nonce);
            Assert.AreEqual(Keccak.OfAnEmptyString, proof.CodeHash);
            Assert.AreEqual(Keccak.EmptyTreeHash, proof.StorageRoot);
        }
        public void Nonce_is_correct()
        {
            StateTree tree = new StateTree();

            byte[]  code     = new byte[] { 1, 2, 3 };
            Account account1 = Build.An.Account.WithBalance(1).WithNonce(UInt256.One).TestObject;
            Account account2 = Build.An.Account.WithBalance(2).TestObject;

            tree.Set(TestItem.AddressA, account1);
            tree.Set(TestItem.AddressB, account2);
            tree.Commit(0);

            AccountProofCollector accountProofCollector = new AccountProofCollector(TestItem.AddressA);

            tree.Accept(accountProofCollector, tree.RootHash, true);
            AccountProof proof = accountProofCollector.BuildResult();

            Assert.AreEqual(account1.Nonce, proof.Nonce);

            AccountProofCollector accountProofCollector2 = new AccountProofCollector(TestItem.AddressB);

            tree.Accept(accountProofCollector2, tree.RootHash, true);
            AccountProof proof2 = accountProofCollector2.BuildResult();

            Assert.AreEqual(UInt256.Zero, proof2.Nonce);
        }
        public void Storage_root_is_correct()
        {
            StateTree tree = new StateTree();

            byte[]  code     = new byte[] { 1, 2, 3 };
            Account account1 = Build.An.Account.WithBalance(1).WithStorageRoot(TestItem.KeccakA).TestObject;
            Account account2 = Build.An.Account.WithBalance(2).TestObject;

            tree.Set(TestItem.AddressA, account1);
            tree.Set(TestItem.AddressB, account2);
            tree.Commit(0);

            AccountProofCollector accountProofCollector = new AccountProofCollector(TestItem.AddressA);

            tree.Accept(accountProofCollector, tree.RootHash, true);
            AccountProof proof = accountProofCollector.BuildResult();

            Assert.AreEqual(TestItem.KeccakA, proof.StorageRoot);

            AccountProofCollector accountProofCollector2 = new AccountProofCollector(TestItem.AddressB);

            tree.Accept(accountProofCollector2, tree.RootHash, true);
            AccountProof proof2 = accountProofCollector2.BuildResult();

            Assert.AreEqual(Keccak.EmptyTreeHash, proof2.StorageRoot);
        }
        public void Addresses_are_correct()
        {
            StateTree tree = new StateTree();

            Account account1 = Build.An.Account.WithBalance(1).TestObject;
            Account account2 = Build.An.Account.WithBalance(2).TestObject;

            tree.Set(TestItem.AddressA, account1);
            tree.Set(TestItem.AddressB, account2);
            tree.Commit(0);

            AccountProofCollector accountProofCollector = new AccountProofCollector(TestItem.AddressA);

            tree.Accept(accountProofCollector, tree.RootHash, true);
            AccountProof proof = accountProofCollector.BuildResult();

            Assert.AreEqual(TestItem.AddressA, proof.Address);

            AccountProofCollector accountProofCollector2 = new AccountProofCollector(TestItem.AddressB);

            tree.Accept(accountProofCollector2, tree.RootHash, true);
            AccountProof proof2 = accountProofCollector2.BuildResult();

            Assert.AreEqual(TestItem.AddressB, proof2.Address);
        }
        public void Code_hash_is_correct()
        {
            StateTree tree = new StateTree();

            byte[]  code     = new byte[] { 1, 2, 3 };
            Account account1 = Build.An.Account.WithBalance(1).WithCode(code).TestObject;
            Account account2 = Build.An.Account.WithBalance(2).TestObject;

            tree.Set(TestItem.AddressA, account1);
            tree.Set(TestItem.AddressB, account2);
            tree.Commit(0);

            AccountProofCollector accountProofCollector = new AccountProofCollector(TestItem.AddressA);

            tree.Accept(accountProofCollector, tree.RootHash, true);
            AccountProof proof = accountProofCollector.BuildResult();

            Assert.AreEqual(account1.CodeHash, proof.CodeHash);

            AccountProofCollector accountProofCollector2 = new AccountProofCollector(TestItem.AddressB);

            tree.Accept(accountProofCollector2, tree.RootHash, true);
            AccountProof proof2 = accountProofCollector2.BuildResult();

            Assert.AreEqual(Keccak.OfAnEmptyString, proof2.CodeHash);
        }
        public void Non_existing_account_is_valid_even_when_extension_on_the_way_is_not_fully_matched()
        {
            // extension for a & b of the same length as for the c & d
            byte[] a = Bytes.FromHexString("0xeeeeeeeeeeeeeeeeeeeeeeee0eeeeeeeeeeeeeeeee1111111111111111111111");
            byte[] b = Bytes.FromHexString("0xeeeeeeeeeeeeeeeeeeeeeeee0eeeeeeeeeeeeeeeee2222222222222222222222");
            // but the extensions themselves have a difference in the middle (0 instead of e)
            byte[] c = Bytes.FromHexString("0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee3333333333333333333333");
            byte[] d = Bytes.FromHexString("0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee4444444444444444444444");

            StateTree tree = new StateTree();

            // we ensure that accounts a and b do not exist in the trie
            Account account = Build.An.Account.WithBalance(1).TestObject;

            tree.Set(c.AsSpan(), Rlp.Encode(account.WithChangedBalance(3)));
            tree.Set(d.AsSpan(), Rlp.Encode(account.WithChangedBalance(4)));
            tree.Commit(0);

            // now wer are looking for a trying to trick the code to think that the extension of c and d is a good match
            // if everything is ok the proof length of 1 is enough since the extension from the root is not matched
            AccountProofCollector accountProofCollector = new AccountProofCollector(a);

            tree.Accept(accountProofCollector, tree.RootHash, true);
            AccountProof proof = accountProofCollector.BuildResult();

            proof.Proof.Should().HaveCount(1);

            // and because the account does not exist, the balance should be 0
            proof.Balance.Should().Be(UInt256.Zero);
        }
예제 #8
0
        // https://github.com/ethereum/EIPs/issues/1186
        public ResultWrapper <AccountProof> eth_getProof(Address accountAddress, byte[][] storageKeys, BlockParameter blockParameter)
        {
            BlockHeader header;

            try
            {
                header = _blockFinder.FindHeader(blockParameter);
                if (header == null)
                {
                    return(ResultWrapper <AccountProof> .Fail($"{blockParameter} block not found", ErrorCodes.ResourceNotFound, null));
                }

                if (!HasStateForBlock(header))
                {
                    return(ResultWrapper <AccountProof> .Fail($"No state available for block {header.Hash}", ErrorCodes.ResourceUnavailable));
                }
            }
            catch (Exception ex)
            {
                return(ResultWrapper <AccountProof> .Fail(ex.Message, ErrorCodes.InternalError, null));
            }

            AccountProofCollector accountProofCollector = new AccountProofCollector(accountAddress, storageKeys);

            _blockchainBridge.RunTreeVisitor(accountProofCollector, header.StateRoot);

            return(ResultWrapper <AccountProof> .Success(accountProofCollector.BuildResult()));
        }
예제 #9
0
        public void Storage_proofs_have_values_set_complex_3_setup()
        {
            byte[] a = Bytes.FromHexString("0x000000000000000000000000000000000000000000aaaaaaaaaaaaaaaaaaaaaa");
            byte[] b = Bytes.FromHexString("0x0000000000000000000000000bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb");
            byte[] c = Bytes.FromHexString("0x00000000001ccccccccccccccccccccccccccccccccccccccccccccccccccccc");
            byte[] d = Bytes.FromHexString("0x00000000001ddddddddddddddddddddddddddddddddddddddddddddddddddddd");
            byte[] e = Bytes.FromHexString("0x00000000001eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee");

            IDb         memDb       = new MemDb();
            TrieStore   trieStore   = new TrieStore(memDb, LimboLogs.Instance);
            StateTree   tree        = new StateTree(trieStore, LimboLogs.Instance);
            StorageTree storageTree = new StorageTree(trieStore, Keccak.EmptyTreeHash, LimboLogs.Instance);

            storageTree.Set(Keccak.Compute(a).Bytes, Rlp.Encode(Bytes.FromHexString("0xab12000000000000000000000000000000000000000000000000000000000000000000000000000000")));
            storageTree.Set(Keccak.Compute(b).Bytes, Rlp.Encode(Bytes.FromHexString("0xab34000000000000000000000000000000000000000000000000000000000000000000000000000000")));
            storageTree.Set(Keccak.Compute(c).Bytes, Rlp.Encode(Bytes.FromHexString("0xab56000000000000000000000000000000000000000000000000000000000000000000000000000000")));
            storageTree.Set(Keccak.Compute(d).Bytes, Rlp.Encode(Bytes.FromHexString("0xab78000000000000000000000000000000000000000000000000000000000000000000000000000000")));
            storageTree.Set(Keccak.Compute(e).Bytes, Rlp.Encode(Bytes.FromHexString("0xab9a000000000000000000000000000000000000000000000000000000000000000000000000000000")));
            storageTree.Commit(0);

            byte[]  code     = new byte[] { 1, 2, 3 };
            Account account1 = Build.An.Account.WithBalance(1).WithStorageRoot(storageTree.RootHash).TestObject;
            Account account2 = Build.An.Account.WithBalance(2).TestObject;

            tree.Set(TestItem.AddressA, account1);
            tree.Set(TestItem.AddressB, account2);
            tree.Commit(0);

            AccountProofCollector accountProofCollector = new AccountProofCollector(TestItem.AddressA, new byte[][] { a, b, c, d, e });

            tree.Accept(accountProofCollector, tree.RootHash, true);
            AccountProof proof = accountProofCollector.BuildResult();

            TestToJson(proof, "{\"accountProof\":[\"0xe215a08c9a7cdf08d4425c138ef5ba3d1f6c2ae18786fe88d9a56230a00b3e83367b25\",\"0xf8518080808080a017934c1c90ce30ca48f32b4f449dab308cfba803fd6d142cab01eb1fad1b70038080808080808080a02352504a0cd6095829b18bae394d0c882d84eead7be5b6ad0a87daaff9d2fb4a8080\",\"0xf869a020227dead52ea912e013e7641ccd6b3b174498e55066b0c174a09c8c3cc4bf5eb846f8448001a0b2375a34ff2c8037d9ff04ebc16367b51d156d9a905ca54cef50bfad1a4c0711a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\"],\"address\":\"0xb7705ae4c6f81b66cdb323c65f4e8133690fc099\",\"balance\":\"0x1\",\"codeHash\":\"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\",\"nonce\":\"0x0\",\"storageHash\":\"0xb2375a34ff2c8037d9ff04ebc16367b51d156d9a905ca54cef50bfad1a4c0711\",\"storageProof\":[{\"key\":\"0x000000000000000000000000000000000000000000aaaaaaaaaaaaaaaaaaaaaa\",\"proof\":[\"0xf8918080a02474007b0486d5e951fe3fbcdae3e63cadf9c85cb8f178d3c7ca972e2d77705a808080808080a059c4fa21a1e4c40dc3c87e925befbb78a5b6f729865a12f6f0490d9801bcbf22a06b3576bbd6c91ca7128f69f728f3e30bf8980c6381430a5e80186d0dfec89d4e8080a098cfc3bf071c19a2e230165f4152bb98a5d1ab0fee47c952de65da85fcbdfdb2808080\",\"0xf85180a0aec9a5fc3ba2ebedf137fbcf6987b303c9d8718f75253e6e2444b81a4049e5b980808080808080808080a0397f22cb0ad24543caffaad031e3a0a538e5d8ac106d8f6858a703d442c0e4d380808080\",\"0xf84ca02046d62176084b9d1eace1c8bcc2353228d10569a500ccfd1bdbd8c093f4b4e9aaa9ab12000000000000000000000000000000000000000000000000000000000000000000000000000000\"],\"value\":\"0xab12000000000000000000000000000000000000000000000000000000000000000000000000000000\"},{\"key\":\"0x0000000000000000000000000bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\",\"proof\":[\"0xf8918080a02474007b0486d5e951fe3fbcdae3e63cadf9c85cb8f178d3c7ca972e2d77705a808080808080a059c4fa21a1e4c40dc3c87e925befbb78a5b6f729865a12f6f0490d9801bcbf22a06b3576bbd6c91ca7128f69f728f3e30bf8980c6381430a5e80186d0dfec89d4e8080a098cfc3bf071c19a2e230165f4152bb98a5d1ab0fee47c952de65da85fcbdfdb2808080\",\"0xf85180a0aec9a5fc3ba2ebedf137fbcf6987b303c9d8718f75253e6e2444b81a4049e5b980808080808080808080a0397f22cb0ad24543caffaad031e3a0a538e5d8ac106d8f6858a703d442c0e4d380808080\",\"0xf84ca020cc5921315fe8a051acdea77b782ecb469470d4e94248cb4ff49a1ff26fe982aaa9ab34000000000000000000000000000000000000000000000000000000000000000000000000000000\"],\"value\":\"0xab34000000000000000000000000000000000000000000000000000000000000000000000000000000\"},{\"key\":\"0x00000000001ccccccccccccccccccccccccccccccccccccccccccccccccccccc\",\"proof\":[\"0xf8918080a02474007b0486d5e951fe3fbcdae3e63cadf9c85cb8f178d3c7ca972e2d77705a808080808080a059c4fa21a1e4c40dc3c87e925befbb78a5b6f729865a12f6f0490d9801bcbf22a06b3576bbd6c91ca7128f69f728f3e30bf8980c6381430a5e80186d0dfec89d4e8080a098cfc3bf071c19a2e230165f4152bb98a5d1ab0fee47c952de65da85fcbdfdb2808080\",\"0xf84ca0383dacaf928fae678bb3ccca17c746816e9bcfc5628853ae37c67b2d3bbaad32aaa9ab56000000000000000000000000000000000000000000000000000000000000000000000000000000\"],\"value\":\"0xab56000000000000000000000000000000000000000000000000000000000000000000000000000000\"},{\"key\":\"0x00000000001ddddddddddddddddddddddddddddddddddddddddddddddddddddd\",\"proof\":[\"0xf8918080a02474007b0486d5e951fe3fbcdae3e63cadf9c85cb8f178d3c7ca972e2d77705a808080808080a059c4fa21a1e4c40dc3c87e925befbb78a5b6f729865a12f6f0490d9801bcbf22a06b3576bbd6c91ca7128f69f728f3e30bf8980c6381430a5e80186d0dfec89d4e8080a098cfc3bf071c19a2e230165f4152bb98a5d1ab0fee47c952de65da85fcbdfdb2808080\",\"0xf84ca031c208aebac39ba1b4503fa46a491619019fc1a910b3bfe3c78dc3da4abdb097aaa9ab78000000000000000000000000000000000000000000000000000000000000000000000000000000\"],\"value\":\"0xab78000000000000000000000000000000000000000000000000000000000000000000000000000000\"},{\"key\":\"0x00000000001eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee\",\"proof\":[\"0xf8918080a02474007b0486d5e951fe3fbcdae3e63cadf9c85cb8f178d3c7ca972e2d77705a808080808080a059c4fa21a1e4c40dc3c87e925befbb78a5b6f729865a12f6f0490d9801bcbf22a06b3576bbd6c91ca7128f69f728f3e30bf8980c6381430a5e80186d0dfec89d4e8080a098cfc3bf071c19a2e230165f4152bb98a5d1ab0fee47c952de65da85fcbdfdb2808080\",\"0xf84ca03ca9062cf1266ae3ad77045eb67b33d4c9a4f5e2be44c79cad975ace0bc6ed22aaa9ab9a000000000000000000000000000000000000000000000000000000000000000000000000000000\"],\"value\":\"0xab9a000000000000000000000000000000000000000000000000000000000000000000000000000000\"}]}");
        }
        public void Non_existing_account_is_valid_on_non_empty_tree_with_branch_without_matching_child()
        {
            StateTree tree = new StateTree();

            Account account1 = Build.An.Account.WithBalance(1).TestObject;
            Account account2 = Build.An.Account.WithBalance(2).TestObject;

            tree.Set(TestItem.AddressA, account1);
            tree.Set(TestItem.AddressB, account2);
            tree.Commit(0);

            AccountProofCollector accountProofCollector = new AccountProofCollector(TestItem.AddressC, new UInt256[] { 1, 2, 3 });

            tree.Accept(accountProofCollector, tree.RootHash, true);
            AccountProof proof = accountProofCollector.BuildResult();

            proof.Proof.Should().HaveCount(1);
            Assert.AreEqual(TestItem.AddressC, proof.Address);
            Assert.AreEqual(Keccak.OfAnEmptyString, proof.CodeHash);
            Assert.AreEqual(Keccak.EmptyTreeHash, proof.StorageRoot);
            Assert.AreEqual(UInt256.Zero, proof.Balance);
            Assert.AreEqual(new byte[] { 0 }, proof.StorageProofs[0].Value);
            Assert.AreEqual(new byte[] { 0 }, proof.StorageProofs[1].Value);
            Assert.AreEqual(new byte[] { 0 }, proof.StorageProofs[2].Value);
        }
예제 #11
0
        public void Does_not_fail_when_proofs_are_longer_than_number_of_proofs_regression()
        {
            byte[] a = Bytes.FromHexString("0x000000000000000000000000000000000000000000aaaaaaaaaaaaaaaaaaaaaa");
            byte[] b = Bytes.FromHexString("0x0000000000000000000000000bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb");
            byte[] c = Bytes.FromHexString("0x00000000001ccccccccccccccccccccccccccccccccccccccccccccccccccccc");
            byte[] d = Bytes.FromHexString("0x00000000001ddddddddddddddddddddddddddddddddddddddddddddddddddddd");
            byte[] e = Bytes.FromHexString("0x00000000001eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee");

            IDb         memDb       = new MemDb();
            StateTree   tree        = new StateTree(memDb);
            StorageTree storageTree = new StorageTree(memDb);

            storageTree.Set(Keccak.Compute(a).Bytes, Rlp.Encode(Bytes.FromHexString("0xab12000000000000000000000000000000000000000000000000000000000000000000000000000000")));
            storageTree.Set(Keccak.Compute(b).Bytes, Rlp.Encode(Bytes.FromHexString("0xab34000000000000000000000000000000000000000000000000000000000000000000000000000000")));
            storageTree.Set(Keccak.Compute(c).Bytes, Rlp.Encode(Bytes.FromHexString("0xab56000000000000000000000000000000000000000000000000000000000000000000000000000000")));
            storageTree.Set(Keccak.Compute(d).Bytes, Rlp.Encode(Bytes.FromHexString("0xab78000000000000000000000000000000000000000000000000000000000000000000000000000000")));
            storageTree.Set(Keccak.Compute(e).Bytes, Rlp.Encode(Bytes.FromHexString("0xab9a000000000000000000000000000000000000000000000000000000000000000000000000000000")));
            storageTree.Commit();

            byte[]  code     = new byte[] { 1, 2, 3 };
            Account account1 = Build.An.Account.WithBalance(1).WithStorageRoot(storageTree.RootHash).TestObject;
            Account account2 = Build.An.Account.WithBalance(2).TestObject;

            tree.Set(TestItem.AddressA, account1);
            tree.Set(TestItem.AddressB, account2);
            tree.Commit();

            AccountProofCollector accountProofCollector = new AccountProofCollector(TestItem.AddressA, new byte[][] { a });

            tree.Accept(accountProofCollector, tree.RootHash, true);
            AccountProof proof = accountProofCollector.BuildResult();

            TestToJson(proof, "{\"accountProof\":[\"0xe215a08c9a7cdf08d4425c138ef5ba3d1f6c2ae18786fe88d9a56230a00b3e83367b25\",\"0xf8518080808080a017934c1c90ce30ca48f32b4f449dab308cfba803fd6d142cab01eb1fad1b70038080808080808080a02352504a0cd6095829b18bae394d0c882d84eead7be5b6ad0a87daaff9d2fb4a8080\",\"0xf869a020227dead52ea912e013e7641ccd6b3b174498e55066b0c174a09c8c3cc4bf5eb846f8448001a0b2375a34ff2c8037d9ff04ebc16367b51d156d9a905ca54cef50bfad1a4c0711a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\"],\"address\":\"0xb7705ae4c6f81b66cdb323c65f4e8133690fc099\",\"balance\":\"0x1\",\"codeHash\":\"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\",\"nonce\":\"0x0\",\"storageHash\":\"0xb2375a34ff2c8037d9ff04ebc16367b51d156d9a905ca54cef50bfad1a4c0711\",\"storageProof\":[{\"key\":\"0x000000000000000000000000000000000000000000aaaaaaaaaaaaaaaaaaaaaa\",\"proof\":[\"0xf8918080a02474007b0486d5e951fe3fbcdae3e63cadf9c85cb8f178d3c7ca972e2d77705a808080808080a059c4fa21a1e4c40dc3c87e925befbb78a5b6f729865a12f6f0490d9801bcbf22a06b3576bbd6c91ca7128f69f728f3e30bf8980c6381430a5e80186d0dfec89d4e8080a098cfc3bf071c19a2e230165f4152bb98a5d1ab0fee47c952de65da85fcbdfdb2808080\",\"0xf85180a0aec9a5fc3ba2ebedf137fbcf6987b303c9d8718f75253e6e2444b81a4049e5b980808080808080808080a0397f22cb0ad24543caffaad031e3a0a538e5d8ac106d8f6858a703d442c0e4d380808080\",\"0xf84ca02046d62176084b9d1eace1c8bcc2353228d10569a500ccfd1bdbd8c093f4b4e9aaa9ab12000000000000000000000000000000000000000000000000000000000000000000000000000000\"],\"value\":\"0xab12000000000000000000000000000000000000000000000000000000000000000000000000000000\"}]}");
        }
        public void Non_existing_account_is_valid()
        {
            StateTree             tree = new StateTree();
            AccountProofCollector accountProofCollector = new AccountProofCollector(TestItem.AddressA, new UInt256[] { 1, 2, 3 });

            tree.Accept(accountProofCollector, tree.RootHash, true);
            AccountProof proof = accountProofCollector.BuildResult();

            Assert.AreEqual(TestItem.AddressA, proof.Address);
            Assert.AreEqual(Keccak.OfAnEmptyString, proof.CodeHash);
            Assert.AreEqual(Keccak.EmptyTreeHash, proof.StorageRoot);
            Assert.AreEqual(UInt256.Zero, proof.Balance);
            Assert.AreEqual(new byte[] { 0 }, proof.StorageProofs[0].Value);
            Assert.AreEqual(new byte[] { 0 }, proof.StorageProofs[1].Value);
            Assert.AreEqual(new byte[] { 0 }, proof.StorageProofs[2].Value);
        }
예제 #13
0
        private AccountProof[] CollectAccountProofs(Keccak stateRoot, ProofTxTracer proofTxTracer)
        {
            List <AccountProof> accountProofs = new List <AccountProof>();

            foreach (Address address in proofTxTracer.Accounts)
            {
                AccountProofCollector collector = new AccountProofCollector(address, proofTxTracer.Storages
                                                                            .Where(s => s.Address == address)
                                                                            .Select(s => s.Index).ToArray());

                _tracer.Accept(collector, stateRoot);
                accountProofs.Add(collector.BuildResult());
            }

            return(accountProofs.ToArray());
        }
        public void Storage_proofs_when_values_are_missing_setup()
        {
            byte[] a = Bytes.FromHexString("0x000000000000000000000000000000000000000000aaaaaaaaaaaaaaaaaaaaaa");
            byte[] b = Bytes.FromHexString("0x0000000000000000000000000bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb");
            byte[] c = Bytes.FromHexString("0x00000000001ccccccccccccccccccccccccccccccccccccccccccccccccccccc");
            byte[] d = Bytes.FromHexString("0x00000000001ddddddddddddddddddddddddddddddddddddddddddddddddddddd");
            byte[] e = Bytes.FromHexString("0x00000000001eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee");

            IDb         memDb       = new MemDb();
            TrieStore   trieStore   = new TrieStore(memDb, LimboLogs.Instance);
            StateTree   tree        = new StateTree(trieStore, LimboLogs.Instance);
            StorageTree storageTree = new StorageTree(trieStore, Keccak.EmptyTreeHash, LimboLogs.Instance);

            storageTree.Set(Keccak.Compute(a).Bytes, Rlp.Encode(Bytes.FromHexString("0xab12000000000000000000000000000000000000000000000000000000000000000000000000000000")));
            storageTree.Set(Keccak.Compute(c).Bytes, Rlp.Encode(Bytes.FromHexString("0xab56000000000000000000000000000000000000000000000000000000000000000000000000000000")));
            storageTree.Set(Keccak.Compute(e).Bytes, Rlp.Encode(Bytes.FromHexString("0xab9a000000000000000000000000000000000000000000000000000000000000000000000000000000")));
            storageTree.Commit(0);

            byte[]  code     = new byte[] { 1, 2, 3 };
            Account account1 = Build.An.Account.WithBalance(1).WithStorageRoot(storageTree.RootHash).TestObject;
            Account account2 = Build.An.Account.WithBalance(2).TestObject;

            tree.Set(TestItem.AddressA, account1);
            tree.Set(TestItem.AddressB, account2);
            tree.Commit(0);

            TreeDumper dumper = new TreeDumper();

            tree.Accept(dumper, tree.RootHash, true);
            Console.WriteLine(dumper.ToString());

            AccountProofCollector accountProofCollector = new AccountProofCollector(TestItem.AddressA, new byte[][] { a, b, c, d, e });

            tree.Accept(accountProofCollector, tree.RootHash, true);
            AccountProof proof = accountProofCollector.BuildResult();

            Assert.AreEqual("0xab12000000000000000000000000000000000000000000000000000000000000000000000000000000", proof.StorageProofs[0].Value?.ToHexString(true) ?? "0x");
            Assert.AreEqual("0x00", proof.StorageProofs[1].Value?.ToHexString(true) ?? "0x");
            Assert.AreEqual("0xab56000000000000000000000000000000000000000000000000000000000000000000000000000000", proof.StorageProofs[2].Value?.ToHexString(true) ?? "0x");
            Assert.AreEqual("0x00", proof.StorageProofs[3].Value?.ToHexString(true) ?? "0x");
            Assert.AreEqual("0xab9a000000000000000000000000000000000000000000000000000000000000000000000000000000", proof.StorageProofs[4].Value?.ToHexString(true) ?? "0x");

            proof.StorageProofs[1].Proof.Should().HaveCount(3);
            proof.StorageProofs[3].Proof.Should().HaveCount(2);
        }
        public void Proof_path_is_filled()
        {
            StateTree tree = new StateTree();

            byte[]  code     = new byte[] { 1, 2, 3 };
            Account account1 = Build.An.Account.WithBalance(1).WithStorageRoot(TestItem.KeccakA).TestObject;
            Account account2 = Build.An.Account.WithBalance(2).TestObject;

            tree.Set(TestItem.AddressA, account1);
            tree.Set(TestItem.AddressB, account2);
            tree.Commit(0);

            AccountProofCollector accountProofCollector = new AccountProofCollector(TestItem.AddressA);

            tree.Accept(accountProofCollector, tree.RootHash, true);
            AccountProof proof = accountProofCollector.BuildResult();

            Assert.AreEqual(3, proof.Proof.Length);
        }
        public void Storage_proofs_length_is_as_expected()
        {
            StateTree tree = new StateTree();

            byte[]  code     = new byte[] { 1, 2, 3 };
            Account account1 = Build.An.Account.WithBalance(1).WithStorageRoot(TestItem.KeccakA).TestObject;
            Account account2 = Build.An.Account.WithBalance(2).TestObject;

            tree.Set(TestItem.AddressA, account1);
            tree.Set(TestItem.AddressB, account2);
            tree.Commit(0);

            AccountProofCollector accountProofCollector = new AccountProofCollector(TestItem.AddressA, new[] { Bytes.FromHexString("0x0000000000000000000000000000000000000000000000000000000000000000"), Bytes.FromHexString("0x0000000000000000000000000000000000000000000000000000000000000001") });

            tree.Accept(accountProofCollector, tree.RootHash, true);
            AccountProof proof = accountProofCollector.BuildResult();

            Assert.AreEqual(2, proof.StorageProofs.Length);
        }
예제 #17
0
        public void Storage_proofs_have_values_set_complex_3_setup()
        {
            byte[] a = Bytes.FromHexString("0x000000000000000000000000000000000000000000aaaaaaaaaaaaaaaaaaaaaa");
            byte[] b = Bytes.FromHexString("0x0000000000000000000000000bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb");
            byte[] c = Bytes.FromHexString("0x00000000001ccccccccccccccccccccccccccccccccccccccccccccccccccccc");
            byte[] d = Bytes.FromHexString("0x00000000001ddddddddddddddddddddddddddddddddddddddddddddddddddddd");
            byte[] e = Bytes.FromHexString("0x00000000001eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee");

            IDb         memDb       = new MemDb();
            StateTree   tree        = new StateTree(memDb);
            StorageTree storageTree = new StorageTree(memDb);

            storageTree.Set(Keccak.Compute(a).Bytes, Rlp.Encode(Bytes.FromHexString("0xab12000000000000000000000000000000000000000000000000000000000000000000000000000000")));
            storageTree.Set(Keccak.Compute(b).Bytes, Rlp.Encode(Bytes.FromHexString("0xab34000000000000000000000000000000000000000000000000000000000000000000000000000000")));
            storageTree.Set(Keccak.Compute(c).Bytes, Rlp.Encode(Bytes.FromHexString("0xab56000000000000000000000000000000000000000000000000000000000000000000000000000000")));
            storageTree.Set(Keccak.Compute(d).Bytes, Rlp.Encode(Bytes.FromHexString("0xab78000000000000000000000000000000000000000000000000000000000000000000000000000000")));
            storageTree.Set(Keccak.Compute(e).Bytes, Rlp.Encode(Bytes.FromHexString("0xab9a000000000000000000000000000000000000000000000000000000000000000000000000000000")));
            storageTree.Commit();

            byte[]  code     = new byte[] { 1, 2, 3 };
            Account account1 = Build.An.Account.WithBalance(1).WithStorageRoot(storageTree.RootHash).TestObject;
            Account account2 = Build.An.Account.WithBalance(2).TestObject;

            tree.Set(TestItem.AddressA, account1);
            tree.Set(TestItem.AddressB, account2);
            tree.Commit();

            TreeDumper dumper = new TreeDumper();

            tree.Accept(dumper, tree.RootHash, true);
            Console.WriteLine(dumper.ToString());

            AccountProofCollector accountProofCollector = new AccountProofCollector(TestItem.AddressA, new byte[][] { a, b, c, d, e });

            tree.Accept(accountProofCollector, tree.RootHash, true);
            AccountProof proof = accountProofCollector.BuildResult();

            Assert.AreEqual("0xab12000000000000000000000000000000000000000000000000000000000000000000000000000000", proof.StorageProofs[0].Value.ToHexString(true));
            Assert.AreEqual("0xab34000000000000000000000000000000000000000000000000000000000000000000000000000000", proof.StorageProofs[1].Value.ToHexString(true));
            Assert.AreEqual("0xab56000000000000000000000000000000000000000000000000000000000000000000000000000000", proof.StorageProofs[2].Value.ToHexString(true));
            Assert.AreEqual("0xab78000000000000000000000000000000000000000000000000000000000000000000000000000000", proof.StorageProofs[3].Value.ToHexString(true));
            Assert.AreEqual("0xab9a000000000000000000000000000000000000000000000000000000000000000000000000000000", proof.StorageProofs[4].Value.ToHexString(true));
        }
예제 #18
0
        public void Non_existing_account_is_valid_even_when_leaf_is_the_last_part_of_the_proof()
        {
            StateTree tree = new StateTree();

            Account account1 = Build.An.Account.WithBalance(1).TestObject;

            tree.Set(TestItem.AddressA, account1);
            tree.Commit();

            AccountProofCollector accountProofCollector = new AccountProofCollector(TestItem.AddressC, new UInt256[] { 1, 2, 3 });

            tree.Accept(accountProofCollector, tree.RootHash, true);
            AccountProof proof = accountProofCollector.BuildResult();

            proof.Proof.Should().HaveCount(1);
            Assert.AreEqual(TestItem.AddressC, proof.Address);
            Assert.AreEqual(Keccak.OfAnEmptyString, proof.CodeHash);
            Assert.AreEqual(Keccak.EmptyTreeHash, proof.StorageRoot);
            Assert.AreEqual(UInt256.Zero, proof.Balance);
            Assert.AreEqual(null, proof.StorageProofs[0].Value);
            Assert.AreEqual(null, proof.StorageProofs[1].Value);
            Assert.AreEqual(null, proof.StorageProofs[2].Value);
        }
        public void Chaotic_test()
        {
            const int accountsCount = 100;

            CryptoRandom random = new CryptoRandom();
            List <AddressWithStorage> addressesWithStorage = new List <AddressWithStorage>();

            for (int i = 0; i < accountsCount; i++)
            {
                AddressWithStorage addressWithStorage = new AddressWithStorage();
                addressWithStorage.StorageCells = new StorageCell[i];
                byte[] addressBytes = random.GenerateRandomBytes(20);
                addressWithStorage.Address = new Address(addressBytes);

                for (int j = 0; j < i; j++)
                {
                    byte[]      storageIndex = random.GenerateRandomBytes(32);
                    UInt256     index        = new UInt256(storageIndex);
                    StorageCell storageCell  = new StorageCell(addressWithStorage.Address, index);
                    addressWithStorage.StorageCells[j] = storageCell;
                }

                addressesWithStorage.Add(addressWithStorage);
            }

            IDb       memDb     = new MemDb();
            TrieStore trieStore = new TrieStore(memDb, LimboLogs.Instance);
            StateTree tree      = new StateTree(trieStore, LimboLogs.Instance);

            for (int i = 0; i < accountsCount; i++)
            {
                Account     account     = Build.An.Account.WithBalance((UInt256)i).TestObject;
                StorageTree storageTree = new StorageTree(trieStore, Keccak.EmptyTreeHash, LimboLogs.Instance);
                for (int j = 0; j < i; j++)
                {
                    storageTree.Set(addressesWithStorage[i].StorageCells[j].Index, new byte[1] {
                        1
                    });
                }

                storageTree.UpdateRootHash();
                storageTree.Commit(0);

                account = account.WithChangedStorageRoot(storageTree.RootHash);
                tree.Set(addressesWithStorage[i].Address, account);
            }

            tree.UpdateRootHash();
            tree.Commit(0);

            for (int i = 0; i < accountsCount; i++)
            {
                AccountProofCollector collector = new AccountProofCollector(addressesWithStorage[i].Address, addressesWithStorage[i].StorageCells.Select(sc => sc.Index).ToArray());
                tree.Accept(collector, tree.RootHash, true);

                AccountProof accountProof = collector.BuildResult();
                accountProof.Address.Should().Be(addressesWithStorage[i].Address);
                accountProof.Balance.Should().Be((UInt256)i);
                accountProof.Nonce.Should().Be(0);
                accountProof.CodeHash.Should().Be(Keccak.OfAnEmptyString);
                if (i != 0)
                {
                    accountProof.StorageRoot.Should().NotBe(Keccak.EmptyTreeHash);
                }
                accountProof.StorageProofs.Length.Should().Be(i);

                for (int j = 0; j < i; j++)
                {
                    byte[] indexBytes = new byte[32];
                    addressesWithStorage[i].StorageCells[j].Index.ToBigEndian(indexBytes.AsSpan());
                    accountProof.StorageProofs[j].Key.ToHexString().Should().Be(indexBytes.ToHexString(), $"{i} {j}");

                    TrieNode node = new TrieNode(NodeType.Unknown, accountProof.StorageProofs[j].Proof.Last());
                    node.ResolveNode(null);
                    // TestContext.Write($"|[{i},{j}]");
                    if (node.Value.Length != 1)
                    {
                        TestContext.WriteLine();
                        TestContext.WriteLine(addressesWithStorage[i].Address);
                        TestContext.WriteLine(i);
                        foreach (StorageCell storageCell in addressesWithStorage[i].StorageCells)
                        {
                            TestContext.WriteLine("storage: " + storageCell.Index);
                        }
                    }

                    node.Value.Should().BeEquivalentTo(new byte[] { 1 });
                }
            }
        }
        public void _Test_storage_failed_case(string historicallyFailingCase)
        {
            string[] lines        = historicallyFailingCase.Split(Environment.NewLine);
            int      storageCount = lines.Length - 2;

            IDb       memDb     = new MemDb();
            TrieStore trieStore = new TrieStore(memDb, LimboLogs.Instance);
            StateTree tree      = new StateTree(trieStore, LimboLogs.Instance);

            Address address      = new Address(Bytes.FromHexString(lines[0]));
            int     accountIndex = int.Parse(lines[1]);

            UInt256[] indexes = new UInt256[storageCount];
            for (int j = 0; j < storageCount; j++)
            {
                indexes[j] = UInt256.Parse(lines[j + 2].Replace("storage: ", string.Empty));
            }

            AddressWithStorage addressWithStorage = new AddressWithStorage();

            addressWithStorage.StorageCells = new StorageCell[storageCount];
            addressWithStorage.Address      = address;

            StorageTree storageTree = new StorageTree(trieStore, Keccak.EmptyTreeHash, LimboLogs.Instance);

            for (int j = 0; j < storageCount; j++)
            {
                UInt256     index       = UInt256.Parse(lines[j + 2].Replace("storage: ", string.Empty));
                StorageCell storageCell = new StorageCell(address, index);
                addressWithStorage.StorageCells[j] = storageCell;
                byte[] rawKey = new byte[32];
                addressWithStorage.StorageCells[j].Index.ToBigEndian(rawKey);
                TestContext.WriteLine($"Set {Keccak.Compute(rawKey).Bytes.ToHexString()}");
                storageTree.Set(addressWithStorage.StorageCells[j].Index, new byte[] { 1 });
                storageTree.UpdateRootHash();
                storageTree.Commit(0);
            }

            Account account = Build.An.Account.WithBalance((UInt256)accountIndex).WithStorageRoot(storageTree.RootHash).TestObject;

            tree.Set(addressWithStorage.Address, account);

            tree.UpdateRootHash();
            tree.Commit(0);

            TreeDumper treeDumper = new TreeDumper();

            tree.Accept(treeDumper, tree.RootHash, true);
            TestContext.WriteLine(treeDumper.ToString());

            AccountProofCollector collector = new AccountProofCollector(address, indexes);

            tree.Accept(collector, tree.RootHash, true);

            AccountProof accountProof = collector.BuildResult();

            accountProof.Address.Should().Be(address);
            accountProof.Balance.Should().Be((UInt256)accountIndex);
            accountProof.Nonce.Should().Be(0);
            accountProof.CodeHash.Should().Be(Keccak.OfAnEmptyString);
            if (accountIndex != 0)
            {
                accountProof.StorageRoot.Should().NotBe(Keccak.EmptyTreeHash);
            }
            accountProof.StorageProofs.Length.Should().Be(accountIndex);

            for (int j = 0; j < accountProof.StorageProofs.Length; j++)
            {
                TrieNode node = new TrieNode(NodeType.Unknown, accountProof.StorageProofs[j].Proof.Last());
                node.ResolveNode(new TrieStore(memDb, NullLogManager.Instance));
                if (node.Value.Length != 1)
                {
                    TestContext.WriteLine($"{j}");
                    // throw new InvalidDataException($"{j}");
                }
            }
        }