github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/libs/cosmos-sdk/x/auth/ante/sigverify_test.go (about) 1 package ante_test 2 3 import ( 4 "fmt" 5 "testing" 6 7 "github.com/fibonacci-chain/fbc/libs/tendermint/crypto" 8 "github.com/fibonacci-chain/fbc/libs/tendermint/crypto/ed25519" 9 "github.com/fibonacci-chain/fbc/libs/tendermint/crypto/multisig" 10 "github.com/fibonacci-chain/fbc/libs/tendermint/crypto/secp256k1" 11 "github.com/stretchr/testify/require" 12 13 sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types" 14 sdkerrors "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types/errors" 15 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types/tx/signing" 16 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/auth/ante" 17 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/auth/types" 18 ) 19 20 func TestSetPubKey(t *testing.T) { 21 // setup 22 app, ctx := createTestApp(true) 23 24 // keys and addresses 25 priv1, pub1, addr1 := types.KeyTestPubAddr() 26 priv2, pub2, addr2 := types.KeyTestPubAddr() 27 priv3, pub3, addr3 := types.KeyTestPubAddr() 28 29 addrs := []sdk.AccAddress{addr1, addr2, addr3} 30 pubs := []crypto.PubKey{pub1, pub2, pub3} 31 32 msgs := make([]sdk.Msg, len(addrs)) 33 // set accounts and create msg for each address 34 for i, addr := range addrs { 35 acc := app.AccountKeeper.NewAccountWithAddress(ctx, addr) 36 require.NoError(t, acc.SetAccountNumber(uint64(i))) 37 app.AccountKeeper.SetAccount(ctx, acc) 38 msgs[i] = types.NewTestMsg(addr) 39 } 40 41 fee := types.NewTestStdFee() 42 43 privs, accNums, seqs := []crypto.PrivKey{priv1, priv2, priv3}, []uint64{0, 1, 2}, []uint64{0, 0, 0} 44 tx := types.NewTestTx(ctx, msgs, privs, accNums, seqs, fee) 45 46 spkd := ante.NewSetPubKeyDecorator(app.AccountKeeper) 47 antehandler := sdk.ChainAnteDecorators(spkd) 48 49 ctx, err := antehandler(ctx, tx, false) 50 require.Nil(t, err) 51 52 // Require that all accounts have pubkey set after Decorator runs 53 for i, addr := range addrs { 54 pk, err := app.AccountKeeper.GetPubKey(ctx, addr) 55 require.Nil(t, err, "Error on retrieving pubkey from account") 56 require.Equal(t, pubs[i], pk, "Pubkey retrieved from account is unexpected") 57 } 58 } 59 60 func TestConsumeSignatureVerificationGas(t *testing.T) { 61 params := types.DefaultParams() 62 msg := []byte{1, 2, 3, 4} 63 64 pkSet1, sigSet1 := generatePubKeysAndSignatures(5, msg, false) 65 multisigKey1 := multisig.NewPubKeyMultisigThreshold(2, pkSet1) 66 multisignature1 := multisig.NewMultisig(len(pkSet1)) 67 expectedCost1 := expectedGasCostByKeys(pkSet1) 68 for i := 0; i < len(pkSet1); i++ { 69 multisignature1.AddSignatureFromPubKey(sigSet1[i], pkSet1[i], pkSet1) 70 } 71 72 type args struct { 73 meter sdk.GasMeter 74 sig []byte 75 pubkey crypto.PubKey 76 params types.Params 77 } 78 tests := []struct { 79 name string 80 args args 81 gasConsumed uint64 82 shouldErr bool 83 }{ 84 {"PubKeyEd25519", args{sdk.NewInfiniteGasMeter(), nil, ed25519.GenPrivKey().PubKey(), params}, types.DefaultSigVerifyCostED25519, true}, 85 {"PubKeySecp256k1", args{sdk.NewInfiniteGasMeter(), nil, secp256k1.GenPrivKey().PubKey(), params}, types.DefaultSigVerifyCostSecp256k1, false}, 86 {"Multisig", args{sdk.NewInfiniteGasMeter(), multisignature1.Marshal(), multisigKey1, params}, expectedCost1, false}, 87 {"unknown key", args{sdk.NewInfiniteGasMeter(), nil, nil, params}, 0, true}, 88 } 89 for _, tt := range tests { 90 tt := tt 91 t.Run(tt.name, func(t *testing.T) { 92 err := ante.DefaultSigVerificationGasConsumer(tt.args.meter, tt.args.sig, tt.args.pubkey, tt.args.params) 93 94 if tt.shouldErr { 95 require.NotNil(t, err) 96 } else { 97 require.Nil(t, err) 98 require.Equal(t, tt.gasConsumed, tt.args.meter.GasConsumed(), fmt.Sprintf("%d != %d", tt.gasConsumed, tt.args.meter.GasConsumed())) 99 } 100 }) 101 } 102 } 103 104 func TestSigVerification(t *testing.T) { 105 // setup 106 app, ctx := createTestApp(true) 107 // make block height non-zero to ensure account numbers part of signBytes 108 ctx.SetBlockHeight(1) 109 110 // keys and addresses 111 priv1, _, addr1 := types.KeyTestPubAddr() 112 priv2, _, addr2 := types.KeyTestPubAddr() 113 priv3, _, addr3 := types.KeyTestPubAddr() 114 115 addrs := []sdk.AccAddress{addr1, addr2, addr3} 116 117 msgs := make([]sdk.Msg, len(addrs)) 118 // set accounts and create msg for each address 119 for i, addr := range addrs { 120 acc := app.AccountKeeper.NewAccountWithAddress(ctx, addr) 121 require.NoError(t, acc.SetAccountNumber(uint64(i))) 122 app.AccountKeeper.SetAccount(ctx, acc) 123 msgs[i] = types.NewTestMsg(addr) 124 } 125 126 fee := types.NewTestStdFee() 127 128 spkd := ante.NewSetPubKeyDecorator(app.AccountKeeper) 129 svd := ante.NewSigVerificationDecorator(app.AccountKeeper) 130 antehandler := sdk.ChainAnteDecorators(spkd, svd) 131 132 type testCase struct { 133 name string 134 privs []crypto.PrivKey 135 accNums []uint64 136 seqs []uint64 137 recheck bool 138 shouldErr bool 139 } 140 testCases := []testCase{ 141 {"no signers", []crypto.PrivKey{}, []uint64{}, []uint64{}, false, true}, 142 {"not enough signers", []crypto.PrivKey{priv1, priv2}, []uint64{0, 1}, []uint64{0, 0}, false, true}, 143 {"wrong order signers", []crypto.PrivKey{priv3, priv2, priv1}, []uint64{2, 1, 0}, []uint64{0, 0, 0}, false, true}, 144 {"wrong accnums", []crypto.PrivKey{priv1, priv2, priv3}, []uint64{7, 8, 9}, []uint64{0, 0, 0}, false, true}, 145 {"wrong sequences", []crypto.PrivKey{priv1, priv2, priv3}, []uint64{0, 1, 2}, []uint64{3, 4, 5}, false, true}, 146 {"valid tx", []crypto.PrivKey{priv1, priv2, priv3}, []uint64{0, 1, 2}, []uint64{0, 0, 0}, false, false}, 147 {"no err on recheck", []crypto.PrivKey{}, []uint64{}, []uint64{}, true, false}, 148 } 149 for i, tc := range testCases { 150 ctx.SetIsReCheckTx(tc.recheck) 151 152 tx := types.NewTestTx(ctx, msgs, tc.privs, tc.accNums, tc.seqs, fee) 153 154 _, err := antehandler(ctx, tx, false) 155 if tc.shouldErr { 156 require.NotNil(t, err, "TestCase %d: %s did not error as expected", i, tc.name) 157 } else { 158 require.Nil(t, err, "TestCase %d: %s errored unexpectedly. Err: %v", i, tc.name, err) 159 } 160 } 161 } 162 163 func TestIbcSignModeSigVerify(t *testing.T) { 164 app, ctx := createTestApp(true) 165 ctx.SetBlockHeight(1) 166 priv, _, addr := types.KeyTestPubAddr() 167 app.AccountKeeper.SetAccount(ctx, app.AccountKeeper.NewAccountWithAddress(ctx, addr)) 168 handler := sdk.ChainAnteDecorators(ante.NewSetPubKeyDecorator(app.AccountKeeper), ante.NewSigVerificationDecorator(app.AccountKeeper)) 169 170 type testCase struct { 171 name string 172 simulate bool 173 signMode signing.SignMode 174 err error 175 } 176 testCases := []testCase{ 177 { 178 "sign mode unspecified, error", 179 false, 180 signing.SignMode_SIGN_MODE_UNSPECIFIED, 181 sdkerrors.Wrap(sdkerrors.ErrUnauthorized, "signature verification failed"), 182 }, { 183 "sign mode unspecified, success", 184 true, 185 signing.SignMode_SIGN_MODE_UNSPECIFIED, 186 nil, 187 }, { 188 "sign mode legacy amino, error", 189 false, 190 signing.SignMode_SIGN_MODE_LEGACY_AMINO_JSON, 191 sdkerrors.Wrap(sdkerrors.ErrUnauthorized, "signature verification failed"), 192 }, { 193 "sign mode legacy amino, success", 194 true, 195 signing.SignMode_SIGN_MODE_LEGACY_AMINO_JSON, 196 nil, 197 }, 198 } 199 for _, tc := range testCases { 200 stdTx := types.NewTestTx(ctx, []sdk.Msg{types.NewTestMsg(addr)}, []crypto.PrivKey{priv}, []uint64{0}, []uint64{0}, types.NewTestStdFee()) 201 tx := fakeIbcTx(stdTx, []signing.SignMode{tc.signMode}, types.IbcFee{}, []uint64{0}) 202 _, err := handler(ctx, tx, tc.simulate) 203 if tc.err == nil { 204 require.Equal(t, tc.err, err) 205 } else { 206 require.Equal(t, tc.err.Error()[0:30], err.Error()[0:30]) 207 } 208 } 209 } 210 211 func fakeIbcTx(stdTx sdk.Tx, signMode []signing.SignMode, sigFee types.IbcFee, sequences []uint64) *types.IbcTx { 212 return &types.IbcTx{ 213 StdTx: stdTx.(*types.StdTx), 214 SignMode: signMode, 215 SigFee: sigFee, 216 Sequences: sequences, 217 } 218 } 219 220 func TestSigIntegration(t *testing.T) { 221 // generate private keys 222 privs := []crypto.PrivKey{secp256k1.GenPrivKey(), secp256k1.GenPrivKey(), secp256k1.GenPrivKey()} 223 224 params := types.DefaultParams() 225 initialSigCost := params.SigVerifyCostSecp256k1 226 initialCost, err := runSigDecorators(t, params, false, privs...) 227 require.Nil(t, err) 228 229 params.SigVerifyCostSecp256k1 *= 2 230 doubleCost, err := runSigDecorators(t, params, false, privs...) 231 require.Nil(t, err) 232 233 require.Equal(t, initialSigCost*uint64(len(privs)), doubleCost-initialCost) 234 } 235 236 func runSigDecorators(t *testing.T, params types.Params, multisig bool, privs ...crypto.PrivKey) (sdk.Gas, error) { 237 // setup 238 app, ctx := createTestApp(true) 239 // Make block-height non-zero to include accNum in SignBytes 240 ctx.SetBlockHeight(1) 241 app.AccountKeeper.SetParams(ctx, params) 242 243 msgs := make([]sdk.Msg, len(privs)) 244 accNums := make([]uint64, len(privs)) 245 seqs := make([]uint64, len(privs)) 246 // set accounts and create msg for each address 247 for i, priv := range privs { 248 addr := sdk.AccAddress(priv.PubKey().Address()) 249 acc := app.AccountKeeper.NewAccountWithAddress(ctx, addr) 250 require.NoError(t, acc.SetAccountNumber(uint64(i))) 251 app.AccountKeeper.SetAccount(ctx, acc) 252 msgs[i] = types.NewTestMsg(addr) 253 accNums[i] = uint64(i) 254 seqs[i] = uint64(0) 255 } 256 257 fee := types.NewTestStdFee() 258 259 tx := types.NewTestTx(ctx, msgs, privs, accNums, seqs, fee) 260 261 spkd := ante.NewSetPubKeyDecorator(app.AccountKeeper) 262 svgc := ante.NewSigGasConsumeDecorator(app.AccountKeeper, ante.DefaultSigVerificationGasConsumer) 263 svd := ante.NewSigVerificationDecorator(app.AccountKeeper) 264 antehandler := sdk.ChainAnteDecorators(spkd, svgc, svd) 265 266 // Determine gas consumption of antehandler with default params 267 before := ctx.GasMeter().GasConsumed() 268 ctx, err := antehandler(ctx, tx, false) 269 after := ctx.GasMeter().GasConsumed() 270 271 return after - before, err 272 } 273 274 func TestIncrementSequenceDecorator(t *testing.T) { 275 app, ctx := createTestApp(true) 276 277 priv, _, addr := types.KeyTestPubAddr() 278 acc := app.AccountKeeper.NewAccountWithAddress(ctx, addr) 279 require.NoError(t, acc.SetAccountNumber(uint64(50))) 280 app.AccountKeeper.SetAccount(ctx, acc) 281 282 msgs := []sdk.Msg{types.NewTestMsg(addr)} 283 privKeys := []crypto.PrivKey{priv} 284 accNums := []uint64{app.AccountKeeper.GetAccount(ctx, addr).GetAccountNumber()} 285 accSeqs := []uint64{app.AccountKeeper.GetAccount(ctx, addr).GetSequence()} 286 fee := types.NewTestStdFee() 287 tx := types.NewTestTx(ctx, msgs, privKeys, accNums, accSeqs, fee) 288 289 isd := ante.NewIncrementSequenceDecorator(app.AccountKeeper) 290 antehandler := sdk.ChainAnteDecorators(isd) 291 292 testCases := []struct { 293 ctx sdk.Context 294 simulate bool 295 expectedSeq uint64 296 }{ 297 {ctx.WithIsReCheckTx(true), false, 1}, 298 {ctx.WithIsCheckTx(true).WithIsReCheckTx(false), false, 2}, 299 {ctx.WithIsReCheckTx(true), false, 3}, 300 {ctx.WithIsReCheckTx(true), false, 4}, 301 {ctx.WithIsReCheckTx(true), true, 5}, 302 } 303 304 for i, tc := range testCases { 305 _, err := antehandler(tc.ctx, tx, tc.simulate) 306 require.NoError(t, err, "unexpected error; tc #%d, %v", i, tc) 307 require.Equal(t, tc.expectedSeq, app.AccountKeeper.GetAccount(ctx, addr).GetSequence()) 308 } 309 }