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 }