public void Test(VirtualMachineTest test) { // TODO: check why the tests are incorrect here string[] incorrectTests = { "blockhash258Block", "blockhashMyBlock", "blockhashNotExistingBlock" }; if (incorrectTests.Contains(test.Name)) { return; } RunTest(test); }
private static VirtualMachineTest Convert(string name, VirtualMachineTestJson testJson) { VirtualMachineTest test = new VirtualMachineTest(); test.Name = name; test.Environment = Convert(testJson.Env); test.Execution = Convert(testJson.Exec); test.Gas = testJson.Gas == null ? (UInt256?)null : Bytes.FromHexString(testJson.Gas).ToUInt256(); test.Logs = testJson.Logs == null ? null : Bytes.FromHexString(testJson.Gas); test.Out = testJson.Out == null ? null : Bytes.FromHexString(testJson.Out); test.Post = testJson.Post?.ToDictionary(p => new Address(p.Key), p => Convert(p.Value)); test.Pre = testJson.Pre.ToDictionary(p => new Address(p.Key), p => Convert(p.Value)); return(test); }
public void Test(VirtualMachineTest test) { RunTest(test); }
protected void RunTest(VirtualMachineTest test) { TestContext.WriteLine($"Running {test.GetType().FullName}"); VirtualMachine machine = new VirtualMachine(_stateProvider, _storageProvider, _blockhashProvider, _specProvider, _logManager); ExecutionEnvironment environment = new ExecutionEnvironment(); environment.Value = test.Execution.Value; environment.CallDepth = 0; environment.Sender = test.Execution.Caller; environment.ExecutingAccount = test.Execution.Address; BlockHeader header = new BlockHeader( Keccak.OfAnEmptyString, Keccak.OfAnEmptySequenceRlp, test.Environment.CurrentCoinbase, test.Environment.CurrentDifficulty, test.Environment.CurrentNumber, (long)test.Environment.CurrentGasLimit, test.Environment.CurrentTimestamp, Bytes.Empty); environment.CurrentBlock = header; environment.GasPrice = test.Execution.GasPrice; environment.InputData = test.Execution.Data; environment.CodeInfo = new CodeInfo(test.Execution.Code); environment.Originator = test.Execution.Origin; 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); if (accountState.Key.Equals(test.Execution.Address)) { _storageProvider.Set(new StorageCell(accountState.Key, storageItem.Key), storageItem.Value); } } _stateProvider.UpdateCode(accountState.Value.Code); _stateProvider.CreateAccount(accountState.Key, accountState.Value.Balance); Keccak codeHash = _stateProvider.UpdateCode(accountState.Value.Code); _stateProvider.UpdateCodeHash(accountState.Key, codeHash, Olympic.Instance); for (int i = 0; i < accountState.Value.Nonce; i++) { _stateProvider.IncrementNonce(accountState.Key); } } EvmState state = new EvmState((long)test.Execution.Gas, environment, ExecutionType.Transaction, true, false); _storageProvider.Commit(); _stateProvider.Commit(Olympic.Instance); TransactionSubstate substate = machine.Run(state, NullTxTracer.Instance); if (test.Out == null) { Assert.NotNull(substate.Error); return; } Assert.True(Bytes.AreEqual(test.Out, substate.Output), $"Exp: {test.Out.ToHexString(true)} != Actual: {substate.Output.ToHexString(true)}"); Assert.AreEqual((long)test.Gas, state.GasAvailable, "gas available"); foreach (KeyValuePair <Address, AccountState> accountState in test.Post) { bool accountExists = _stateProvider.AccountExists(accountState.Key); UInt256 balance = accountExists ? _stateProvider.GetBalance(accountState.Key) : 0; UInt256 nonce = accountExists ? _stateProvider.GetNonce(accountState.Key) : 0; Assert.AreEqual(accountState.Value.Balance, balance, $"{accountState.Key} Balance"); Assert.AreEqual(accountState.Value.Nonce, nonce, $"{accountState.Key} Nonce"); // TODO: not testing properly 0 balance accounts if (accountExists) { byte[] code = _stateProvider.GetCode(accountState.Key); Assert.AreEqual(accountState.Value.Code, code, $"{accountState.Key} Code"); } foreach (KeyValuePair <UInt256, byte[]> storageItem in accountState.Value.Storage) { byte[] value = _storageProvider.Get(new StorageCell(accountState.Key, storageItem.Key)); Assert.True(Bytes.AreEqual(storageItem.Value, value), $"Storage[{accountState.Key}_{storageItem.Key}] Exp: {storageItem.Value.ToHexString(true)} != Actual: {value.ToHexString(true)}"); } } }
protected void RunTest(VirtualMachineTest test) { VirtualMachine machine = new VirtualMachine(_stateProvider, _storageProvider, _blockhashProvider, _logManager); ExecutionEnvironment environment = new ExecutionEnvironment(); environment.Value = test.Execution.Value; environment.CallDepth = 0; environment.Sender = test.Execution.Caller; environment.ExecutingAccount = test.Execution.Address; BlockHeader header = new BlockHeader( Keccak.OfAnEmptyString, Keccak.OfAnEmptySequenceRlp, test.Environment.CurrentCoinbase, test.Environment.CurrentDifficulty, test.Environment.CurrentNumber, (long)test.Environment.CurrentGasLimit, test.Environment.CurrentTimestamp, Bytes.Empty); environment.CurrentBlock = header; environment.GasPrice = test.Execution.GasPrice; environment.InputData = test.Execution.Data; environment.CodeInfo = new CodeInfo(test.Execution.Code); environment.Originator = test.Execution.Origin; foreach (KeyValuePair <Address, AccountState> accountState in test.Pre) { foreach (KeyValuePair <BigInteger, byte[]> storageItem in accountState.Value.Storage) { _storageProvider.Set(new StorageAddress(accountState.Key, storageItem.Key), storageItem.Value); if (accountState.Key.Equals(test.Execution.Address)) { _storageProvider.Set(new StorageAddress(accountState.Key, storageItem.Key), storageItem.Value); } } _stateProvider.UpdateCode(accountState.Value.Code); _stateProvider.CreateAccount(accountState.Key, accountState.Value.Balance); _stateProvider.UpdateStorageRoot(accountState.Key, _storageProvider.GetRoot(accountState.Key)); Keccak codeHash = _stateProvider.UpdateCode(accountState.Value.Code); _stateProvider.UpdateCodeHash(accountState.Key, codeHash, Olympic.Instance); for (int i = 0; i < accountState.Value.Nonce; i++) { _stateProvider.IncrementNonce(accountState.Key); } } EvmState state = new EvmState((long)test.Execution.Gas, environment, ExecutionType.Transaction, false); if (test.Out == null) { Assert.That(() => machine.Run(state, Olympic.Instance, null), Throws.Exception); return; } _stateProvider.Commit(Olympic.Instance); _storageProvider.Commit(Olympic.Instance); (byte[] output, TransactionSubstate substate) = machine.Run(state, Olympic.Instance, null); Assert.True(Bytes.UnsafeCompare(test.Out, output), $"Exp: {Hex.FromBytes(test.Out, true)} != Actual: {Hex.FromBytes(output, true)}"); Assert.AreEqual((long)test.Gas, state.GasAvailable); foreach (KeyValuePair <Address, AccountState> accountState in test.Post) { bool accountExists = _stateProvider.AccountExists(accountState.Key); BigInteger balance = accountExists ? _stateProvider.GetBalance(accountState.Key) : 0; BigInteger nonce = accountExists ? _stateProvider.GetNonce(accountState.Key) : 0; Assert.AreEqual(accountState.Value.Balance, balance, $"{accountState.Key} Balance"); Assert.AreEqual(accountState.Value.Nonce, nonce, $"{accountState.Key} Nonce"); // TODO: not testing properly 0 balance accounts if (accountExists) { byte[] code = _stateProvider.GetCode(accountState.Key); Assert.AreEqual(accountState.Value.Code, code, $"{accountState.Key} Code"); } foreach (KeyValuePair <BigInteger, byte[]> storageItem in accountState.Value.Storage) { byte[] value = _storageProvider.Get(new StorageAddress(accountState.Key, storageItem.Key)); Assert.True(Bytes.UnsafeCompare(storageItem.Value, value), $"Storage[{accountState.Key}_{storageItem.Key}] Exp: {Hex.FromBytes(storageItem.Value, true)} != Actual: {Hex.FromBytes(value, true)}"); } } }