public void Keep_in_cache()
        {
            StateProvider provider = new StateProvider(new StateDb(new MemDb()), Substitute.For <IDb>(), Logger);

            provider.CreateAccount(_address1, 0);
            provider.Commit(Frontier.Instance);
            provider.GetBalance(_address1);
            provider.AddToBalance(_address1, 1, Frontier.Instance);
            provider.Restore(-1);
            provider.AddToBalance(_address1, 1, Frontier.Instance);
            provider.Restore(-1);
            provider.AddToBalance(_address1, 1, Frontier.Instance);
            provider.Restore(-1);
            Assert.AreEqual(UInt256.Zero, provider.GetBalance(_address1));
        }
示例#2
0
        public async Task Can_ask_about_storage_in_parallel()
        {
            StorageCell     storageCell     = new StorageCell(_address1, UInt256.One);
            IReleaseSpec    spec            = MuirGlacier.Instance;
            MemDb           stateDb         = new MemDb();
            TrieStore       trieStore       = new TrieStore(stateDb, Logger);
            StateProvider   provider        = new StateProvider(trieStore, new MemDb(), Logger);
            StorageProvider storageProvider = new StorageProvider(trieStore, provider, Logger);

            void UpdateStorageValue(byte[] newValue)
            {
                storageProvider.Set(storageCell, newValue);
            }

            void AddOneToBalance()
            {
                provider.AddToBalance(_address1, 1, spec);
            }

            void CommitEverything()
            {
                storageProvider.Commit();
                storageProvider.CommitTrees(0);
                provider.Commit(spec);
                provider.CommitTree(0);
            }

            provider.CreateAccount(_address1, 1);
            CommitEverything();

            AddOneToBalance();
            UpdateStorageValue(new byte[] { 1 });
            CommitEverything();
            Keccak stateRoot0 = provider.StateRoot;

            AddOneToBalance();
            UpdateStorageValue(new byte[] { 2 });
            CommitEverything();
            Keccak stateRoot1 = provider.StateRoot;

            AddOneToBalance();
            UpdateStorageValue(new byte[] { 3 });
            CommitEverything();
            Keccak stateRoot2 = provider.StateRoot;

            AddOneToBalance();
            UpdateStorageValue(new byte[] { 4 });
            CommitEverything();
            Keccak stateRoot3 = provider.StateRoot;

            StateReader reader =
                new StateReader(new TrieStore(stateDb, LimboLogs.Instance), Substitute.For <IDb>(), Logger);

            Task a = StartStorageTask(reader, stateRoot0, storageCell, new byte[] { 1 });
            Task b = StartStorageTask(reader, stateRoot1, storageCell, new byte[] { 2 });
            Task c = StartStorageTask(reader, stateRoot2, storageCell, new byte[] { 3 });
            Task d = StartStorageTask(reader, stateRoot3, storageCell, new byte[] { 4 });

            await Task.WhenAll(a, b, c, d);
        }
示例#3
0
        public async Task Can_ask_about_balance_in_parallel()
        {
            IReleaseSpec  spec     = MainnetSpecProvider.Instance.GetSpec(MainnetSpecProvider.ConstantinopleFixBlockNumber);
            MemDb         stateDb  = new MemDb();
            StateProvider provider =
                new StateProvider(new TrieStore(stateDb, Logger), Substitute.For <IDb>(), Logger);

            provider.CreateAccount(_address1, 0);
            provider.AddToBalance(_address1, 1, spec);
            provider.Commit(spec);
            provider.CommitTree(0);
            Keccak stateRoot0 = provider.StateRoot;

            provider.AddToBalance(_address1, 1, spec);
            provider.Commit(spec);
            provider.CommitTree(0);
            Keccak stateRoot1 = provider.StateRoot;

            provider.AddToBalance(_address1, 1, spec);
            provider.Commit(spec);
            provider.CommitTree(0);
            Keccak stateRoot2 = provider.StateRoot;

            provider.AddToBalance(_address1, 1, spec);
            provider.Commit(spec);
            provider.CommitTree(0);
            Keccak stateRoot3 = provider.StateRoot;

            provider.CommitTree(0);

            StateReader reader =
                new StateReader(new TrieStore(stateDb, LimboLogs.Instance), Substitute.For <IDb>(), Logger);

            Task a = StartTask(reader, stateRoot0, 1);
            Task b = StartTask(reader, stateRoot1, 2);
            Task c = StartTask(reader, stateRoot2, 3);
            Task d = StartTask(reader, stateRoot3, 4);

            await Task.WhenAll(a, b, c, d);
        }
        public void Eip_158_zero_value_transfer_deletes()
        {
            StateTree     tree             = new StateTree(new MemDb());
            StateProvider frontierProvider = new StateProvider(tree, Substitute.For <IDb>(), Logger);

            frontierProvider.CreateAccount(_address1, 0);
            frontierProvider.Commit(Frontier.Instance);
            StateProvider provider = new StateProvider(tree, Substitute.For <IDb>(), Logger);

            provider.AddToBalance(_address1, 0, SpuriousDragon.Instance);
            provider.Commit(SpuriousDragon.Instance);
            Assert.False(provider.AccountExists(_address1));
        }
        public void Touch_empty_trace_does_not_throw()
        {
            ParityLikeTxTracer tracer = new ParityLikeTxTracer(Build.A.Block.TestObject, null, ParityTraceTypes.StateDiff);

            StateProvider provider = new StateProvider(new StateDb(new MemDb()), Substitute.For <IDb>(), Logger);

            provider.CreateAccount(_address1, 0);
            Account account = provider.GetAccount(_address1);

            Assert.True(account.IsEmpty);
            provider.Commit(Frontier.Instance); // commit empty account (before the empty account fix in Spurious Dragon)
            Assert.True(provider.AccountExists(_address1));

            provider.Reset();                                             // clear all caches

            provider.GetBalance(_address1);                               // justcache
            provider.AddToBalance(_address1, 0, SpuriousDragon.Instance); // touch
            Assert.DoesNotThrow(() => provider.Commit(SpuriousDragon.Instance, tracer));
        }
