public void Handles_well_serial_calls() { EstimateGasTracer tracer = new EstimateGasTracer(); tracer.ReportAction(1000, 0, Address.Zero, Address.Zero, Bytes.Empty, ExecutionType.Transaction, false); tracer.ReportAction(1000, 0, Address.Zero, Address.Zero, Bytes.Empty, _executionType, false); tracer.ReportActionEnd(400, Bytes.Empty); tracer.ReportAction(400, 0, Address.Zero, Address.Zero, Bytes.Empty, _executionType, false); if (_executionType == ExecutionType.Create) { tracer.ReportActionEnd(200, Address.Zero, Bytes.Empty); tracer.ReportActionEnd(300, Bytes.Empty); } else { tracer.ReportActionEnd(200, Bytes.Empty); tracer.ReportActionEnd(300, Bytes.Empty); // should not happen } tracer.ExcessiveGas.Should().Be(203L); }
public void Handles_well_serial_calls() { EstimateGasTracer tracer = new EstimateGasTracer(); tracer.ReportAction(1000, 0, Address.Zero, Address.Zero, Array.Empty <byte>(), ExecutionType.Transaction, false); tracer.ReportAction(1000, 0, Address.Zero, Address.Zero, Array.Empty <byte>(), _executionType, false); tracer.ReportActionEnd(400, Array.Empty <byte>()); tracer.ReportAction(400, 0, Address.Zero, Address.Zero, Array.Empty <byte>(), _executionType, false); if (_executionType.IsAnyCreate()) { tracer.ReportActionEnd(200, Address.Zero, Array.Empty <byte>()); tracer.ReportActionEnd(300, Array.Empty <byte>()); } else { tracer.ReportActionEnd(200, Array.Empty <byte>()); tracer.ReportActionEnd(300, Array.Empty <byte>()); // should not happen } tracer.CalculateEstimate(Build.A.Transaction.WithGasLimit(1000).TestObject).Should().Be(14L); }
public void Can_estimate_with_refund() { byte[] initByteCode = Prepare.EvmCode .PushData(1) .PushData(1) .Op(Instruction.SSTORE) .PushData(0) .PushData(1) .Op(Instruction.SSTORE) .Op(Instruction.STOP) .Done; long gasLimit = 100000; Transaction tx = Build.A.Transaction.SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA, _isEip155Enabled).WithInit(initByteCode).WithGasLimit(gasLimit).TestObject; Block block = Build.A.Block.WithNumber(MainnetSpecProvider.MuirGlacierBlockNumber).WithTransactions(tx).WithGasLimit(2 * gasLimit).TestObject; IntrinsicGasCalculator gasCalculator = new IntrinsicGasCalculator(); long intrinsic = gasCalculator.Calculate(tx, MuirGlacier.Instance); GethLikeTxTracer gethTracer = new GethLikeTxTracer(GethTraceOptions.Default); _transactionProcessor.CallAndRestore(tx, block.Header, gethTracer); TestContext.WriteLine(new EthereumJsonSerializer().Serialize(gethTracer.BuildResult(), true)); EstimateGasTracer tracer = new EstimateGasTracer(); _transactionProcessor.CallAndRestore(tx, block.Header, tracer); long actualIntrinsic = tx.GasLimit - tracer.IntrinsicGasAt; actualIntrinsic.Should().Be(intrinsic); tracer.CalculateAdditionalGasRequired(tx).Should().Be(RefundOf.SSetReversedEip2200 + GasCostOf.CallStipend - GasCostOf.SStoreNetMeteredEip2200 + 1); tracer.GasSpent.Should().Be(54764L); long estimate = tracer.CalculateEstimate(tx); estimate.Should().Be(75465L); ConfirmEnoughEstimate(tx, block, estimate); }
public void Can_estimate_with_destroy_refund_and_below_intrinsic() { byte[] initByteCode = Prepare.EvmCode.ForInitOf(Prepare.EvmCode.PushData(Address.Zero).Op(Instruction.SELFDESTRUCT).Done).Done; Address contractAddress = ContractAddress.From(TestItem.PrivateKeyA.Address, 0); byte[] byteCode = Prepare.EvmCode .Call(contractAddress, 46179) .Op(Instruction.STOP).Done; long gasLimit = 100000; Transaction initTx = Build.A.Transaction.SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA, _isEip155Enabled).WithInit(initByteCode).WithGasLimit(gasLimit).TestObject; Transaction tx = Build.A.Transaction.SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA, _isEip155Enabled).WithInit(byteCode).WithGasLimit(gasLimit).WithNonce(1).TestObject; Block block = Build.A.Block.WithNumber(MainnetSpecProvider.MuirGlacierBlockNumber).WithTransactions(tx).WithGasLimit(2 * gasLimit).TestObject; IntrinsicGasCalculator gasCalculator = new IntrinsicGasCalculator(); long intrinsic = gasCalculator.Calculate(tx, MuirGlacier.Instance); _transactionProcessor.Execute(initTx, block.Header, NullTxTracer.Instance); EstimateGasTracer tracer = new EstimateGasTracer(); GethLikeTxTracer gethTracer = new GethLikeTxTracer(GethTraceOptions.Default); _transactionProcessor.CallAndRestore(tx, block.Header, tracer); _transactionProcessor.CallAndRestore(tx, block.Header, gethTracer); TestContext.WriteLine(new EthereumJsonSerializer().Serialize(gethTracer.BuildResult(), true)); long actualIntrinsic = tx.GasLimit - tracer.IntrinsicGasAt; actualIntrinsic.Should().Be(intrinsic); tracer.CalculateAdditionalGasRequired(tx).Should().Be(24080); tracer.GasSpent.Should().Be(35228L); long estimate = tracer.CalculateEstimate(tx); estimate.Should().Be(59308); ConfirmEnoughEstimate(tx, block, estimate); }
public void Handles_well_errors() { EstimateGasTracer tracer = new EstimateGasTracer(); tracer.ReportAction(1000, 0, Address.Zero, Address.Zero, Bytes.Empty, ExecutionType.Transaction, false); tracer.ReportAction(1000, 0, Address.Zero, Address.Zero, Bytes.Empty, _executionType, false); tracer.ReportAction(400, 0, Address.Zero, Address.Zero, Bytes.Empty, _executionType, false); if (_executionType.IsAnyCreate()) { tracer.ReportActionError(EvmExceptionType.Other); tracer.ReportActionEnd(400, Address.Zero, Bytes.Empty); tracer.ReportActionEnd(500, Bytes.Empty); // should not happen } else { tracer.ReportActionError(EvmExceptionType.Other); tracer.ReportActionEnd(400, Bytes.Empty); tracer.ReportActionEnd(500, Bytes.Empty); // should not happen } tracer.CalculateEstimate(Build.A.Transaction.WithGasLimit(1000).TestObject).Should().Be(24L); }
public void Handles_well_nested_calls_where_least_nested_defines_excess() { EstimateGasTracer tracer = new EstimateGasTracer(); tracer.ReportAction(1000, 0, Address.Zero, Address.Zero, Bytes.Empty, ExecutionType.Transaction, false); tracer.ReportAction(1000, 0, Address.Zero, Address.Zero, Bytes.Empty, _executionType, false); tracer.ReportAction(400, 0, Address.Zero, Address.Zero, Bytes.Empty, _executionType, false); if (_executionType.IsAnyCreate()) { tracer.ReportActionEnd(300, Address.Zero, Bytes.Empty); // second level tracer.ReportActionEnd(200, Address.Zero, Bytes.Empty); tracer.ReportActionEnd(500, Bytes.Empty); // should not happen } else { tracer.ReportActionEnd(300, Bytes.Empty); // second level tracer.ReportActionEnd(200, Bytes.Empty); tracer.ReportActionEnd(500, Bytes.Empty); // should not happen } tracer.CalculateEstimate(Build.A.Transaction.WithGasLimit(1000).TestObject).Should().Be(17); }
public void Handles_well_errors() { EstimateGasTracer tracer = new EstimateGasTracer(); tracer.ReportAction(1000, 0, Address.Zero, Address.Zero, Bytes.Empty, ExecutionType.Transaction, false); tracer.ReportAction(1000, 0, Address.Zero, Address.Zero, Bytes.Empty, _executionType, false); tracer.ReportAction(400, 0, Address.Zero, Address.Zero, Bytes.Empty, _executionType, false); if (_executionType == ExecutionType.Create) { tracer.ReportActionError(EvmExceptionType.Other); tracer.ReportActionEnd(400, Address.Zero, Bytes.Empty); tracer.ReportActionEnd(500, Bytes.Empty); // should not happen } else { tracer.ReportActionError(EvmExceptionType.Other); tracer.ReportActionEnd(400, Bytes.Empty); tracer.ReportActionEnd(500, Bytes.Empty); // should not happen } tracer.ExcessiveGas.Should().Be(406L); }
public void Handles_well_nested_calls_where_most_nested_defines_excess() { EstimateGasTracer tracer = new EstimateGasTracer(); tracer.ReportAction(1000, 0, Address.Zero, Address.Zero, Bytes.Empty, ExecutionType.Transaction, false); tracer.ReportAction(1000, 0, Address.Zero, Address.Zero, Bytes.Empty, _executionType, false); tracer.ReportAction(400, 0, Address.Zero, Address.Zero, Bytes.Empty, _executionType, false); if (_executionType == ExecutionType.Create) { tracer.ReportActionEnd(200, Address.Zero, Bytes.Empty); // second level tracer.ReportActionEnd(400, Address.Zero, Bytes.Empty); tracer.ReportActionEnd(500, Bytes.Empty); // should not happen } else { tracer.ReportActionEnd(200, Bytes.Empty); // second level tracer.ReportActionEnd(400, Bytes.Empty); tracer.ReportActionEnd(500, Bytes.Empty); // should not happen } tracer.ExcessiveGas.Should().Be(206L); }
public void Can_estimate_with_single_call() { byte[] initByteCode = Prepare.EvmCode .ForInitOf(Bytes.FromHexString("6000")).Done; Address contractAddress = ContractAddress.From(TestItem.PrivateKeyA.Address, 0); byte[] byteCode = Prepare.EvmCode .Call(contractAddress, 46179).Done; long gasLimit = 100000; Transaction initTx = Build.A.Transaction.SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA, _isEip155Enabled).WithInit(initByteCode).WithGasLimit(gasLimit).TestObject; Transaction tx = Build.A.Transaction.SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA, _isEip155Enabled).WithInit(byteCode).WithGasLimit(gasLimit).WithNonce(1).TestObject; Block block = Build.A.Block.WithNumber(MainnetSpecProvider.MuirGlacierBlockNumber).WithTransactions(tx).WithGasLimit(2 * gasLimit).TestObject; IntrinsicGasCalculator gasCalculator = new IntrinsicGasCalculator(); long intrinsic = gasCalculator.Calculate(tx, MuirGlacier.Instance); _transactionProcessor.Execute(initTx, block.Header, NullTxTracer.Instance); EstimateGasTracer tracer = new EstimateGasTracer(); _transactionProcessor.CallAndRestore(tx, block.Header, tracer); long actualIntrinsic = tx.GasLimit - tracer.IntrinsicGasAt; actualIntrinsic.Should().Be(intrinsic); tracer.CalculateAdditionalGasRequired(tx).Should().Be(1); tracer.GasSpent.Should().Be(54224L); long estimate = tracer.CalculateEstimate(tx); estimate.Should().Be(54225L); ConfirmEnoughEstimate(tx, block, estimate); }