github.com/iotexproject/iotex-core@v1.14.1-rc1/action/protocol/generic_validator_test.go (about)

     1  // Copyright (c) 2019 IoTeX Foundation
     2  // This source code is provided 'as is' and no warranties are given as to title or non-infringement, merchantability
     3  // or fitness for purpose and, to the extent permitted by law, all liability for your use of the code is disclaimed.
     4  // This source code is governed by Apache License 2.0 that can be found in the LICENSE file.
     5  
     6  package protocol
     7  
     8  import (
     9  	"context"
    10  	"encoding/hex"
    11  	"math/big"
    12  	"strings"
    13  	"testing"
    14  	"time"
    15  
    16  	"github.com/golang/mock/gomock"
    17  	"github.com/iotexproject/iotex-address/address"
    18  	"github.com/pkg/errors"
    19  	"github.com/stretchr/testify/require"
    20  
    21  	"github.com/iotexproject/iotex-core/action"
    22  	"github.com/iotexproject/iotex-core/blockchain/genesis"
    23  	"github.com/iotexproject/iotex-core/state"
    24  	"github.com/iotexproject/iotex-core/test/identityset"
    25  )
    26  
    27  const _evmNetworkID uint32 = 4689
    28  
    29  func TestActionProtoAndGenericValidator(t *testing.T) {
    30  	require := require.New(t)
    31  	ctrl := gomock.NewController(t)
    32  	defer ctrl.Finish()
    33  
    34  	caller, err := address.FromString("io1mflp9m6hcgm2qcghchsdqj3z3eccrnekx9p0ms")
    35  	require.NoError(err)
    36  	producer, err := address.FromString("io1emxf8zzqckhgjde6dqd97ts0y3q496gm3fdrl6")
    37  	require.NoError(err)
    38  
    39  	ctx := WithBlockCtx(context.Background(),
    40  		BlockCtx{
    41  			BlockHeight: 1,
    42  			Producer:    producer,
    43  		})
    44  	ctx = WithActionCtx(ctx,
    45  		ActionCtx{
    46  			Caller: caller,
    47  		})
    48  
    49  	ctx = WithBlockchainCtx(
    50  		ctx,
    51  		BlockchainCtx{
    52  			Tip: TipInfo{
    53  				Height:    0,
    54  				Hash:      genesis.Default.Hash(),
    55  				Timestamp: time.Unix(genesis.Default.Timestamp, 0),
    56  			},
    57  		},
    58  	)
    59  
    60  	ctx = WithFeatureCtx(genesis.WithGenesisContext(ctx, genesis.Default))
    61  
    62  	valid := NewGenericValidator(nil, func(_ context.Context, sr StateReader, addr address.Address) (*state.Account, error) {
    63  		pk := identityset.PrivateKey(27).PublicKey()
    64  		eAddr := pk.Address()
    65  		if strings.EqualFold(eAddr.String(), addr.String()) {
    66  			return nil, errors.New("MockChainManager nonce error")
    67  		}
    68  		acct, err := state.NewAccount()
    69  		if err != nil {
    70  			return nil, err
    71  		}
    72  		if err := acct.SetPendingNonce(1); err != nil {
    73  			return nil, err
    74  		}
    75  		if err := acct.SetPendingNonce(2); err != nil {
    76  			return nil, err
    77  		}
    78  		if err := acct.SetPendingNonce(3); err != nil {
    79  			return nil, err
    80  		}
    81  
    82  		return acct, nil
    83  	})
    84  	data, err := hex.DecodeString("")
    85  	require.NoError(err)
    86  	t.Run("normal", func(t *testing.T) {
    87  		v, err := action.NewExecution("", 3, big.NewInt(10), uint64(10), big.NewInt(10), data)
    88  		require.NoError(err)
    89  		bd := &action.EnvelopeBuilder{}
    90  		elp := bd.SetGasPrice(big.NewInt(10)).
    91  			SetGasLimit(uint64(100000)).
    92  			SetNonce(3).
    93  			SetAction(v).Build()
    94  		selp, err := action.Sign(elp, identityset.PrivateKey(28))
    95  		require.NoError(err)
    96  		nselp, err := (&action.Deserializer{}).SetEvmNetworkID(_evmNetworkID).ActionToSealedEnvelope(selp.Proto())
    97  		require.NoError(err)
    98  		require.NoError(valid.Validate(ctx, nselp))
    99  	})
   100  	t.Run("Gas limit low", func(t *testing.T) {
   101  		v, err := action.NewExecution("", 0, big.NewInt(10), uint64(10), big.NewInt(10), data)
   102  		require.NoError(err)
   103  		bd := &action.EnvelopeBuilder{}
   104  		elp := bd.SetGasPrice(big.NewInt(10)).
   105  			SetGasLimit(uint64(10)).
   106  			SetAction(v).Build()
   107  		selp, err := action.Sign(elp, identityset.PrivateKey(28))
   108  		require.NoError(err)
   109  		nselp, err := (&action.Deserializer{}).SetEvmNetworkID(_evmNetworkID).ActionToSealedEnvelope(selp.Proto())
   110  		require.NoError(err)
   111  		err = valid.Validate(ctx, nselp)
   112  		require.Error(err)
   113  		require.Contains(err.Error(), action.ErrIntrinsicGas.Error())
   114  	})
   115  	t.Run("state error", func(t *testing.T) {
   116  		v, err := action.NewExecution("", 1, big.NewInt(10), uint64(10), big.NewInt(10), data)
   117  		require.NoError(err)
   118  		bd := &action.EnvelopeBuilder{}
   119  		elp := bd.SetGasPrice(big.NewInt(10)).
   120  			SetGasLimit(uint64(100000)).
   121  			SetNonce(1).
   122  			SetAction(v).Build()
   123  		selp, err := action.Sign(elp, identityset.PrivateKey(27))
   124  		require.NoError(err)
   125  		nselp, err := (&action.Deserializer{}).SetEvmNetworkID(_evmNetworkID).ActionToSealedEnvelope(selp.Proto())
   126  		require.NoError(err)
   127  		err = valid.Validate(ctx, nselp)
   128  		require.Error(err)
   129  		require.Contains(err.Error(), "invalid state of account")
   130  	})
   131  	t.Run("invalid system action nonce", func(t *testing.T) {
   132  		gr := action.GrantReward{}
   133  		gr.SetNonce(1)
   134  		bd := &action.EnvelopeBuilder{}
   135  		elp := bd.SetGasPrice(big.NewInt(10)).
   136  			SetNonce(1).
   137  			SetGasLimit(uint64(100000)).
   138  			SetAction(&gr).Build()
   139  		selp, err := action.Sign(elp, identityset.PrivateKey(28))
   140  		require.NoError(err)
   141  		nselp, err := (&action.Deserializer{}).SetEvmNetworkID(_evmNetworkID).ActionToSealedEnvelope(selp.Proto())
   142  		require.NoError(err)
   143  		err = valid.Validate(ctx, nselp)
   144  		require.Equal(action.ErrSystemActionNonce, errors.Cause(err))
   145  	})
   146  	t.Run("nonce too low", func(t *testing.T) {
   147  		v, err := action.NewExecution("", 1, big.NewInt(10), uint64(10), big.NewInt(10), data)
   148  		require.NoError(err)
   149  		bd := &action.EnvelopeBuilder{}
   150  		elp := bd.SetGasPrice(big.NewInt(10)).
   151  			SetNonce(1).
   152  			SetGasLimit(uint64(100000)).
   153  			SetAction(v).Build()
   154  		selp, err := action.Sign(elp, identityset.PrivateKey(28))
   155  		require.NoError(err)
   156  		nselp, err := (&action.Deserializer{}).SetEvmNetworkID(_evmNetworkID).ActionToSealedEnvelope(selp.Proto())
   157  		require.NoError(err)
   158  		err = valid.Validate(ctx, nselp)
   159  		require.Error(err)
   160  		require.Equal(action.ErrNonceTooLow, errors.Cause(err))
   161  	})
   162  	t.Run("wrong recipient", func(t *testing.T) {
   163  		v, err := action.NewTransfer(1, big.NewInt(1), "io1qyqsyqcyq5narhapakcsrhksfajfcpl24us3xp38zwvsep", []byte{}, uint64(100000), big.NewInt(10))
   164  		require.NoError(err)
   165  		bd := &action.EnvelopeBuilder{}
   166  		elp := bd.SetAction(v).SetGasLimit(100000).
   167  			SetGasPrice(big.NewInt(10)).
   168  			SetNonce(1).Build()
   169  		selp, err := action.Sign(elp, identityset.PrivateKey(27))
   170  		require.NoError(err)
   171  		require.Error(valid.Validate(ctx, selp))
   172  	})
   173  	t.Run("wrong signature", func(t *testing.T) {
   174  		unsignedTsf, err := action.NewTransfer(uint64(1), big.NewInt(1), caller.String(), []byte{}, uint64(100000), big.NewInt(0))
   175  		require.NoError(err)
   176  
   177  		bd := &action.EnvelopeBuilder{}
   178  		elp := bd.SetNonce(1).
   179  			SetAction(unsignedTsf).
   180  			SetGasLimit(100000).Build()
   181  		selp := action.FakeSeal(elp, identityset.PrivateKey(27).PublicKey())
   182  		err = valid.Validate(ctx, selp)
   183  		require.Contains(err.Error(), action.ErrInvalidSender.Error())
   184  	})
   185  }