public void Contract_Transfer_To_Other_Contract_Balance_Error() { var contractTransferMessage = new ContractTransferMessage( uint160.One, uint160.Zero, 10, (Gas)(GasPriceList.BaseCost + 100000) ); var state = new Mock <IState>(); // Setup the balance with less than the required amount. state.Setup(s => s.GetBalance(contractTransferMessage.From)) .Returns(contractTransferMessage.Amount - 1); var stateProcessor = new StateProcessor(this.vm.Object, this.addressGenerator.Object); StateTransitionResult result = stateProcessor.Apply(state.Object, contractTransferMessage); state.Verify(s => s.GetBalance(contractTransferMessage.From)); Assert.True(result.IsFailure); Assert.NotNull(result.Error); Assert.Null(result.Error.VmError); Assert.Equal(StateTransitionErrorKind.InsufficientBalance, result.Error.Kind); Assert.Equal((Gas)0, result.GasConsumed); }
public void Contract_Transfer_To_Other_Contract_Success() { // There is code at the destination address, which causes an internal call to the receive method var vmExecutionResult = VmExecutionResult.Success(true, "Test"); var code = new byte[1]; var typeName = "Test"; var contractTransferMessage = new ContractTransferMessage( uint160.One, uint160.Zero, 10, (Gas)(GasPriceList.BaseCost + 100000) ); // Code must be returned for this test to ensure we apply the call. this.contractStateRoot .Setup(sr => sr.GetCode(contractTransferMessage.To)) .Returns(code); this.contractStateRoot .Setup(sr => sr.GetContractType(contractTransferMessage.To)) .Returns(typeName); this.vm.Setup(v => v.ExecuteMethod(It.IsAny <ISmartContractState>(), contractTransferMessage.Method, code, typeName)) .Returns(vmExecutionResult); var state = new Mock <IState>(); // Return the sent amount + 1 state.Setup(s => s.GetBalance(contractTransferMessage.From)).Returns(contractTransferMessage.Amount + 1); state.SetupGet(s => s.ContractState).Returns(this.contractStateRoot.Object); var stateProcessor = new StateProcessor(this.vm.Object, this.addressGenerator.Object); StateTransitionResult result = stateProcessor.Apply(state.Object, contractTransferMessage); // Verify we check the balance of the sender first state.Verify(s => s.GetBalance(contractTransferMessage.From)); // Verify we get the code from the destination address' code cache this.contractStateRoot.Verify(s => s.GetCode(contractTransferMessage.To), Times.Once); // Verify we set up the smart contract state state.Verify(s => s.CreateSmartContractState(state.Object, It.IsAny <GasMeter>(), contractTransferMessage.To, contractTransferMessage, this.contractStateRoot.Object)); // Verify the VM was invoked this.vm.Verify(v => v.ExecuteMethod(It.IsAny <ISmartContractState>(), contractTransferMessage.Method, code, typeName), Times.Once); // Verify the value was added to the internal transfer list state.Verify(s => s.AddInternalTransfer(It.Is <TransferInfo>(t => t.From == contractTransferMessage.From && t.To == contractTransferMessage.To && t.Value == contractTransferMessage.Amount))); Assert.True(result.IsSuccess); Assert.NotNull(result.Success); Assert.Equal(contractTransferMessage.To, result.Success.ContractAddress); Assert.Equal(vmExecutionResult.Result, result.Success.ExecutionResult); Assert.Equal(GasPriceList.BaseCost, result.GasConsumed); }
public void Contract_Transfer_To_Other_Contract_VM_Error() { var vmExecutionResult = VmExecutionResult.Fail(VmExecutionErrorKind.InvocationFailed, "Error"); // Code must have a length to pass precondition checks. var code = new byte[1]; var typeName = "Test"; var contractTransferMessage = new ContractTransferMessage( uint160.One, uint160.Zero, 10, (RuntimeObserver.Gas)(GasPriceList.BaseCost + 100000) ); this.vm.Setup(v => v.ExecuteMethod( It.IsAny <ISmartContractState>(), It.IsAny <ExecutionContext>(), contractTransferMessage.Method, code, typeName)) .Returns(vmExecutionResult); this.contractStateRoot .Setup(sr => sr.GetCode(contractTransferMessage.To)) .Returns(code); this.contractStateRoot .Setup(sr => sr.GetContractType(contractTransferMessage.To)) .Returns(typeName); var state = new Mock <IState>(); state.Setup(s => s.GetBalance(contractTransferMessage.From)) .Returns(contractTransferMessage.Amount + 1); state.SetupGet(s => s.ContractState).Returns(this.contractStateRoot.Object); var stateProcessor = new StateProcessor(this.vm.Object, this.addressGenerator.Object); StateTransitionResult result = stateProcessor.Apply(state.Object, contractTransferMessage); state.Verify(s => s.CreateSmartContractState(state.Object, It.IsAny <RuntimeObserver.IGasMeter>(), contractTransferMessage.To, contractTransferMessage, this.contractStateRoot.Object)); this.vm.Verify( v => v.ExecuteMethod( It.IsAny <ISmartContractState>(), It.IsAny <ExecutionContext>(), contractTransferMessage.Method, code, typeName), Times.Once); Assert.True(result.IsFailure); Assert.NotNull(result.Error); Assert.Equal(result.Error.VmError, vmExecutionResult.Error.Message); Assert.Equal(StateTransitionErrorKind.VmError, result.Error.Kind); Assert.Equal(GasPriceList.BaseCost, result.GasConsumed); }
public void Contract_Transfer_To_Other_P2PKH_Success() { // There is no code at the destination address, which causes a regular P2PKH transaction to be created var emptyCode = new byte[0]; var contractTransferMessage = new ContractTransferMessage( uint160.One, uint160.Zero, 10, (Gas)(GasPriceList.BaseCost + 100000) ); // No code should be returned this.contractStateRoot .Setup(sr => sr.GetCode(contractTransferMessage.To)) .Returns(emptyCode); var state = new Mock <IState>(); // Return the sent amount + 1 state.Setup(s => s.GetBalance(contractTransferMessage.From)).Returns(contractTransferMessage.Amount + 1); state.SetupGet(s => s.ContractState).Returns(this.contractStateRoot.Object); var stateProcessor = new StateProcessor(this.vm.Object, this.addressGenerator.Object); StateTransitionResult result = stateProcessor.Apply(state.Object, contractTransferMessage); // Verify we check the balance of the sender first state.Verify(s => s.GetBalance(contractTransferMessage.From)); // Verify we get the code from the destination address' code cache this.contractStateRoot.Verify(s => s.GetCode(contractTransferMessage.To), Times.Once); // Verify the VM was NOT invoked this.vm.Verify(v => v.ExecuteMethod(It.IsAny <ISmartContractState>(), It.IsAny <MethodCall>(), It.IsAny <byte[]>(), It.IsAny <string>()), Times.Never); // Verify the value was added to the internal transfer list state.Verify(s => s.AddInternalTransfer(It.Is <TransferInfo>(t => t.From == contractTransferMessage.From && t.To == contractTransferMessage.To && t.Value == contractTransferMessage.Amount))); Assert.True(result.IsSuccess); Assert.NotNull(result.Success); Assert.Equal(contractTransferMessage.To, result.Success.ContractAddress); Assert.Null(result.Success.ExecutionResult); // No gas is consumed Assert.Equal((Gas)0, result.GasConsumed); }