Пример #1
0
        public void Scenario_traverse_leaf_read_missing()
        {
            MemDb     db   = new MemDb();
            StateTree tree = new StateTree(new TrieStore(db, LimboLogs.Instance), LimboLogs.Instance);

            tree.Set(new Keccak("1111111111111111111111111111111111111111111111111111111111111111"), _account0);
            Account account = tree.Get(new Keccak("111111111111111111111111111111111111111111111111111111111ddddddd"));

            Assert.Null(account);
            tree.UpdateRootHash();
            Keccak rootHash = tree.RootHash;

            Assert.AreEqual("0x491fbb33aaff22c0a7ff68d5c81ec114dddf89d022ccdee838a0e9d6cd45cab4", rootHash.ToString(true));
            tree.Commit(0);
            Assert.AreEqual("0x491fbb33aaff22c0a7ff68d5c81ec114dddf89d022ccdee838a0e9d6cd45cab4", rootHash.ToString(true));
        }
Пример #2
0
        public void Create_commit_change_balance_get()
        {
            Account   account   = new Account(1);
            StateTree stateTree = new StateTree();

            stateTree.Set(TestItem.AddressA, account);
            stateTree.Commit(0);

            account = account.WithChangedBalance(2);
            stateTree.Set(TestItem.AddressA, account);
            stateTree.Commit(0);

            Account accountRestored = stateTree.Get(TestItem.AddressA);

            Assert.AreEqual((UInt256)2, accountRestored.Balance);
        }
Пример #3
0
        public void Scenario_traverse_leaf_delete_matching_leaf()
        {
            MemDb     db   = new MemDb();
            StateTree tree = new StateTree(db);

            tree.Set(new Keccak("1111111111111111111111111111111111111111111111111111111111111111"), _account0);
            Account account = tree.Get(new Keccak("1111111111111111111111111111111111111111111111111111111111111111"));

            Assert.NotNull(account);
            tree.UpdateRootHash();
            Keccak rootHash = tree.RootHash;

            Assert.AreEqual("0x491fbb33aaff22c0a7ff68d5c81ec114dddf89d022ccdee838a0e9d6cd45cab4", rootHash.ToString(true));
            tree.Commit();
            Assert.AreEqual("0x491fbb33aaff22c0a7ff68d5c81ec114dddf89d022ccdee838a0e9d6cd45cab4", rootHash.ToString(true));
        }
Пример #4
0
        public void Scenario_traverse_branch_read_missing()
        {
            MemDb     db   = new MemDb();
            StateTree tree = new StateTree(new TrieStore(db, LimboLogs.Instance), LimboLogs.Instance);

            tree.Set(new Keccak("eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeb00000"), _account0);
            tree.Set(new Keccak("eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeb11111"), _account1);
            Account account = tree.Get(new Keccak("eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeb22222"));

            Assert.Null(account);
            tree.UpdateRootHash();
            Keccak rootHash = tree.RootHash;

            Assert.AreEqual("0x94a193704e99c219d9a21428eb37d6d2d71b3d2cea80c77ff0e201c0df70a283", rootHash.ToString(true));
            tree.Commit(0);
            Assert.AreEqual("0x94a193704e99c219d9a21428eb37d6d2d71b3d2cea80c77ff0e201c0df70a283", rootHash.ToString(true));
        }
Пример #5
0
        public void Scenario_traverse_extension_read_missing()
        {
            MemDb     db   = new MemDb();
            StateTree tree = new StateTree(new TrieStore(db, LimboLogs.Instance), LimboLogs.Instance);

            tree.Set(new Keccak("eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeb00000000"), _account0);
            tree.Set(new Keccak("eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeb11111111"), _account1);
            Account account = tree.Get(new Keccak("eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeedddddddddddddddddddddddd"));

            Assert.Null(account);
            tree.UpdateRootHash();
            Keccak rootHash = tree.RootHash;

            Assert.AreEqual("0xf99f1d3234bad8d63d818db36ff63eefc8916263e654db8b800d3bd03f6339a5", rootHash.ToString(true));
            tree.Commit(0);
            Assert.AreEqual("0xf99f1d3234bad8d63d818db36ff63eefc8916263e654db8b800d3bd03f6339a5", rootHash.ToString(true));
        }
Пример #6
0
        public void Scenario_traverse_extension_read_full_match()
        {
            MemDb     db   = new MemDb();
            StateTree tree = new StateTree(db);

            tree.Set(new Keccak("eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeb00000000"), _account0);
            tree.Set(new Keccak("eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeb11111111"), _account1);
            Account account = tree.Get(new Keccak("eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeb11111111"));

            Assert.AreEqual(0, db.ReadsCount);
            Assert.AreEqual(_account1.Balance, account.Balance);
            tree.UpdateRootHash();
            Keccak rootHash = tree.RootHash;

            Assert.AreEqual("0xf99f1d3234bad8d63d818db36ff63eefc8916263e654db8b800d3bd03f6339a5", rootHash.ToString(true));
            tree.Commit();
            Assert.AreEqual("0xf99f1d3234bad8d63d818db36ff63eefc8916263e654db8b800d3bd03f6339a5", rootHash.ToString(true));
        }
