public void Create_Contract_Success()
        {
            var contractTxData = new ContractTxData(1, 1, (Gas)1000, new byte[] { 0xAA, 0xBB, 0xCC });

            VmExecutionResult vmExecutionResult = VmExecutionResult.Ok(new object(), null);

            StateTransitionResult stateTransitionResult = StateTransitionResult.Ok((Gas)100, uint160.One, vmExecutionResult.Success.Result);

            var    fixture  = new ExecutorFixture(contractTxData);
            IState snapshot = fixture.State.Object.Snapshot();

            fixture.StateProcessor
            .Setup(s => s.Apply(snapshot, It.IsAny <ExternalCreateMessage>()))
            .Returns(stateTransitionResult);

            IStateRepository trackedMock = Mock.Of <IStateRepository>();

            fixture.ContractStateRoot.Setup(s => s.StartTracking()).Returns(trackedMock);

            var sut = new LocalExecutor(
                fixture.LoggerFactory,
                fixture.CallDataSerializer.Object,
                fixture.ContractStateRoot.Object,
                fixture.StateFactory.Object,
                fixture.StateProcessor.Object,
                fixture.ContractPrimitiveSerializer.Object);

            ILocalExecutionResult result = sut.Execute(fixture.ContractTransactionContext);

            fixture.CallDataSerializer.Verify(s => s.Deserialize(fixture.ContractTransactionContext.Data), Times.Once);

            fixture.StateFactory.Verify(sf => sf
                                        .Create(
                                            trackedMock,
                                            It.IsAny <IBlock>(),
                                            fixture.ContractTransactionContext.TxOutValue,
                                            fixture.ContractTransactionContext.TransactionHash),
                                        Times.Once);

            // We only apply the message to the snapshot.
            fixture.StateProcessor.Verify(sm => sm.Apply(snapshot, It.IsAny <ExternalCreateMessage>()), Times.Once);

            // Should never transition to the snapshot.
            fixture.State.Verify(sm => sm.TransitionTo(snapshot), Times.Never);

            // Should never save on the state
            fixture.ContractStateRoot.Verify(sr => sr.Commit(), Times.Never);

            Assert.Null(result.ErrorMessage);
            Assert.False(result.Revert);
            Assert.Equal(fixture.State.Object.InternalTransfers, result.InternalTransfers);
            Assert.Equal(stateTransitionResult.GasConsumed, result.GasConsumed);
            Assert.Equal(stateTransitionResult.Success.ExecutionResult, result.Return);
            Assert.Equal(fixture.State.Object.GetLogs(fixture.ContractPrimitiveSerializer.Object), result.Logs);
        }
        public void Call_StateTransition_Success()
        {
            ulong amount     = 100UL;
            var   to         = new Address("Sj2p6ZRHdLvywyi43HYoE4bu2TF1nvavjR");
            var   method     = "Test";
            var   parameters = new object[] { };
            var   gasLimit   = (Gas)100_000;

            var fixture = new InternalExecutorTestFixture();

            fixture.SetGasMeterLimitAbove(gasLimit);

            StateTransitionResult stateTransitionResult = StateTransitionResult.Ok((Gas)1000, uint160.One, new object());

            fixture.StateProcessor
            .Setup(sp => sp.Apply(It.IsAny <IState>(), It.IsAny <InternalCallMessage>()))
            .Returns(stateTransitionResult);

            var internalExecutor = new InternalExecutor(
                fixture.LoggerFactory,
                fixture.Network,
                fixture.State.Object,
                fixture.StateProcessor.Object);

            ITransferResult result = internalExecutor.Call(fixture.SmartContractState, to, amount, method, parameters, gasLimit);

            fixture.State.Verify(s => s.Snapshot(), Times.Once);

            fixture.StateProcessor.Verify(sp =>
                                          sp.Apply(fixture.Snapshot, It.Is <InternalCallMessage>(m =>
                                                                                                 m.Amount == amount &&
                                                                                                 m.Method.Name == method &&
                                                                                                 m.Method.Parameters == parameters &&
                                                                                                 m.GasLimit == gasLimit &&
                                                                                                 m.From == fixture.FromAddress &&
                                                                                                 m.To == to.ToUint160(fixture.Network)
                                                                                                 )));

            fixture.State.Verify(s => s.TransitionTo(fixture.Snapshot));

            fixture.GasMeter.Verify(g => g.Spend(stateTransitionResult.GasConsumed));

            Assert.True(result.Success);
            Assert.Equal(stateTransitionResult.Success.ExecutionResult, result.ReturnValue);
        }
        public void Call_StateTransition_Success()
        {
            var fixture = new InternalExecutorTestFixture();

            ulong amount     = 100UL;
            var   to         = "0x95D34980095380851902ccd9A1Fb4C813C2cb639".HexToAddress();
            var   method     = "Test";
            var   parameters = new object[] { };
            var   gasLimit   = (RuntimeObserver.Gas) 100_000;


            fixture.SetGasMeterLimitAbove(gasLimit);

            StateTransitionResult stateTransitionResult = StateTransitionResult.Ok((RuntimeObserver.Gas) 1000, uint160.One, new object());

            fixture.StateProcessor
            .Setup(sp => sp.Apply(It.IsAny <IState>(), It.IsAny <InternalCallMessage>()))
            .Returns(stateTransitionResult);

            var internalExecutor = new InternalExecutor(
                fixture.GasMeter.Object,
                fixture.State.Object,
                fixture.StateProcessor.Object);

            ITransferResult result = internalExecutor.Call(fixture.SmartContractState, to, amount, method, parameters, gasLimit);

            fixture.State.Verify(s => s.Snapshot(), Times.Once);

            fixture.StateProcessor.Verify(sp =>
                                          sp.Apply(fixture.Snapshot, It.Is <InternalCallMessage>(m =>
                                                                                                 m.Amount == amount &&
                                                                                                 m.Method.Name == method &&
                                                                                                 m.Method.Parameters == parameters &&
                                                                                                 m.GasLimit == gasLimit &&
                                                                                                 m.From == fixture.FromAddress &&
                                                                                                 m.To == to.ToUint160()
                                                                                                 )));

            fixture.State.Verify(s => s.TransitionTo(fixture.Snapshot));

            fixture.GasMeter.Verify(g => g.Spend(stateTransitionResult.GasConsumed));

            Assert.True(result.Success);
            Assert.Equal(stateTransitionResult.Success.ExecutionResult, result.ReturnValue);
        }
        public void Create_StateTransition_Success()
        {
            ulong amount     = 100UL;
            var   parameters = new object[] { };
            var   gasLimit   = (Gas)100_000;

            var fixture = new InternalExecutorTestFixture();

            fixture.SetGasMeterLimitAbove(gasLimit);

            StateTransitionResult stateTransitionResult = StateTransitionResult.Ok((Gas)1000, uint160.One, new object());

            fixture.StateProcessor
            .Setup(sp => sp.Apply(It.IsAny <IState>(), It.IsAny <InternalCreateMessage>()))
            .Returns(stateTransitionResult);

            var internalExecutor = new InternalExecutor(
                fixture.LoggerFactory,
                fixture.Network,
                fixture.State.Object,
                fixture.StateProcessor.Object);

            ICreateResult result = internalExecutor.Create <string>(fixture.SmartContractState, amount, parameters, gasLimit);

            fixture.State.Verify(s => s.Snapshot(), Times.Once);

            fixture.StateProcessor.Verify(sp =>
                                          sp.Apply(fixture.Snapshot, It.Is <InternalCreateMessage>(m =>
                                                                                                   m.Amount == amount &&
                                                                                                   m.Parameters == parameters &&
                                                                                                   m.GasLimit == gasLimit &&
                                                                                                   m.From == fixture.FromAddress &&
                                                                                                   m.Type == typeof(string).Name
                                                                                                   )));

            fixture.State.Verify(s => s.TransitionTo(fixture.Snapshot));

            fixture.GasMeter.Verify(g => g.Spend(stateTransitionResult.GasConsumed));

            Assert.True(result.Success);
            Assert.Equal(stateTransitionResult.Success.ContractAddress.ToAddress(fixture.Network), result.NewContractAddress);
        }
        public void Transfer_StateTransition_Success()
        {
            ulong amount = 100UL;
            var   to     = new Address("Sj2p6ZRHdLvywyi43HYoE4bu2TF1nvavjR");

            var fixture = new InternalExecutorTestFixture();

            fixture.SetGasMeterLimitAbove((Gas)InternalExecutor.DefaultGasLimit);

            StateTransitionResult stateTransitionResult = StateTransitionResult.Ok((Gas)1000, uint160.One, new object());

            fixture.StateProcessor
            .Setup(sp => sp.Apply(It.IsAny <IState>(), It.IsAny <ContractTransferMessage>()))
            .Returns(stateTransitionResult);

            var internalExecutor = new InternalExecutor(
                fixture.LoggerFactory,
                fixture.Network,
                fixture.State.Object,
                fixture.StateProcessor.Object);

            ITransferResult result = internalExecutor.Transfer(fixture.SmartContractState, to, amount);

            fixture.State.Verify(s => s.Snapshot(), Times.Once);

            fixture.StateProcessor.Verify(sp =>
                                          sp.Apply(fixture.Snapshot, It.Is <ContractTransferMessage>(m =>
                                                                                                     m.Amount == amount &&
                                                                                                     m.GasLimit == InternalExecutor.DefaultGasLimit &&
                                                                                                     m.From == fixture.FromAddress &&
                                                                                                     m.To == to.ToUint160(fixture.Network)
                                                                                                     )));

            fixture.State.Verify(s => s.TransitionTo(fixture.Snapshot));

            fixture.GasMeter.Verify(g => g.Spend(stateTransitionResult.GasConsumed));

            Assert.True(result.Success);
            Assert.Null(result.ReturnValue);
        }
        public void Transfer_StateTransition_Success()
        {
            var fixture = new InternalExecutorTestFixture();

            ulong amount = 100UL;
            var   to     = "0x95D34980095380851902ccd9A1Fb4C813C2cb639".HexToAddress();

            fixture.SetGasMeterLimitAbove((RuntimeObserver.Gas)InternalExecutor.DefaultGasLimit);

            StateTransitionResult stateTransitionResult = StateTransitionResult.Ok((RuntimeObserver.Gas) 1000, uint160.One, new object());

            fixture.StateProcessor
            .Setup(sp => sp.Apply(It.IsAny <IState>(), It.IsAny <ContractTransferMessage>()))
            .Returns(stateTransitionResult);

            var internalExecutor = new InternalExecutor(
                fixture.GasMeter.Object,
                fixture.State.Object,
                fixture.StateProcessor.Object);

            ITransferResult result = internalExecutor.Transfer(fixture.SmartContractState, to, amount);

            fixture.State.Verify(s => s.Snapshot(), Times.Once);

            fixture.StateProcessor.Verify(sp =>
                                          sp.Apply(fixture.Snapshot, It.Is <ContractTransferMessage>(m =>
                                                                                                     m.Amount == amount &&
                                                                                                     m.GasLimit == InternalExecutor.DefaultGasLimit &&
                                                                                                     m.From == fixture.FromAddress &&
                                                                                                     m.To == to.ToUint160()
                                                                                                     )));

            fixture.State.Verify(s => s.TransitionTo(fixture.Snapshot));

            fixture.GasMeter.Verify(g => g.Spend(stateTransitionResult.GasConsumed));

            Assert.True(result.Success);
            Assert.Null(result.ReturnValue);
        }
