public void Get_storage() { /* all testing will be touching just a single storage cell */ var storageCell = new StorageCell(TestItem.AddressA, 1); /* to start with we need to create an account that we will be setting storage at */ _stateProvider.CreateAccount(storageCell.Address, UInt256.One); _stateProvider.Commit(MuirGlacier.Instance); _stateProvider.CommitTree(); /* at this stage we have an account with empty storage at the address that we want to test */ byte[] initialValue = new byte[] { 1, 2, 3 }; _storageProvider.Set(storageCell, initialValue); _storageProvider.Commit(); _storageProvider.CommitTrees(); _stateProvider.Commit(MuirGlacier.Instance); _stateProvider.CommitTree(); var retrieved = _blockchainBridge.GetStorage(storageCell.Address, storageCell.Index, _stateProvider.StateRoot); retrieved.Should().BeEquivalentTo(initialValue); /* at this stage we set the value in storage to 1,2,3 at the tested storage cell */ /* Now we are testing scenario where the storage is being changed by the block processor. * To do that we create some different storage / state access stack that represents the processor. * It is a different stack of objects than the one that is used by the blockchain bridge. */ byte[] newValue = new byte[] { 1, 2, 3, 4, 5 }; StateProvider processorStateProvider = new StateProvider(_dbProvider.StateDb, _dbProvider.CodeDb, LimboLogs.Instance); processorStateProvider.StateRoot = _stateProvider.StateRoot; StorageProvider processorStorageProvider = new StorageProvider(_dbProvider.StateDb, processorStateProvider, LimboLogs.Instance); processorStorageProvider.Set(storageCell, newValue); processorStorageProvider.Commit(); processorStorageProvider.CommitTrees(); processorStateProvider.Commit(MuirGlacier.Instance); processorStateProvider.CommitTree(); /* At this stage the DB should have the storage value updated to 5. * We will try to retrieve the value by taking the state root from the processor.*/ retrieved = _blockchainBridge.GetStorage(storageCell.Address, storageCell.Index, processorStateProvider.StateRoot); retrieved.Should().BeEquivalentTo(newValue); /* If it failed then it means that the blockchain bridge cached the previous call value */ }
private void InitializeTestState(BlockchainTest test, IStateProvider stateProvider, IStorageProvider storageProvider, ISpecProvider specProvider) { foreach (KeyValuePair <Address, AccountState> accountState in ((IEnumerable <KeyValuePair <Address, AccountState> >)test.Pre ?? Array.Empty <KeyValuePair <Address, AccountState> >())) { foreach (KeyValuePair <UInt256, byte[]> storageItem in accountState.Value.Storage) { storageProvider.Set(new StorageCell(accountState.Key, storageItem.Key), storageItem.Value); } stateProvider.CreateAccount(accountState.Key, accountState.Value.Balance); Keccak codeHash = stateProvider.UpdateCode(accountState.Value.Code); stateProvider.UpdateCodeHash(accountState.Key, codeHash, specProvider.GenesisSpec); for (int i = 0; i < accountState.Value.Nonce; i++) { stateProvider.IncrementNonce(accountState.Key); } } storageProvider.Commit(); stateProvider.Commit(specProvider.GenesisSpec); storageProvider.CommitTrees(0); stateProvider.CommitTree(0); storageProvider.Reset(); stateProvider.Reset(); }
protected async Task Prepare() { _wallet = new DevWallet(new WalletConfig(), _logManager); _feeAccount = _wallet.GetAccounts()[0]; _consumerAccount = _wallet.GetAccounts()[1]; _providerAccount = _wallet.GetAccounts()[2]; _ndmConfig = new NdmConfig(); IReleaseSpec spec = _releaseSpec; ISpecProvider specProvider = new SingleReleaseSpecProvider(spec, 99); StateDb stateDb = new StateDb(); _state = new StateProvider(stateDb, new StateDb(), _logManager); StorageProvider storageProvider = new StorageProvider(stateDb, _state, _logManager); _state.CreateAccount(_consumerAccount, 1000.Ether()); _state.CreateAccount(_providerAccount, 1.Ether()); _state.Commit(spec); _state.CommitTree(); VirtualMachine machine = new VirtualMachine(_state, storageProvider, Substitute.For <IBlockhashProvider>(), specProvider, _logManager); TransactionProcessor processor = new TransactionProcessor(specProvider, _state, storageProvider, machine, _logManager); _bridge = new BlockchainBridge(processor); TxReceipt receipt = await DeployContract(Bytes.FromHexString(ContractData.GetInitCode(_feeAccount))); ((NdmConfig)_ndmConfig).ContractAddress = receipt.ContractAddress.ToString(); _contractAddress = receipt.ContractAddress; _txPool = new TxPool.TxPool(new InMemoryTxStorage(), Timestamper.Default, new EthereumEcdsa(specProvider.ChainId, _logManager), specProvider, new TxPoolConfig(), _state, _logManager); _ndmBridge = new NdmBlockchainBridge(_bridge, _bridge, _bridge, _bridge); }
protected void Prepare() { _wallet = new DevWallet(new WalletConfig(), _logManager); _feeAccount = _wallet.GetAccounts()[0]; _consumerAccount = _wallet.GetAccounts()[1]; _providerAccount = _wallet.GetAccounts()[2]; _ndmConfig = new NdmConfig(); IReleaseSpec spec = _releaseSpec; ISpecProvider specProvider = new SingleReleaseSpecProvider(spec, 99); StateDb stateDb = new StateDb(); _state = new StateProvider(stateDb, new StateDb(), _logManager); StorageProvider storageProvider = new StorageProvider(stateDb, _state, _logManager); _state.CreateAccount(_consumerAccount, 1000.Ether()); _state.CreateAccount(_providerAccount, 1.Ether()); _state.Commit(spec); _state.CommitTree(); VirtualMachine machine = new VirtualMachine(_state, storageProvider, Substitute.For <IBlockhashProvider>(), _logManager); TransactionProcessor processor = new TransactionProcessor(specProvider, _state, storageProvider, machine, _logManager); _bridge = new BlockchainBridge(processor, _releaseSpec); TxReceipt receipt = DeployContract(Bytes.FromHexString(ContractData.GetInitCode(_feeAccount))); _ndmConfig.ContractAddress = receipt.ContractAddress.ToString(); }
public void Commit_trees_clear_caches_get_previous_root() { // block 1 StorageProvider storageProvider = BuildStorageProvider(); storageProvider.Set(new StorageCell(_address1, 1), _values[1]); storageProvider.Commit(); _stateProvider.Commit(Frontier.Instance); storageProvider.CommitTrees(); _stateProvider.CommitTree(); // block 2 Keccak stateRoot = _stateProvider.StateRoot; storageProvider.Set(new StorageCell(_address1, 1), _values[2]); storageProvider.Commit(); _stateProvider.Commit(Frontier.Instance); // revert _stateProvider.Reset(); storageProvider.Reset(); _stateProvider.StateRoot = stateRoot; byte[] valueAfter = storageProvider.Get(new StorageCell(_address1, 1)); Assert.AreEqual(_values[1], valueAfter); }
private void InitializeTestState(GeneralStateTest test, IStateProvider stateProvider, IStorageProvider storageProvider, ISpecProvider specProvider) { foreach (KeyValuePair <Address, AccountState> accountState in test.Pre) { foreach (KeyValuePair <UInt256, byte[]> storageItem in accountState.Value.Storage) { storageProvider.Set(new StorageCell(accountState.Key, storageItem.Key), storageItem.Value.WithoutLeadingZeros().ToArray()); } stateProvider.CreateAccount(accountState.Key, accountState.Value.Balance); Keccak codeHash = stateProvider.UpdateCode(accountState.Value.Code); stateProvider.UpdateCodeHash(accountState.Key, codeHash, specProvider.GenesisSpec); for (int i = 0; i < accountState.Value.Nonce; i++) { stateProvider.IncrementNonce(accountState.Key); } } storageProvider.Commit(); stateProvider.Commit(specProvider.GenesisSpec); storageProvider.CommitTrees(); stateProvider.CommitTree(); storageProvider.Reset(); stateProvider.Reset(); }
public Block Load() { Block genesis = _chainSpec.Genesis; foreach ((Address address, ChainSpecAllocation allocation) in _chainSpec.Allocations.OrderBy(a => a.Key)) { _stateProvider.CreateAccount(address, allocation.Balance); if (allocation.Code != null) { Keccak codeHash = _stateProvider.UpdateCode(allocation.Code); _stateProvider.UpdateCodeHash(address, codeHash, _specProvider.GenesisSpec); } if (allocation.Storage != null) { foreach (KeyValuePair <UInt256, byte[]> storage in allocation.Storage) { _storageProvider.Set(new StorageCell(address, storage.Key), storage.Value.WithoutLeadingZeros().ToArray()); } } if (allocation.Constructor != null) { Transaction constructorTransaction = new SystemTransaction() { SenderAddress = address, Init = allocation.Constructor, GasLimit = genesis.GasLimit }; CallOutputTracer outputTracer = new CallOutputTracer(); _transactionProcessor.Execute(constructorTransaction, genesis.Header, outputTracer); if (outputTracer.StatusCode != StatusCode.Success) { throw new InvalidOperationException($"Failed to initialize constructor for address {address}. Error: {outputTracer.Error}"); } } } // we no longer need the allocations - 0.5MB RAM, 9000 objects for mainnet _chainSpec.Allocations = null; _storageProvider.Commit(); _stateProvider.Commit(_specProvider.GenesisSpec); _storageProvider.CommitTrees(); _stateProvider.CommitTree(); _dbProvider.StateDb.Commit(); _dbProvider.CodeDb.Commit(); genesis.Header.StateRoot = _stateProvider.StateRoot; genesis.Header.Hash = genesis.Header.CalculateHash(); return(genesis); }
public Block[] Process(Keccak branchStateRoot, Block[] suggestedBlocks, ProcessingOptions options, IBlockTracer blockTracer) { if (_logger.IsTrace) { _logger.Trace($"Processing block {suggestedBlocks[0].Number} from state root: {branchStateRoot}"); } if (suggestedBlocks.Length == 0) { return(Array.Empty <Block>()); } int stateSnapshot = _stateDb.TakeSnapshot(); int codeSnapshot = _codeDb.TakeSnapshot(); Keccak snapshotStateRoot = _stateProvider.StateRoot; if (branchStateRoot != null && _stateProvider.StateRoot != branchStateRoot) { /* discarding the other branch data - chain reorganization */ Metrics.Reorganizations++; _storageProvider.Reset(); _stateProvider.Reset(); _stateProvider.StateRoot = branchStateRoot; } var processedBlocks = new Block[suggestedBlocks.Length]; try { for (int i = 0; i < suggestedBlocks.Length; i++) { processedBlocks[i] = ProcessOne(suggestedBlocks[i], options, blockTracer); if (_logger.IsTrace) { _logger.Trace($"Committing trees - state root {_stateProvider.StateRoot}"); } _stateProvider.CommitTree(); _storageProvider.CommitTrees(); } if ((options & ProcessingOptions.ReadOnlyChain) != 0) { Restore(stateSnapshot, codeSnapshot, snapshotStateRoot); } else { _stateDb.Commit(); _codeDb.Commit(); } return(processedBlocks); } catch (InvalidBlockException) { Restore(stateSnapshot, codeSnapshot, snapshotStateRoot); throw; } }
private void PreCommitBlock(Keccak newBranchStateRoot) { if (_logger.IsTrace) { _logger.Trace($"Committing the branch - {newBranchStateRoot} | {_stateProvider.StateRoot}"); } _stateProvider.CommitTree(); _storageProvider.CommitTrees(); }
private Block ProcessOne(Block suggestedBlock, bool tryOnly) { Block processedBlock = suggestedBlock; if (!suggestedBlock.IsGenesis) { processedBlock = ProcessNonGenesis(suggestedBlock, tryOnly); } _stateProvider.CommitTree(); _storageProvider.CommitTrees(); return(processedBlock); }
public void Setup() { MemDb stateDb = new(); TrieStore trieStore = new(stateDb, LimboLogs.Instance); _stateProvider = new StateProvider(trieStore, new MemDb(), LimboLogs.Instance); _stateProvider.CreateAccount(TestItem.AddressA, 1.Ether()); _stateProvider.Commit(_specProvider.GenesisSpec); _stateProvider.CommitTree(0); StorageProvider storageProvider = new(trieStore, _stateProvider, LimboLogs.Instance); VirtualMachine virtualMachine = new(TestBlockhashProvider.Instance, _specProvider, LimboLogs.Instance); _transactionProcessor = new TransactionProcessor(_specProvider, _stateProvider, storageProvider, virtualMachine, LimboLogs.Instance); _ethereumEcdsa = new EthereumEcdsa(_specProvider.ChainId, LimboLogs.Instance); }
protected async Task Prepare() { _wallet = new DevWallet(new WalletConfig(), _logManager); _feeAccount = _wallet.GetAccounts()[0]; _consumerAccount = _wallet.GetAccounts()[1]; _providerAccount = _wallet.GetAccounts()[2]; _ndmConfig = new NdmConfig(); IReleaseSpec spec = _releaseSpec; ISpecProvider specProvider = new SingleReleaseSpecProvider(spec, 99); MemDb stateDb = new MemDb(); TrieStore trieStore = new TrieStore(stateDb, _logManager); _state = new StateProvider(trieStore, new MemDb(), _logManager); StorageProvider storageProvider = new StorageProvider(trieStore, _state, _logManager); _state.CreateAccount(_consumerAccount, 1000.Ether()); _state.CreateAccount(_providerAccount, 1.Ether()); _state.Commit(spec); _state.CommitTree(0); VirtualMachine machine = new VirtualMachine(Substitute.For <IBlockhashProvider>(), specProvider, _logManager); TransactionProcessor processor = new TransactionProcessor(specProvider, _state, storageProvider, machine, _logManager); _bridge = new BlockchainBridge(processor); TxReceipt receipt = await DeployContract(Bytes.FromHexString(ContractData.GetInitCode(_feeAccount))); ((NdmConfig)_ndmConfig).ContractAddress = receipt.ContractAddress.ToString(); _contractAddress = receipt.ContractAddress; IBlockTree blockTree = Substitute.For <IBlockTree>(); Block block = Build.A.Block.WithNumber(0).TestObject; blockTree.Head.Returns(block); TransactionComparerProvider transactionComparerProvider = new TransactionComparerProvider(specProvider, blockTree); _txPool = new TxPool.TxPool( new EthereumEcdsa(specProvider.ChainId, _logManager), new ChainHeadInfoProvider(specProvider, blockTree, _state), new TxPoolConfig(), new TxValidator(specProvider.ChainId), _logManager, transactionComparerProvider.GetDefaultComparer()); _ndmBridge = new NdmBlockchainBridge(_bridge, _bridge, _bridge, _bridge); }
private Block ProcessOne(Block suggestedBlock, bool tryOnly) { IDb db = _dbProvider.GetOrCreateStateDb(); Block processedBlock = suggestedBlock; if (!suggestedBlock.IsGenesis) { processedBlock = ProcessNonGenesis(suggestedBlock, tryOnly); } db.StartBatch(); _stateProvider.CommitTree(); _storageProvider.CommitTrees(); db.CommitBatch(); _dbProvider.Commit(_specProvider.GetSpec(suggestedBlock.Number)); return(processedBlock); }
public Block Load() { Block genesis = _chainSpec.Genesis; foreach ((Address address, ChainSpecAllocation allocation) in _chainSpec.Allocations) { _stateProvider.CreateAccount(address, allocation.Balance); if (allocation.Code != null) { Keccak codeHash = _stateProvider.UpdateCode(allocation.Code); _stateProvider.UpdateCodeHash(address, codeHash, _specProvider.GenesisSpec); } if (allocation.Constructor != null) { Transaction constructorTransaction = new SystemTransaction() { SenderAddress = address, Init = allocation.Constructor, GasLimit = genesis.GasLimit }; _transactionProcessor.Execute(constructorTransaction, genesis.Header, NullTxTracer.Instance); } } // we no longer need the allocations - 0.5MB RAM, 9000 objects for mainnet _chainSpec.Allocations = null; _storageProvider.Commit(); _stateProvider.Commit(_specProvider.GenesisSpec); _storageProvider.CommitTrees(); _stateProvider.CommitTree(); _dbProvider.StateDb.Commit(); _dbProvider.CodeDb.Commit(); genesis.Header.StateRoot = _stateProvider.StateRoot; genesis.Header.Hash = genesis.Header.CalculateHash(); return(genesis); }
public Block Load() { Block genesis = _chainSpec.Genesis; Preallocate(genesis); // we no longer need the allocations - 0.5MB RAM, 9000 objects for mainnet _chainSpec.Allocations = null; _storageProvider.Commit(); _stateProvider.Commit(_specProvider.GenesisSpec); _storageProvider.CommitTrees(0); _stateProvider.CommitTree(0); genesis.Header.StateRoot = _stateProvider.StateRoot; genesis.Header.Hash = genesis.Header.CalculateHash(); return(genesis); }
private void Execute(Delta delta, ITxTracer txTracer, bool readOnly) { var stateUpdate = ToStateUpdate(delta); // revert state if any fails (take snapshot) foreach (var publicEntry in delta.PublicEntries) { Execute(publicEntry, stateUpdate, txTracer); } var spec = _specProvider.GetSpec(stateUpdate.Number); _storageProvider.Commit(txTracer.IsTracingState ? txTracer : null); _stateProvider.Commit(spec, txTracer.IsTracingState ? txTracer : null); _stateProvider.RecalculateStateRoot(); if (!readOnly) { if (new Keccak(delta.StateRoot.ToByteArray()) != _stateProvider.StateRoot) { if (_logger.IsEnabled(LogEventLevel.Error)) { _logger.Error("Invalid delta state root - found {found} and should be {shouldBe}", _stateProvider.StateRoot, new Keccak(delta.StateRoot.ToByteArray())); } } // compare state roots _storageProvider.CommitTrees(); _stateProvider.CommitTree(); } else { delta.StateRoot = _stateProvider.StateRoot.ToByteString(); if (_logger.IsEnabled(LogEventLevel.Debug)) { _logger.Debug($"Setting candidate delta {delta.DeltaNumber} root to {delta.StateRoot.ToKeccak()}"); } _stateProvider.Reset(); _storageProvider.Reset(); } }
public DeltaCache(IHashProvider hashProvider, IMemoryCache memoryCache, IDeltaDfsReader dfsReader, IDeltaCacheChangeTokenProvider changeTokenProvider, IStorageProvider storageProvider, IStateProvider stateProvider, ISnapshotableDb stateDb, IDeltaIndexService deltaIndexService, ILogger logger) { _deltaIndexService = deltaIndexService; stateProvider.CreateAccount(TruffleTestAccount, 1_000_000_000.Kat()); stateProvider.CreateAccount(CatalystTruffleTestAccount, 1_000_000_000.Kat()); storageProvider.Commit(); stateProvider.Commit(CatalystGenesisSpec.Instance); storageProvider.CommitTrees(); stateProvider.CommitTree(); stateDb.Commit(); var genesisDelta = new Delta { TimeStamp = Timestamp.FromDateTime(DateTime.UnixEpoch), StateRoot = ByteString.CopyFrom(stateProvider.StateRoot.Bytes), }; GenesisHash = hashProvider.ComputeMultiHash(genesisDelta).ToCid(); _dfsReader = dfsReader; _logger = logger; _entryOptions = () => new MemoryCacheEntryOptions() .AddExpirationToken(changeTokenProvider.GetChangeToken()) .RegisterPostEvictionCallback(EvictionCallback); _memoryCache = memoryCache; _memoryCache.Set(GenesisHash, genesisDelta); }
private void Execute(Delta delta, ITxTracer txTracer, bool readOnly) { var stateUpdate = ToStateUpdate(delta); // revert state if any fails (take snapshot) foreach (var publicEntry in delta.PublicEntries) { Execute(publicEntry, stateUpdate, txTracer, readOnly); } if (!readOnly) { // we should assign block rewards here (or in Ledger) _stateProvider.CommitTree(); _storageProvider.CommitTrees(); } else { _storageProvider.Reset(); _stateProvider.Reset(); } }
public Block[] Process(Keccak branchStateRoot, Block[] suggestedBlocks, ProcessingOptions options, IBlockTracer blockTracer) { if (suggestedBlocks.Length == 0) { return(Array.Empty <Block>()); } int stateSnapshot = _stateDb.TakeSnapshot(); int codeSnapshot = _codeDb.TakeSnapshot(); if (stateSnapshot != -1 || codeSnapshot != -1) { if (_logger.IsError) { _logger.Error($"Uncommitted state ({stateSnapshot}, {codeSnapshot}) when processing from a branch root {branchStateRoot} starting with block {suggestedBlocks[0].ToString(Block.Format.Short)}"); } } Keccak snapshotStateRoot = _stateProvider.StateRoot; if (branchStateRoot != null && _stateProvider.StateRoot != branchStateRoot) { /* discarding the other branch data - chain reorganization */ Metrics.Reorganizations++; _storageProvider.Reset(); _stateProvider.Reset(); _stateProvider.StateRoot = branchStateRoot; } var readOnly = (options & ProcessingOptions.ReadOnlyChain) != 0; var processedBlocks = new Block[suggestedBlocks.Length]; try { for (int i = 0; i < suggestedBlocks.Length; i++) { processedBlocks[i] = ProcessOne(suggestedBlocks[i], options, blockTracer); if (_logger.IsTrace) { _logger.Trace($"Committing trees - state root {_stateProvider.StateRoot}"); } _stateProvider.CommitTree(); _storageProvider.CommitTrees(); if (!readOnly) { BlockProcessed?.Invoke(this, new BlockProcessedEventArgs(processedBlocks[i])); } } if (readOnly) { _receiptsTracer.BeforeRestore(_stateProvider); Restore(stateSnapshot, codeSnapshot, snapshotStateRoot); } else { _stateDb.Commit(); _codeDb.Commit(); } return(processedBlocks); } catch (InvalidBlockException) { Restore(stateSnapshot, codeSnapshot, snapshotStateRoot); throw; } }
private void LoadGenesisBlock(Keccak expectedGenesisHash) { // if we already have a database with blocks then we do not need to load genesis from spec if (_blockTree.Genesis != null) { ValidateGenesisHash(expectedGenesisHash); return; } Block genesis = _chainSpec.Genesis; CreateSystemAccounts(); foreach ((Address address, ChainSpecAllocation allocation) in _chainSpec.Allocations) { _stateProvider.CreateAccount(address, allocation.Balance); if (allocation.Code != null) { Keccak codeHash = _stateProvider.UpdateCode(allocation.Code); _stateProvider.UpdateCodeHash(address, codeHash, _specProvider.GenesisSpec); } if (allocation.Constructor != null) { Transaction constructorTransaction = new Transaction(true) { SenderAddress = address, Init = allocation.Constructor, GasLimit = genesis.GasLimit }; _transactionProcessor.Execute(constructorTransaction, genesis.Header, NullTxTracer.Instance); } } _storageProvider.Commit(); _stateProvider.Commit(_specProvider.GenesisSpec); _storageProvider.CommitTrees(); _stateProvider.CommitTree(); _dbProvider.StateDb.Commit(); _dbProvider.CodeDb.Commit(); genesis.StateRoot = _stateProvider.StateRoot; genesis.Hash = BlockHeader.CalculateHash(genesis.Header); ManualResetEventSlim genesisProcessedEvent = new ManualResetEventSlim(false); bool genesisLoaded = false; void GenesisProcessed(object sender, BlockEventArgs args) { genesisLoaded = true; _blockTree.NewHeadBlock -= GenesisProcessed; genesisProcessedEvent.Set(); } _blockTree.NewHeadBlock += GenesisProcessed; _blockTree.SuggestBlock(genesis); genesisProcessedEvent.Wait(TimeSpan.FromSeconds(5)); if (!genesisLoaded) { throw new BlockchainException("Genesis block processing failure"); } ValidateGenesisHash(expectedGenesisHash); }