github.com/nspcc-dev/neo-go@v0.105.2-0.20240517133400-6be757af3eba/pkg/vm/fuzz_test.go (about)

     1  package vm
     2  
     3  import (
     4  	"testing"
     5  
     6  	"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
     7  	"github.com/nspcc-dev/neo-go/pkg/smartcontract"
     8  	"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
     9  	"github.com/stretchr/testify/require"
    10  )
    11  
    12  var fuzzSeedValidScripts = [][]byte{
    13  	makeProgram(opcode.PUSH1, opcode.PUSH10, opcode.ADD),
    14  	makeProgram(opcode.PUSH10, opcode.JMP, 3, opcode.ABORT, opcode.RET),
    15  	makeProgram(opcode.PUSHINT16, 1, 2, opcode.PUSHINT32, 3, 4, opcode.DROP),
    16  	makeProgram(opcode.PUSH2, opcode.NEWARRAY, opcode.DUP, opcode.PUSH0, opcode.PUSH1, opcode.SETITEM, opcode.VALUES),
    17  	append([]byte{byte(opcode.PUSHDATA1), 10}, randomBytes(10)...),
    18  	append([]byte{byte(opcode.PUSHDATA1), 100}, randomBytes(100)...),
    19  	// Simplified version of fuzzer output from #2659.
    20  	{byte(opcode.CALL), 3, byte(opcode.ASSERT),
    21  		byte(opcode.CALL), 3, byte(opcode.ASSERT),
    22  		byte(opcode.DEPTH), byte(opcode.PACKSTRUCT), byte(opcode.DUP),
    23  		byte(opcode.UNPACK), byte(opcode.PACKSTRUCT), byte(opcode.POPITEM),
    24  		byte(opcode.DEPTH)},
    25  }
    26  
    27  func FuzzIsScriptCorrect(f *testing.F) {
    28  	for _, s := range fuzzSeedValidScripts {
    29  		f.Add(s)
    30  	}
    31  	f.Fuzz(func(t *testing.T, script []byte) {
    32  		require.NotPanics(t, func() {
    33  			_ = IsScriptCorrect(script, nil)
    34  		})
    35  	})
    36  }
    37  
    38  func FuzzParseMultiSigContract(f *testing.F) {
    39  	pubs := make(keys.PublicKeys, 10)
    40  	for i := range pubs {
    41  		p, _ := keys.NewPrivateKey()
    42  		pubs[i] = p.PublicKey()
    43  	}
    44  
    45  	s, _ := smartcontract.CreateMultiSigRedeemScript(1, pubs[:1])
    46  	f.Add(s)
    47  
    48  	s, _ = smartcontract.CreateMultiSigRedeemScript(3, pubs[:6])
    49  	f.Add(s)
    50  
    51  	s, _ = smartcontract.CreateMultiSigRedeemScript(1, pubs)
    52  	f.Add(s)
    53  
    54  	f.Fuzz(func(t *testing.T, script []byte) {
    55  		var b [][]byte
    56  		var ok bool
    57  		var n int
    58  		require.NotPanics(t, func() {
    59  			n, b, ok = ParseMultiSigContract(script)
    60  		})
    61  		if ok {
    62  			require.True(t, n <= len(b))
    63  		}
    64  	})
    65  }
    66  
    67  func FuzzVMDontPanic(f *testing.F) {
    68  	for _, s := range fuzzSeedValidScripts {
    69  		f.Add(s)
    70  	}
    71  	f.Fuzz(func(t *testing.T, script []byte) {
    72  		if IsScriptCorrect(script, nil) != nil {
    73  			return
    74  		}
    75  
    76  		v := load(script)
    77  
    78  		// Prevent infinite loops from being reported as fail.
    79  		v.GasLimit = 1000
    80  		v.getPrice = func(opcode.Opcode, []byte) int64 {
    81  			return 1
    82  		}
    83  
    84  		require.NotPanics(t, func() {
    85  			_ = v.Run()
    86  		})
    87  	})
    88  }