Exemplo n.º 7
0
        public void Call_Contract_Success()
        {
            var parameters     = new object[] { };
            var contractTxData = new ContractTxData(1, 1, (RuntimeObserver.Gas) 1000, uint160.One, "TestMethod", parameters);

            VmExecutionResult vmExecutionResult = VmExecutionResult.Ok(new object(), null);

            StateTransitionResult stateTransitionResult = StateTransitionResult.Ok((RuntimeObserver.Gas) 100, uint160.One, vmExecutionResult.Success.Result);

            var    fixture  = new ExecutorFixture(contractTxData);
            IState snapshot = fixture.State.Object.Snapshot();

            fixture.StateProcessor
            .Setup(s => s.Apply(snapshot, It.IsAny <ExternalCallMessage>()))
            .Returns(stateTransitionResult);

            IStateRepository trackedMock = Mock.Of <IStateRepository>();

            fixture.ContractStateRoot.Setup(s => s.StartTracking()).Returns(trackedMock);

            var sut = new LocalExecutor(
                fixture.LoggerFactory,
                fixture.CallDataSerializer.Object,
                fixture.ContractStateRoot.Object,
                fixture.StateFactory.Object,
                fixture.StateProcessor.Object,
                fixture.ContractPrimitiveSerializer.Object);

            ILocalExecutionResult result = sut.Execute(fixture.ContractTransactionContext.BlockHeight,
                                                       fixture.ContractTransactionContext.Sender,
                                                       fixture.ContractTransactionContext.TxOutValue,
                                                       contractTxData);

            // Local executor used a tracked staterepository
            fixture.StateFactory.Verify(sf => sf
                                        .Create(
                                            trackedMock,
                                            It.IsAny <IBlock>(),
                                            fixture.ContractTransactionContext.TxOutValue,
                                            It.IsAny <uint256>()),
                                        Times.Once);

            // We only apply the message to the snapshot.
            fixture.StateProcessor.Verify(sm => sm.Apply(snapshot, It.Is <ExternalCallMessage>(m =>
                                                                                               m.Method.Name == contractTxData.MethodName &&
                                                                                               m.Method.Parameters == contractTxData.MethodParameters &&
                                                                                               m.Amount == fixture.ContractTransactionContext.TxOutValue &&
                                                                                               m.From == fixture.ContractTransactionContext.Sender &&
                                                                                               m.To == contractTxData.ContractAddress)), Times.Once);

            // Should never transition to the snapshot.
            fixture.State.Verify(sm => sm.TransitionTo(snapshot), Times.Never);

            // Should never save on the state
            fixture.ContractStateRoot.Verify(sr => sr.Commit(), Times.Never);

            Assert.Null(result.ErrorMessage);
            Assert.False(result.Revert);
            Assert.Equal <IReadOnlyList <TransferInfo> >(fixture.State.Object.InternalTransfers, result.InternalTransfers);
            Assert.Equal(stateTransitionResult.GasConsumed, result.GasConsumed);
            Assert.Equal(stateTransitionResult.Success.ExecutionResult, result.Return);
            Assert.Equal <IList <Log> >(fixture.State.Object.GetLogs(fixture.ContractPrimitiveSerializer.Object), result.Logs);
        }
