cosmos-sdk/x/tx/decode/fuzz_test.go
testinginprod 6d2f6ff068
feat(tx): port simappv2 changes (#20648)
Co-authored-by: unknown unknown <unknown@unknown>
Co-authored-by: Julien Robert <julien@rbrt.fr>
2024-06-17 09:54:52 +00:00

149 lines
3.1 KiB
Go

package decode
import (
"encoding/hex"
"testing"
"github.com/cosmos/cosmos-proto/anyutil"
gogoproto "github.com/cosmos/gogoproto/proto"
fuzz "github.com/google/gofuzz"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/types/known/anypb"
bankv1beta1 "cosmossdk.io/api/cosmos/bank/v1beta1"
basev1beta1 "cosmossdk.io/api/cosmos/base/v1beta1"
"cosmossdk.io/api/cosmos/crypto/secp256k1"
signingv1beta1 "cosmossdk.io/api/cosmos/tx/signing/v1beta1"
txv1beta1 "cosmossdk.io/api/cosmos/tx/v1beta1"
"cosmossdk.io/x/tx/signing"
)
type mockCodec struct{}
func (m mockCodec) Unmarshal(bytes []byte, message gogoproto.Message) error {
return gogoproto.Unmarshal(bytes, message)
}
var (
accSeq = uint64(2)
signerInfo = []*txv1beta1.SignerInfo{
{
PublicKey: pkAny,
ModeInfo: &txv1beta1.ModeInfo{
Sum: &txv1beta1.ModeInfo_Single_{
Single: &txv1beta1.ModeInfo_Single{
Mode: signingv1beta1.SignMode_SIGN_MODE_DIRECT,
},
},
},
Sequence: accSeq,
},
}
anyMsg, _ = anyutil.New(&bankv1beta1.MsgSend{})
pkAny, _ = anyutil.New(&secp256k1.PubKey{Key: []byte("foo")})
)
func generateAndAddSeedsFromTx(f *testing.F) {
f.Helper()
// 1. Add some seeds.
tx := &txv1beta1.Tx{
Body: &txv1beta1.TxBody{
Messages: []*anypb.Any{anyMsg},
Memo: "memo",
TimeoutHeight: 0,
},
AuthInfo: &txv1beta1.AuthInfo{
SignerInfos: signerInfo,
Fee: &txv1beta1.Fee{
Amount: []*basev1beta1.Coin{{Amount: "100", Denom: "denom"}},
GasLimit: 100,
Payer: "payer",
Granter: "",
},
},
Signatures: nil,
}
f.Add(mustMarshal(f, tx))
fz := fuzz.New()
// 1.1. Mutate tx as much and add those as seeds.
for i := 0; i < 1e4; i++ {
func() {
defer func() {
_ = recover() // Catch any panics and continue
}()
fz.Fuzz(tx)
f.Add(mustMarshal(f, tx))
}()
}
}
func FuzzInternal_rejectNonADR027TxRaw(f *testing.F) {
if testing.Short() {
f.Skip("Skipping in -short mode")
}
// 1. Add some seeds.
generateAndAddSeedsFromTx(f)
// 2. Now run the fuzzer.
f.Fuzz(func(t *testing.T, in []byte) {
// Just ensure it doesn't crash.
_ = rejectNonADR027TxRaw(in)
})
}
func FuzzDecode(f *testing.F) {
if testing.Short() {
f.Skip("Skipping in -short mode")
}
// 1. Add some seeds.
generateAndAddSeedsFromTx(f)
// 2. Now fuzz it.
cdc := new(asHexCodec)
signingCtx, err := signing.NewContext(signing.Options{
AddressCodec: cdc,
ValidatorAddressCodec: cdc,
})
if err != nil {
return
}
dec, err := NewDecoder(Options{
SigningContext: signingCtx,
ProtoCodec: mockCodec{},
})
if err != nil {
return
}
f.Fuzz(func(t *testing.T, in []byte) {
txr, err := dec.Decode(in)
if err == nil && txr == nil {
t.Fatal("inconsistency: err==nil yet tx==nil")
}
})
}
func mustMarshal(f *testing.F, m proto.Message) []byte {
f.Helper()
blob, err := proto.Marshal(m)
if err != nil {
f.Fatal(err)
}
return blob
}
type asHexCodec int
func (d asHexCodec) StringToBytes(text string) ([]byte, error) {
return hex.DecodeString(text)
}
func (d asHexCodec) BytesToString(bz []byte) (string, error) {
return hex.EncodeToString(bz), nil
}