示例#6
0
        public void Eip_158_zero_value_transfer_deletes()
        {
            var           trieStore        = new TrieStore(new MemDb(), Logger);
            StateProvider frontierProvider = new StateProvider(trieStore, _codeDb, Logger);

            frontierProvider.CreateAccount(_address1, 0);
            frontierProvider.Commit(Frontier.Instance);
            frontierProvider.CommitTree(0);

            StateProvider provider = new StateProvider(trieStore, _codeDb, Logger);

            provider.StateRoot = frontierProvider.StateRoot;

            provider.AddToBalance(_address1, 0, SpuriousDragon.Instance);
            provider.Commit(SpuriousDragon.Instance);
            Assert.False(provider.AccountExists(_address1));

            _codeDb = Substitute.For <IDb>();
        }
        public void Restore_in_the_middle()
        {
            byte[] code = new byte[] { 1 };

            StateProvider provider = new StateProvider(new StateDb(new MemDb()), Substitute.For <IDb>(), Logger);

            provider.CreateAccount(_address1, 1);
            provider.AddToBalance(_address1, 1, Frontier.Instance);
            provider.IncrementNonce(_address1);
            Keccak codeHash = provider.UpdateCode(new byte[] { 1 });

            provider.UpdateCodeHash(_address1, codeHash, Frontier.Instance);
            provider.UpdateStorageRoot(_address1, Hash2);

            Assert.AreEqual(UInt256.One, provider.GetNonce(_address1));
            Assert.AreEqual(UInt256.One + 1, provider.GetBalance(_address1));
            Assert.AreEqual(code, provider.GetCode(_address1));
            provider.Restore(4);
            Assert.AreEqual(UInt256.One, provider.GetNonce(_address1));
            Assert.AreEqual(UInt256.One + 1, provider.GetBalance(_address1));
            Assert.AreEqual(code, provider.GetCode(_address1));
            provider.Restore(3);
            Assert.AreEqual(UInt256.One, provider.GetNonce(_address1));
            Assert.AreEqual(UInt256.One + 1, provider.GetBalance(_address1));
            Assert.AreEqual(code, provider.GetCode(_address1));
            provider.Restore(2);
            Assert.AreEqual(UInt256.One, provider.GetNonce(_address1));
            Assert.AreEqual(UInt256.One + 1, provider.GetBalance(_address1));
            Assert.AreEqual(new byte[0], provider.GetCode(_address1));
            provider.Restore(1);
            Assert.AreEqual(UInt256.Zero, provider.GetNonce(_address1));
            Assert.AreEqual(UInt256.One + 1, provider.GetBalance(_address1));
            Assert.AreEqual(new byte[0], provider.GetCode(_address1));
            provider.Restore(0);
            Assert.AreEqual(UInt256.Zero, provider.GetNonce(_address1));
            Assert.AreEqual(UInt256.One, provider.GetBalance(_address1));
            Assert.AreEqual(new byte[0], provider.GetCode(_address1));
            provider.Restore(-1);
            Assert.AreEqual(false, provider.AccountExists(_address1));
        }
        public void Restore_update_restore()
        {
            StateProvider provider = new StateProvider(new StateDb(new MemDb()), Substitute.For <IDb>(), Logger);

            provider.CreateAccount(_address1, 0);
            provider.AddToBalance(_address1, 1, Frontier.Instance);
            provider.AddToBalance(_address1, 1, Frontier.Instance);
            provider.AddToBalance(_address1, 1, Frontier.Instance);
            provider.AddToBalance(_address1, 1, Frontier.Instance);
            provider.AddToBalance(_address1, 1, Frontier.Instance);
            provider.AddToBalance(_address1, 1, Frontier.Instance);
            provider.AddToBalance(_address1, 1, Frontier.Instance);
            provider.AddToBalance(_address1, 1, Frontier.Instance);
            provider.Restore(4);
            provider.AddToBalance(_address1, 1, Frontier.Instance);
            provider.AddToBalance(_address1, 1, Frontier.Instance);
            provider.AddToBalance(_address1, 1, Frontier.Instance);
            provider.AddToBalance(_address1, 1, Frontier.Instance);
            provider.AddToBalance(_address1, 1, Frontier.Instance);
            provider.AddToBalance(_address1, 1, Frontier.Instance);
            provider.AddToBalance(_address1, 1, Frontier.Instance);
            provider.AddToBalance(_address1, 1, Frontier.Instance);
            provider.Restore(4);
            Assert.AreEqual((UInt256)4, provider.GetBalance(_address1));
        }
        public void Update_balance_on_non_existing_acccount_throws()
        {
            StateProvider provider = new StateProvider(new StateDb(new MemDb()), Substitute.For <IDb>(), Logger);

            Assert.Throws <InvalidOperationException>(() => provider.AddToBalance(TestItem.AddressA, 1.Ether(), Olympic.Instance));
        }
