private static BlockHeader Convert(TestBlockHeaderJson headerJson) { if (headerJson == null) { return(null); } BlockHeader header = new BlockHeader( new Keccak(headerJson.ParentHash), new Keccak(headerJson.UncleHash), new Address(headerJson.Coinbase), Hex.ToBytes(headerJson.Difficulty).ToUnsignedBigInteger(), Hex.ToBytes(headerJson.Number).ToUnsignedBigInteger(), (long)Hex.ToBytes(headerJson.GasLimit).ToUnsignedBigInteger(), Hex.ToBytes(headerJson.Timestamp).ToUnsignedBigInteger(), Hex.ToBytes(headerJson.ExtraData) ); header.Bloom = new Bloom(Hex.ToBytes(headerJson.Bloom).ToBigEndianBitArray2048()); header.GasUsed = (long)Hex.ToBytes(headerJson.GasUsed).ToUnsignedBigInteger(); header.Hash = new Keccak(headerJson.Hash); header.MixHash = new Keccak(headerJson.MixHash); header.Nonce = (ulong)Hex.ToBytes(headerJson.Nonce).ToUnsignedBigInteger(); header.ReceiptsRoot = new Keccak(headerJson.ReceiptTrie); header.StateRoot = new Keccak(headerJson.StateRoot); header.TransactionsRoot = new Keccak(headerJson.TransactionsTrie); return(header); }
private void RunAssertions(BlockchainTest test, Block headBlock) { TestBlockHeaderJson testHeaderJson = test.Blocks .Where(b => b.BlockHeader != null) .SingleOrDefault(b => new Keccak(b.BlockHeader.Hash) == headBlock.Hash)?.BlockHeader ?? test.GenesisBlockHeader; BlockHeader testHeader = Convert(testHeaderJson); List <string> differences = new List <string>(); foreach (KeyValuePair <Address, AccountState> accountState in test.PostState) { if (differences.Count > 8) { Console.WriteLine("More than 8 differences..."); break; } bool accountExists = _stateProviders[test.Network].AccountExists(accountState.Key); BigInteger?balance = accountExists ? _stateProviders[test.Network].GetBalance(accountState.Key) : (BigInteger?)null; BigInteger?nonce = accountExists ? _stateProviders[test.Network].GetNonce(accountState.Key) : (BigInteger?)null; if (accountState.Value.Balance != balance) { differences.Add($"{accountState.Key} balance exp: {accountState.Value.Balance}, actual: {balance}, diff: {balance - accountState.Value.Balance}"); } if (accountState.Value.Nonce != nonce) { differences.Add($"{accountState.Key} nonce exp: {accountState.Value.Nonce}, actual: {nonce}"); } byte[] code = accountExists ? _stateProviders[test.Network].GetCode(accountState.Key) : new byte[0]; if (!Bytes.UnsafeCompare(accountState.Value.Code, code)) { differences.Add($"{accountState.Key} code exp: {accountState.Value.Code?.Length}, actual: {code?.Length}"); } foreach (KeyValuePair <BigInteger, byte[]> storageItem in accountState.Value.Storage) { byte[] value = _storageProviders[test.Network].Get(accountState.Key, storageItem.Key) ?? new byte[0]; if (!Bytes.UnsafeCompare(storageItem.Value, value)) { differences.Add($"{accountState.Key} storage[{storageItem.Key}] exp: {Hex.FromBytes(storageItem.Value, true)}, actual: {Hex.FromBytes(value, true)}"); } } } BigInteger gasUsed = headBlock.Header.GasUsed; if ((testHeader?.GasUsed ?? 0) != gasUsed) { differences.Add($"GAS USED exp: {testHeader?.GasUsed ?? 0}, actual: {gasUsed}"); } if (headBlock.Transactions.Any() && testHeader.Bloom.ToString() != headBlock.Receipts.Last().Bloom.ToString()) { differences.Add($"BLOOM exp: {testHeader.Bloom}, actual: {headBlock.Receipts.Last().Bloom}"); } if (testHeader.StateRoot != _stateProviders[test.Network].StateRoot) { differences.Add($"STATE ROOT exp: {testHeader.StateRoot}, actual: {_stateProviders[test.Network].StateRoot}"); } if (testHeader.TransactionsRoot != headBlock.Header.TransactionsRoot) { differences.Add($"TRANSACTIONS ROOT exp: {testHeader.TransactionsRoot}, actual: {headBlock.Header.TransactionsRoot}"); } if (testHeader.ReceiptsRoot != headBlock.Header.ReceiptsRoot) { differences.Add($"RECEIPT ROOT exp: {testHeader.ReceiptsRoot}, actual: {headBlock.Header.ReceiptsRoot}"); } foreach (string difference in differences) { _logger?.Log(difference); } Assert.Zero(differences.Count, "differences"); }