Exemplo n.º 8
0
        public void Create_Contract_Success()
        {
            var         network            = new SmartContractsRegTest();
            uint160     newContractAddress = uint160.One;
            var         gasConsumed        = (Gas)100;
            var         code           = new byte[] { 0xAA, 0xBB, 0xCC };
            var         contractTxData = new ContractTxData(1, 1, (Gas)1000, code);
            var         refund         = new Money(0);
            const ulong mempoolFee     = 2UL; // MOQ doesn't like it when you use a type with implicit conversions (Money)
            ISmartContractTransactionContext context = Mock.Of <ISmartContractTransactionContext>(c =>
                                                                                                  c.Data == code &&
                                                                                                  c.MempoolFee == mempoolFee &&
                                                                                                  c.Sender == uint160.One &&
                                                                                                  c.CoinbaseAddress == uint160.Zero);

            var            logger        = new Mock <ILogger>();
            ILoggerFactory loggerFactory = Mock.Of <ILoggerFactory>
                                               (l => l.CreateLogger(It.IsAny <string>()) == logger.Object);

            var callDataSerializer = new Mock <ICallDataSerializer>();

            callDataSerializer
            .Setup(s => s.Deserialize(It.IsAny <byte[]>()))
            .Returns(Result.Ok(contractTxData));

            var vmExecutionResult = VmExecutionResult.Success(null, null);

            var contractStateRoot = new Mock <IContractStateRoot>();
            var transferProcessor = new Mock <ISmartContractResultTransferProcessor>();

            (Money refund, TxOut)refundResult = (refund, null);
            var refundProcessor = new Mock <ISmartContractResultRefundProcessor>();

            refundProcessor
            .Setup(r => r.Process(
                       contractTxData,
                       mempoolFee,
                       context.Sender,
                       It.IsAny <Gas>(),
                       false))
            .Returns(refundResult);

            var stateTransitionResult = StateTransitionResult.Ok(gasConsumed, newContractAddress, vmExecutionResult.Result);

            var internalTransfers = new List <TransferInfo>().AsReadOnly();
            var stateMock         = new Mock <IState>();

            stateMock.Setup(s => s.Apply(It.IsAny <ExternalCreateMessage>()))
            .Returns(stateTransitionResult);
            stateMock.SetupGet(p => p.InternalTransfers).Returns(internalTransfers);

            var stateFactory = new Mock <IStateFactory>();

            stateFactory.Setup(sf => sf.Create(
                                   contractStateRoot.Object,
                                   It.IsAny <IBlock>(),
                                   context.TxOutValue,
                                   context.TransactionHash,
                                   contractTxData.GasLimit))
            .Returns(stateMock.Object);

            var sut = new Executor(
                loggerFactory,
                callDataSerializer.Object,
                contractStateRoot.Object,
                refundProcessor.Object,
                transferProcessor.Object,
                network,
                stateFactory.Object);

            sut.Execute(context);

            callDataSerializer.Verify(s => s.Deserialize(code), Times.Once);

            stateFactory.Verify(sf => sf
                                .Create(
                                    contractStateRoot.Object,
                                    It.IsAny <IBlock>(),
                                    context.TxOutValue,
                                    context.TransactionHash,
                                    contractTxData.GasLimit),
                                Times.Once);

            stateMock.Verify(sm => sm
                             .Apply(It.IsAny <ExternalCreateMessage>()), Times.Once);

            transferProcessor.Verify(t => t
                                     .Process(
                                         contractStateRoot.Object,
                                         newContractAddress,
                                         context,
                                         internalTransfers,
                                         false),
                                     Times.Once);

            refundProcessor.Verify(t => t
                                   .Process(
                                       contractTxData,
                                       mempoolFee,
                                       context.Sender,
                                       It.IsAny <Gas>(),
                                       false),
                                   Times.Once);
        }
        public void Call_Contract_Success()
        {
            var parameters     = new object[] { };
            var contractTxData = new ContractTxData(1, 1, (Gas)1000, uint160.One, "TestMethod", parameters);

            VmExecutionResult vmExecutionResult = VmExecutionResult.Ok(new object(), null);

            StateTransitionResult stateTransitionResult = StateTransitionResult.Ok((Gas)100, uint160.One, vmExecutionResult.Success.Result);

            var    fixture  = new ExecutorFixture(contractTxData);
            IState snapshot = fixture.State.Object.Snapshot();

            fixture.StateProcessor
            .Setup(s => s.Apply(snapshot, It.IsAny <ExternalCallMessage>()))
            .Returns(stateTransitionResult);

            var sut = new ContractExecutor(
                fixture.LoggerFactory,
                fixture.CallDataSerializer.Object,
                fixture.ContractStateRoot.Object,
                fixture.RefundProcessor.Object,
                fixture.TransferProcessor.Object,
                fixture.StateFactory.Object,
                fixture.StateProcessor.Object,
                fixture.ContractPrimitiveSerializer.Object);

            IContractExecutionResult result = sut.Execute(fixture.ContractTransactionContext);

            fixture.CallDataSerializer.Verify(s => s.Deserialize(fixture.ContractTransactionContext.Data), Times.Once);

            fixture.StateFactory.Verify(sf => sf
                                        .Create(
                                            fixture.ContractStateRoot.Object,
                                            It.IsAny <IBlock>(),
                                            fixture.ContractTransactionContext.TxOutValue,
                                            fixture.ContractTransactionContext.TransactionHash),
                                        Times.Once);

            // We only apply the message to the snapshot.
            fixture.StateProcessor.Verify(sm => sm.Apply(snapshot, It.Is <ExternalCallMessage>(m =>
                                                                                               m.Method.Name == contractTxData.MethodName &&
                                                                                               m.Method.Parameters == contractTxData.MethodParameters &&
                                                                                               m.Amount == fixture.ContractTransactionContext.TxOutValue &&
                                                                                               m.From == fixture.ContractTransactionContext.Sender &&
                                                                                               m.To == contractTxData.ContractAddress)), Times.Once);

            // Must transition to the snapshot.
            fixture.State.Verify(sm => sm.TransitionTo(snapshot), Times.Once);

            fixture.TransferProcessor.Verify(t => t
                                             .Process(
                                                 snapshot.ContractState,
                                                 stateTransitionResult.Success.ContractAddress,
                                                 fixture.ContractTransactionContext,
                                                 snapshot.InternalTransfers,
                                                 false),
                                             Times.Once);

            fixture.RefundProcessor.Verify(t => t
                                           .Process(
                                               contractTxData,
                                               fixture.MempoolFee,
                                               fixture.ContractTransactionContext.Sender,
                                               It.IsAny <Gas>(),
                                               false),
                                           Times.Once);

            Assert.Equal(contractTxData.ContractAddress, result.To);
            Assert.Null(result.NewContractAddress);
            Assert.Null(result.ErrorMessage);
            Assert.False(result.Revert);
            Assert.Equal(stateTransitionResult.GasConsumed, result.GasConsumed);
            Assert.Equal(stateTransitionResult.Success.ExecutionResult, result.Return);
            Assert.Equal(fixture.InternalTransaction, result.InternalTransaction);
            Assert.Equal(fixture.Fee, (Money)result.Fee);
            Assert.Equal(fixture.Refund, result.Refund);
            Assert.Equal(fixture.State.Object.GetLogs(fixture.ContractPrimitiveSerializer.Object), result.Logs);
        }