示例#10
0
        // [TestCase(8, 32, 8, 1543322391)]
        public void Fuzz_accounts_with_storage(
            int accountsCount,
            int blocksCount,
            int lookupLimit,
            int?seed)
        {
            int usedSeed = seed ?? _random.Next(int.MaxValue);

            _random = new Random(usedSeed);
            _logger.Info($"RANDOM SEED {usedSeed}");

            string fileName = Path.GetTempFileName();

            //string fileName = "C:\\Temp\\fuzz.txt";
            _logger.Info(
                $"Fuzzing with accounts: {accountsCount}, " +
                $"blocks {blocksCount}, " +
                $"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);
            StateProvider   stateProvider   = new StateProvider(trieStore, new MemDb(), _logManager);
            StorageProvider storageProvider = new StorageProvider(trieStore, stateProvider, _logManager);

            Account[] accounts  = new Account[accountsCount];
            Address[] addresses = new Address[accountsCount];

            for (int i = 0; i < accounts.Length; i++)
            {
                bool isEmptyValue = _random.Next(0, 2) == 0;
                if (isEmptyValue)
                {
                    accounts[i] = Account.TotallyEmpty;
                }
                else
                {
                    accounts[i] = GenerateRandomAccount();
                }

                addresses[i] = TestItem.GetRandomAddress(_random);
            }

            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 randomAddressIndex = _random.Next(addresses.Length);
                        int randomAccountIndex = _random.Next(accounts.Length);

                        Address address = addresses[randomAddressIndex];
                        Account account = accounts[randomAccountIndex];

                        if (stateProvider.AccountExists(address))
                        {
                            Account existing = stateProvider.GetAccount(address);
                            if (existing.Balance != account.Balance)
                            {
                                if (account.Balance > existing.Balance)
                                {
                                    stateProvider.AddToBalance(
                                        address, account.Balance - existing.Balance, MuirGlacier.Instance);
                                }
                                else
                                {
                                    stateProvider.SubtractFromBalance(
                                        address, existing.Balance - account.Balance, MuirGlacier.Instance);
                                }

                                stateProvider.IncrementNonce(address);
                            }

                            byte[] storage = new byte[1];
                            _random.NextBytes(storage);
                            storageProvider.Set(new StorageCell(address, 1), storage);
                        }
                        else if (!account.IsTotallyEmpty)
                        {
                            stateProvider.CreateAccount(address, account.Balance);

                            byte[] storage = new byte[1];
                            _random.NextBytes(storage);
                            storageProvider.Set(new StorageCell(address, 1), storage);
                        }
                    }
                }

                streamWriter.WriteLine(
                    $"Commit block {blockNumber} | empty: {isEmptyBlock}");

                storageProvider.Commit();
                stateProvider.Commit(MuirGlacier.Instance);

                storageProvider.CommitTrees(blockNumber);
                stateProvider.CommitTree(blockNumber);
                rootQueue.Enqueue(stateProvider.StateRoot);
            }

            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
                {
                    stateProvider.StateRoot = currentRoot;
                    for (int i = 0; i < addresses.Length; i++)
                    {
                        Account account = stateProvider.GetAccount(addresses[i]);
                        if (account != null)
                        {
                            for (int j = 0; j < 256; j++)
                            {
                                storageProvider.Get(new StorageCell(addresses[i], (UInt256)j));
                            }
                        }
                    }

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

                verifiedBlocks++;
            }
        }