github.com/dim4egster/coreth@v0.10.2/plugin/evm/tx_test.go (about)

     1  // (c) 2019-2020, Ava Labs, Inc. All rights reserved.
     2  // See the file LICENSE for licensing terms.
     3  
     4  package evm
     5  
     6  import (
     7  	"math/big"
     8  	"strings"
     9  	"testing"
    10  
    11  	"github.com/dim4egster/qmallgo/chains/atomic"
    12  	"github.com/dim4egster/qmallgo/snow"
    13  	"github.com/dim4egster/coreth/params"
    14  	"github.com/stretchr/testify/require"
    15  )
    16  
    17  func TestCalculateDynamicFee(t *testing.T) {
    18  	type test struct {
    19  		gas           uint64
    20  		baseFee       *big.Int
    21  		expectedErr   error
    22  		expectedValue uint64
    23  	}
    24  	var tests []test = []test{
    25  		{
    26  			gas:           1,
    27  			baseFee:       new(big.Int).Set(x2cRate),
    28  			expectedValue: 1,
    29  		},
    30  		{
    31  			gas:           21000,
    32  			baseFee:       big.NewInt(25 * params.GWei),
    33  			expectedValue: 525000,
    34  		},
    35  	}
    36  
    37  	for _, test := range tests {
    38  		cost, err := calculateDynamicFee(test.gas, test.baseFee)
    39  		if test.expectedErr == nil {
    40  			if err != nil {
    41  				t.Fatalf("Unexpectedly failed to calculate dynamic fee: %s", err)
    42  			}
    43  			if cost != test.expectedValue {
    44  				t.Fatalf("Expected value: %d, found: %d", test.expectedValue, cost)
    45  			}
    46  		} else {
    47  			if err != test.expectedErr {
    48  				t.Fatalf("Expected error: %s, found error: %s", test.expectedErr, err)
    49  			}
    50  		}
    51  	}
    52  }
    53  
    54  type atomicTxVerifyTest struct {
    55  	ctx         *snow.Context
    56  	generate    func(t *testing.T) UnsignedAtomicTx
    57  	rules       params.Rules
    58  	expectedErr string
    59  }
    60  
    61  // executeTxVerifyTest tests
    62  func executeTxVerifyTest(t *testing.T, test atomicTxVerifyTest) {
    63  	require := require.New(t)
    64  	atomicTx := test.generate(t)
    65  	err := atomicTx.Verify(test.ctx, test.rules)
    66  	if len(test.expectedErr) == 0 {
    67  		require.NoError(err)
    68  	} else {
    69  		require.ErrorContains(err, test.expectedErr, "expected tx verify to fail with specified error")
    70  	}
    71  }
    72  
    73  type atomicTxTest struct {
    74  	// setup returns the atomic transaction for the test
    75  	setup func(t *testing.T, vm *VM, sharedMemory *atomic.Memory) *Tx
    76  	// define a string that should be contained in the error message if the tx fails verification
    77  	// at some point. If the strings are empty, then the tx should pass verification at the
    78  	// respective step.
    79  	semanticVerifyErr, evmStateTransferErr, acceptErr string
    80  	// checkState is called iff building and verifying a block containing the transaction is successful. Verifies
    81  	// the state of the VM following the block's acceptance.
    82  	checkState func(t *testing.T, vm *VM)
    83  
    84  	// Whether or not the VM should be considered to still be bootstrapping
    85  	bootstrapping bool
    86  	// genesisJSON to use for the VM genesis (also defines the rule set that will be used in verification)
    87  	// If this is left empty, [genesisJSONApricotPhase0], will be used
    88  	genesisJSON string
    89  
    90  	// passed directly into GenesisVM
    91  	configJSON, upgradeJSON string
    92  }
    93  
    94  func executeTxTest(t *testing.T, test atomicTxTest) {
    95  	genesisJSON := test.genesisJSON
    96  	if len(genesisJSON) == 0 {
    97  		genesisJSON = genesisJSONApricotPhase0
    98  	}
    99  	issuer, vm, _, sharedMemory, _ := GenesisVM(t, !test.bootstrapping, genesisJSON, test.configJSON, test.upgradeJSON)
   100  	rules := vm.currentRules()
   101  
   102  	tx := test.setup(t, vm, sharedMemory)
   103  
   104  	var baseFee *big.Int
   105  	// If ApricotPhase3 is active, use the initial base fee for the atomic transaction
   106  	switch {
   107  	case rules.IsApricotPhase3:
   108  		baseFee = initialBaseFee
   109  	}
   110  
   111  	lastAcceptedBlock := vm.LastAcceptedBlockInternal().(*Block)
   112  	if err := tx.UnsignedAtomicTx.SemanticVerify(vm, tx, lastAcceptedBlock, baseFee, rules); len(test.semanticVerifyErr) == 0 && err != nil {
   113  		t.Fatalf("SemanticVerify failed unexpectedly due to: %s", err)
   114  	} else if len(test.semanticVerifyErr) != 0 {
   115  		if err == nil {
   116  			t.Fatalf("SemanticVerify unexpectedly returned a nil error. Expected err: %s", test.semanticVerifyErr)
   117  		}
   118  		if !strings.Contains(err.Error(), test.semanticVerifyErr) {
   119  			t.Fatalf("Expected SemanticVerify to fail due to %s, but failed with: %s", test.semanticVerifyErr, err)
   120  		}
   121  		// If SemanticVerify failed for the expected reason, return early
   122  		return
   123  	}
   124  
   125  	// Retrieve dummy state to test that EVMStateTransfer works correctly
   126  	sdb, err := vm.blockChain.StateAt(lastAcceptedBlock.ethBlock.Root())
   127  	if err != nil {
   128  		t.Fatal(err)
   129  	}
   130  	if err := tx.UnsignedAtomicTx.EVMStateTransfer(vm.ctx, sdb); len(test.evmStateTransferErr) == 0 && err != nil {
   131  		t.Fatalf("EVMStateTransfer failed unexpectedly due to: %s", err)
   132  	} else if len(test.evmStateTransferErr) != 0 {
   133  		if err == nil {
   134  			t.Fatalf("EVMStateTransfer unexpectedly returned a nil error. Expected err: %s", test.evmStateTransferErr)
   135  		}
   136  		if !strings.Contains(err.Error(), test.evmStateTransferErr) {
   137  			t.Fatalf("Expected SemanticVerify to fail due to %s, but failed with: %s", test.evmStateTransferErr, err)
   138  		}
   139  		// If EVMStateTransfer failed for the expected reason, return early
   140  		return
   141  	}
   142  
   143  	if test.bootstrapping {
   144  		// If this test simulates processing txs during bootstrapping (where some verification is skipped),
   145  		// initialize the block building goroutines normally initialized in SetState(snow.NormalOps).
   146  		// This ensures that the VM can build a block correctly during the test.
   147  		vm.initBlockBuilding()
   148  	}
   149  
   150  	if err := vm.issueTx(tx, true /*=local*/); err != nil {
   151  		t.Fatal(err)
   152  	}
   153  	<-issuer
   154  
   155  	// If we've reached this point, we expect to be able to build and verify the block without any errors
   156  	blk, err := vm.BuildBlock()
   157  	if err != nil {
   158  		t.Fatal(err)
   159  	}
   160  
   161  	if err := blk.Verify(); err != nil {
   162  		t.Fatal(err)
   163  	}
   164  
   165  	if err := blk.Accept(); len(test.acceptErr) == 0 && err != nil {
   166  		t.Fatalf("Accept failed unexpectedly due to: %s", err)
   167  	} else if len(test.acceptErr) != 0 {
   168  		if err == nil {
   169  			t.Fatalf("Accept unexpectedly returned a nil error. Expected err: %s", test.acceptErr)
   170  		}
   171  		if !strings.Contains(err.Error(), test.acceptErr) {
   172  			t.Fatalf("Expected Accept to fail due to %s, but failed with: %s", test.acceptErr, err)
   173  		}
   174  		// If Accept failed for the expected reason, return early
   175  		return
   176  	}
   177  
   178  	if test.checkState != nil {
   179  		test.checkState(t, vm)
   180  	}
   181  }