Пример #7
0
        public void Create_commit_reset_change_balance_get()
        {
            MemDb     db        = new MemDb();
            Account   account   = new Account(1);
            StateTree stateTree = new StateTree(new TrieStore(db, LimboLogs.Instance), LimboLogs.Instance);

            stateTree.Set(TestItem.AddressA, account);
            stateTree.Commit(0);

            Keccak rootHash = stateTree.RootHash;

            stateTree.RootHash = null;

            stateTree.RootHash = rootHash;
            stateTree.Get(TestItem.AddressA);
            account = account.WithChangedBalance(2);
            stateTree.Set(TestItem.AddressA, account);
            stateTree.Commit(0);

            Assert.AreEqual(2, db.Keys.Count);
        }
Пример #8
0
        public Account GetAccount(Address address, Keccak stateRoot)
        {
            var stateTree = new StateTree(_db, stateRoot);

            return(stateTree.Get(address));
        }
Пример #9
0
        // [TestCase(4, 16, 4, 4)]
        public void Fuzz_accounts(
            int accountsCount,
            int blocksCount,
            int uniqueValuesCount,
            int lookupLimit)
        {
            string fileName = Path.GetTempFileName();

            //string fileName = "C:\\Temp\\fuzz.txt";
            _logger.Info(
                $"Fuzzing with accounts: {accountsCount}, " +
                $"blocks {blocksCount}, " +
                $"values: {uniqueValuesCount}, " +
                $"lookup: {lookupLimit} into file {fileName}");

            using FileStream fileStream     = new FileStream(fileName, FileMode.Create);
            using StreamWriter streamWriter = new StreamWriter(fileStream);

            Queue <Keccak> rootQueue = new Queue <Keccak>();

            MemDb memDb = new MemDb();

            TrieStore trieStore    = new TrieStore(memDb, Prune.WhenCacheReaches(1.MB()), Persist.IfBlockOlderThan(lookupLimit), _logManager);
            StateTree patriciaTree = new StateTree(trieStore, _logManager);

            byte[][] accounts     = new byte[accountsCount][];
            byte[][] randomValues = new byte[uniqueValuesCount][];

            for (int i = 0; i < randomValues.Length; i++)
            {
                bool isEmptyValue = _random.Next(0, 2) == 0;
                if (isEmptyValue)
                {
                    randomValues[i] = Array.Empty <byte>();
                }
                else
                {
                    randomValues[i] = GenerateRandomAccountRlp();
                }
            }

            for (int accountIndex = 0; accountIndex < accounts.Length; accountIndex++)
            {
                byte[] key = new byte[32];
                ((UInt256)accountIndex).ToBigEndian(key);
                accounts[accountIndex] = key;
            }

            for (int blockNumber = 0; blockNumber < blocksCount; blockNumber++)
            {
                bool isEmptyBlock = _random.Next(5) == 0;
                if (!isEmptyBlock)
                {
                    for (int i = 0; i < Math.Max(1, accountsCount / 8); i++)
                    {
                        int randomAccountIndex = _random.Next(accounts.Length);
                        int randomValueIndex   = _random.Next(randomValues.Length);

                        byte[] account = accounts[randomAccountIndex];
                        byte[] value   = randomValues[randomValueIndex];

                        streamWriter.WriteLine(
                            $"Block {blockNumber} - setting {account.ToHexString()} = {value.ToHexString()}");
                        patriciaTree.Set(account, value);
                    }
                }

                streamWriter.WriteLine(
                    $"Commit block {blockNumber} | empty: {isEmptyBlock}");
                patriciaTree.UpdateRootHash();
                patriciaTree.Commit(blockNumber);
                rootQueue.Enqueue(patriciaTree.RootHash);
            }

            streamWriter.Flush();
            fileStream.Seek(0, SeekOrigin.Begin);

            streamWriter.WriteLine($"DB size: {memDb.Keys.Count}");
            _logger.Info($"DB size: {memDb.Keys.Count}");

            int verifiedBlocks = 0;

            while (rootQueue.TryDequeue(out Keccak currentRoot))
            {
                try
                {
                    patriciaTree.RootHash = currentRoot;
                    for (int i = 0; i < accounts.Length; i++)
                    {
                        patriciaTree.Get(accounts[i]);
                    }

                    _logger.Info($"Verified positive {verifiedBlocks}");
                }
                catch (Exception ex)
                {
                    if (verifiedBlocks % lookupLimit == 0)
                    {
                        throw new InvalidDataException(ex.ToString());
                    }
                    else
                    {
                        _logger.Info($"Verified negative {verifiedBlocks}");
                    }
                }

                verifiedBlocks++;
            }
        }