diff --git a/pkg/consensus/consensus.go b/pkg/consensus/consensus.go index 61f7fea11..c404561d0 100644 --- a/pkg/consensus/consensus.go +++ b/pkg/consensus/consensus.go @@ -12,7 +12,7 @@ import ( "github.com/CityOfZion/neo-go/pkg/crypto/keys" "github.com/CityOfZion/neo-go/pkg/smartcontract" "github.com/CityOfZion/neo-go/pkg/util" - "github.com/CityOfZion/neo-go/pkg/vm" + "github.com/CityOfZion/neo-go/pkg/vm/opcode" "github.com/CityOfZion/neo-go/pkg/wallet" "github.com/nspcc-dev/dbft" "github.com/nspcc-dev/dbft/block" @@ -283,7 +283,7 @@ func (s *service) getBlockWitness(b *core.Block) *transaction.Witness { var invoc []byte for i, j := 0, 0; i < len(pubs) && j < m; i++ { if sig, ok := sigs[pubs[i]]; ok { - invoc = append(invoc, byte(vm.PUSHBYTES64)) + invoc = append(invoc, byte(opcode.PUSHBYTES64)) invoc = append(invoc, sig...) j++ } diff --git a/pkg/consensus/payload.go b/pkg/consensus/payload.go index 881d0bbf1..e80f4bb79 100644 --- a/pkg/consensus/payload.go +++ b/pkg/consensus/payload.go @@ -10,6 +10,7 @@ import ( "github.com/CityOfZion/neo-go/pkg/smartcontract" "github.com/CityOfZion/neo-go/pkg/util" "github.com/CityOfZion/neo-go/pkg/vm" + "github.com/CityOfZion/neo-go/pkg/vm/opcode" "github.com/nspcc-dev/dbft/payload" "github.com/pkg/errors" ) @@ -193,7 +194,7 @@ func (p *Payload) Sign(key *privateKey) error { return err } - p.Witness.InvocationScript = append([]byte{byte(vm.PUSHBYTES64)}, sig...) + p.Witness.InvocationScript = append([]byte{byte(opcode.PUSHBYTES64)}, sig...) p.Witness.VerificationScript = verif return nil diff --git a/pkg/core/util.go b/pkg/core/util.go index db97c7f86..05ba10bdd 100644 --- a/pkg/core/util.go +++ b/pkg/core/util.go @@ -9,7 +9,7 @@ import ( "github.com/CityOfZion/neo-go/pkg/crypto/keys" "github.com/CityOfZion/neo-go/pkg/smartcontract" "github.com/CityOfZion/neo-go/pkg/util" - "github.com/CityOfZion/neo-go/pkg/vm" + "github.com/CityOfZion/neo-go/pkg/vm/opcode" ) // createGenesisBlock creates a genesis block based on the given configuration. @@ -33,7 +33,7 @@ func createGenesisBlock(cfg config.ProtocolConfiguration) (*Block, error) { NextConsensus: nextConsensus, Script: &transaction.Witness{ InvocationScript: []byte{}, - VerificationScript: []byte{byte(vm.PUSHT)}, + VerificationScript: []byte{byte(opcode.PUSHT)}, }, } @@ -77,7 +77,7 @@ func createGenesisBlock(cfg config.ProtocolConfiguration) (*Block, error) { Scripts: []*transaction.Witness{ { InvocationScript: []byte{}, - VerificationScript: []byte{byte(vm.PUSHT)}, + VerificationScript: []byte{byte(opcode.PUSHT)}, }, }, }, @@ -92,7 +92,7 @@ func createGenesisBlock(cfg config.ProtocolConfiguration) (*Block, error) { } func governingTokenTX() *transaction.Transaction { - admin := hash.Hash160([]byte{byte(vm.PUSHT)}) + admin := hash.Hash160([]byte{byte(opcode.PUSHT)}) registerTX := &transaction.RegisterTX{ AssetType: transaction.GoverningToken, Name: "[{\"lang\":\"zh-CN\",\"name\":\"小蚁股\"},{\"lang\":\"en\",\"name\":\"AntShare\"}]", @@ -115,7 +115,7 @@ func governingTokenTX() *transaction.Transaction { } func utilityTokenTX() *transaction.Transaction { - admin := hash.Hash160([]byte{byte(vm.PUSHF)}) + admin := hash.Hash160([]byte{byte(opcode.PUSHF)}) registerTX := &transaction.RegisterTX{ AssetType: transaction.UtilityToken, Name: "[{\"lang\":\"zh-CN\",\"name\":\"小蚁币\"},{\"lang\":\"en\",\"name\":\"AntCoin\"}]", diff --git a/pkg/rpc/txBuilder.go b/pkg/rpc/txBuilder.go index d9519d5fc..bd79511ef 100644 --- a/pkg/rpc/txBuilder.go +++ b/pkg/rpc/txBuilder.go @@ -13,6 +13,7 @@ import ( "github.com/CityOfZion/neo-go/pkg/smartcontract" "github.com/CityOfZion/neo-go/pkg/util" "github.com/CityOfZion/neo-go/pkg/vm" + "github.com/CityOfZion/neo-go/pkg/vm/opcode" errs "github.com/pkg/errors" ) @@ -281,7 +282,7 @@ func CreateFunctionInvocationScript(contract util.Uint160, params Params) ([]byt if err != nil { return nil, err } - err = vm.EmitOpcode(script, vm.PACK) + err = vm.EmitOpcode(script, opcode.PACK) if err != nil { return nil, err } diff --git a/pkg/smartcontract/contract.go b/pkg/smartcontract/contract.go index e51e356cb..123971d32 100644 --- a/pkg/smartcontract/contract.go +++ b/pkg/smartcontract/contract.go @@ -7,6 +7,7 @@ import ( "github.com/CityOfZion/neo-go/pkg/crypto/keys" "github.com/CityOfZion/neo-go/pkg/vm" + "github.com/CityOfZion/neo-go/pkg/vm/opcode" ) // CreateSignatureRedeemScript creates a check signature script runnable by VM. @@ -16,7 +17,7 @@ func CreateSignatureRedeemScript(key *keys.PublicKey) ([]byte, error) { if err != nil { return nil, err } - err = vm.EmitOpcode(buf, vm.CHECKSIG) + err = vm.EmitOpcode(buf, opcode.CHECKSIG) if err != nil { return nil, err } @@ -49,7 +50,7 @@ func CreateMultiSigRedeemScript(m int, publicKeys keys.PublicKeys) ([]byte, erro if err := vm.EmitInt(buf, int64(len(publicKeys))); err != nil { return nil, err } - if err := vm.EmitOpcode(buf, vm.CHECKMULTISIG); err != nil { + if err := vm.EmitOpcode(buf, opcode.CHECKMULTISIG); err != nil { return nil, err } diff --git a/pkg/smartcontract/contract_test.go b/pkg/smartcontract/contract_test.go index d011aa1b7..3f9667e16 100644 --- a/pkg/smartcontract/contract_test.go +++ b/pkg/smartcontract/contract_test.go @@ -5,7 +5,7 @@ import ( "github.com/CityOfZion/neo-go/pkg/crypto/keys" "github.com/CityOfZion/neo-go/pkg/io" - "github.com/CityOfZion/neo-go/pkg/vm" + "github.com/CityOfZion/neo-go/pkg/vm/opcode" "github.com/stretchr/testify/assert" ) @@ -24,7 +24,7 @@ func TestCreateMultiSigRedeemScript(t *testing.T) { br := io.NewBinReaderFromBuf(out) var b uint8 br.ReadLE(&b) - assert.Equal(t, vm.PUSH3, vm.Instruction(b)) + assert.Equal(t, opcode.PUSH3, opcode.Opcode(b)) for i := 0; i < len(validators); i++ { bb := br.ReadBytes() @@ -35,7 +35,7 @@ func TestCreateMultiSigRedeemScript(t *testing.T) { } br.ReadLE(&b) - assert.Equal(t, vm.PUSH3, vm.Instruction(b)) + assert.Equal(t, opcode.PUSH3, opcode.Opcode(b)) br.ReadLE(&b) - assert.Equal(t, vm.CHECKMULTISIG, vm.Instruction(b)) + assert.Equal(t, opcode.CHECKMULTISIG, opcode.Opcode(b)) } diff --git a/pkg/vm/compiler/codegen.go b/pkg/vm/compiler/codegen.go index c850b8dbc..45c9dde69 100644 --- a/pkg/vm/compiler/codegen.go +++ b/pkg/vm/compiler/codegen.go @@ -13,7 +13,7 @@ import ( "github.com/CityOfZion/neo-go/pkg/crypto" "github.com/CityOfZion/neo-go/pkg/io" - "github.com/CityOfZion/neo-go/pkg/vm" + "github.com/CityOfZion/neo-go/pkg/vm/opcode" ) // The identifier of the entry function. Default set to Main. @@ -95,13 +95,13 @@ func (c *codegen) emitLoadLocal(name string) { } func (c *codegen) emitLoadLocalPos(pos int) { - emitOpcode(c.prog.BinWriter, vm.DUPFROMALTSTACK) + emitOpcode(c.prog.BinWriter, opcode.DUPFROMALTSTACK) emitInt(c.prog.BinWriter, int64(pos)) - emitOpcode(c.prog.BinWriter, vm.PICKITEM) + emitOpcode(c.prog.BinWriter, opcode.PICKITEM) } func (c *codegen) emitStoreLocal(pos int) { - emitOpcode(c.prog.BinWriter, vm.DUPFROMALTSTACK) + emitOpcode(c.prog.BinWriter, opcode.DUPFROMALTSTACK) if pos < 0 { c.prog.Err = fmt.Errorf("invalid position to store local: %d", pos) @@ -110,19 +110,19 @@ func (c *codegen) emitStoreLocal(pos int) { emitInt(c.prog.BinWriter, int64(pos)) emitInt(c.prog.BinWriter, 2) - emitOpcode(c.prog.BinWriter, vm.ROLL) - emitOpcode(c.prog.BinWriter, vm.SETITEM) + emitOpcode(c.prog.BinWriter, opcode.ROLL) + emitOpcode(c.prog.BinWriter, opcode.SETITEM) } func (c *codegen) emitLoadField(i int) { emitInt(c.prog.BinWriter, int64(i)) - emitOpcode(c.prog.BinWriter, vm.PICKITEM) + emitOpcode(c.prog.BinWriter, opcode.PICKITEM) } func (c *codegen) emitStoreStructField(i int) { emitInt(c.prog.BinWriter, int64(i)) - emitOpcode(c.prog.BinWriter, vm.ROT) - emitOpcode(c.prog.BinWriter, vm.SETITEM) + emitOpcode(c.prog.BinWriter, opcode.ROT) + emitOpcode(c.prog.BinWriter, opcode.SETITEM) } // convertGlobals traverses the AST and only converts global declarations. @@ -163,8 +163,8 @@ func (c *codegen) convertFuncDecl(file ast.Node, decl *ast.FuncDecl) { // All globals copied into the scope of the function need to be added // to the stack size of the function. emitInt(c.prog.BinWriter, f.stackSize()+countGlobals(file)) - emitOpcode(c.prog.BinWriter, vm.NEWARRAY) - emitOpcode(c.prog.BinWriter, vm.TOALTSTACK) + emitOpcode(c.prog.BinWriter, opcode.NEWARRAY) + emitOpcode(c.prog.BinWriter, opcode.TOALTSTACK) // We need to handle methods, which in Go, is just syntactic sugar. // The method receiver will be passed in as first argument. @@ -202,9 +202,9 @@ func (c *codegen) convertFuncDecl(file ast.Node, decl *ast.FuncDecl) { // If this function returns the void (no return stmt) we will cleanup its junk on the stack. if !hasReturnStmt(decl) { - emitOpcode(c.prog.BinWriter, vm.FROMALTSTACK) - emitOpcode(c.prog.BinWriter, vm.DROP) - emitOpcode(c.prog.BinWriter, vm.RET) + emitOpcode(c.prog.BinWriter, opcode.FROMALTSTACK) + emitOpcode(c.prog.BinWriter, opcode.DROP) + emitOpcode(c.prog.BinWriter, opcode.RET) } } @@ -295,9 +295,9 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor { ast.Walk(c, n.Results[0]) } - emitOpcode(c.prog.BinWriter, vm.FROMALTSTACK) - emitOpcode(c.prog.BinWriter, vm.DROP) // Cleanup the stack. - emitOpcode(c.prog.BinWriter, vm.RET) + emitOpcode(c.prog.BinWriter, opcode.FROMALTSTACK) + emitOpcode(c.prog.BinWriter, opcode.DROP) // Cleanup the stack. + emitOpcode(c.prog.BinWriter, opcode.RET) return nil case *ast.IfStmt: @@ -307,13 +307,13 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor { if n.Cond != nil { ast.Walk(c, n.Cond) - emitJmp(c.prog.BinWriter, vm.JMPIFNOT, int16(lElse)) + emitJmp(c.prog.BinWriter, opcode.JMPIFNOT, int16(lElse)) } c.setLabel(lIf) ast.Walk(c, n.Body) if n.Else != nil { - emitJmp(c.prog.BinWriter, vm.JMP, int16(lElseEnd)) + emitJmp(c.prog.BinWriter, opcode.JMP, int16(lElseEnd)) } c.setLabel(lElse) @@ -359,7 +359,7 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor { c.emitLoadConst(c.typeInfo.Types[n.Elts[i]]) } emitInt(c.prog.BinWriter, int64(ln)) - emitOpcode(c.prog.BinWriter, vm.PACK) + emitOpcode(c.prog.BinWriter, opcode.PACK) return nil } @@ -374,13 +374,13 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor { switch n.Op { case token.LAND: ast.Walk(c, n.X) - emitJmp(c.prog.BinWriter, vm.JMPIFNOT, int16(len(c.l)-1)) + emitJmp(c.prog.BinWriter, opcode.JMPIFNOT, int16(len(c.l)-1)) ast.Walk(c, n.Y) return nil case token.LOR: ast.Walk(c, n.X) - emitJmp(c.prog.BinWriter, vm.JMPIF, int16(len(c.l)-3)) + emitJmp(c.prog.BinWriter, opcode.JMPIF, int16(len(c.l)-3)) ast.Walk(c, n.Y) return nil @@ -405,24 +405,24 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor { case n.Op == token.ADD: // VM has separate opcodes for number and string concatenation if isStringType(tinfo.Type) { - emitOpcode(c.prog.BinWriter, vm.CAT) + emitOpcode(c.prog.BinWriter, opcode.CAT) } else { - emitOpcode(c.prog.BinWriter, vm.ADD) + emitOpcode(c.prog.BinWriter, opcode.ADD) } case n.Op == token.EQL: // VM has separate opcodes for number and string equality if isStringType(c.typeInfo.Types[n.X].Type) { - emitOpcode(c.prog.BinWriter, vm.EQUAL) + emitOpcode(c.prog.BinWriter, opcode.EQUAL) } else { - emitOpcode(c.prog.BinWriter, vm.NUMEQUAL) + emitOpcode(c.prog.BinWriter, opcode.NUMEQUAL) } case n.Op == token.NEQ: // VM has separate opcodes for number and string equality if isStringType(c.typeInfo.Types[n.X].Type) { - emitOpcode(c.prog.BinWriter, vm.EQUAL) - emitOpcode(c.prog.BinWriter, vm.NOT) + emitOpcode(c.prog.BinWriter, opcode.EQUAL) + emitOpcode(c.prog.BinWriter, opcode.NOT) } else { - emitOpcode(c.prog.BinWriter, vm.NUMNOTEQUAL) + emitOpcode(c.prog.BinWriter, opcode.NUMNOTEQUAL) } default: c.convertToken(n.Op) @@ -478,14 +478,14 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor { // Do not swap for builtin functions. if !isBuiltin { if numArgs == 2 { - emitOpcode(c.prog.BinWriter, vm.SWAP) + emitOpcode(c.prog.BinWriter, opcode.SWAP) } else if numArgs == 3 { emitInt(c.prog.BinWriter, 2) - emitOpcode(c.prog.BinWriter, vm.XSWAP) + emitOpcode(c.prog.BinWriter, opcode.XSWAP) } else { for i := 1; i < numArgs; i++ { emitInt(c.prog.BinWriter, int64(i)) - emitOpcode(c.prog.BinWriter, vm.ROLL) + emitOpcode(c.prog.BinWriter, opcode.ROLL) } } } @@ -499,7 +499,7 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor { case isSyscall(f): c.convertSyscall(f.selector.Name, f.name) default: - emitCall(c.prog.BinWriter, vm.CALL, int16(f.label)) + emitCall(c.prog.BinWriter, opcode.CALL, int16(f.label)) } return nil @@ -529,11 +529,11 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor { case token.ADD: // +10 == 10, no need to do anything in this case case token.SUB: - emitOpcode(c.prog.BinWriter, vm.NEGATE) + emitOpcode(c.prog.BinWriter, opcode.NEGATE) case token.NOT: - emitOpcode(c.prog.BinWriter, vm.NOT) + emitOpcode(c.prog.BinWriter, opcode.NOT) case token.XOR: - emitOpcode(c.prog.BinWriter, vm.INVERT) + emitOpcode(c.prog.BinWriter, opcode.INVERT) default: c.prog.Err = fmt.Errorf("invalid unary operator: %s", n.Op) return nil @@ -565,7 +565,7 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor { c.emitLoadField(int(val)) default: ast.Walk(c, n.Index) - emitOpcode(c.prog.BinWriter, vm.PICKITEM) // just pickitem here + emitOpcode(c.prog.BinWriter, opcode.PICKITEM) // just pickitem here } return nil @@ -583,14 +583,14 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor { ast.Walk(c, n.Cond) // Jump if the condition is false - emitJmp(c.prog.BinWriter, vm.JMPIFNOT, int16(fend)) + emitJmp(c.prog.BinWriter, opcode.JMPIFNOT, int16(fend)) // Walk body followed by the iterator (post stmt). ast.Walk(c, n.Body) ast.Walk(c, n.Post) // Jump back to condition. - emitJmp(c.prog.BinWriter, vm.JMP, int16(fstart)) + emitJmp(c.prog.BinWriter, opcode.JMP, int16(fstart)) c.setLabel(fend) return nil @@ -616,7 +616,7 @@ func (c *codegen) convertSyscall(api, name string) { // This NOP instruction is basically not needed, but if we do, we have a // one to one matching avm file with neo-python which is very nice for debugging. - emitOpcode(c.prog.BinWriter, vm.NOP) + emitOpcode(c.prog.BinWriter, opcode.NOP) } func (c *codegen) convertBuiltin(expr *ast.CallExpr) { @@ -633,32 +633,32 @@ func (c *codegen) convertBuiltin(expr *ast.CallExpr) { arg := expr.Args[0] typ := c.typeInfo.Types[arg].Type if isStringType(typ) { - emitOpcode(c.prog.BinWriter, vm.SIZE) + emitOpcode(c.prog.BinWriter, opcode.SIZE) } else { - emitOpcode(c.prog.BinWriter, vm.ARRAYSIZE) + emitOpcode(c.prog.BinWriter, opcode.ARRAYSIZE) } case "append": arg := expr.Args[0] typ := c.typeInfo.Types[arg].Type if isByteArrayType(typ) { - emitOpcode(c.prog.BinWriter, vm.CAT) + emitOpcode(c.prog.BinWriter, opcode.CAT) } else { - emitOpcode(c.prog.BinWriter, vm.SWAP) - emitOpcode(c.prog.BinWriter, vm.DUP) - emitOpcode(c.prog.BinWriter, vm.PUSH2) - emitOpcode(c.prog.BinWriter, vm.XSWAP) - emitOpcode(c.prog.BinWriter, vm.APPEND) + emitOpcode(c.prog.BinWriter, opcode.SWAP) + emitOpcode(c.prog.BinWriter, opcode.DUP) + emitOpcode(c.prog.BinWriter, opcode.PUSH2) + emitOpcode(c.prog.BinWriter, opcode.XSWAP) + emitOpcode(c.prog.BinWriter, opcode.APPEND) } case "SHA256": - emitOpcode(c.prog.BinWriter, vm.SHA256) + emitOpcode(c.prog.BinWriter, opcode.SHA256) case "SHA1": - emitOpcode(c.prog.BinWriter, vm.SHA1) + emitOpcode(c.prog.BinWriter, opcode.SHA1) case "Hash256": - emitOpcode(c.prog.BinWriter, vm.HASH256) + emitOpcode(c.prog.BinWriter, opcode.HASH256) case "Hash160": - emitOpcode(c.prog.BinWriter, vm.HASH160) + emitOpcode(c.prog.BinWriter, opcode.HASH160) case "Equals": - emitOpcode(c.prog.BinWriter, vm.EQUAL) + emitOpcode(c.prog.BinWriter, opcode.EQUAL) case "FromAddress": // We can be sure that this is a ast.BasicLit just containing a simple // address string. Note that the string returned from calling Value will @@ -694,10 +694,10 @@ func (c *codegen) convertStruct(lit *ast.CompositeLit) { return } - emitOpcode(c.prog.BinWriter, vm.NOP) + emitOpcode(c.prog.BinWriter, opcode.NOP) emitInt(c.prog.BinWriter, int64(strct.NumFields())) - emitOpcode(c.prog.BinWriter, vm.NEWSTRUCT) - emitOpcode(c.prog.BinWriter, vm.TOALTSTACK) + emitOpcode(c.prog.BinWriter, opcode.NEWSTRUCT) + emitOpcode(c.prog.BinWriter, opcode.TOALTSTACK) // We need to locally store all the fields, even if they are not initialized. // We will initialize all fields to their "zero" value. @@ -730,55 +730,55 @@ func (c *codegen) convertStruct(lit *ast.CompositeLit) { c.emitLoadConst(typeAndVal) c.emitStoreLocal(i) } - emitOpcode(c.prog.BinWriter, vm.FROMALTSTACK) + emitOpcode(c.prog.BinWriter, opcode.FROMALTSTACK) } func (c *codegen) convertToken(tok token.Token) { switch tok { case token.ADD_ASSIGN: - emitOpcode(c.prog.BinWriter, vm.ADD) + emitOpcode(c.prog.BinWriter, opcode.ADD) case token.SUB_ASSIGN: - emitOpcode(c.prog.BinWriter, vm.SUB) + emitOpcode(c.prog.BinWriter, opcode.SUB) case token.MUL_ASSIGN: - emitOpcode(c.prog.BinWriter, vm.MUL) + emitOpcode(c.prog.BinWriter, opcode.MUL) case token.QUO_ASSIGN: - emitOpcode(c.prog.BinWriter, vm.DIV) + emitOpcode(c.prog.BinWriter, opcode.DIV) case token.ADD: - emitOpcode(c.prog.BinWriter, vm.ADD) + emitOpcode(c.prog.BinWriter, opcode.ADD) case token.SUB: - emitOpcode(c.prog.BinWriter, vm.SUB) + emitOpcode(c.prog.BinWriter, opcode.SUB) case token.MUL: - emitOpcode(c.prog.BinWriter, vm.MUL) + emitOpcode(c.prog.BinWriter, opcode.MUL) case token.QUO: - emitOpcode(c.prog.BinWriter, vm.DIV) + emitOpcode(c.prog.BinWriter, opcode.DIV) case token.LSS: - emitOpcode(c.prog.BinWriter, vm.LT) + emitOpcode(c.prog.BinWriter, opcode.LT) case token.LEQ: - emitOpcode(c.prog.BinWriter, vm.LTE) + emitOpcode(c.prog.BinWriter, opcode.LTE) case token.GTR: - emitOpcode(c.prog.BinWriter, vm.GT) + emitOpcode(c.prog.BinWriter, opcode.GT) case token.GEQ: - emitOpcode(c.prog.BinWriter, vm.GTE) + emitOpcode(c.prog.BinWriter, opcode.GTE) case token.EQL: - emitOpcode(c.prog.BinWriter, vm.NUMEQUAL) + emitOpcode(c.prog.BinWriter, opcode.NUMEQUAL) case token.NEQ: - emitOpcode(c.prog.BinWriter, vm.NUMNOTEQUAL) + emitOpcode(c.prog.BinWriter, opcode.NUMNOTEQUAL) case token.DEC: - emitOpcode(c.prog.BinWriter, vm.DEC) + emitOpcode(c.prog.BinWriter, opcode.DEC) case token.INC: - emitOpcode(c.prog.BinWriter, vm.INC) + emitOpcode(c.prog.BinWriter, opcode.INC) case token.NOT: - emitOpcode(c.prog.BinWriter, vm.NOT) + emitOpcode(c.prog.BinWriter, opcode.NOT) case token.AND: - emitOpcode(c.prog.BinWriter, vm.AND) + emitOpcode(c.prog.BinWriter, opcode.AND) case token.OR: - emitOpcode(c.prog.BinWriter, vm.OR) + emitOpcode(c.prog.BinWriter, opcode.OR) case token.SHL: - emitOpcode(c.prog.BinWriter, vm.SHL) + emitOpcode(c.prog.BinWriter, opcode.SHL) case token.SHR: - emitOpcode(c.prog.BinWriter, vm.SHR) + emitOpcode(c.prog.BinWriter, opcode.SHR) case token.XOR: - emitOpcode(c.prog.BinWriter, vm.XOR) + emitOpcode(c.prog.BinWriter, opcode.XOR) default: c.prog.Err = fmt.Errorf("compiler could not convert token: %s", tok) return @@ -869,8 +869,8 @@ func (c *codegen) resolveFuncDecls(f *ast.File) { func (c *codegen) writeJumps(b []byte) { for i, op := range b { j := i + 1 - switch vm.Instruction(op) { - case vm.JMP, vm.JMPIFNOT, vm.JMPIF, vm.CALL: + switch opcode.Opcode(op) { + case opcode.JMP, opcode.JMPIFNOT, opcode.JMPIF, opcode.CALL: index := int16(binary.LittleEndian.Uint16(b[j : j+2])) if int(index) > len(c.l) || int(index) < 0 { continue diff --git a/pkg/vm/compiler/emit.go b/pkg/vm/compiler/emit.go index 6e1834e5a..a73b59475 100644 --- a/pkg/vm/compiler/emit.go +++ b/pkg/vm/compiler/emit.go @@ -8,40 +8,40 @@ import ( "github.com/CityOfZion/neo-go/pkg/io" "github.com/CityOfZion/neo-go/pkg/util" - "github.com/CityOfZion/neo-go/pkg/vm" + "github.com/CityOfZion/neo-go/pkg/vm/opcode" ) // emit a VM Instruction with data to the given buffer. -func emit(w *io.BinWriter, instr vm.Instruction, b []byte) { +func emit(w *io.BinWriter, instr opcode.Opcode, b []byte) { emitOpcode(w, instr) w.WriteBytes(b) } // emitOpcode emits a single VM Instruction the given buffer. -func emitOpcode(w *io.BinWriter, instr vm.Instruction) { +func emitOpcode(w *io.BinWriter, instr opcode.Opcode) { w.WriteLE(byte(instr)) } // emitBool emits a bool type the given buffer. func emitBool(w *io.BinWriter, ok bool) { if ok { - emitOpcode(w, vm.PUSHT) + emitOpcode(w, opcode.PUSHT) return } - emitOpcode(w, vm.PUSHF) + emitOpcode(w, opcode.PUSHF) } // emitInt emits a int type to the given buffer. func emitInt(w *io.BinWriter, i int64) { switch { case i == -1: - emitOpcode(w, vm.PUSHM1) + emitOpcode(w, opcode.PUSHM1) return case i == 0: - emitOpcode(w, vm.PUSHF) + emitOpcode(w, opcode.PUSHF) return case i > 0 && i < 16: - val := vm.Instruction(int(vm.PUSH1) - 1 + int(i)) + val := opcode.Opcode(int(opcode.PUSH1) - 1 + int(i)) emitOpcode(w, val) return } @@ -61,19 +61,19 @@ func emitBytes(w *io.BinWriter, b []byte) { n := len(b) switch { - case n <= int(vm.PUSHBYTES75): - emit(w, vm.Instruction(n), b) + case n <= int(opcode.PUSHBYTES75): + emit(w, opcode.Opcode(n), b) return case n < 0x100: - emit(w, vm.PUSHDATA1, []byte{byte(n)}) + emit(w, opcode.PUSHDATA1, []byte{byte(n)}) case n < 0x10000: buf := make([]byte, 2) binary.LittleEndian.PutUint16(buf, uint16(n)) - emit(w, vm.PUSHDATA2, buf) + emit(w, opcode.PUSHDATA2, buf) default: buf := make([]byte, 4) binary.LittleEndian.PutUint32(buf, uint32(n)) - emit(w, vm.PUSHDATA4, buf) + emit(w, opcode.PUSHDATA4, buf) if w.Err != nil { return } @@ -92,16 +92,16 @@ func emitSyscall(w *io.BinWriter, api string) { buf := make([]byte, len(api)+1) buf[0] = byte(len(api)) copy(buf[1:], api) - emit(w, vm.SYSCALL, buf) + emit(w, opcode.SYSCALL, buf) } // emitCall emits a call Instruction with label to the given buffer. -func emitCall(w *io.BinWriter, instr vm.Instruction, label int16) { +func emitCall(w *io.BinWriter, instr opcode.Opcode, label int16) { emitJmp(w, instr, label) } // emitJmp emits a jump Instruction along with label to the given buffer. -func emitJmp(w *io.BinWriter, instr vm.Instruction, label int16) { +func emitJmp(w *io.BinWriter, instr opcode.Opcode, label int16) { if !isInstrJmp(instr) { w.Err = fmt.Errorf("opcode %s is not a jump or call type", instr) return @@ -111,8 +111,8 @@ func emitJmp(w *io.BinWriter, instr vm.Instruction, label int16) { emit(w, instr, buf) } -func isInstrJmp(instr vm.Instruction) bool { - if instr == vm.JMP || instr == vm.JMPIFNOT || instr == vm.JMPIF || instr == vm.CALL { +func isInstrJmp(instr opcode.Opcode) bool { + if instr == opcode.JMP || instr == opcode.JMPIFNOT || instr == opcode.JMPIF || instr == opcode.CALL { return true } return false diff --git a/pkg/vm/context.go b/pkg/vm/context.go index cefb183dd..413fc1c3c 100644 --- a/pkg/vm/context.go +++ b/pkg/vm/context.go @@ -4,6 +4,7 @@ import ( "errors" "github.com/CityOfZion/neo-go/pkg/io" + "github.com/CityOfZion/neo-go/pkg/vm/opcode" ) // Context represents the current execution context of the VM. @@ -42,31 +43,31 @@ func NewContext(b []byte) *Context { // Next returns the next instruction to execute with its parameter if any. After // its invocation the instruction pointer points to the instruction being // returned. -func (c *Context) Next() (Instruction, []byte, error) { +func (c *Context) Next() (opcode.Opcode, []byte, error) { c.ip = c.nextip if c.ip >= len(c.prog) { - return RET, nil, nil + return opcode.RET, nil, nil } r := io.NewBinReaderFromBuf(c.prog[c.ip:]) var instrbyte byte r.ReadLE(&instrbyte) - instr := Instruction(instrbyte) + instr := opcode.Opcode(instrbyte) c.nextip++ var numtoread int switch instr { - case PUSHDATA1, SYSCALL: + case opcode.PUSHDATA1, opcode.SYSCALL: var n byte r.ReadLE(&n) numtoread = int(n) c.nextip++ - case PUSHDATA2: + case opcode.PUSHDATA2: var n uint16 r.ReadLE(&n) numtoread = int(n) c.nextip += 2 - case PUSHDATA4: + case opcode.PUSHDATA4: var n uint32 r.ReadLE(&n) if n > MaxItemSize { @@ -74,16 +75,16 @@ func (c *Context) Next() (Instruction, []byte, error) { } numtoread = int(n) c.nextip += 4 - case JMP, JMPIF, JMPIFNOT, CALL, CALLED, CALLEDT: + case opcode.JMP, opcode.JMPIF, opcode.JMPIFNOT, opcode.CALL, opcode.CALLED, opcode.CALLEDT: numtoread = 2 - case CALLI: + case opcode.CALLI: numtoread = 4 - case APPCALL, TAILCALL: + case opcode.APPCALL, opcode.TAILCALL: numtoread = 20 - case CALLE, CALLET: + case opcode.CALLE, opcode.CALLET: numtoread = 22 default: - if instr >= PUSHBYTES1 && instr <= PUSHBYTES75 { + if instr >= opcode.PUSHBYTES1 && instr <= opcode.PUSHBYTES75 { numtoread = int(instr) } else { // No parameters, can just return. @@ -112,8 +113,8 @@ func (c *Context) LenInstr() int { } // CurrInstr returns the current instruction and opcode. -func (c *Context) CurrInstr() (int, Instruction) { - return c.ip, Instruction(c.prog[c.ip]) +func (c *Context) CurrInstr() (int, opcode.Opcode) { + return c.ip, opcode.Opcode(c.prog[c.ip]) } // Copy returns an new exact copy of c. diff --git a/pkg/vm/contract_checks.go b/pkg/vm/contract_checks.go index f51e7c99b..375c3ceec 100644 --- a/pkg/vm/contract_checks.go +++ b/pkg/vm/contract_checks.go @@ -2,18 +2,22 @@ package vm import ( "encoding/binary" + + "github.com/CityOfZion/neo-go/pkg/vm/opcode" ) -func getNumOfThingsFromInstr(instr Instruction, param []byte) (int, bool) { +func getNumOfThingsFromInstr(instr opcode.Opcode, param []byte) (int, bool) { var nthings int switch instr { - case PUSH1, PUSH2, PUSH3, PUSH4, PUSH5, PUSH6, PUSH7, PUSH8, - PUSH9, PUSH10, PUSH11, PUSH12, PUSH13, PUSH14, PUSH15, PUSH16: - nthings = int(instr-PUSH1) + 1 - case PUSHBYTES1: + case opcode.PUSH1, opcode.PUSH2, opcode.PUSH3, opcode.PUSH4, + opcode.PUSH5, opcode.PUSH6, opcode.PUSH7, opcode.PUSH8, + opcode.PUSH9, opcode.PUSH10, opcode.PUSH11, opcode.PUSH12, + opcode.PUSH13, opcode.PUSH14, opcode.PUSH15, opcode.PUSH16: + nthings = int(instr-opcode.PUSH1) + 1 + case opcode.PUSHBYTES1: nthings = int(param[0]) - case PUSHBYTES2: + case opcode.PUSHBYTES2: nthings = int(binary.LittleEndian.Uint16(param)) default: return 0, false @@ -43,7 +47,7 @@ func IsMultiSigContract(script []byte) bool { if err != nil { return false } - if instr != PUSHBYTES33 { + if instr != opcode.PUSHBYTES33 { break } nkeys++ @@ -62,11 +66,11 @@ func IsMultiSigContract(script []byte) bool { return false } instr, _, err = ctx.Next() - if err != nil || instr != CHECKMULTISIG { + if err != nil || instr != opcode.CHECKMULTISIG { return false } instr, _, err = ctx.Next() - if err != nil || instr != RET || ctx.ip != len(script) { + if err != nil || instr != opcode.RET || ctx.ip != len(script) { return false } return true @@ -77,15 +81,15 @@ func IsMultiSigContract(script []byte) bool { func IsSignatureContract(script []byte) bool { ctx := NewContext(script) instr, _, err := ctx.Next() - if err != nil || instr != PUSHBYTES33 { + if err != nil || instr != opcode.PUSHBYTES33 { return false } instr, _, err = ctx.Next() - if err != nil || instr != CHECKSIG { + if err != nil || instr != opcode.CHECKSIG { return false } instr, _, err = ctx.Next() - if err != nil || instr != RET || ctx.ip != len(script) { + if err != nil || instr != opcode.RET || ctx.ip != len(script) { return false } return true diff --git a/pkg/vm/contract_checks_test.go b/pkg/vm/contract_checks_test.go index 791912822..bafeaff67 100644 --- a/pkg/vm/contract_checks_test.go +++ b/pkg/vm/contract_checks_test.go @@ -3,225 +3,226 @@ package vm import ( "testing" + "github.com/CityOfZion/neo-go/pkg/vm/opcode" "github.com/stretchr/testify/assert" ) func TestIsSignatureContractGood(t *testing.T) { prog := make([]byte, 35) - prog[0] = byte(PUSHBYTES33) - prog[34] = byte(CHECKSIG) + prog[0] = byte(opcode.PUSHBYTES33) + prog[34] = byte(opcode.CHECKSIG) assert.Equal(t, true, IsSignatureContract(prog)) assert.Equal(t, true, IsStandardContract(prog)) } func TestIsSignatureContractBadNoCheckSig(t *testing.T) { prog := make([]byte, 34) - prog[0] = byte(PUSHBYTES33) + prog[0] = byte(opcode.PUSHBYTES33) assert.Equal(t, false, IsSignatureContract(prog)) assert.Equal(t, false, IsStandardContract(prog)) } func TestIsSignatureContractBadNoCheckSig2(t *testing.T) { prog := make([]byte, 35) - prog[0] = byte(PUSHBYTES33) - prog[34] = byte(CHECKMULTISIG) + prog[0] = byte(opcode.PUSHBYTES33) + prog[34] = byte(opcode.CHECKMULTISIG) assert.Equal(t, false, IsSignatureContract(prog)) } func TestIsSignatureContractBadWrongPush(t *testing.T) { prog := make([]byte, 35) - prog[0] = byte(PUSHBYTES32) - prog[33] = byte(NOP) - prog[34] = byte(CHECKSIG) + prog[0] = byte(opcode.PUSHBYTES32) + prog[33] = byte(opcode.NOP) + prog[34] = byte(opcode.CHECKSIG) assert.Equal(t, false, IsSignatureContract(prog)) } func TestIsSignatureContractBadWrongInstr(t *testing.T) { prog := make([]byte, 30) - prog[0] = byte(PUSHBYTES33) + prog[0] = byte(opcode.PUSHBYTES33) assert.Equal(t, false, IsSignatureContract(prog)) } func TestIsSignatureContractBadExcessiveInstr(t *testing.T) { prog := make([]byte, 36) - prog[0] = byte(PUSHBYTES33) - prog[34] = byte(CHECKSIG) - prog[35] = byte(RET) + prog[0] = byte(opcode.PUSHBYTES33) + prog[34] = byte(opcode.CHECKSIG) + prog[35] = byte(opcode.RET) assert.Equal(t, false, IsSignatureContract(prog)) } func TestIsMultiSigContractGood(t *testing.T) { prog := make([]byte, 71) - prog[0] = byte(PUSH2) - prog[1] = byte(PUSHBYTES33) - prog[35] = byte(PUSHBYTES33) - prog[69] = byte(PUSH2) - prog[70] = byte(CHECKMULTISIG) + prog[0] = byte(opcode.PUSH2) + prog[1] = byte(opcode.PUSHBYTES33) + prog[35] = byte(opcode.PUSHBYTES33) + prog[69] = byte(opcode.PUSH2) + prog[70] = byte(opcode.CHECKMULTISIG) assert.Equal(t, true, IsMultiSigContract(prog)) assert.Equal(t, true, IsStandardContract(prog)) } func TestIsMultiSigContractGoodPushBytes1(t *testing.T) { prog := make([]byte, 73) - prog[0] = byte(PUSHBYTES1) + prog[0] = byte(opcode.PUSHBYTES1) prog[1] = 2 - prog[2] = byte(PUSHBYTES33) - prog[36] = byte(PUSHBYTES33) - prog[70] = byte(PUSHBYTES1) + prog[2] = byte(opcode.PUSHBYTES33) + prog[36] = byte(opcode.PUSHBYTES33) + prog[70] = byte(opcode.PUSHBYTES1) prog[71] = 2 - prog[72] = byte(CHECKMULTISIG) + prog[72] = byte(opcode.CHECKMULTISIG) assert.Equal(t, true, IsMultiSigContract(prog)) } func TestIsMultiSigContractGoodPushBytes2(t *testing.T) { prog := make([]byte, 75) - prog[0] = byte(PUSHBYTES2) + prog[0] = byte(opcode.PUSHBYTES2) prog[1] = 2 - prog[3] = byte(PUSHBYTES33) - prog[37] = byte(PUSHBYTES33) - prog[71] = byte(PUSHBYTES2) + prog[3] = byte(opcode.PUSHBYTES33) + prog[37] = byte(opcode.PUSHBYTES33) + prog[71] = byte(opcode.PUSHBYTES2) prog[72] = 2 - prog[74] = byte(CHECKMULTISIG) + prog[74] = byte(opcode.CHECKMULTISIG) assert.Equal(t, true, IsMultiSigContract(prog)) } func TestIsMultiSigContractBadNSigs1(t *testing.T) { prog := make([]byte, 71) - prog[0] = byte(PUSH0) - prog[1] = byte(PUSHBYTES33) - prog[35] = byte(PUSHBYTES33) - prog[69] = byte(PUSH2) - prog[70] = byte(CHECKMULTISIG) + prog[0] = byte(opcode.PUSH0) + prog[1] = byte(opcode.PUSHBYTES33) + prog[35] = byte(opcode.PUSHBYTES33) + prog[69] = byte(opcode.PUSH2) + prog[70] = byte(opcode.CHECKMULTISIG) assert.Equal(t, false, IsMultiSigContract(prog)) assert.Equal(t, false, IsStandardContract(prog)) } func TestIsMultiSigContractBadNSigs2(t *testing.T) { prog := make([]byte, 73) - prog[0] = byte(PUSHBYTES2) + prog[0] = byte(opcode.PUSHBYTES2) prog[1] = 0xff prog[2] = 0xff - prog[3] = byte(PUSHBYTES33) - prog[37] = byte(PUSHBYTES33) - prog[71] = byte(PUSH2) - prog[72] = byte(CHECKMULTISIG) + prog[3] = byte(opcode.PUSHBYTES33) + prog[37] = byte(opcode.PUSHBYTES33) + prog[71] = byte(opcode.PUSH2) + prog[72] = byte(opcode.CHECKMULTISIG) assert.Equal(t, false, IsMultiSigContract(prog)) } func TestIsMultiSigContractBadNSigs3(t *testing.T) { prog := make([]byte, 71) - prog[0] = byte(PUSH5) - prog[1] = byte(PUSHBYTES33) - prog[35] = byte(PUSHBYTES33) - prog[69] = byte(PUSH2) - prog[70] = byte(CHECKMULTISIG) + prog[0] = byte(opcode.PUSH5) + prog[1] = byte(opcode.PUSHBYTES33) + prog[35] = byte(opcode.PUSHBYTES33) + prog[69] = byte(opcode.PUSH2) + prog[70] = byte(opcode.CHECKMULTISIG) assert.Equal(t, false, IsMultiSigContract(prog)) } func TestIsMultiSigContractBadExcessiveNOP1(t *testing.T) { prog := make([]byte, 72) - prog[0] = byte(PUSH2) - prog[1] = byte(NOP) - prog[2] = byte(PUSHBYTES33) - prog[36] = byte(PUSHBYTES33) - prog[70] = byte(PUSH2) - prog[71] = byte(CHECKMULTISIG) + prog[0] = byte(opcode.PUSH2) + prog[1] = byte(opcode.NOP) + prog[2] = byte(opcode.PUSHBYTES33) + prog[36] = byte(opcode.PUSHBYTES33) + prog[70] = byte(opcode.PUSH2) + prog[71] = byte(opcode.CHECKMULTISIG) assert.Equal(t, false, IsMultiSigContract(prog)) } func TestIsMultiSigContractBadExcessiveNOP2(t *testing.T) { prog := make([]byte, 72) - prog[0] = byte(PUSH2) - prog[1] = byte(PUSHBYTES33) - prog[35] = byte(NOP) - prog[36] = byte(PUSHBYTES33) - prog[70] = byte(PUSH2) - prog[71] = byte(CHECKMULTISIG) + prog[0] = byte(opcode.PUSH2) + prog[1] = byte(opcode.PUSHBYTES33) + prog[35] = byte(opcode.NOP) + prog[36] = byte(opcode.PUSHBYTES33) + prog[70] = byte(opcode.PUSH2) + prog[71] = byte(opcode.CHECKMULTISIG) assert.Equal(t, false, IsMultiSigContract(prog)) } func TestIsMultiSigContractBadExcessiveNOP3(t *testing.T) { prog := make([]byte, 72) - prog[0] = byte(PUSH2) - prog[1] = byte(PUSHBYTES33) - prog[35] = byte(PUSHBYTES33) - prog[69] = byte(NOP) - prog[70] = byte(PUSH2) - prog[71] = byte(CHECKMULTISIG) + prog[0] = byte(opcode.PUSH2) + prog[1] = byte(opcode.PUSHBYTES33) + prog[35] = byte(opcode.PUSHBYTES33) + prog[69] = byte(opcode.NOP) + prog[70] = byte(opcode.PUSH2) + prog[71] = byte(opcode.CHECKMULTISIG) assert.Equal(t, false, IsMultiSigContract(prog)) } func TestIsMultiSigContractBadExcessiveNOP4(t *testing.T) { prog := make([]byte, 72) - prog[0] = byte(PUSH2) - prog[1] = byte(PUSHBYTES33) - prog[35] = byte(PUSHBYTES33) - prog[69] = byte(PUSH2) - prog[70] = byte(NOP) - prog[71] = byte(CHECKMULTISIG) + prog[0] = byte(opcode.PUSH2) + prog[1] = byte(opcode.PUSHBYTES33) + prog[35] = byte(opcode.PUSHBYTES33) + prog[69] = byte(opcode.PUSH2) + prog[70] = byte(opcode.NOP) + prog[71] = byte(opcode.CHECKMULTISIG) assert.Equal(t, false, IsMultiSigContract(prog)) } func TestIsMultiSigContractBadExcessiveNOP5(t *testing.T) { prog := make([]byte, 72) - prog[0] = byte(PUSH2) - prog[1] = byte(PUSHBYTES33) - prog[35] = byte(PUSHBYTES33) - prog[69] = byte(PUSH2) - prog[70] = byte(CHECKMULTISIG) - prog[71] = byte(NOP) + prog[0] = byte(opcode.PUSH2) + prog[1] = byte(opcode.PUSHBYTES33) + prog[35] = byte(opcode.PUSHBYTES33) + prog[69] = byte(opcode.PUSH2) + prog[70] = byte(opcode.CHECKMULTISIG) + prog[71] = byte(opcode.NOP) assert.Equal(t, false, IsMultiSigContract(prog)) } func TestIsMultiSigContractBadNKeys1(t *testing.T) { prog := make([]byte, 71) - prog[0] = byte(PUSH2) - prog[1] = byte(PUSHBYTES33) - prog[35] = byte(PUSHBYTES33) - prog[69] = byte(PUSH3) - prog[70] = byte(CHECKMULTISIG) + prog[0] = byte(opcode.PUSH2) + prog[1] = byte(opcode.PUSHBYTES33) + prog[35] = byte(opcode.PUSHBYTES33) + prog[69] = byte(opcode.PUSH3) + prog[70] = byte(opcode.CHECKMULTISIG) assert.Equal(t, false, IsMultiSigContract(prog)) } func TestIsMultiSigContractBadNKeys2(t *testing.T) { prog := make([]byte, 1) - prog[0] = byte(PUSH10) + prog[0] = byte(opcode.PUSH10) key := make([]byte, 33) var asize = uint16(MaxArraySize + 1) for i := 0; i < int(asize); i++ { - prog = append(prog, byte(PUSHBYTES33)) + prog = append(prog, byte(opcode.PUSHBYTES33)) prog = append(prog, key...) } - prog = append(prog, byte(PUSHBYTES2), byte(asize&0xff), byte((asize<<8)&0xff), byte(CHECKMULTISIG)) + prog = append(prog, byte(opcode.PUSHBYTES2), byte(asize&0xff), byte((asize<<8)&0xff), byte(opcode.CHECKMULTISIG)) assert.Equal(t, false, IsMultiSigContract(prog)) } func TestIsMultiSigContractBadRead1(t *testing.T) { prog := make([]byte, 71) - prog[0] = byte(PUSHBYTES75) - prog[1] = byte(PUSHBYTES33) - prog[35] = byte(PUSHBYTES33) - prog[69] = byte(PUSH2) - prog[70] = byte(CHECKMULTISIG) + prog[0] = byte(opcode.PUSHBYTES75) + prog[1] = byte(opcode.PUSHBYTES33) + prog[35] = byte(opcode.PUSHBYTES33) + prog[69] = byte(opcode.PUSH2) + prog[70] = byte(opcode.CHECKMULTISIG) assert.Equal(t, false, IsMultiSigContract(prog)) } func TestIsMultiSigContractBadRead2(t *testing.T) { prog := make([]byte, 71) - prog[0] = byte(PUSH2) - prog[1] = byte(PUSHBYTES33) - prog[35] = byte(PUSHBYTES75) - prog[69] = byte(PUSH2) - prog[70] = byte(CHECKMULTISIG) + prog[0] = byte(opcode.PUSH2) + prog[1] = byte(opcode.PUSHBYTES33) + prog[35] = byte(opcode.PUSHBYTES75) + prog[69] = byte(opcode.PUSH2) + prog[70] = byte(opcode.CHECKMULTISIG) assert.Equal(t, false, IsMultiSigContract(prog)) } func TestIsMultiSigContractBadRead3(t *testing.T) { prog := make([]byte, 71) - prog[0] = byte(PUSH2) - prog[1] = byte(PUSHBYTES33) - prog[35] = byte(PUSHBYTES33) - prog[69] = byte(PUSH2) - prog[70] = byte(PUSHBYTES1) + prog[0] = byte(opcode.PUSH2) + prog[1] = byte(opcode.PUSHBYTES33) + prog[35] = byte(opcode.PUSHBYTES33) + prog[69] = byte(opcode.PUSH2) + prog[70] = byte(opcode.PUSHBYTES1) assert.Equal(t, false, IsMultiSigContract(prog)) } diff --git a/pkg/vm/emit.go b/pkg/vm/emit.go index db76fc238..f9c2f4a78 100644 --- a/pkg/vm/emit.go +++ b/pkg/vm/emit.go @@ -9,10 +9,11 @@ import ( "math/big" "github.com/CityOfZion/neo-go/pkg/util" + "github.com/CityOfZion/neo-go/pkg/vm/opcode" ) // Emit a VM Instruction with data to the given buffer. -func Emit(w *bytes.Buffer, op Instruction, b []byte) error { +func Emit(w *bytes.Buffer, op opcode.Opcode, b []byte) error { if err := w.WriteByte(byte(op)); err != nil { return err } @@ -21,28 +22,28 @@ func Emit(w *bytes.Buffer, op Instruction, b []byte) error { } // EmitOpcode emits a single VM Instruction the given buffer. -func EmitOpcode(w io.ByteWriter, op Instruction) error { +func EmitOpcode(w io.ByteWriter, op opcode.Opcode) error { return w.WriteByte(byte(op)) } // EmitBool emits a bool type the given buffer. func EmitBool(w io.ByteWriter, ok bool) error { if ok { - return EmitOpcode(w, PUSHT) + return EmitOpcode(w, opcode.PUSHT) } - return EmitOpcode(w, PUSHF) + return EmitOpcode(w, opcode.PUSHF) } // EmitInt emits a int type to the given buffer. func EmitInt(w *bytes.Buffer, i int64) error { if i == -1 { - return EmitOpcode(w, PUSHM1) + return EmitOpcode(w, opcode.PUSHM1) } if i == 0 { - return EmitOpcode(w, PUSHF) + return EmitOpcode(w, opcode.PUSHF) } if i > 0 && i < 16 { - val := Instruction(int(PUSH1) - 1 + int(i)) + val := opcode.Opcode(int(opcode.PUSH1) - 1 + int(i)) return EmitOpcode(w, val) } @@ -63,18 +64,18 @@ func EmitBytes(w *bytes.Buffer, b []byte) error { n = len(b) ) - if n <= int(PUSHBYTES75) { - return Emit(w, Instruction(n), b) + if n <= int(opcode.PUSHBYTES75) { + return Emit(w, opcode.Opcode(n), b) } else if n < 0x100 { - err = Emit(w, PUSHDATA1, []byte{byte(n)}) + err = Emit(w, opcode.PUSHDATA1, []byte{byte(n)}) } else if n < 0x10000 { buf := make([]byte, 2) binary.LittleEndian.PutUint16(buf, uint16(n)) - err = Emit(w, PUSHDATA2, buf) + err = Emit(w, opcode.PUSHDATA2, buf) } else { buf := make([]byte, 4) binary.LittleEndian.PutUint32(buf, uint32(n)) - err = Emit(w, PUSHDATA4, buf) + err = Emit(w, opcode.PUSHDATA4, buf) } if err != nil { return err @@ -92,16 +93,16 @@ func EmitSyscall(w *bytes.Buffer, api string) error { buf := make([]byte, len(api)+1) buf[0] = byte(len(api)) copy(buf[1:], api) - return Emit(w, SYSCALL, buf) + return Emit(w, opcode.SYSCALL, buf) } // EmitCall emits a call Instruction with label to the given buffer. -func EmitCall(w *bytes.Buffer, op Instruction, label int16) error { +func EmitCall(w *bytes.Buffer, op opcode.Opcode, label int16) error { return EmitJmp(w, op, label) } // EmitJmp emits a jump Instruction along with label to the given buffer. -func EmitJmp(w *bytes.Buffer, op Instruction, label int16) error { +func EmitJmp(w *bytes.Buffer, op opcode.Opcode, label int16) error { if !isInstructionJmp(op) { return fmt.Errorf("opcode %s is not a jump or call type", op.String()) } @@ -113,9 +114,9 @@ func EmitJmp(w *bytes.Buffer, op Instruction, label int16) error { // EmitAppCall emits an appcall, if tailCall is true, tailCall opcode will be // emitted instead. func EmitAppCall(w *bytes.Buffer, scriptHash util.Uint160, tailCall bool) error { - op := APPCALL + op := opcode.APPCALL if tailCall { - op = TAILCALL + op = opcode.TAILCALL } return Emit(w, op, scriptHash.Bytes()) } @@ -142,8 +143,8 @@ func EmitAppCallWithOperation(w *bytes.Buffer, scriptHash util.Uint160, operatio return EmitAppCall(w, scriptHash, false) } -func isInstructionJmp(op Instruction) bool { - if op == JMP || op == JMPIFNOT || op == JMPIF || op == CALL { +func isInstructionJmp(op opcode.Opcode) bool { + if op == opcode.JMP || op == opcode.JMPIFNOT || op == opcode.JMPIF || op == opcode.CALL { return true } return false diff --git a/pkg/vm/emit_test.go b/pkg/vm/emit_test.go index 0baf995bc..1278f3d7b 100644 --- a/pkg/vm/emit_test.go +++ b/pkg/vm/emit_test.go @@ -5,13 +5,14 @@ import ( "encoding/binary" "testing" + "github.com/CityOfZion/neo-go/pkg/vm/opcode" "github.com/stretchr/testify/assert" ) func TestEmitInt(t *testing.T) { buf := new(bytes.Buffer) EmitInt(buf, 10) - assert.Equal(t, Instruction(buf.Bytes()[0]), PUSH10) + assert.Equal(t, opcode.Opcode(buf.Bytes()[0]), opcode.PUSH10) buf.Reset() EmitInt(buf, 100) assert.Equal(t, buf.Bytes()[0], uint8(1)) @@ -26,8 +27,8 @@ func TestEmitBool(t *testing.T) { buf := new(bytes.Buffer) EmitBool(buf, true) EmitBool(buf, false) - assert.Equal(t, Instruction(buf.Bytes()[0]), PUSH1) - assert.Equal(t, Instruction(buf.Bytes()[1]), PUSH0) + assert.Equal(t, opcode.Opcode(buf.Bytes()[0]), opcode.PUSH1) + assert.Equal(t, opcode.Opcode(buf.Bytes()[1]), opcode.PUSH0) } func TestEmitString(t *testing.T) { @@ -48,7 +49,7 @@ func TestEmitSyscall(t *testing.T) { buf := new(bytes.Buffer) for _, syscall := range syscalls { EmitSyscall(buf, syscall) - assert.Equal(t, Instruction(buf.Bytes()[0]), SYSCALL) + assert.Equal(t, opcode.Opcode(buf.Bytes()[0]), opcode.SYSCALL) assert.Equal(t, buf.Bytes()[1], uint8(len(syscall))) assert.Equal(t, buf.Bytes()[2:], []byte(syscall)) buf.Reset() @@ -57,8 +58,8 @@ func TestEmitSyscall(t *testing.T) { func TestEmitCall(t *testing.T) { buf := new(bytes.Buffer) - EmitCall(buf, JMP, 100) - assert.Equal(t, Instruction(buf.Bytes()[0]), JMP) + EmitCall(buf, opcode.JMP, 100) + assert.Equal(t, opcode.Opcode(buf.Bytes()[0]), opcode.JMP) label := binary.LittleEndian.Uint16(buf.Bytes()[1:3]) assert.Equal(t, label, uint16(100)) } diff --git a/pkg/vm/instruction_string.go b/pkg/vm/instruction_string.go deleted file mode 100644 index 9e463de49..000000000 --- a/pkg/vm/instruction_string.go +++ /dev/null @@ -1,393 +0,0 @@ -// Code generated by "stringer -type=Instruction"; DO NOT EDIT. - -package vm - -import "strconv" - -func _() { - // An "invalid array index" compiler error signifies that the constant values have changed. - // Re-run the stringer command to generate them again. - var x [1]struct{} - _ = x[PUSH0-0] - _ = x[PUSHF-0] - _ = x[PUSHBYTES1-1] - _ = x[PUSHBYTES2-2] - _ = x[PUSHBYTES3-3] - _ = x[PUSHBYTES4-4] - _ = x[PUSHBYTES5-5] - _ = x[PUSHBYTES6-6] - _ = x[PUSHBYTES7-7] - _ = x[PUSHBYTES8-8] - _ = x[PUSHBYTES9-9] - _ = x[PUSHBYTES10-10] - _ = x[PUSHBYTES11-11] - _ = x[PUSHBYTES12-12] - _ = x[PUSHBYTES13-13] - _ = x[PUSHBYTES14-14] - _ = x[PUSHBYTES15-15] - _ = x[PUSHBYTES16-16] - _ = x[PUSHBYTES17-17] - _ = x[PUSHBYTES18-18] - _ = x[PUSHBYTES19-19] - _ = x[PUSHBYTES20-20] - _ = x[PUSHBYTES21-21] - _ = x[PUSHBYTES22-22] - _ = x[PUSHBYTES23-23] - _ = x[PUSHBYTES24-24] - _ = x[PUSHBYTES25-25] - _ = x[PUSHBYTES26-26] - _ = x[PUSHBYTES27-27] - _ = x[PUSHBYTES28-28] - _ = x[PUSHBYTES29-29] - _ = x[PUSHBYTES30-30] - _ = x[PUSHBYTES31-31] - _ = x[PUSHBYTES32-32] - _ = x[PUSHBYTES33-33] - _ = x[PUSHBYTES34-34] - _ = x[PUSHBYTES35-35] - _ = x[PUSHBYTES36-36] - _ = x[PUSHBYTES37-37] - _ = x[PUSHBYTES38-38] - _ = x[PUSHBYTES39-39] - _ = x[PUSHBYTES40-40] - _ = x[PUSHBYTES41-41] - _ = x[PUSHBYTES42-42] - _ = x[PUSHBYTES43-43] - _ = x[PUSHBYTES44-44] - _ = x[PUSHBYTES45-45] - _ = x[PUSHBYTES46-46] - _ = x[PUSHBYTES47-47] - _ = x[PUSHBYTES48-48] - _ = x[PUSHBYTES49-49] - _ = x[PUSHBYTES50-50] - _ = x[PUSHBYTES51-51] - _ = x[PUSHBYTES52-52] - _ = x[PUSHBYTES53-53] - _ = x[PUSHBYTES54-54] - _ = x[PUSHBYTES55-55] - _ = x[PUSHBYTES56-56] - _ = x[PUSHBYTES57-57] - _ = x[PUSHBYTES58-58] - _ = x[PUSHBYTES59-59] - _ = x[PUSHBYTES60-60] - _ = x[PUSHBYTES61-61] - _ = x[PUSHBYTES62-62] - _ = x[PUSHBYTES63-63] - _ = x[PUSHBYTES64-64] - _ = x[PUSHBYTES65-65] - _ = x[PUSHBYTES66-66] - _ = x[PUSHBYTES67-67] - _ = x[PUSHBYTES68-68] - _ = x[PUSHBYTES69-69] - _ = x[PUSHBYTES70-70] - _ = x[PUSHBYTES71-71] - _ = x[PUSHBYTES72-72] - _ = x[PUSHBYTES73-73] - _ = x[PUSHBYTES74-74] - _ = x[PUSHBYTES75-75] - _ = x[PUSHDATA1-76] - _ = x[PUSHDATA2-77] - _ = x[PUSHDATA4-78] - _ = x[PUSHM1-79] - _ = x[PUSH1-81] - _ = x[PUSHT-81] - _ = x[PUSH2-82] - _ = x[PUSH3-83] - _ = x[PUSH4-84] - _ = x[PUSH5-85] - _ = x[PUSH6-86] - _ = x[PUSH7-87] - _ = x[PUSH8-88] - _ = x[PUSH9-89] - _ = x[PUSH10-90] - _ = x[PUSH11-91] - _ = x[PUSH12-92] - _ = x[PUSH13-93] - _ = x[PUSH14-94] - _ = x[PUSH15-95] - _ = x[PUSH16-96] - _ = x[NOP-97] - _ = x[JMP-98] - _ = x[JMPIF-99] - _ = x[JMPIFNOT-100] - _ = x[CALL-101] - _ = x[RET-102] - _ = x[APPCALL-103] - _ = x[SYSCALL-104] - _ = x[TAILCALL-105] - _ = x[DUPFROMALTSTACK-106] - _ = x[TOALTSTACK-107] - _ = x[FROMALTSTACK-108] - _ = x[XDROP-109] - _ = x[XSWAP-114] - _ = x[XTUCK-115] - _ = x[DEPTH-116] - _ = x[DROP-117] - _ = x[DUP-118] - _ = x[NIP-119] - _ = x[OVER-120] - _ = x[PICK-121] - _ = x[ROLL-122] - _ = x[ROT-123] - _ = x[SWAP-124] - _ = x[TUCK-125] - _ = x[CAT-126] - _ = x[SUBSTR-127] - _ = x[LEFT-128] - _ = x[RIGHT-129] - _ = x[SIZE-130] - _ = x[INVERT-131] - _ = x[AND-132] - _ = x[OR-133] - _ = x[XOR-134] - _ = x[EQUAL-135] - _ = x[INC-139] - _ = x[DEC-140] - _ = x[SIGN-141] - _ = x[NEGATE-143] - _ = x[ABS-144] - _ = x[NOT-145] - _ = x[NZ-146] - _ = x[ADD-147] - _ = x[SUB-148] - _ = x[MUL-149] - _ = x[DIV-150] - _ = x[MOD-151] - _ = x[SHL-152] - _ = x[SHR-153] - _ = x[BOOLAND-154] - _ = x[BOOLOR-155] - _ = x[NUMEQUAL-156] - _ = x[NUMNOTEQUAL-158] - _ = x[LT-159] - _ = x[GT-160] - _ = x[LTE-161] - _ = x[GTE-162] - _ = x[MIN-163] - _ = x[MAX-164] - _ = x[WITHIN-165] - _ = x[SHA1-167] - _ = x[SHA256-168] - _ = x[HASH160-169] - _ = x[HASH256-170] - _ = x[CHECKSIG-172] - _ = x[VERIFY-173] - _ = x[CHECKMULTISIG-174] - _ = x[ARRAYSIZE-192] - _ = x[PACK-193] - _ = x[UNPACK-194] - _ = x[PICKITEM-195] - _ = x[SETITEM-196] - _ = x[NEWARRAY-197] - _ = x[NEWSTRUCT-198] - _ = x[NEWMAP-199] - _ = x[APPEND-200] - _ = x[REVERSE-201] - _ = x[REMOVE-202] - _ = x[HASKEY-203] - _ = x[KEYS-204] - _ = x[VALUES-205] - _ = x[CALLI-224] - _ = x[CALLE-225] - _ = x[CALLED-226] - _ = x[CALLET-227] - _ = x[CALLEDT-228] - _ = x[THROW-240] - _ = x[THROWIFNOT-241] -} - -const _Instruction_name = "PUSH0PUSHBYTES1PUSHBYTES2PUSHBYTES3PUSHBYTES4PUSHBYTES5PUSHBYTES6PUSHBYTES7PUSHBYTES8PUSHBYTES9PUSHBYTES10PUSHBYTES11PUSHBYTES12PUSHBYTES13PUSHBYTES14PUSHBYTES15PUSHBYTES16PUSHBYTES17PUSHBYTES18PUSHBYTES19PUSHBYTES20PUSHBYTES21PUSHBYTES22PUSHBYTES23PUSHBYTES24PUSHBYTES25PUSHBYTES26PUSHBYTES27PUSHBYTES28PUSHBYTES29PUSHBYTES30PUSHBYTES31PUSHBYTES32PUSHBYTES33PUSHBYTES34PUSHBYTES35PUSHBYTES36PUSHBYTES37PUSHBYTES38PUSHBYTES39PUSHBYTES40PUSHBYTES41PUSHBYTES42PUSHBYTES43PUSHBYTES44PUSHBYTES45PUSHBYTES46PUSHBYTES47PUSHBYTES48PUSHBYTES49PUSHBYTES50PUSHBYTES51PUSHBYTES52PUSHBYTES53PUSHBYTES54PUSHBYTES55PUSHBYTES56PUSHBYTES57PUSHBYTES58PUSHBYTES59PUSHBYTES60PUSHBYTES61PUSHBYTES62PUSHBYTES63PUSHBYTES64PUSHBYTES65PUSHBYTES66PUSHBYTES67PUSHBYTES68PUSHBYTES69PUSHBYTES70PUSHBYTES71PUSHBYTES72PUSHBYTES73PUSHBYTES74PUSHBYTES75PUSHDATA1PUSHDATA2PUSHDATA4PUSHM1PUSH1PUSH2PUSH3PUSH4PUSH5PUSH6PUSH7PUSH8PUSH9PUSH10PUSH11PUSH12PUSH13PUSH14PUSH15PUSH16NOPJMPJMPIFJMPIFNOTCALLRETAPPCALLSYSCALLTAILCALLDUPFROMALTSTACKTOALTSTACKFROMALTSTACKXDROPXSWAPXTUCKDEPTHDROPDUPNIPOVERPICKROLLROTSWAPTUCKCATSUBSTRLEFTRIGHTSIZEINVERTANDORXOREQUALINCDECSIGNNEGATEABSNOTNZADDSUBMULDIVMODSHLSHRBOOLANDBOOLORNUMEQUALNUMNOTEQUALLTGTLTEGTEMINMAXWITHINSHA1SHA256HASH160HASH256CHECKSIGVERIFYCHECKMULTISIGARRAYSIZEPACKUNPACKPICKITEMSETITEMNEWARRAYNEWSTRUCTNEWMAPAPPENDREVERSEREMOVEHASKEYKEYSVALUESCALLICALLECALLEDCALLETCALLEDTTHROWTHROWIFNOT" - -var _Instruction_map = map[Instruction]string{ - 0: _Instruction_name[0:5], - 1: _Instruction_name[5:15], - 2: _Instruction_name[15:25], - 3: _Instruction_name[25:35], - 4: _Instruction_name[35:45], - 5: _Instruction_name[45:55], - 6: _Instruction_name[55:65], - 7: _Instruction_name[65:75], - 8: _Instruction_name[75:85], - 9: _Instruction_name[85:95], - 10: _Instruction_name[95:106], - 11: _Instruction_name[106:117], - 12: _Instruction_name[117:128], - 13: _Instruction_name[128:139], - 14: _Instruction_name[139:150], - 15: _Instruction_name[150:161], - 16: _Instruction_name[161:172], - 17: _Instruction_name[172:183], - 18: _Instruction_name[183:194], - 19: _Instruction_name[194:205], - 20: _Instruction_name[205:216], - 21: _Instruction_name[216:227], - 22: _Instruction_name[227:238], - 23: _Instruction_name[238:249], - 24: _Instruction_name[249:260], - 25: _Instruction_name[260:271], - 26: _Instruction_name[271:282], - 27: _Instruction_name[282:293], - 28: _Instruction_name[293:304], - 29: _Instruction_name[304:315], - 30: _Instruction_name[315:326], - 31: _Instruction_name[326:337], - 32: _Instruction_name[337:348], - 33: _Instruction_name[348:359], - 34: _Instruction_name[359:370], - 35: _Instruction_name[370:381], - 36: _Instruction_name[381:392], - 37: _Instruction_name[392:403], - 38: _Instruction_name[403:414], - 39: _Instruction_name[414:425], - 40: _Instruction_name[425:436], - 41: _Instruction_name[436:447], - 42: _Instruction_name[447:458], - 43: _Instruction_name[458:469], - 44: _Instruction_name[469:480], - 45: _Instruction_name[480:491], - 46: _Instruction_name[491:502], - 47: _Instruction_name[502:513], - 48: _Instruction_name[513:524], - 49: _Instruction_name[524:535], - 50: _Instruction_name[535:546], - 51: _Instruction_name[546:557], - 52: _Instruction_name[557:568], - 53: _Instruction_name[568:579], - 54: _Instruction_name[579:590], - 55: _Instruction_name[590:601], - 56: _Instruction_name[601:612], - 57: _Instruction_name[612:623], - 58: _Instruction_name[623:634], - 59: _Instruction_name[634:645], - 60: _Instruction_name[645:656], - 61: _Instruction_name[656:667], - 62: _Instruction_name[667:678], - 63: _Instruction_name[678:689], - 64: _Instruction_name[689:700], - 65: _Instruction_name[700:711], - 66: _Instruction_name[711:722], - 67: _Instruction_name[722:733], - 68: _Instruction_name[733:744], - 69: _Instruction_name[744:755], - 70: _Instruction_name[755:766], - 71: _Instruction_name[766:777], - 72: _Instruction_name[777:788], - 73: _Instruction_name[788:799], - 74: _Instruction_name[799:810], - 75: _Instruction_name[810:821], - 76: _Instruction_name[821:830], - 77: _Instruction_name[830:839], - 78: _Instruction_name[839:848], - 79: _Instruction_name[848:854], - 81: _Instruction_name[854:859], - 82: _Instruction_name[859:864], - 83: _Instruction_name[864:869], - 84: _Instruction_name[869:874], - 85: _Instruction_name[874:879], - 86: _Instruction_name[879:884], - 87: _Instruction_name[884:889], - 88: _Instruction_name[889:894], - 89: _Instruction_name[894:899], - 90: _Instruction_name[899:905], - 91: _Instruction_name[905:911], - 92: _Instruction_name[911:917], - 93: _Instruction_name[917:923], - 94: _Instruction_name[923:929], - 95: _Instruction_name[929:935], - 96: _Instruction_name[935:941], - 97: _Instruction_name[941:944], - 98: _Instruction_name[944:947], - 99: _Instruction_name[947:952], - 100: _Instruction_name[952:960], - 101: _Instruction_name[960:964], - 102: _Instruction_name[964:967], - 103: _Instruction_name[967:974], - 104: _Instruction_name[974:981], - 105: _Instruction_name[981:989], - 106: _Instruction_name[989:1004], - 107: _Instruction_name[1004:1014], - 108: _Instruction_name[1014:1026], - 109: _Instruction_name[1026:1031], - 114: _Instruction_name[1031:1036], - 115: _Instruction_name[1036:1041], - 116: _Instruction_name[1041:1046], - 117: _Instruction_name[1046:1050], - 118: _Instruction_name[1050:1053], - 119: _Instruction_name[1053:1056], - 120: _Instruction_name[1056:1060], - 121: _Instruction_name[1060:1064], - 122: _Instruction_name[1064:1068], - 123: _Instruction_name[1068:1071], - 124: _Instruction_name[1071:1075], - 125: _Instruction_name[1075:1079], - 126: _Instruction_name[1079:1082], - 127: _Instruction_name[1082:1088], - 128: _Instruction_name[1088:1092], - 129: _Instruction_name[1092:1097], - 130: _Instruction_name[1097:1101], - 131: _Instruction_name[1101:1107], - 132: _Instruction_name[1107:1110], - 133: _Instruction_name[1110:1112], - 134: _Instruction_name[1112:1115], - 135: _Instruction_name[1115:1120], - 139: _Instruction_name[1120:1123], - 140: _Instruction_name[1123:1126], - 141: _Instruction_name[1126:1130], - 143: _Instruction_name[1130:1136], - 144: _Instruction_name[1136:1139], - 145: _Instruction_name[1139:1142], - 146: _Instruction_name[1142:1144], - 147: _Instruction_name[1144:1147], - 148: _Instruction_name[1147:1150], - 149: _Instruction_name[1150:1153], - 150: _Instruction_name[1153:1156], - 151: _Instruction_name[1156:1159], - 152: _Instruction_name[1159:1162], - 153: _Instruction_name[1162:1165], - 154: _Instruction_name[1165:1172], - 155: _Instruction_name[1172:1178], - 156: _Instruction_name[1178:1186], - 158: _Instruction_name[1186:1197], - 159: _Instruction_name[1197:1199], - 160: _Instruction_name[1199:1201], - 161: _Instruction_name[1201:1204], - 162: _Instruction_name[1204:1207], - 163: _Instruction_name[1207:1210], - 164: _Instruction_name[1210:1213], - 165: _Instruction_name[1213:1219], - 167: _Instruction_name[1219:1223], - 168: _Instruction_name[1223:1229], - 169: _Instruction_name[1229:1236], - 170: _Instruction_name[1236:1243], - 172: _Instruction_name[1243:1251], - 173: _Instruction_name[1251:1257], - 174: _Instruction_name[1257:1270], - 192: _Instruction_name[1270:1279], - 193: _Instruction_name[1279:1283], - 194: _Instruction_name[1283:1289], - 195: _Instruction_name[1289:1297], - 196: _Instruction_name[1297:1304], - 197: _Instruction_name[1304:1312], - 198: _Instruction_name[1312:1321], - 199: _Instruction_name[1321:1327], - 200: _Instruction_name[1327:1333], - 201: _Instruction_name[1333:1340], - 202: _Instruction_name[1340:1346], - 203: _Instruction_name[1346:1352], - 204: _Instruction_name[1352:1356], - 205: _Instruction_name[1356:1362], - 224: _Instruction_name[1362:1367], - 225: _Instruction_name[1367:1372], - 226: _Instruction_name[1372:1378], - 227: _Instruction_name[1378:1384], - 228: _Instruction_name[1384:1391], - 240: _Instruction_name[1391:1396], - 241: _Instruction_name[1396:1406], -} - -func (i Instruction) String() string { - if str, ok := _Instruction_map[i]; ok { - return str - } - return "Instruction(" + strconv.FormatInt(int64(i), 10) + ")" -} diff --git a/pkg/vm/instructions.go b/pkg/vm/instructions.go deleted file mode 100644 index bfbc8221e..000000000 --- a/pkg/vm/instructions.go +++ /dev/null @@ -1,215 +0,0 @@ -package vm - -//go:generate stringer -type=Instruction - -// Instruction represents an single operation for the NEO virtual machine. -type Instruction byte - -// Viable list of supported instruction constants. -const ( - // Constants - PUSH0 Instruction = 0x00 - PUSHF Instruction = PUSH0 - PUSHBYTES1 Instruction = 0x01 - PUSHBYTES2 Instruction = 0x02 - PUSHBYTES3 Instruction = 0x03 - PUSHBYTES4 Instruction = 0x04 - PUSHBYTES5 Instruction = 0x05 - PUSHBYTES6 Instruction = 0x06 - PUSHBYTES7 Instruction = 0x07 - PUSHBYTES8 Instruction = 0x08 - PUSHBYTES9 Instruction = 0x09 - PUSHBYTES10 Instruction = 0x0A - PUSHBYTES11 Instruction = 0x0B - PUSHBYTES12 Instruction = 0x0C - PUSHBYTES13 Instruction = 0x0D - PUSHBYTES14 Instruction = 0x0E - PUSHBYTES15 Instruction = 0x0F - PUSHBYTES16 Instruction = 0x10 - PUSHBYTES17 Instruction = 0x11 - PUSHBYTES18 Instruction = 0x12 - PUSHBYTES19 Instruction = 0x13 - PUSHBYTES20 Instruction = 0x14 - PUSHBYTES21 Instruction = 0x15 - PUSHBYTES22 Instruction = 0x16 - PUSHBYTES23 Instruction = 0x17 - PUSHBYTES24 Instruction = 0x18 - PUSHBYTES25 Instruction = 0x19 - PUSHBYTES26 Instruction = 0x1A - PUSHBYTES27 Instruction = 0x1B - PUSHBYTES28 Instruction = 0x1C - PUSHBYTES29 Instruction = 0x1D - PUSHBYTES30 Instruction = 0x1E - PUSHBYTES31 Instruction = 0x1F - PUSHBYTES32 Instruction = 0x20 - PUSHBYTES33 Instruction = 0x21 - PUSHBYTES34 Instruction = 0x22 - PUSHBYTES35 Instruction = 0x23 - PUSHBYTES36 Instruction = 0x24 - PUSHBYTES37 Instruction = 0x25 - PUSHBYTES38 Instruction = 0x26 - PUSHBYTES39 Instruction = 0x27 - PUSHBYTES40 Instruction = 0x28 - PUSHBYTES41 Instruction = 0x29 - PUSHBYTES42 Instruction = 0x2A - PUSHBYTES43 Instruction = 0x2B - PUSHBYTES44 Instruction = 0x2C - PUSHBYTES45 Instruction = 0x2D - PUSHBYTES46 Instruction = 0x2E - PUSHBYTES47 Instruction = 0x2F - PUSHBYTES48 Instruction = 0x30 - PUSHBYTES49 Instruction = 0x31 - PUSHBYTES50 Instruction = 0x32 - PUSHBYTES51 Instruction = 0x33 - PUSHBYTES52 Instruction = 0x34 - PUSHBYTES53 Instruction = 0x35 - PUSHBYTES54 Instruction = 0x36 - PUSHBYTES55 Instruction = 0x37 - PUSHBYTES56 Instruction = 0x38 - PUSHBYTES57 Instruction = 0x39 - PUSHBYTES58 Instruction = 0x3A - PUSHBYTES59 Instruction = 0x3B - PUSHBYTES60 Instruction = 0x3C - PUSHBYTES61 Instruction = 0x3D - PUSHBYTES62 Instruction = 0x3E - PUSHBYTES63 Instruction = 0x3F - PUSHBYTES64 Instruction = 0x40 - PUSHBYTES65 Instruction = 0x41 - PUSHBYTES66 Instruction = 0x42 - PUSHBYTES67 Instruction = 0x43 - PUSHBYTES68 Instruction = 0x44 - PUSHBYTES69 Instruction = 0x45 - PUSHBYTES70 Instruction = 0x46 - PUSHBYTES71 Instruction = 0x47 - PUSHBYTES72 Instruction = 0x48 - PUSHBYTES73 Instruction = 0x49 - PUSHBYTES74 Instruction = 0x4A - PUSHBYTES75 Instruction = 0x4B - PUSHDATA1 Instruction = 0x4C - PUSHDATA2 Instruction = 0x4D - PUSHDATA4 Instruction = 0x4E - PUSHM1 Instruction = 0x4F - PUSH1 Instruction = 0x51 - PUSHT Instruction = PUSH1 - PUSH2 Instruction = 0x52 - PUSH3 Instruction = 0x53 - PUSH4 Instruction = 0x54 - PUSH5 Instruction = 0x55 - PUSH6 Instruction = 0x56 - PUSH7 Instruction = 0x57 - PUSH8 Instruction = 0x58 - PUSH9 Instruction = 0x59 - PUSH10 Instruction = 0x5A - PUSH11 Instruction = 0x5B - PUSH12 Instruction = 0x5C - PUSH13 Instruction = 0x5D - PUSH14 Instruction = 0x5E - PUSH15 Instruction = 0x5F - PUSH16 Instruction = 0x60 - - // Flow control - NOP Instruction = 0x61 - JMP Instruction = 0x62 - JMPIF Instruction = 0x63 - JMPIFNOT Instruction = 0x64 - CALL Instruction = 0x65 - RET Instruction = 0x66 - APPCALL Instruction = 0x67 - SYSCALL Instruction = 0x68 - TAILCALL Instruction = 0x69 - - // Stack - DUPFROMALTSTACK Instruction = 0x6A - TOALTSTACK Instruction = 0x6B - FROMALTSTACK Instruction = 0x6C - XDROP Instruction = 0x6D - XSWAP Instruction = 0x72 - XTUCK Instruction = 0x73 - DEPTH Instruction = 0x74 - DROP Instruction = 0x75 - DUP Instruction = 0x76 - NIP Instruction = 0x77 - OVER Instruction = 0x78 - PICK Instruction = 0x79 - ROLL Instruction = 0x7A - ROT Instruction = 0x7B - SWAP Instruction = 0x7C - TUCK Instruction = 0x7D - - // Splice - CAT Instruction = 0x7E - SUBSTR Instruction = 0x7F - LEFT Instruction = 0x80 - RIGHT Instruction = 0x81 - SIZE Instruction = 0x82 - - // Bitwise logic - INVERT Instruction = 0x83 - AND Instruction = 0x84 - OR Instruction = 0x85 - XOR Instruction = 0x86 - EQUAL Instruction = 0x87 - - // Arithmetic - INC Instruction = 0x8B - DEC Instruction = 0x8C - SIGN Instruction = 0x8D - NEGATE Instruction = 0x8F - ABS Instruction = 0x90 - NOT Instruction = 0x91 - NZ Instruction = 0x92 - ADD Instruction = 0x93 - SUB Instruction = 0x94 - MUL Instruction = 0x95 - DIV Instruction = 0x96 - MOD Instruction = 0x97 - SHL Instruction = 0x98 - SHR Instruction = 0x99 - BOOLAND Instruction = 0x9A - BOOLOR Instruction = 0x9B - NUMEQUAL Instruction = 0x9C - NUMNOTEQUAL Instruction = 0x9E - LT Instruction = 0x9F - GT Instruction = 0xA0 - LTE Instruction = 0xA1 - GTE Instruction = 0xA2 - MIN Instruction = 0xA3 - MAX Instruction = 0xA4 - WITHIN Instruction = 0xA5 - - // Crypto - SHA1 Instruction = 0xA7 - SHA256 Instruction = 0xA8 - HASH160 Instruction = 0xA9 - HASH256 Instruction = 0xAA - CHECKSIG Instruction = 0xAC - VERIFY Instruction = 0xAD - CHECKMULTISIG Instruction = 0xAE - - // Advanced data structures (arrays, structures, maps) - ARRAYSIZE Instruction = 0xC0 - PACK Instruction = 0xC1 - UNPACK Instruction = 0xC2 - PICKITEM Instruction = 0xC3 - SETITEM Instruction = 0xC4 - NEWARRAY Instruction = 0xC5 - NEWSTRUCT Instruction = 0xC6 - NEWMAP Instruction = 0xC7 - APPEND Instruction = 0xC8 - REVERSE Instruction = 0xC9 - REMOVE Instruction = 0xCA - HASKEY Instruction = 0xCB - KEYS Instruction = 0xCC - VALUES Instruction = 0xCD - - // Stack isolation - CALLI Instruction = 0xE0 - CALLE Instruction = 0xE1 - CALLED Instruction = 0xE2 - CALLET Instruction = 0xE3 - CALLEDT Instruction = 0xE4 - - // Exceptions - THROW Instruction = 0xF0 - THROWIFNOT Instruction = 0xF1 -) diff --git a/pkg/vm/json_test.go b/pkg/vm/json_test.go index d0050e6c7..bafbc2f41 100644 --- a/pkg/vm/json_test.go +++ b/pkg/vm/json_test.go @@ -15,6 +15,7 @@ import ( "github.com/CityOfZion/neo-go/pkg/crypto/hash" "github.com/CityOfZion/neo-go/pkg/util" + "github.com/CityOfZion/neo-go/pkg/vm/opcode" "github.com/stretchr/testify/require" ) @@ -154,7 +155,7 @@ func testFile(t *testing.T, filename string) { ctx := vm.istack.Peek(i).Value().(*Context) if ctx.nextip < len(ctx.prog) { require.Equal(t, s.InstructionPointer, ctx.nextip) - require.Equal(t, s.Instruction, Instruction(ctx.prog[ctx.nextip]).String()) + require.Equal(t, s.Instruction, opcode.Opcode(ctx.prog[ctx.nextip]).String()) } compareStacks(t, s.EStack, vm.estack) compareStacks(t, s.AStack, vm.astack) diff --git a/pkg/vm/opcode/opcode.go b/pkg/vm/opcode/opcode.go new file mode 100644 index 000000000..f3e09a5a8 --- /dev/null +++ b/pkg/vm/opcode/opcode.go @@ -0,0 +1,215 @@ +package opcode + +//go:generate stringer -type=Opcode + +// Opcode represents a single operation code for the NEO virtual machine. +type Opcode byte + +// Viable list of supported instruction constants. +const ( + // Constants + PUSH0 Opcode = 0x00 + PUSHF Opcode = PUSH0 + PUSHBYTES1 Opcode = 0x01 + PUSHBYTES2 Opcode = 0x02 + PUSHBYTES3 Opcode = 0x03 + PUSHBYTES4 Opcode = 0x04 + PUSHBYTES5 Opcode = 0x05 + PUSHBYTES6 Opcode = 0x06 + PUSHBYTES7 Opcode = 0x07 + PUSHBYTES8 Opcode = 0x08 + PUSHBYTES9 Opcode = 0x09 + PUSHBYTES10 Opcode = 0x0A + PUSHBYTES11 Opcode = 0x0B + PUSHBYTES12 Opcode = 0x0C + PUSHBYTES13 Opcode = 0x0D + PUSHBYTES14 Opcode = 0x0E + PUSHBYTES15 Opcode = 0x0F + PUSHBYTES16 Opcode = 0x10 + PUSHBYTES17 Opcode = 0x11 + PUSHBYTES18 Opcode = 0x12 + PUSHBYTES19 Opcode = 0x13 + PUSHBYTES20 Opcode = 0x14 + PUSHBYTES21 Opcode = 0x15 + PUSHBYTES22 Opcode = 0x16 + PUSHBYTES23 Opcode = 0x17 + PUSHBYTES24 Opcode = 0x18 + PUSHBYTES25 Opcode = 0x19 + PUSHBYTES26 Opcode = 0x1A + PUSHBYTES27 Opcode = 0x1B + PUSHBYTES28 Opcode = 0x1C + PUSHBYTES29 Opcode = 0x1D + PUSHBYTES30 Opcode = 0x1E + PUSHBYTES31 Opcode = 0x1F + PUSHBYTES32 Opcode = 0x20 + PUSHBYTES33 Opcode = 0x21 + PUSHBYTES34 Opcode = 0x22 + PUSHBYTES35 Opcode = 0x23 + PUSHBYTES36 Opcode = 0x24 + PUSHBYTES37 Opcode = 0x25 + PUSHBYTES38 Opcode = 0x26 + PUSHBYTES39 Opcode = 0x27 + PUSHBYTES40 Opcode = 0x28 + PUSHBYTES41 Opcode = 0x29 + PUSHBYTES42 Opcode = 0x2A + PUSHBYTES43 Opcode = 0x2B + PUSHBYTES44 Opcode = 0x2C + PUSHBYTES45 Opcode = 0x2D + PUSHBYTES46 Opcode = 0x2E + PUSHBYTES47 Opcode = 0x2F + PUSHBYTES48 Opcode = 0x30 + PUSHBYTES49 Opcode = 0x31 + PUSHBYTES50 Opcode = 0x32 + PUSHBYTES51 Opcode = 0x33 + PUSHBYTES52 Opcode = 0x34 + PUSHBYTES53 Opcode = 0x35 + PUSHBYTES54 Opcode = 0x36 + PUSHBYTES55 Opcode = 0x37 + PUSHBYTES56 Opcode = 0x38 + PUSHBYTES57 Opcode = 0x39 + PUSHBYTES58 Opcode = 0x3A + PUSHBYTES59 Opcode = 0x3B + PUSHBYTES60 Opcode = 0x3C + PUSHBYTES61 Opcode = 0x3D + PUSHBYTES62 Opcode = 0x3E + PUSHBYTES63 Opcode = 0x3F + PUSHBYTES64 Opcode = 0x40 + PUSHBYTES65 Opcode = 0x41 + PUSHBYTES66 Opcode = 0x42 + PUSHBYTES67 Opcode = 0x43 + PUSHBYTES68 Opcode = 0x44 + PUSHBYTES69 Opcode = 0x45 + PUSHBYTES70 Opcode = 0x46 + PUSHBYTES71 Opcode = 0x47 + PUSHBYTES72 Opcode = 0x48 + PUSHBYTES73 Opcode = 0x49 + PUSHBYTES74 Opcode = 0x4A + PUSHBYTES75 Opcode = 0x4B + PUSHDATA1 Opcode = 0x4C + PUSHDATA2 Opcode = 0x4D + PUSHDATA4 Opcode = 0x4E + PUSHM1 Opcode = 0x4F + PUSH1 Opcode = 0x51 + PUSHT Opcode = PUSH1 + PUSH2 Opcode = 0x52 + PUSH3 Opcode = 0x53 + PUSH4 Opcode = 0x54 + PUSH5 Opcode = 0x55 + PUSH6 Opcode = 0x56 + PUSH7 Opcode = 0x57 + PUSH8 Opcode = 0x58 + PUSH9 Opcode = 0x59 + PUSH10 Opcode = 0x5A + PUSH11 Opcode = 0x5B + PUSH12 Opcode = 0x5C + PUSH13 Opcode = 0x5D + PUSH14 Opcode = 0x5E + PUSH15 Opcode = 0x5F + PUSH16 Opcode = 0x60 + + // Flow control + NOP Opcode = 0x61 + JMP Opcode = 0x62 + JMPIF Opcode = 0x63 + JMPIFNOT Opcode = 0x64 + CALL Opcode = 0x65 + RET Opcode = 0x66 + APPCALL Opcode = 0x67 + SYSCALL Opcode = 0x68 + TAILCALL Opcode = 0x69 + + // Stack + DUPFROMALTSTACK Opcode = 0x6A + TOALTSTACK Opcode = 0x6B + FROMALTSTACK Opcode = 0x6C + XDROP Opcode = 0x6D + XSWAP Opcode = 0x72 + XTUCK Opcode = 0x73 + DEPTH Opcode = 0x74 + DROP Opcode = 0x75 + DUP Opcode = 0x76 + NIP Opcode = 0x77 + OVER Opcode = 0x78 + PICK Opcode = 0x79 + ROLL Opcode = 0x7A + ROT Opcode = 0x7B + SWAP Opcode = 0x7C + TUCK Opcode = 0x7D + + // Splice + CAT Opcode = 0x7E + SUBSTR Opcode = 0x7F + LEFT Opcode = 0x80 + RIGHT Opcode = 0x81 + SIZE Opcode = 0x82 + + // Bitwise logic + INVERT Opcode = 0x83 + AND Opcode = 0x84 + OR Opcode = 0x85 + XOR Opcode = 0x86 + EQUAL Opcode = 0x87 + + // Arithmetic + INC Opcode = 0x8B + DEC Opcode = 0x8C + SIGN Opcode = 0x8D + NEGATE Opcode = 0x8F + ABS Opcode = 0x90 + NOT Opcode = 0x91 + NZ Opcode = 0x92 + ADD Opcode = 0x93 + SUB Opcode = 0x94 + MUL Opcode = 0x95 + DIV Opcode = 0x96 + MOD Opcode = 0x97 + SHL Opcode = 0x98 + SHR Opcode = 0x99 + BOOLAND Opcode = 0x9A + BOOLOR Opcode = 0x9B + NUMEQUAL Opcode = 0x9C + NUMNOTEQUAL Opcode = 0x9E + LT Opcode = 0x9F + GT Opcode = 0xA0 + LTE Opcode = 0xA1 + GTE Opcode = 0xA2 + MIN Opcode = 0xA3 + MAX Opcode = 0xA4 + WITHIN Opcode = 0xA5 + + // Crypto + SHA1 Opcode = 0xA7 + SHA256 Opcode = 0xA8 + HASH160 Opcode = 0xA9 + HASH256 Opcode = 0xAA + CHECKSIG Opcode = 0xAC + VERIFY Opcode = 0xAD + CHECKMULTISIG Opcode = 0xAE + + // Advanced data structures (arrays, structures, maps) + ARRAYSIZE Opcode = 0xC0 + PACK Opcode = 0xC1 + UNPACK Opcode = 0xC2 + PICKITEM Opcode = 0xC3 + SETITEM Opcode = 0xC4 + NEWARRAY Opcode = 0xC5 + NEWSTRUCT Opcode = 0xC6 + NEWMAP Opcode = 0xC7 + APPEND Opcode = 0xC8 + REVERSE Opcode = 0xC9 + REMOVE Opcode = 0xCA + HASKEY Opcode = 0xCB + KEYS Opcode = 0xCC + VALUES Opcode = 0xCD + + // Stack isolation + CALLI Opcode = 0xE0 + CALLE Opcode = 0xE1 + CALLED Opcode = 0xE2 + CALLET Opcode = 0xE3 + CALLEDT Opcode = 0xE4 + + // Exceptions + THROW Opcode = 0xF0 + THROWIFNOT Opcode = 0xF1 +) diff --git a/pkg/vm/opcode/opcode_string.go b/pkg/vm/opcode/opcode_string.go new file mode 100644 index 000000000..7a7ed4cb9 --- /dev/null +++ b/pkg/vm/opcode/opcode_string.go @@ -0,0 +1,393 @@ +// Code generated by "stringer -type=Opcode"; DO NOT EDIT. + +package opcode + +import "strconv" + +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + // Re-run the stringer command to generate them again. + var x [1]struct{} + _ = x[PUSH0-0] + _ = x[PUSHF-0] + _ = x[PUSHBYTES1-1] + _ = x[PUSHBYTES2-2] + _ = x[PUSHBYTES3-3] + _ = x[PUSHBYTES4-4] + _ = x[PUSHBYTES5-5] + _ = x[PUSHBYTES6-6] + _ = x[PUSHBYTES7-7] + _ = x[PUSHBYTES8-8] + _ = x[PUSHBYTES9-9] + _ = x[PUSHBYTES10-10] + _ = x[PUSHBYTES11-11] + _ = x[PUSHBYTES12-12] + _ = x[PUSHBYTES13-13] + _ = x[PUSHBYTES14-14] + _ = x[PUSHBYTES15-15] + _ = x[PUSHBYTES16-16] + _ = x[PUSHBYTES17-17] + _ = x[PUSHBYTES18-18] + _ = x[PUSHBYTES19-19] + _ = x[PUSHBYTES20-20] + _ = x[PUSHBYTES21-21] + _ = x[PUSHBYTES22-22] + _ = x[PUSHBYTES23-23] + _ = x[PUSHBYTES24-24] + _ = x[PUSHBYTES25-25] + _ = x[PUSHBYTES26-26] + _ = x[PUSHBYTES27-27] + _ = x[PUSHBYTES28-28] + _ = x[PUSHBYTES29-29] + _ = x[PUSHBYTES30-30] + _ = x[PUSHBYTES31-31] + _ = x[PUSHBYTES32-32] + _ = x[PUSHBYTES33-33] + _ = x[PUSHBYTES34-34] + _ = x[PUSHBYTES35-35] + _ = x[PUSHBYTES36-36] + _ = x[PUSHBYTES37-37] + _ = x[PUSHBYTES38-38] + _ = x[PUSHBYTES39-39] + _ = x[PUSHBYTES40-40] + _ = x[PUSHBYTES41-41] + _ = x[PUSHBYTES42-42] + _ = x[PUSHBYTES43-43] + _ = x[PUSHBYTES44-44] + _ = x[PUSHBYTES45-45] + _ = x[PUSHBYTES46-46] + _ = x[PUSHBYTES47-47] + _ = x[PUSHBYTES48-48] + _ = x[PUSHBYTES49-49] + _ = x[PUSHBYTES50-50] + _ = x[PUSHBYTES51-51] + _ = x[PUSHBYTES52-52] + _ = x[PUSHBYTES53-53] + _ = x[PUSHBYTES54-54] + _ = x[PUSHBYTES55-55] + _ = x[PUSHBYTES56-56] + _ = x[PUSHBYTES57-57] + _ = x[PUSHBYTES58-58] + _ = x[PUSHBYTES59-59] + _ = x[PUSHBYTES60-60] + _ = x[PUSHBYTES61-61] + _ = x[PUSHBYTES62-62] + _ = x[PUSHBYTES63-63] + _ = x[PUSHBYTES64-64] + _ = x[PUSHBYTES65-65] + _ = x[PUSHBYTES66-66] + _ = x[PUSHBYTES67-67] + _ = x[PUSHBYTES68-68] + _ = x[PUSHBYTES69-69] + _ = x[PUSHBYTES70-70] + _ = x[PUSHBYTES71-71] + _ = x[PUSHBYTES72-72] + _ = x[PUSHBYTES73-73] + _ = x[PUSHBYTES74-74] + _ = x[PUSHBYTES75-75] + _ = x[PUSHDATA1-76] + _ = x[PUSHDATA2-77] + _ = x[PUSHDATA4-78] + _ = x[PUSHM1-79] + _ = x[PUSH1-81] + _ = x[PUSHT-81] + _ = x[PUSH2-82] + _ = x[PUSH3-83] + _ = x[PUSH4-84] + _ = x[PUSH5-85] + _ = x[PUSH6-86] + _ = x[PUSH7-87] + _ = x[PUSH8-88] + _ = x[PUSH9-89] + _ = x[PUSH10-90] + _ = x[PUSH11-91] + _ = x[PUSH12-92] + _ = x[PUSH13-93] + _ = x[PUSH14-94] + _ = x[PUSH15-95] + _ = x[PUSH16-96] + _ = x[NOP-97] + _ = x[JMP-98] + _ = x[JMPIF-99] + _ = x[JMPIFNOT-100] + _ = x[CALL-101] + _ = x[RET-102] + _ = x[APPCALL-103] + _ = x[SYSCALL-104] + _ = x[TAILCALL-105] + _ = x[DUPFROMALTSTACK-106] + _ = x[TOALTSTACK-107] + _ = x[FROMALTSTACK-108] + _ = x[XDROP-109] + _ = x[XSWAP-114] + _ = x[XTUCK-115] + _ = x[DEPTH-116] + _ = x[DROP-117] + _ = x[DUP-118] + _ = x[NIP-119] + _ = x[OVER-120] + _ = x[PICK-121] + _ = x[ROLL-122] + _ = x[ROT-123] + _ = x[SWAP-124] + _ = x[TUCK-125] + _ = x[CAT-126] + _ = x[SUBSTR-127] + _ = x[LEFT-128] + _ = x[RIGHT-129] + _ = x[SIZE-130] + _ = x[INVERT-131] + _ = x[AND-132] + _ = x[OR-133] + _ = x[XOR-134] + _ = x[EQUAL-135] + _ = x[INC-139] + _ = x[DEC-140] + _ = x[SIGN-141] + _ = x[NEGATE-143] + _ = x[ABS-144] + _ = x[NOT-145] + _ = x[NZ-146] + _ = x[ADD-147] + _ = x[SUB-148] + _ = x[MUL-149] + _ = x[DIV-150] + _ = x[MOD-151] + _ = x[SHL-152] + _ = x[SHR-153] + _ = x[BOOLAND-154] + _ = x[BOOLOR-155] + _ = x[NUMEQUAL-156] + _ = x[NUMNOTEQUAL-158] + _ = x[LT-159] + _ = x[GT-160] + _ = x[LTE-161] + _ = x[GTE-162] + _ = x[MIN-163] + _ = x[MAX-164] + _ = x[WITHIN-165] + _ = x[SHA1-167] + _ = x[SHA256-168] + _ = x[HASH160-169] + _ = x[HASH256-170] + _ = x[CHECKSIG-172] + _ = x[VERIFY-173] + _ = x[CHECKMULTISIG-174] + _ = x[ARRAYSIZE-192] + _ = x[PACK-193] + _ = x[UNPACK-194] + _ = x[PICKITEM-195] + _ = x[SETITEM-196] + _ = x[NEWARRAY-197] + _ = x[NEWSTRUCT-198] + _ = x[NEWMAP-199] + _ = x[APPEND-200] + _ = x[REVERSE-201] + _ = x[REMOVE-202] + _ = x[HASKEY-203] + _ = x[KEYS-204] + _ = x[VALUES-205] + _ = x[CALLI-224] + _ = x[CALLE-225] + _ = x[CALLED-226] + _ = x[CALLET-227] + _ = x[CALLEDT-228] + _ = x[THROW-240] + _ = x[THROWIFNOT-241] +} + +const _Opcode_name = "PUSH0PUSHBYTES1PUSHBYTES2PUSHBYTES3PUSHBYTES4PUSHBYTES5PUSHBYTES6PUSHBYTES7PUSHBYTES8PUSHBYTES9PUSHBYTES10PUSHBYTES11PUSHBYTES12PUSHBYTES13PUSHBYTES14PUSHBYTES15PUSHBYTES16PUSHBYTES17PUSHBYTES18PUSHBYTES19PUSHBYTES20PUSHBYTES21PUSHBYTES22PUSHBYTES23PUSHBYTES24PUSHBYTES25PUSHBYTES26PUSHBYTES27PUSHBYTES28PUSHBYTES29PUSHBYTES30PUSHBYTES31PUSHBYTES32PUSHBYTES33PUSHBYTES34PUSHBYTES35PUSHBYTES36PUSHBYTES37PUSHBYTES38PUSHBYTES39PUSHBYTES40PUSHBYTES41PUSHBYTES42PUSHBYTES43PUSHBYTES44PUSHBYTES45PUSHBYTES46PUSHBYTES47PUSHBYTES48PUSHBYTES49PUSHBYTES50PUSHBYTES51PUSHBYTES52PUSHBYTES53PUSHBYTES54PUSHBYTES55PUSHBYTES56PUSHBYTES57PUSHBYTES58PUSHBYTES59PUSHBYTES60PUSHBYTES61PUSHBYTES62PUSHBYTES63PUSHBYTES64PUSHBYTES65PUSHBYTES66PUSHBYTES67PUSHBYTES68PUSHBYTES69PUSHBYTES70PUSHBYTES71PUSHBYTES72PUSHBYTES73PUSHBYTES74PUSHBYTES75PUSHDATA1PUSHDATA2PUSHDATA4PUSHM1PUSH1PUSH2PUSH3PUSH4PUSH5PUSH6PUSH7PUSH8PUSH9PUSH10PUSH11PUSH12PUSH13PUSH14PUSH15PUSH16NOPJMPJMPIFJMPIFNOTCALLRETAPPCALLSYSCALLTAILCALLDUPFROMALTSTACKTOALTSTACKFROMALTSTACKXDROPXSWAPXTUCKDEPTHDROPDUPNIPOVERPICKROLLROTSWAPTUCKCATSUBSTRLEFTRIGHTSIZEINVERTANDORXOREQUALINCDECSIGNNEGATEABSNOTNZADDSUBMULDIVMODSHLSHRBOOLANDBOOLORNUMEQUALNUMNOTEQUALLTGTLTEGTEMINMAXWITHINSHA1SHA256HASH160HASH256CHECKSIGVERIFYCHECKMULTISIGARRAYSIZEPACKUNPACKPICKITEMSETITEMNEWARRAYNEWSTRUCTNEWMAPAPPENDREVERSEREMOVEHASKEYKEYSVALUESCALLICALLECALLEDCALLETCALLEDTTHROWTHROWIFNOT" + +var _Opcode_map = map[Opcode]string{ + 0: _Opcode_name[0:5], + 1: _Opcode_name[5:15], + 2: _Opcode_name[15:25], + 3: _Opcode_name[25:35], + 4: _Opcode_name[35:45], + 5: _Opcode_name[45:55], + 6: _Opcode_name[55:65], + 7: _Opcode_name[65:75], + 8: _Opcode_name[75:85], + 9: _Opcode_name[85:95], + 10: _Opcode_name[95:106], + 11: _Opcode_name[106:117], + 12: _Opcode_name[117:128], + 13: _Opcode_name[128:139], + 14: _Opcode_name[139:150], + 15: _Opcode_name[150:161], + 16: _Opcode_name[161:172], + 17: _Opcode_name[172:183], + 18: _Opcode_name[183:194], + 19: _Opcode_name[194:205], + 20: _Opcode_name[205:216], + 21: _Opcode_name[216:227], + 22: _Opcode_name[227:238], + 23: _Opcode_name[238:249], + 24: _Opcode_name[249:260], + 25: _Opcode_name[260:271], + 26: _Opcode_name[271:282], + 27: _Opcode_name[282:293], + 28: _Opcode_name[293:304], + 29: _Opcode_name[304:315], + 30: _Opcode_name[315:326], + 31: _Opcode_name[326:337], + 32: _Opcode_name[337:348], + 33: _Opcode_name[348:359], + 34: _Opcode_name[359:370], + 35: _Opcode_name[370:381], + 36: _Opcode_name[381:392], + 37: _Opcode_name[392:403], + 38: _Opcode_name[403:414], + 39: _Opcode_name[414:425], + 40: _Opcode_name[425:436], + 41: _Opcode_name[436:447], + 42: _Opcode_name[447:458], + 43: _Opcode_name[458:469], + 44: _Opcode_name[469:480], + 45: _Opcode_name[480:491], + 46: _Opcode_name[491:502], + 47: _Opcode_name[502:513], + 48: _Opcode_name[513:524], + 49: _Opcode_name[524:535], + 50: _Opcode_name[535:546], + 51: _Opcode_name[546:557], + 52: _Opcode_name[557:568], + 53: _Opcode_name[568:579], + 54: _Opcode_name[579:590], + 55: _Opcode_name[590:601], + 56: _Opcode_name[601:612], + 57: _Opcode_name[612:623], + 58: _Opcode_name[623:634], + 59: _Opcode_name[634:645], + 60: _Opcode_name[645:656], + 61: _Opcode_name[656:667], + 62: _Opcode_name[667:678], + 63: _Opcode_name[678:689], + 64: _Opcode_name[689:700], + 65: _Opcode_name[700:711], + 66: _Opcode_name[711:722], + 67: _Opcode_name[722:733], + 68: _Opcode_name[733:744], + 69: _Opcode_name[744:755], + 70: _Opcode_name[755:766], + 71: _Opcode_name[766:777], + 72: _Opcode_name[777:788], + 73: _Opcode_name[788:799], + 74: _Opcode_name[799:810], + 75: _Opcode_name[810:821], + 76: _Opcode_name[821:830], + 77: _Opcode_name[830:839], + 78: _Opcode_name[839:848], + 79: _Opcode_name[848:854], + 81: _Opcode_name[854:859], + 82: _Opcode_name[859:864], + 83: _Opcode_name[864:869], + 84: _Opcode_name[869:874], + 85: _Opcode_name[874:879], + 86: _Opcode_name[879:884], + 87: _Opcode_name[884:889], + 88: _Opcode_name[889:894], + 89: _Opcode_name[894:899], + 90: _Opcode_name[899:905], + 91: _Opcode_name[905:911], + 92: _Opcode_name[911:917], + 93: _Opcode_name[917:923], + 94: _Opcode_name[923:929], + 95: _Opcode_name[929:935], + 96: _Opcode_name[935:941], + 97: _Opcode_name[941:944], + 98: _Opcode_name[944:947], + 99: _Opcode_name[947:952], + 100: _Opcode_name[952:960], + 101: _Opcode_name[960:964], + 102: _Opcode_name[964:967], + 103: _Opcode_name[967:974], + 104: _Opcode_name[974:981], + 105: _Opcode_name[981:989], + 106: _Opcode_name[989:1004], + 107: _Opcode_name[1004:1014], + 108: _Opcode_name[1014:1026], + 109: _Opcode_name[1026:1031], + 114: _Opcode_name[1031:1036], + 115: _Opcode_name[1036:1041], + 116: _Opcode_name[1041:1046], + 117: _Opcode_name[1046:1050], + 118: _Opcode_name[1050:1053], + 119: _Opcode_name[1053:1056], + 120: _Opcode_name[1056:1060], + 121: _Opcode_name[1060:1064], + 122: _Opcode_name[1064:1068], + 123: _Opcode_name[1068:1071], + 124: _Opcode_name[1071:1075], + 125: _Opcode_name[1075:1079], + 126: _Opcode_name[1079:1082], + 127: _Opcode_name[1082:1088], + 128: _Opcode_name[1088:1092], + 129: _Opcode_name[1092:1097], + 130: _Opcode_name[1097:1101], + 131: _Opcode_name[1101:1107], + 132: _Opcode_name[1107:1110], + 133: _Opcode_name[1110:1112], + 134: _Opcode_name[1112:1115], + 135: _Opcode_name[1115:1120], + 139: _Opcode_name[1120:1123], + 140: _Opcode_name[1123:1126], + 141: _Opcode_name[1126:1130], + 143: _Opcode_name[1130:1136], + 144: _Opcode_name[1136:1139], + 145: _Opcode_name[1139:1142], + 146: _Opcode_name[1142:1144], + 147: _Opcode_name[1144:1147], + 148: _Opcode_name[1147:1150], + 149: _Opcode_name[1150:1153], + 150: _Opcode_name[1153:1156], + 151: _Opcode_name[1156:1159], + 152: _Opcode_name[1159:1162], + 153: _Opcode_name[1162:1165], + 154: _Opcode_name[1165:1172], + 155: _Opcode_name[1172:1178], + 156: _Opcode_name[1178:1186], + 158: _Opcode_name[1186:1197], + 159: _Opcode_name[1197:1199], + 160: _Opcode_name[1199:1201], + 161: _Opcode_name[1201:1204], + 162: _Opcode_name[1204:1207], + 163: _Opcode_name[1207:1210], + 164: _Opcode_name[1210:1213], + 165: _Opcode_name[1213:1219], + 167: _Opcode_name[1219:1223], + 168: _Opcode_name[1223:1229], + 169: _Opcode_name[1229:1236], + 170: _Opcode_name[1236:1243], + 172: _Opcode_name[1243:1251], + 173: _Opcode_name[1251:1257], + 174: _Opcode_name[1257:1270], + 192: _Opcode_name[1270:1279], + 193: _Opcode_name[1279:1283], + 194: _Opcode_name[1283:1289], + 195: _Opcode_name[1289:1297], + 196: _Opcode_name[1297:1304], + 197: _Opcode_name[1304:1312], + 198: _Opcode_name[1312:1321], + 199: _Opcode_name[1321:1327], + 200: _Opcode_name[1327:1333], + 201: _Opcode_name[1333:1340], + 202: _Opcode_name[1340:1346], + 203: _Opcode_name[1346:1352], + 204: _Opcode_name[1352:1356], + 205: _Opcode_name[1356:1362], + 224: _Opcode_name[1362:1367], + 225: _Opcode_name[1367:1372], + 226: _Opcode_name[1372:1378], + 227: _Opcode_name[1378:1384], + 228: _Opcode_name[1384:1391], + 240: _Opcode_name[1391:1396], + 241: _Opcode_name[1396:1406], +} + +func (i Opcode) String() string { + if str, ok := _Opcode_map[i]; ok { + return str + } + return "Opcode(" + strconv.FormatInt(int64(i), 10) + ")" +} diff --git a/pkg/vm/opcode/opcode_test.go b/pkg/vm/opcode/opcode_test.go new file mode 100644 index 000000000..256d13137 --- /dev/null +++ b/pkg/vm/opcode/opcode_test.go @@ -0,0 +1,20 @@ +package opcode + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +// Nothing more to test here, really. +func TestStringer(t *testing.T) { + tests := map[Opcode]string{ + ADD: "ADD", + SUB: "SUB", + THROWIFNOT: "THROWIFNOT", + 0xff: "Opcode(255)", + } + for o, s := range tests { + assert.Equal(t, s, o.String()) + } +} diff --git a/pkg/vm/vm.go b/pkg/vm/vm.go index 2c131c772..9eb83f209 100644 --- a/pkg/vm/vm.go +++ b/pkg/vm/vm.go @@ -14,12 +14,13 @@ import ( "github.com/CityOfZion/neo-go/pkg/crypto/hash" "github.com/CityOfZion/neo-go/pkg/crypto/keys" "github.com/CityOfZion/neo-go/pkg/util" + "github.com/CityOfZion/neo-go/pkg/vm/opcode" "github.com/pkg/errors" ) type errorAtInstruct struct { ip int - op Instruction + op opcode.Opcode err interface{} } @@ -27,7 +28,7 @@ func (e *errorAtInstruct) Error() string { return fmt.Sprintf("error encountered at instruction %d (%s): %s", e.ip, e.op, e.err) } -func newError(ip int, op Instruction, err interface{}) *errorAtInstruct { +func newError(ip int, op opcode.Opcode, err interface{}) *errorAtInstruct { return &errorAtInstruct{ip: ip, op: op, err: err} } @@ -175,12 +176,12 @@ func (v *VM) PrintOps() { var desc = "" if parameter != nil { switch instr { - case JMP, JMPIF, JMPIFNOT, CALL: + case opcode.JMP, opcode.JMPIF, opcode.JMPIFNOT, opcode.CALL: offset := int16(binary.LittleEndian.Uint16(parameter)) desc = fmt.Sprintf("%d (%d/%x)", ctx.ip+int(offset), offset, parameter) - case SYSCALL: + case opcode.SYSCALL: desc = fmt.Sprintf("%q", parameter) - case APPCALL, TAILCALL: + case opcode.APPCALL, opcode.TAILCALL: desc = fmt.Sprintf("%x", parameter) default: if utf8.Valid(parameter) { @@ -447,7 +448,7 @@ func (v *VM) SetScriptGetter(gs func(util.Uint160) []byte) { } // execute performs an instruction cycle in the VM. Acting on the instruction (opcode). -func (v *VM) execute(ctx *Context, op Instruction, parameter []byte) (err error) { +func (v *VM) execute(ctx *Context, op opcode.Opcode, parameter []byte) (err error) { // Instead of polluting the whole VM logic with error handling, we will recover // each panic at a central point, putting the VM in a fault state and setting error. defer func() { @@ -460,44 +461,46 @@ func (v *VM) execute(ctx *Context, op Instruction, parameter []byte) (err error) } }() - if op >= PUSHBYTES1 && op <= PUSHBYTES75 { + if op >= opcode.PUSHBYTES1 && op <= opcode.PUSHBYTES75 { v.estack.PushVal(parameter) return } switch op { - case PUSHM1, PUSH1, PUSH2, PUSH3, PUSH4, PUSH5, - PUSH6, PUSH7, PUSH8, PUSH9, PUSH10, PUSH11, - PUSH12, PUSH13, PUSH14, PUSH15, PUSH16: - val := int(op) - int(PUSH1) + 1 + case opcode.PUSHM1, opcode.PUSH1, opcode.PUSH2, opcode.PUSH3, + opcode.PUSH4, opcode.PUSH5, opcode.PUSH6, opcode.PUSH7, + opcode.PUSH8, opcode.PUSH9, opcode.PUSH10, opcode.PUSH11, + opcode.PUSH12, opcode.PUSH13, opcode.PUSH14, opcode.PUSH15, + opcode.PUSH16: + val := int(op) - int(opcode.PUSH1) + 1 v.estack.PushVal(val) - case PUSH0: + case opcode.PUSH0: v.estack.PushVal([]byte{}) - case PUSHDATA1, PUSHDATA2, PUSHDATA4: + case opcode.PUSHDATA1, opcode.PUSHDATA2, opcode.PUSHDATA4: v.estack.PushVal(parameter) // Stack operations. - case TOALTSTACK: + case opcode.TOALTSTACK: v.astack.Push(v.estack.Pop()) - case FROMALTSTACK: + case opcode.FROMALTSTACK: v.estack.Push(v.astack.Pop()) - case DUPFROMALTSTACK: + case opcode.DUPFROMALTSTACK: v.estack.Push(v.astack.Dup(0)) - case DUP: + case opcode.DUP: v.estack.Push(v.estack.Dup(0)) - case SWAP: + case opcode.SWAP: a := v.estack.Pop() b := v.estack.Pop() v.estack.Push(a) v.estack.Push(b) - case TUCK: + case opcode.TUCK: a := v.estack.Dup(0) if a == nil { panic("no top-level element found") @@ -507,7 +510,7 @@ func (v *VM) execute(ctx *Context, op Instruction, parameter []byte) (err error) } v.estack.InsertAt(a, 2) - case CAT: + case opcode.CAT: b := v.estack.Pop().Bytes() a := v.estack.Pop().Bytes() if l := len(a) + len(b); l > MaxItemSize { @@ -516,7 +519,7 @@ func (v *VM) execute(ctx *Context, op Instruction, parameter []byte) (err error) ab := append(a, b...) v.estack.PushVal(ab) - case SUBSTR: + case opcode.SUBSTR: l := int(v.estack.Pop().BigInt().Int64()) if l < 0 { panic("negative length") @@ -538,7 +541,7 @@ func (v *VM) execute(ctx *Context, op Instruction, parameter []byte) (err error) } v.estack.PushVal(s[o:last]) - case LEFT: + case opcode.LEFT: l := int(v.estack.Pop().BigInt().Int64()) if l < 0 { panic("negative length") @@ -549,7 +552,7 @@ func (v *VM) execute(ctx *Context, op Instruction, parameter []byte) (err error) } v.estack.PushVal(s[:l]) - case RIGHT: + case opcode.RIGHT: l := int(v.estack.Pop().BigInt().Int64()) if l < 0 { panic("negative length") @@ -557,7 +560,7 @@ func (v *VM) execute(ctx *Context, op Instruction, parameter []byte) (err error) s := v.estack.Pop().Bytes() v.estack.PushVal(s[len(s)-l:]) - case XDROP: + case opcode.XDROP: n := int(v.estack.Pop().BigInt().Int64()) if n < 0 { panic("invalid length") @@ -567,7 +570,7 @@ func (v *VM) execute(ctx *Context, op Instruction, parameter []byte) (err error) panic("bad index") } - case XSWAP: + case opcode.XSWAP: n := int(v.estack.Pop().BigInt().Int64()) if n < 0 { panic("XSWAP: invalid length") @@ -583,7 +586,7 @@ func (v *VM) execute(ctx *Context, op Instruction, parameter []byte) (err error) b.value = aval } - case XTUCK: + case opcode.XTUCK: n := int(v.estack.Pop().BigInt().Int64()) if n <= 0 { panic("XTUCK: invalid length") @@ -597,30 +600,30 @@ func (v *VM) execute(ctx *Context, op Instruction, parameter []byte) (err error) } v.estack.InsertAt(a, n) - case ROT: + case opcode.ROT: e := v.estack.RemoveAt(2) if e == nil { panic("no top-level element found") } v.estack.Push(e) - case DEPTH: + case opcode.DEPTH: v.estack.PushVal(v.estack.Len()) - case NIP: + case opcode.NIP: elem := v.estack.RemoveAt(1) if elem == nil { panic("no second element found") } - case OVER: + case opcode.OVER: a := v.estack.Peek(1) if a == nil { panic("no second element found") } v.estack.Push(a) - case PICK: + case opcode.PICK: n := int(v.estack.Pop().BigInt().Int64()) if n < 0 { panic("negative stack item returned") @@ -631,7 +634,7 @@ func (v *VM) execute(ctx *Context, op Instruction, parameter []byte) (err error) } v.estack.Push(a) - case ROLL: + case opcode.ROLL: n := int(v.estack.Pop().BigInt().Int64()) if n < 0 { panic("negative stack item returned") @@ -644,13 +647,13 @@ func (v *VM) execute(ctx *Context, op Instruction, parameter []byte) (err error) v.estack.Push(e) } - case DROP: + case opcode.DROP: if v.estack.Len() < 1 { panic("stack is too small") } v.estack.Pop() - case EQUAL: + case opcode.EQUAL: b := v.estack.Pop() if b == nil { panic("no top-level element found") @@ -673,28 +676,28 @@ func (v *VM) execute(ctx *Context, op Instruction, parameter []byte) (err error) v.estack.PushVal(reflect.DeepEqual(a, b)) // Bit operations. - case INVERT: + case opcode.INVERT: // inplace a := v.estack.Peek(0).BigInt() a.Not(a) - case AND: + case opcode.AND: b := v.estack.Pop().BigInt() a := v.estack.Pop().BigInt() v.estack.PushVal(new(big.Int).And(b, a)) - case OR: + case opcode.OR: b := v.estack.Pop().BigInt() a := v.estack.Pop().BigInt() v.estack.PushVal(new(big.Int).Or(b, a)) - case XOR: + case opcode.XOR: b := v.estack.Pop().BigInt() a := v.estack.Pop().BigInt() v.estack.PushVal(new(big.Int).Xor(b, a)) // Numeric operations. - case ADD: + case opcode.ADD: a := v.estack.Pop().BigInt() v.checkBigIntSize(a) b := v.estack.Pop().BigInt() @@ -704,7 +707,7 @@ func (v *VM) execute(ctx *Context, op Instruction, parameter []byte) (err error) v.checkBigIntSize(c) v.estack.PushVal(c) - case SUB: + case opcode.SUB: b := v.estack.Pop().BigInt() v.checkBigIntSize(b) a := v.estack.Pop().BigInt() @@ -714,7 +717,7 @@ func (v *VM) execute(ctx *Context, op Instruction, parameter []byte) (err error) v.checkBigIntSize(c) v.estack.PushVal(c) - case DIV: + case opcode.DIV: b := v.estack.Pop().BigInt() v.checkBigIntSize(b) a := v.estack.Pop().BigInt() @@ -722,7 +725,7 @@ func (v *VM) execute(ctx *Context, op Instruction, parameter []byte) (err error) v.estack.PushVal(new(big.Int).Div(a, b)) - case MUL: + case opcode.MUL: a := v.estack.Pop().BigInt() v.checkBigIntSize(a) b := v.estack.Pop().BigInt() @@ -732,7 +735,7 @@ func (v *VM) execute(ctx *Context, op Instruction, parameter []byte) (err error) v.checkBigIntSize(c) v.estack.PushVal(c) - case MOD: + case opcode.MOD: b := v.estack.Pop().BigInt() v.checkBigIntSize(b) a := v.estack.Pop().BigInt() @@ -740,7 +743,7 @@ func (v *VM) execute(ctx *Context, op Instruction, parameter []byte) (err error) v.estack.PushVal(new(big.Int).Mod(a, b)) - case SHL, SHR: + case opcode.SHL, opcode.SHR: b := v.estack.Pop().BigInt().Int64() if b == 0 { return @@ -751,7 +754,7 @@ func (v *VM) execute(ctx *Context, op Instruction, parameter []byte) (err error) v.checkBigIntSize(a) var item big.Int - if op == SHL { + if op == opcode.SHL { item.Lsh(a, uint(b)) } else { item.Rsh(a, uint(b)) @@ -760,47 +763,47 @@ func (v *VM) execute(ctx *Context, op Instruction, parameter []byte) (err error) v.checkBigIntSize(&item) v.estack.PushVal(&item) - case BOOLAND: + case opcode.BOOLAND: b := v.estack.Pop().Bool() a := v.estack.Pop().Bool() v.estack.PushVal(a && b) - case BOOLOR: + case opcode.BOOLOR: b := v.estack.Pop().Bool() a := v.estack.Pop().Bool() v.estack.PushVal(a || b) - case NUMEQUAL: + case opcode.NUMEQUAL: b := v.estack.Pop().BigInt() a := v.estack.Pop().BigInt() v.estack.PushVal(a.Cmp(b) == 0) - case NUMNOTEQUAL: + case opcode.NUMNOTEQUAL: b := v.estack.Pop().BigInt() a := v.estack.Pop().BigInt() v.estack.PushVal(a.Cmp(b) != 0) - case LT: + case opcode.LT: b := v.estack.Pop().BigInt() a := v.estack.Pop().BigInt() v.estack.PushVal(a.Cmp(b) == -1) - case GT: + case opcode.GT: b := v.estack.Pop().BigInt() a := v.estack.Pop().BigInt() v.estack.PushVal(a.Cmp(b) == 1) - case LTE: + case opcode.LTE: b := v.estack.Pop().BigInt() a := v.estack.Pop().BigInt() v.estack.PushVal(a.Cmp(b) <= 0) - case GTE: + case opcode.GTE: b := v.estack.Pop().BigInt() a := v.estack.Pop().BigInt() v.estack.PushVal(a.Cmp(b) >= 0) - case MIN: + case opcode.MIN: b := v.estack.Pop().BigInt() a := v.estack.Pop().BigInt() val := a @@ -809,7 +812,7 @@ func (v *VM) execute(ctx *Context, op Instruction, parameter []byte) (err error) } v.estack.PushVal(val) - case MAX: + case opcode.MAX: b := v.estack.Pop().BigInt() a := v.estack.Pop().BigInt() val := a @@ -818,46 +821,46 @@ func (v *VM) execute(ctx *Context, op Instruction, parameter []byte) (err error) } v.estack.PushVal(val) - case WITHIN: + case opcode.WITHIN: b := v.estack.Pop().BigInt() a := v.estack.Pop().BigInt() x := v.estack.Pop().BigInt() v.estack.PushVal(a.Cmp(x) <= 0 && x.Cmp(b) == -1) - case INC: + case opcode.INC: x := v.estack.Pop().BigInt() a := new(big.Int).Add(x, big.NewInt(1)) v.checkBigIntSize(a) v.estack.PushVal(a) - case DEC: + case opcode.DEC: x := v.estack.Pop().BigInt() a := new(big.Int).Sub(x, big.NewInt(1)) v.checkBigIntSize(a) v.estack.PushVal(a) - case SIGN: + case opcode.SIGN: x := v.estack.Pop().BigInt() v.estack.PushVal(x.Sign()) - case NEGATE: + case opcode.NEGATE: x := v.estack.Pop().BigInt() v.estack.PushVal(x.Neg(x)) - case ABS: + case opcode.ABS: x := v.estack.Pop().BigInt() v.estack.PushVal(x.Abs(x)) - case NOT: + case opcode.NOT: x := v.estack.Pop().Bool() v.estack.PushVal(!x) - case NZ: + case opcode.NZ: x := v.estack.Pop().BigInt() v.estack.PushVal(x.Cmp(big.NewInt(0)) != 0) // Object operations. - case NEWARRAY: + case opcode.NEWARRAY: item := v.estack.Pop() switch t := item.value.(type) { case *StructItem: @@ -875,7 +878,7 @@ func (v *VM) execute(ctx *Context, op Instruction, parameter []byte) (err error) v.estack.PushVal(&ArrayItem{items}) } - case NEWSTRUCT: + case opcode.NEWSTRUCT: item := v.estack.Pop() switch t := item.value.(type) { case *ArrayItem: @@ -893,7 +896,7 @@ func (v *VM) execute(ctx *Context, op Instruction, parameter []byte) (err error) v.estack.PushVal(&StructItem{items}) } - case APPEND: + case opcode.APPEND: itemElem := v.estack.Pop() arrElem := v.estack.Pop() @@ -920,7 +923,7 @@ func (v *VM) execute(ctx *Context, op Instruction, parameter []byte) (err error) v.estack.updateSizeAdd(val) - case PACK: + case opcode.PACK: n := int(v.estack.Pop().BigInt().Int64()) if n < 0 || n > v.estack.Len() || n > MaxArraySize { panic("OPACK: invalid length") @@ -933,7 +936,7 @@ func (v *VM) execute(ctx *Context, op Instruction, parameter []byte) (err error) v.estack.PushVal(items) - case UNPACK: + case opcode.UNPACK: a := v.estack.Pop().Array() l := len(a) for i := l - 1; i >= 0; i-- { @@ -941,7 +944,7 @@ func (v *VM) execute(ctx *Context, op Instruction, parameter []byte) (err error) } v.estack.PushVal(l) - case PICKITEM: + case opcode.PICKITEM: key := v.estack.Pop() validateMapKey(key) @@ -972,7 +975,7 @@ func (v *VM) execute(ctx *Context, op Instruction, parameter []byte) (err error) v.estack.PushVal(int(item)) } - case SETITEM: + case opcode.SETITEM: item := v.estack.Pop().value key := v.estack.Pop() validateMapKey(key) @@ -1003,14 +1006,14 @@ func (v *VM) execute(ctx *Context, op Instruction, parameter []byte) (err error) panic(fmt.Sprintf("SETITEM: invalid item type %s", t)) } - case REVERSE: + case opcode.REVERSE: a := v.estack.Pop().Array() if len(a) > 1 { for i, j := 0, len(a)-1; i <= j; i, j = i+1, j-1 { a[i], a[j] = a[j], a[i] } } - case REMOVE: + case opcode.REMOVE: key := v.estack.Pop() validateMapKey(key) @@ -1043,7 +1046,7 @@ func (v *VM) execute(ctx *Context, op Instruction, parameter []byte) (err error) panic("REMOVE: invalid type") } - case ARRAYSIZE: + case opcode.ARRAYSIZE: elem := v.estack.Pop() // Cause there is no native (byte) item type here, hence we need to check // the type of the item for array size operations. @@ -1056,12 +1059,12 @@ func (v *VM) execute(ctx *Context, op Instruction, parameter []byte) (err error) v.estack.PushVal(len(elem.Bytes())) } - case SIZE: + case opcode.SIZE: elem := v.estack.Pop() arr := elem.Bytes() v.estack.PushVal(len(arr)) - case JMP, JMPIF, JMPIFNOT: + case opcode.JMP, opcode.JMPIF, opcode.JMPIFNOT: var ( rOffset = int16(binary.LittleEndian.Uint16(parameter)) offset = ctx.ip + int(rOffset) @@ -1070,9 +1073,9 @@ func (v *VM) execute(ctx *Context, op Instruction, parameter []byte) (err error) panic(fmt.Sprintf("JMP: invalid offset %d ip at %d", offset, ctx.ip)) } cond := true - if op > JMP { + if op > opcode.JMP { cond = v.estack.Pop().Bool() - if op == JMPIFNOT { + if op == opcode.JMPIFNOT { cond = !cond } } @@ -1080,18 +1083,18 @@ func (v *VM) execute(ctx *Context, op Instruction, parameter []byte) (err error) ctx.nextip = offset } - case CALL: + case opcode.CALL: v.checkInvocationStackSize() newCtx := ctx.Copy() newCtx.rvcount = -1 v.istack.PushVal(newCtx) - err = v.execute(v.Context(), JMP, parameter) + err = v.execute(v.Context(), opcode.JMP, parameter) if err != nil { return } - case SYSCALL: + case opcode.SYSCALL: ifunc, ok := v.interop[string(parameter)] if !ok { panic(fmt.Sprintf("interop hook (%q) not registered", parameter)) @@ -1100,12 +1103,12 @@ func (v *VM) execute(ctx *Context, op Instruction, parameter []byte) (err error) panic(fmt.Sprintf("failed to invoke syscall: %s", err)) } - case APPCALL, TAILCALL: + case opcode.APPCALL, opcode.TAILCALL: if v.getScript == nil { panic("no getScript callback is set up") } - if op == APPCALL { + if op == opcode.APPCALL { v.checkInvocationStackSize() } @@ -1119,13 +1122,13 @@ func (v *VM) execute(ctx *Context, op Instruction, parameter []byte) (err error) panic("could not find script") } - if op == TAILCALL { + if op == opcode.TAILCALL { _ = v.istack.Pop() } v.LoadScript(script) - case RET: + case opcode.RET: oldCtx := v.istack.Pop().Value().(*Context) rvcount := oldCtx.rvcount oldEstack := v.estack @@ -1151,12 +1154,12 @@ func (v *VM) execute(ctx *Context, op Instruction, parameter []byte) (err error) v.astack = v.Context().astack } - case CHECKSIG, VERIFY: + case opcode.CHECKSIG, opcode.VERIFY: var hashToCheck []byte keyb := v.estack.Pop().Bytes() signature := v.estack.Pop().Bytes() - if op == CHECKSIG { + if op == opcode.CHECKSIG { if v.checkhash == nil { panic("VM is not set up properly for signature checks") } @@ -1173,7 +1176,7 @@ func (v *VM) execute(ctx *Context, op Instruction, parameter []byte) (err error) res := pkey.Verify(signature, hashToCheck) v.estack.PushVal(res) - case CHECKMULTISIG: + case opcode.CHECKMULTISIG: pkeys, err := v.estack.popSigElements() if err != nil { panic(fmt.Sprintf("wrong parameters: %s", err.Error())) @@ -1214,10 +1217,10 @@ func (v *VM) execute(ctx *Context, op Instruction, parameter []byte) (err error) } v.estack.PushVal(sigok) - case NEWMAP: + case opcode.NEWMAP: v.estack.Push(&Element{value: NewMapItem()}) - case KEYS: + case opcode.KEYS: item := v.estack.Pop() if item == nil { panic("no argument") @@ -1234,7 +1237,7 @@ func (v *VM) execute(ctx *Context, op Instruction, parameter []byte) (err error) } v.estack.PushVal(arr) - case VALUES: + case opcode.VALUES: item := v.estack.Pop() if item == nil { panic("no argument") @@ -1259,7 +1262,7 @@ func (v *VM) execute(ctx *Context, op Instruction, parameter []byte) (err error) v.estack.PushVal(arr) - case HASKEY: + case opcode.HASKEY: key := v.estack.Pop() validateMapKey(key) @@ -1281,31 +1284,31 @@ func (v *VM) execute(ctx *Context, op Instruction, parameter []byte) (err error) } // Cryptographic operations. - case SHA1: + case opcode.SHA1: b := v.estack.Pop().Bytes() sha := sha1.New() sha.Write(b) v.estack.PushVal(sha.Sum(nil)) - case SHA256: + case opcode.SHA256: b := v.estack.Pop().Bytes() v.estack.PushVal(hash.Sha256(b).Bytes()) - case HASH160: + case opcode.HASH160: b := v.estack.Pop().Bytes() v.estack.PushVal(hash.Hash160(b).Bytes()) - case HASH256: + case opcode.HASH256: b := v.estack.Pop().Bytes() v.estack.PushVal(hash.DoubleSha256(b).Bytes()) - case NOP: + case opcode.NOP: // unlucky ^^ - case CALLI, CALLE, CALLED, CALLET, CALLEDT: + case opcode.CALLI, opcode.CALLE, opcode.CALLED, opcode.CALLET, opcode.CALLEDT: var ( - tailCall = (op == CALLET || op == CALLEDT) - hashOnStack = (op == CALLED || op == CALLEDT) + tailCall = (op == opcode.CALLET || op == opcode.CALLEDT) + hashOnStack = (op == opcode.CALLED || op == opcode.CALLEDT) addElement int newCtx *Context ) @@ -1327,7 +1330,7 @@ func (v *VM) execute(ctx *Context, op Instruction, parameter []byte) (err error) v.checkInvocationStackSize() } - if op == CALLI { + if op == opcode.CALLI { newCtx = ctx.Copy() } else { var hashBytes []byte @@ -1362,17 +1365,17 @@ func (v *VM) execute(ctx *Context, op Instruction, parameter []byte) (err error) v.istack.PushVal(newCtx) v.estack = newCtx.estack v.astack = newCtx.astack - if op == CALLI { - err = v.execute(v.Context(), JMP, parameter[2:]) + if op == opcode.CALLI { + err = v.execute(v.Context(), opcode.JMP, parameter[2:]) if err != nil { return } } - case THROW: + case opcode.THROW: panic("THROW") - case THROWIFNOT: + case opcode.THROWIFNOT: if !v.estack.Pop().Bool() { panic("THROWIFNOT") } diff --git a/pkg/vm/vm_test.go b/pkg/vm/vm_test.go index 2a254aabe..7f89eb6e7 100644 --- a/pkg/vm/vm_test.go +++ b/pkg/vm/vm_test.go @@ -11,6 +11,7 @@ import ( "github.com/CityOfZion/neo-go/pkg/crypto/hash" "github.com/CityOfZion/neo-go/pkg/crypto/keys" "github.com/CityOfZion/neo-go/pkg/util" + "github.com/CityOfZion/neo-go/pkg/vm/opcode" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -24,7 +25,7 @@ func TestInteropHook(t *testing.T) { buf := new(bytes.Buffer) EmitSyscall(buf, "foo") - EmitOpcode(buf, RET) + EmitOpcode(buf, opcode.RET) v.Load(buf.Bytes()) runVM(t, v) assert.Equal(t, 1, v.estack.Len()) @@ -56,7 +57,7 @@ func TestPushBytes1to75(t *testing.T) { assert.IsType(t, elem.Bytes(), b) assert.Equal(t, 0, vm.estack.Len()) - errExec := vm.execute(nil, RET, nil) + errExec := vm.execute(nil, opcode.RET, nil) require.NoError(t, errExec) assert.Equal(t, 0, vm.astack.Len()) @@ -67,7 +68,7 @@ func TestPushBytes1to75(t *testing.T) { func TestPushBytesNoParam(t *testing.T) { prog := make([]byte, 1) - prog[0] = byte(PUSHBYTES1) + prog[0] = byte(opcode.PUSHBYTES1) vm := load(prog) checkVMFailed(t, vm) } @@ -87,10 +88,10 @@ func checkVMFailed(t *testing.T, vm *VM) { func TestStackLimitPUSH1Good(t *testing.T) { prog := make([]byte, MaxStackSize*2) for i := 0; i < MaxStackSize; i++ { - prog[i] = byte(PUSH1) + prog[i] = byte(opcode.PUSH1) } for i := MaxStackSize; i < MaxStackSize*2; i++ { - prog[i] = byte(DROP) + prog[i] = byte(opcode.DROP) } v := load(prog) @@ -100,7 +101,7 @@ func TestStackLimitPUSH1Good(t *testing.T) { func TestStackLimitPUSH1Bad(t *testing.T) { prog := make([]byte, MaxStackSize+1) for i := range prog { - prog[i] = byte(PUSH1) + prog[i] = byte(opcode.PUSH1) } v := load(prog) checkVMFailed(t, v) @@ -114,20 +115,20 @@ func TestStackLimitPUSH1Bad(t *testing.T) { // - struct (size+1) // - array (1) of struct (size+1) // which equals to size*2+3 elements in total. -func appendBigStruct(size uint16) []Instruction { - prog := make([]Instruction, size*2) +func appendBigStruct(size uint16) []opcode.Opcode { + prog := make([]opcode.Opcode, size*2) for i := uint16(0); i < size; i++ { - prog[i*2] = PUSH0 - prog[i*2+1] = NEWSTRUCT + prog[i*2] = opcode.PUSH0 + prog[i*2+1] = opcode.NEWSTRUCT } return append(prog, - PUSHBYTES2, Instruction(size), Instruction(size>>8), // LE - PACK, NEWSTRUCT, - DUP, - PUSH0, NEWARRAY, TOALTSTACK, DUPFROMALTSTACK, - SWAP, - APPEND, RET) + opcode.PUSHBYTES2, opcode.Opcode(size), opcode.Opcode(size>>8), // LE + opcode.PACK, opcode.NEWSTRUCT, + opcode.DUP, + opcode.PUSH0, opcode.NEWARRAY, opcode.TOALTSTACK, opcode.DUPFROMALTSTACK, + opcode.SWAP, + opcode.APPEND, opcode.RET) } func TestStackLimitAPPENDStructGood(t *testing.T) { @@ -144,30 +145,30 @@ func TestStackLimitAPPENDStructBad(t *testing.T) { func TestStackLimit(t *testing.T) { expected := []struct { - inst Instruction + inst opcode.Opcode size int }{ - {PUSH2, 1}, - {NEWARRAY, 3}, // array + 2 items - {TOALTSTACK, 3}, - {DUPFROMALTSTACK, 4}, - {NEWSTRUCT, 6}, // all items are copied - {NEWMAP, 7}, - {DUP, 8}, - {PUSH2, 9}, - {DUPFROMALTSTACK, 10}, - {SETITEM, 8}, // -3 items and 1 new element in map - {DUP, 9}, - {PUSH2, 10}, - {DUPFROMALTSTACK, 11}, - {SETITEM, 8}, // -3 items and no new elements in map - {DUP, 9}, - {PUSH2, 10}, - {REMOVE, 7}, // as we have right after NEWMAP - {DROP, 6}, // DROP map with no elements + {opcode.PUSH2, 1}, + {opcode.NEWARRAY, 3}, // array + 2 items + {opcode.TOALTSTACK, 3}, + {opcode.DUPFROMALTSTACK, 4}, + {opcode.NEWSTRUCT, 6}, // all items are copied + {opcode.NEWMAP, 7}, + {opcode.DUP, 8}, + {opcode.PUSH2, 9}, + {opcode.DUPFROMALTSTACK, 10}, + {opcode.SETITEM, 8}, // -3 items and 1 new element in map + {opcode.DUP, 9}, + {opcode.PUSH2, 10}, + {opcode.DUPFROMALTSTACK, 11}, + {opcode.SETITEM, 8}, // -3 items and no new elements in map + {opcode.DUP, 9}, + {opcode.PUSH2, 10}, + {opcode.REMOVE, 7}, // as we have right after NEWMAP + {opcode.DROP, 6}, // DROP map with no elements } - prog := make([]Instruction, len(expected)) + prog := make([]opcode.Opcode, len(expected)) for i := range expected { prog[i] = expected[i].inst } @@ -181,14 +182,14 @@ func TestStackLimit(t *testing.T) { func TestPushBytesShort(t *testing.T) { prog := make([]byte, 10) - prog[0] = byte(PUSHBYTES10) // but only 9 left in the `prog` + prog[0] = byte(opcode.PUSHBYTES10) // but only 9 left in the `prog` vm := load(prog) checkVMFailed(t, vm) } func TestPushm1to16(t *testing.T) { var prog []byte - for i := int(PUSHM1); i <= int(PUSH16); i++ { + for i := int(opcode.PUSHM1); i <= int(opcode.PUSH16); i++ { if i == 80 { continue // opcode layout we got here. } @@ -196,7 +197,7 @@ func TestPushm1to16(t *testing.T) { } vm := load(prog) - for i := int(PUSHM1); i <= int(PUSH16); i++ { + for i := int(opcode.PUSHM1); i <= int(opcode.PUSH16); i++ { if i == 80 { continue // nice opcode layout we got here. } @@ -205,25 +206,25 @@ func TestPushm1to16(t *testing.T) { elem := vm.estack.Pop() assert.IsType(t, &BigIntegerItem{}, elem.value) - val := i - int(PUSH1) + 1 + val := i - int(opcode.PUSH1) + 1 assert.Equal(t, elem.BigInt().Int64(), int64(val)) } } func TestPushData1BadNoN(t *testing.T) { - prog := []byte{byte(PUSHDATA1)} + prog := []byte{byte(opcode.PUSHDATA1)} vm := load(prog) checkVMFailed(t, vm) } func TestPushData1BadN(t *testing.T) { - prog := []byte{byte(PUSHDATA1), 1} + prog := []byte{byte(opcode.PUSHDATA1), 1} vm := load(prog) checkVMFailed(t, vm) } func TestPushData1Good(t *testing.T) { - prog := makeProgram(PUSHDATA1, 3, 1, 2, 3) + prog := makeProgram(opcode.PUSHDATA1, 3, 1, 2, 3) vm := load(prog) runVM(t, vm) assert.Equal(t, 1, vm.estack.Len()) @@ -231,25 +232,25 @@ func TestPushData1Good(t *testing.T) { } func TestPushData2BadNoN(t *testing.T) { - prog := []byte{byte(PUSHDATA2)} + prog := []byte{byte(opcode.PUSHDATA2)} vm := load(prog) checkVMFailed(t, vm) } func TestPushData2ShortN(t *testing.T) { - prog := []byte{byte(PUSHDATA2), 0} + prog := []byte{byte(opcode.PUSHDATA2), 0} vm := load(prog) checkVMFailed(t, vm) } func TestPushData2BadN(t *testing.T) { - prog := []byte{byte(PUSHDATA2), 1, 0} + prog := []byte{byte(opcode.PUSHDATA2), 1, 0} vm := load(prog) checkVMFailed(t, vm) } func TestPushData2Good(t *testing.T) { - prog := makeProgram(PUSHDATA2, 3, 0, 1, 2, 3) + prog := makeProgram(opcode.PUSHDATA2, 3, 0, 1, 2, 3) vm := load(prog) runVM(t, vm) assert.Equal(t, 1, vm.estack.Len()) @@ -257,26 +258,26 @@ func TestPushData2Good(t *testing.T) { } func TestPushData4BadNoN(t *testing.T) { - prog := []byte{byte(PUSHDATA4)} + prog := []byte{byte(opcode.PUSHDATA4)} vm := load(prog) checkVMFailed(t, vm) } func TestPushData4BadN(t *testing.T) { - prog := []byte{byte(PUSHDATA4), 1, 0, 0, 0} + prog := []byte{byte(opcode.PUSHDATA4), 1, 0, 0, 0} vm := load(prog) checkVMFailed(t, vm) } func TestPushData4ShortN(t *testing.T) { - prog := []byte{byte(PUSHDATA4), 0, 0, 0} + prog := []byte{byte(opcode.PUSHDATA4), 0, 0, 0} vm := load(prog) checkVMFailed(t, vm) } func TestPushData4BigN(t *testing.T) { prog := make([]byte, 1+4+MaxItemSize+1) - prog[0] = byte(PUSHDATA4) + prog[0] = byte(opcode.PUSHDATA4) binary.LittleEndian.PutUint32(prog[1:], MaxItemSize+1) vm := load(prog) @@ -285,7 +286,7 @@ func TestPushData4BigN(t *testing.T) { } func TestPushData4Good(t *testing.T) { - prog := makeProgram(PUSHDATA4, 3, 0, 0, 0, 1, 2, 3) + prog := makeProgram(opcode.PUSHDATA4, 3, 0, 0, 0, 1, 2, 3) vm := load(prog) runVM(t, vm) assert.Equal(t, 1, vm.estack.Len()) @@ -293,7 +294,7 @@ func TestPushData4Good(t *testing.T) { } func getSyscallProg(name string) (prog []byte) { - prog = []byte{byte(SYSCALL)} + prog = []byte{byte(opcode.SYSCALL)} prog = append(prog, byte(len(name))) prog = append(prog, name...) @@ -303,7 +304,7 @@ func getSyscallProg(name string) (prog []byte) { func getSerializeProg() (prog []byte) { prog = append(prog, getSyscallProg("Neo.Runtime.Serialize")...) prog = append(prog, getSyscallProg("Neo.Runtime.Deserialize")...) - prog = append(prog, byte(RET)) + prog = append(prog, byte(opcode.RET)) return } @@ -381,9 +382,9 @@ func TestSerializeArrayBad(t *testing.T) { func TestSerializeDupInteger(t *testing.T) { prog := []byte{ - byte(PUSH0), byte(NEWARRAY), - byte(DUP), byte(PUSH2), byte(DUP), byte(TOALTSTACK), byte(APPEND), - byte(DUP), byte(FROMALTSTACK), byte(APPEND), + byte(opcode.PUSH0), byte(opcode.NEWARRAY), + byte(opcode.DUP), byte(opcode.PUSH2), byte(opcode.DUP), byte(opcode.TOALTSTACK), byte(opcode.APPEND), + byte(opcode.DUP), byte(opcode.FROMALTSTACK), byte(opcode.APPEND), } vm := load(append(prog, getSerializeProg()...)) @@ -407,7 +408,7 @@ func TestSerializeStruct(t *testing.T) { } func TestDeserializeUnknown(t *testing.T) { - prog := append(getSyscallProg("Neo.Runtime.Deserialize"), byte(RET)) + prog := append(getSyscallProg("Neo.Runtime.Deserialize"), byte(opcode.RET)) vm := load(prog) data, err := serializeItem(NewBigIntegerItem(123)) @@ -446,11 +447,11 @@ func TestSerializeInterop(t *testing.T) { func callNTimes(n uint16) []byte { return makeProgram( - PUSHBYTES2, Instruction(n), Instruction(n>>8), // little-endian - TOALTSTACK, DUPFROMALTSTACK, - JMPIF, 0x4, 0, RET, - FROMALTSTACK, DEC, - CALL, 0xF8, 0xFF) // -8 -> JMP to TOALTSTACK) + opcode.PUSHBYTES2, opcode.Opcode(n), opcode.Opcode(n>>8), // little-endian + opcode.TOALTSTACK, opcode.DUPFROMALTSTACK, + opcode.JMPIF, 0x4, 0, opcode.RET, + opcode.FROMALTSTACK, opcode.DEC, + opcode.CALL, 0xF8, 0xFF) // -8 -> JMP to TOALTSTACK) } func TestInvocationLimitGood(t *testing.T) { @@ -466,13 +467,13 @@ func TestInvocationLimitBad(t *testing.T) { } func TestNOTNoArgument(t *testing.T) { - prog := makeProgram(NOT) + prog := makeProgram(opcode.NOT) vm := load(prog) checkVMFailed(t, vm) } func TestNOTBool(t *testing.T) { - prog := makeProgram(NOT) + prog := makeProgram(opcode.NOT) vm := load(prog) vm.estack.PushVal(false) runVM(t, vm) @@ -480,7 +481,7 @@ func TestNOTBool(t *testing.T) { } func TestNOTNonZeroInt(t *testing.T) { - prog := makeProgram(NOT) + prog := makeProgram(opcode.NOT) vm := load(prog) vm.estack.PushVal(3) runVM(t, vm) @@ -488,7 +489,7 @@ func TestNOTNonZeroInt(t *testing.T) { } func TestNOTArray(t *testing.T) { - prog := makeProgram(NOT) + prog := makeProgram(opcode.NOT) vm := load(prog) vm.estack.PushVal([]StackItem{}) runVM(t, vm) @@ -496,7 +497,7 @@ func TestNOTArray(t *testing.T) { } func TestNOTStruct(t *testing.T) { - prog := makeProgram(NOT) + prog := makeProgram(opcode.NOT) vm := load(prog) vm.estack.Push(NewElement(&StructItem{[]StackItem{}})) runVM(t, vm) @@ -504,7 +505,7 @@ func TestNOTStruct(t *testing.T) { } func TestNOTByteArray0(t *testing.T) { - prog := makeProgram(NOT) + prog := makeProgram(opcode.NOT) vm := load(prog) vm.estack.PushVal([]byte{0, 0}) runVM(t, vm) @@ -512,7 +513,7 @@ func TestNOTByteArray0(t *testing.T) { } func TestNOTByteArray1(t *testing.T) { - prog := makeProgram(NOT) + prog := makeProgram(opcode.NOT) vm := load(prog) vm.estack.PushVal([]byte{0, 1}) runVM(t, vm) @@ -527,7 +528,7 @@ func getBigInt(a, b int64) *big.Int { } func TestAdd(t *testing.T) { - prog := makeProgram(ADD) + prog := makeProgram(opcode.ADD) vm := load(prog) vm.estack.PushVal(4) vm.estack.PushVal(2) @@ -536,14 +537,14 @@ func TestAdd(t *testing.T) { } func TestADDBigResult(t *testing.T) { - prog := makeProgram(ADD) + prog := makeProgram(opcode.ADD) vm := load(prog) vm.estack.PushVal(getBigInt(MaxBigIntegerSizeBits, -1)) vm.estack.PushVal(1) checkVMFailed(t, vm) } -func testBigArgument(t *testing.T, inst Instruction) { +func testBigArgument(t *testing.T, inst opcode.Opcode) { prog := makeProgram(inst) x := getBigInt(MaxBigIntegerSizeBits, 0) t.Run(inst.String()+" big 1-st argument", func(t *testing.T) { @@ -561,15 +562,15 @@ func testBigArgument(t *testing.T, inst Instruction) { } func TestArithBigArgument(t *testing.T) { - testBigArgument(t, ADD) - testBigArgument(t, SUB) - testBigArgument(t, MUL) - testBigArgument(t, DIV) - testBigArgument(t, MOD) + testBigArgument(t, opcode.ADD) + testBigArgument(t, opcode.SUB) + testBigArgument(t, opcode.MUL) + testBigArgument(t, opcode.DIV) + testBigArgument(t, opcode.MOD) } func TestMul(t *testing.T) { - prog := makeProgram(MUL) + prog := makeProgram(opcode.MUL) vm := load(prog) vm.estack.PushVal(4) vm.estack.PushVal(2) @@ -578,7 +579,7 @@ func TestMul(t *testing.T) { } func TestMULBigResult(t *testing.T) { - prog := makeProgram(MUL) + prog := makeProgram(opcode.MUL) vm := load(prog) vm.estack.PushVal(getBigInt(MaxBigIntegerSizeBits/2+1, 0)) vm.estack.PushVal(getBigInt(MaxBigIntegerSizeBits/2+1, 0)) @@ -586,7 +587,7 @@ func TestMULBigResult(t *testing.T) { } func TestDiv(t *testing.T) { - prog := makeProgram(DIV) + prog := makeProgram(opcode.DIV) vm := load(prog) vm.estack.PushVal(4) vm.estack.PushVal(2) @@ -595,7 +596,7 @@ func TestDiv(t *testing.T) { } func TestSub(t *testing.T) { - prog := makeProgram(SUB) + prog := makeProgram(opcode.SUB) vm := load(prog) vm.estack.PushVal(4) vm.estack.PushVal(2) @@ -604,7 +605,7 @@ func TestSub(t *testing.T) { } func TestSUBBigResult(t *testing.T) { - prog := makeProgram(SUB) + prog := makeProgram(opcode.SUB) vm := load(prog) vm.estack.PushVal(getBigInt(MaxBigIntegerSizeBits, -1)) vm.estack.PushVal(-1) @@ -612,7 +613,7 @@ func TestSUBBigResult(t *testing.T) { } func TestSHRGood(t *testing.T) { - prog := makeProgram(SHR) + prog := makeProgram(opcode.SHR) vm := load(prog) vm.estack.PushVal(4) vm.estack.PushVal(2) @@ -622,7 +623,7 @@ func TestSHRGood(t *testing.T) { } func TestSHRZero(t *testing.T) { - prog := makeProgram(SHR) + prog := makeProgram(opcode.SHR) vm := load(prog) vm.estack.PushVal([]byte{0, 1}) vm.estack.PushVal(0) @@ -632,7 +633,7 @@ func TestSHRZero(t *testing.T) { } func TestSHRSmallValue(t *testing.T) { - prog := makeProgram(SHR) + prog := makeProgram(opcode.SHR) vm := load(prog) vm.estack.PushVal(5) vm.estack.PushVal(minSHLArg - 1) @@ -640,7 +641,7 @@ func TestSHRSmallValue(t *testing.T) { } func TestSHRBigArgument(t *testing.T) { - prog := makeProgram(SHR) + prog := makeProgram(opcode.SHR) vm := load(prog) vm.estack.PushVal(getBigInt(MaxBigIntegerSizeBits, 0)) vm.estack.PushVal(1) @@ -648,7 +649,7 @@ func TestSHRBigArgument(t *testing.T) { } func TestSHLGood(t *testing.T) { - prog := makeProgram(SHL) + prog := makeProgram(opcode.SHL) vm := load(prog) vm.estack.PushVal(4) vm.estack.PushVal(2) @@ -658,7 +659,7 @@ func TestSHLGood(t *testing.T) { } func TestSHLZero(t *testing.T) { - prog := makeProgram(SHL) + prog := makeProgram(opcode.SHL) vm := load(prog) vm.estack.PushVal([]byte{0, 1}) vm.estack.PushVal(0) @@ -668,7 +669,7 @@ func TestSHLZero(t *testing.T) { } func TestSHLBigValue(t *testing.T) { - prog := makeProgram(SHL) + prog := makeProgram(opcode.SHL) vm := load(prog) vm.estack.PushVal(5) vm.estack.PushVal(maxSHLArg + 1) @@ -676,7 +677,7 @@ func TestSHLBigValue(t *testing.T) { } func TestSHLBigResult(t *testing.T) { - prog := makeProgram(SHL) + prog := makeProgram(opcode.SHL) vm := load(prog) vm.estack.PushVal(getBigInt(MaxBigIntegerSizeBits/2, 0)) vm.estack.PushVal(MaxBigIntegerSizeBits / 2) @@ -684,7 +685,7 @@ func TestSHLBigResult(t *testing.T) { } func TestSHLBigArgument(t *testing.T) { - prog := makeProgram(SHR) + prog := makeProgram(opcode.SHR) vm := load(prog) vm.estack.PushVal(getBigInt(MaxBigIntegerSizeBits, 0)) vm.estack.PushVal(1) @@ -692,7 +693,7 @@ func TestSHLBigArgument(t *testing.T) { } func TestLT(t *testing.T) { - prog := makeProgram(LT) + prog := makeProgram(opcode.LT) vm := load(prog) vm.estack.PushVal(4) vm.estack.PushVal(3) @@ -701,7 +702,7 @@ func TestLT(t *testing.T) { } func TestLTE(t *testing.T) { - prog := makeProgram(LTE) + prog := makeProgram(opcode.LTE) vm := load(prog) vm.estack.PushVal(2) vm.estack.PushVal(3) @@ -710,7 +711,7 @@ func TestLTE(t *testing.T) { } func TestGT(t *testing.T) { - prog := makeProgram(GT) + prog := makeProgram(opcode.GT) vm := load(prog) vm.estack.PushVal(9) vm.estack.PushVal(3) @@ -720,7 +721,7 @@ func TestGT(t *testing.T) { } func TestGTE(t *testing.T) { - prog := makeProgram(GTE) + prog := makeProgram(opcode.GTE) vm := load(prog) vm.estack.PushVal(3) vm.estack.PushVal(3) @@ -729,7 +730,7 @@ func TestGTE(t *testing.T) { } func TestDepth(t *testing.T) { - prog := makeProgram(DEPTH) + prog := makeProgram(opcode.DEPTH) vm := load(prog) vm.estack.PushVal(1) vm.estack.PushVal(2) @@ -739,20 +740,20 @@ func TestDepth(t *testing.T) { } func TestEQUALNoArguments(t *testing.T) { - prog := makeProgram(EQUAL) + prog := makeProgram(opcode.EQUAL) vm := load(prog) checkVMFailed(t, vm) } func TestEQUALBad1Argument(t *testing.T) { - prog := makeProgram(EQUAL) + prog := makeProgram(opcode.EQUAL) vm := load(prog) vm.estack.PushVal(1) checkVMFailed(t, vm) } func TestEQUALGoodInteger(t *testing.T) { - prog := makeProgram(EQUAL) + prog := makeProgram(opcode.EQUAL) vm := load(prog) vm.estack.PushVal(5) vm.estack.PushVal(5) @@ -762,7 +763,7 @@ func TestEQUALGoodInteger(t *testing.T) { } func TestEQUALArrayTrue(t *testing.T) { - prog := makeProgram(DUP, EQUAL) + prog := makeProgram(opcode.DUP, opcode.EQUAL) vm := load(prog) vm.estack.PushVal([]StackItem{}) runVM(t, vm) @@ -771,7 +772,7 @@ func TestEQUALArrayTrue(t *testing.T) { } func TestEQUALArrayFalse(t *testing.T) { - prog := makeProgram(EQUAL) + prog := makeProgram(opcode.EQUAL) vm := load(prog) vm.estack.PushVal([]StackItem{}) vm.estack.PushVal([]StackItem{}) @@ -781,7 +782,7 @@ func TestEQUALArrayFalse(t *testing.T) { } func TestEQUALMapTrue(t *testing.T) { - prog := makeProgram(DUP, EQUAL) + prog := makeProgram(opcode.DUP, opcode.EQUAL) vm := load(prog) vm.estack.Push(&Element{value: NewMapItem()}) runVM(t, vm) @@ -790,7 +791,7 @@ func TestEQUALMapTrue(t *testing.T) { } func TestEQUALMapFalse(t *testing.T) { - prog := makeProgram(EQUAL) + prog := makeProgram(opcode.EQUAL) vm := load(prog) vm.estack.Push(&Element{value: NewMapItem()}) vm.estack.Push(&Element{value: NewMapItem()}) @@ -800,7 +801,7 @@ func TestEQUALMapFalse(t *testing.T) { } func TestNumEqual(t *testing.T) { - prog := makeProgram(NUMEQUAL) + prog := makeProgram(opcode.NUMEQUAL) vm := load(prog) vm.estack.PushVal(1) vm.estack.PushVal(2) @@ -809,7 +810,7 @@ func TestNumEqual(t *testing.T) { } func TestNumNotEqual(t *testing.T) { - prog := makeProgram(NUMNOTEQUAL) + prog := makeProgram(opcode.NUMNOTEQUAL) vm := load(prog) vm.estack.PushVal(2) vm.estack.PushVal(2) @@ -818,7 +819,7 @@ func TestNumNotEqual(t *testing.T) { } func TestINC(t *testing.T) { - prog := makeProgram(INC) + prog := makeProgram(opcode.INC) vm := load(prog) vm.estack.PushVal(1) runVM(t, vm) @@ -826,7 +827,7 @@ func TestINC(t *testing.T) { } func TestINCBigResult(t *testing.T) { - prog := makeProgram(INC, INC) + prog := makeProgram(opcode.INC, opcode.INC) vm := load(prog) x := getBigInt(MaxBigIntegerSizeBits, -2) vm.estack.PushVal(x) @@ -840,7 +841,7 @@ func TestINCBigResult(t *testing.T) { } func TestDECBigResult(t *testing.T) { - prog := makeProgram(DEC, DEC) + prog := makeProgram(opcode.DEC, opcode.DEC) vm := load(prog) x := getBigInt(MaxBigIntegerSizeBits, -2) x.Neg(x) @@ -855,7 +856,7 @@ func TestDECBigResult(t *testing.T) { } func TestNEWARRAYInteger(t *testing.T) { - prog := makeProgram(NEWARRAY) + prog := makeProgram(opcode.NEWARRAY) vm := load(prog) vm.estack.PushVal(1) runVM(t, vm) @@ -864,7 +865,7 @@ func TestNEWARRAYInteger(t *testing.T) { } func TestNEWARRAYStruct(t *testing.T) { - prog := makeProgram(NEWARRAY) + prog := makeProgram(opcode.NEWARRAY) vm := load(prog) arr := []StackItem{makeStackItem(42)} vm.estack.Push(&Element{value: &StructItem{arr}}) @@ -873,13 +874,13 @@ func TestNEWARRAYStruct(t *testing.T) { assert.Equal(t, &ArrayItem{arr}, vm.estack.Pop().value) } -func testNEWARRAYIssue437(t *testing.T, i1, i2 Instruction, appended bool) { +func testNEWARRAYIssue437(t *testing.T, i1, i2 opcode.Opcode, appended bool) { prog := makeProgram( - PUSH2, i1, - DUP, PUSH3, APPEND, - TOALTSTACK, DUPFROMALTSTACK, i2, - DUP, PUSH4, APPEND, - FROMALTSTACK, PUSH5, APPEND) + opcode.PUSH2, i1, + opcode.DUP, opcode.PUSH3, opcode.APPEND, + opcode.TOALTSTACK, opcode.DUPFROMALTSTACK, i2, + opcode.DUP, opcode.PUSH4, opcode.APPEND, + opcode.FROMALTSTACK, opcode.PUSH5, opcode.APPEND) vm := load(prog) vm.Run() @@ -892,7 +893,7 @@ func testNEWARRAYIssue437(t *testing.T, i1, i2 Instruction, appended bool) { assert.Equal(t, false, vm.HasFailed()) assert.Equal(t, 1, vm.estack.Len()) - if i2 == NEWARRAY { + if i2 == opcode.NEWARRAY { assert.Equal(t, &ArrayItem{arr}, vm.estack.Pop().value) } else { assert.Equal(t, &StructItem{arr}, vm.estack.Pop().value) @@ -900,14 +901,14 @@ func testNEWARRAYIssue437(t *testing.T, i1, i2 Instruction, appended bool) { } func TestNEWARRAYIssue437(t *testing.T) { - t.Run("Array+Array", func(t *testing.T) { testNEWARRAYIssue437(t, NEWARRAY, NEWARRAY, true) }) - t.Run("Struct+Struct", func(t *testing.T) { testNEWARRAYIssue437(t, NEWSTRUCT, NEWSTRUCT, true) }) - t.Run("Array+Struct", func(t *testing.T) { testNEWARRAYIssue437(t, NEWARRAY, NEWSTRUCT, false) }) - t.Run("Struct+Array", func(t *testing.T) { testNEWARRAYIssue437(t, NEWSTRUCT, NEWARRAY, false) }) + t.Run("Array+Array", func(t *testing.T) { testNEWARRAYIssue437(t, opcode.NEWARRAY, opcode.NEWARRAY, true) }) + t.Run("Struct+Struct", func(t *testing.T) { testNEWARRAYIssue437(t, opcode.NEWSTRUCT, opcode.NEWSTRUCT, true) }) + t.Run("Array+Struct", func(t *testing.T) { testNEWARRAYIssue437(t, opcode.NEWARRAY, opcode.NEWSTRUCT, false) }) + t.Run("Struct+Array", func(t *testing.T) { testNEWARRAYIssue437(t, opcode.NEWSTRUCT, opcode.NEWARRAY, false) }) } func TestNEWARRAYArray(t *testing.T) { - prog := makeProgram(NEWARRAY) + prog := makeProgram(opcode.NEWARRAY) vm := load(prog) arr := []StackItem{makeStackItem(42)} vm.estack.Push(&Element{value: &ArrayItem{arr}}) @@ -917,7 +918,7 @@ func TestNEWARRAYArray(t *testing.T) { } func TestNEWARRAYByteArray(t *testing.T) { - prog := makeProgram(NEWARRAY) + prog := makeProgram(opcode.NEWARRAY) vm := load(prog) vm.estack.PushVal([]byte{}) runVM(t, vm) @@ -926,14 +927,14 @@ func TestNEWARRAYByteArray(t *testing.T) { } func TestNEWARRAYBadSize(t *testing.T) { - prog := makeProgram(NEWARRAY) + prog := makeProgram(opcode.NEWARRAY) vm := load(prog) vm.estack.PushVal(MaxArraySize + 1) checkVMFailed(t, vm) } func TestNEWSTRUCTInteger(t *testing.T) { - prog := makeProgram(NEWSTRUCT) + prog := makeProgram(opcode.NEWSTRUCT) vm := load(prog) vm.estack.PushVal(1) runVM(t, vm) @@ -942,7 +943,7 @@ func TestNEWSTRUCTInteger(t *testing.T) { } func TestNEWSTRUCTArray(t *testing.T) { - prog := makeProgram(NEWSTRUCT) + prog := makeProgram(opcode.NEWSTRUCT) vm := load(prog) arr := []StackItem{makeStackItem(42)} vm.estack.Push(&Element{value: &ArrayItem{arr}}) @@ -952,7 +953,7 @@ func TestNEWSTRUCTArray(t *testing.T) { } func TestNEWSTRUCTStruct(t *testing.T) { - prog := makeProgram(NEWSTRUCT) + prog := makeProgram(opcode.NEWSTRUCT) vm := load(prog) arr := []StackItem{makeStackItem(42)} vm.estack.Push(&Element{value: &StructItem{arr}}) @@ -962,7 +963,7 @@ func TestNEWSTRUCTStruct(t *testing.T) { } func TestNEWSTRUCTByteArray(t *testing.T) { - prog := makeProgram(NEWSTRUCT) + prog := makeProgram(opcode.NEWSTRUCT) vm := load(prog) vm.estack.PushVal([]byte{}) runVM(t, vm) @@ -971,14 +972,14 @@ func TestNEWSTRUCTByteArray(t *testing.T) { } func TestNEWSTRUCTBadSize(t *testing.T) { - prog := makeProgram(NEWSTRUCT) + prog := makeProgram(opcode.NEWSTRUCT) vm := load(prog) vm.estack.PushVal(MaxArraySize + 1) checkVMFailed(t, vm) } func TestAPPENDArray(t *testing.T) { - prog := makeProgram(DUP, PUSH5, APPEND) + prog := makeProgram(opcode.DUP, opcode.PUSH5, opcode.APPEND) vm := load(prog) vm.estack.Push(&Element{value: &ArrayItem{}}) runVM(t, vm) @@ -987,7 +988,7 @@ func TestAPPENDArray(t *testing.T) { } func TestAPPENDStruct(t *testing.T) { - prog := makeProgram(DUP, PUSH5, APPEND) + prog := makeProgram(opcode.DUP, opcode.PUSH5, opcode.APPEND) vm := load(prog) vm.estack.Push(&Element{value: &StructItem{}}) runVM(t, vm) @@ -996,7 +997,8 @@ func TestAPPENDStruct(t *testing.T) { } func TestAPPENDCloneStruct(t *testing.T) { - prog := makeProgram(DUP, PUSH0, NEWSTRUCT, TOALTSTACK, DUPFROMALTSTACK, APPEND, FROMALTSTACK, PUSH1, APPEND) + prog := makeProgram(opcode.DUP, opcode.PUSH0, opcode.NEWSTRUCT, opcode.TOALTSTACK, + opcode.DUPFROMALTSTACK, opcode.APPEND, opcode.FROMALTSTACK, opcode.PUSH1, opcode.APPEND) vm := load(prog) vm.estack.Push(&Element{value: &ArrayItem{}}) runVM(t, vm) @@ -1007,20 +1009,20 @@ func TestAPPENDCloneStruct(t *testing.T) { } func TestAPPENDBadNoArguments(t *testing.T) { - prog := makeProgram(APPEND) + prog := makeProgram(opcode.APPEND) vm := load(prog) checkVMFailed(t, vm) } func TestAPPENDBad1Argument(t *testing.T) { - prog := makeProgram(APPEND) + prog := makeProgram(opcode.APPEND) vm := load(prog) vm.estack.PushVal(1) checkVMFailed(t, vm) } func TestAPPENDWrongType(t *testing.T) { - prog := makeProgram(APPEND) + prog := makeProgram(opcode.APPEND) vm := load(prog) vm.estack.PushVal([]byte{}) vm.estack.PushVal(1) @@ -1028,7 +1030,7 @@ func TestAPPENDWrongType(t *testing.T) { } func TestAPPENDGoodSizeLimit(t *testing.T) { - prog := makeProgram(NEWARRAY, DUP, PUSH0, APPEND) + prog := makeProgram(opcode.NEWARRAY, opcode.DUP, opcode.PUSH0, opcode.APPEND) vm := load(prog) vm.estack.PushVal(MaxArraySize - 1) runVM(t, vm) @@ -1037,14 +1039,14 @@ func TestAPPENDGoodSizeLimit(t *testing.T) { } func TestAPPENDBadSizeLimit(t *testing.T) { - prog := makeProgram(NEWARRAY, DUP, PUSH0, APPEND) + prog := makeProgram(opcode.NEWARRAY, opcode.DUP, opcode.PUSH0, opcode.APPEND) vm := load(prog) vm.estack.PushVal(MaxArraySize) checkVMFailed(t, vm) } func TestPICKITEMBadIndex(t *testing.T) { - prog := makeProgram(PICKITEM) + prog := makeProgram(opcode.PICKITEM) vm := load(prog) vm.estack.PushVal([]StackItem{}) vm.estack.PushVal(0) @@ -1052,7 +1054,7 @@ func TestPICKITEMBadIndex(t *testing.T) { } func TestPICKITEMArray(t *testing.T) { - prog := makeProgram(PICKITEM) + prog := makeProgram(opcode.PICKITEM) vm := load(prog) vm.estack.PushVal([]StackItem{makeStackItem(1), makeStackItem(2)}) vm.estack.PushVal(1) @@ -1062,7 +1064,7 @@ func TestPICKITEMArray(t *testing.T) { } func TestPICKITEMByteArray(t *testing.T) { - prog := makeProgram(PICKITEM) + prog := makeProgram(opcode.PICKITEM) vm := load(prog) vm.estack.PushVal([]byte{1, 2}) vm.estack.PushVal(1) @@ -1072,7 +1074,7 @@ func TestPICKITEMByteArray(t *testing.T) { } func TestPICKITEMMap(t *testing.T) { - prog := makeProgram(PICKITEM) + prog := makeProgram(opcode.PICKITEM) vm := load(prog) m := NewMapItem() @@ -1086,7 +1088,7 @@ func TestPICKITEMMap(t *testing.T) { } func TestSETITEMMap(t *testing.T) { - prog := makeProgram(SETITEM, PICKITEM) + prog := makeProgram(opcode.SETITEM, opcode.PICKITEM) vm := load(prog) m := NewMapItem() @@ -1103,7 +1105,7 @@ func TestSETITEMMap(t *testing.T) { } func TestSETITEMBigMapBad(t *testing.T) { - prog := makeProgram(SETITEM) + prog := makeProgram(opcode.SETITEM) vm := load(prog) m := NewMapItem() @@ -1118,7 +1120,7 @@ func TestSETITEMBigMapBad(t *testing.T) { } func TestSETITEMBigMapGood(t *testing.T) { - prog := makeProgram(SETITEM) + prog := makeProgram(opcode.SETITEM) vm := load(prog) m := NewMapItem() @@ -1133,13 +1135,13 @@ func TestSETITEMBigMapGood(t *testing.T) { } func TestSIZENoArgument(t *testing.T) { - prog := makeProgram(SIZE) + prog := makeProgram(opcode.SIZE) vm := load(prog) checkVMFailed(t, vm) } func TestSIZEByteArray(t *testing.T) { - prog := makeProgram(SIZE) + prog := makeProgram(opcode.SIZE) vm := load(prog) vm.estack.PushVal([]byte{0, 1}) runVM(t, vm) @@ -1148,7 +1150,7 @@ func TestSIZEByteArray(t *testing.T) { } func TestSIZEBool(t *testing.T) { - prog := makeProgram(SIZE) + prog := makeProgram(opcode.SIZE) vm := load(prog) vm.estack.PushVal(false) runVM(t, vm) @@ -1159,7 +1161,7 @@ func TestSIZEBool(t *testing.T) { } func TestARRAYSIZEArray(t *testing.T) { - prog := makeProgram(ARRAYSIZE) + prog := makeProgram(opcode.ARRAYSIZE) vm := load(prog) vm.estack.PushVal([]StackItem{ makeStackItem(1), @@ -1171,7 +1173,7 @@ func TestARRAYSIZEArray(t *testing.T) { } func TestARRAYSIZEMap(t *testing.T) { - prog := makeProgram(ARRAYSIZE) + prog := makeProgram(opcode.ARRAYSIZE) vm := load(prog) m := NewMapItem() @@ -1185,7 +1187,7 @@ func TestARRAYSIZEMap(t *testing.T) { } func TestKEYSMap(t *testing.T) { - prog := makeProgram(KEYS) + prog := makeProgram(opcode.KEYS) vm := load(prog) m := NewMapItem() @@ -1203,20 +1205,20 @@ func TestKEYSMap(t *testing.T) { } func TestKEYSNoArgument(t *testing.T) { - prog := makeProgram(KEYS) + prog := makeProgram(opcode.KEYS) vm := load(prog) checkVMFailed(t, vm) } func TestKEYSWrongType(t *testing.T) { - prog := makeProgram(KEYS) + prog := makeProgram(opcode.KEYS) vm := load(prog) vm.estack.PushVal([]StackItem{}) checkVMFailed(t, vm) } func TestVALUESMap(t *testing.T) { - prog := makeProgram(VALUES) + prog := makeProgram(opcode.VALUES) vm := load(prog) m := NewMapItem() @@ -1234,7 +1236,7 @@ func TestVALUESMap(t *testing.T) { } func TestVALUESArray(t *testing.T) { - prog := makeProgram(VALUES) + prog := makeProgram(opcode.VALUES) vm := load(prog) vm.estack.PushVal([]StackItem{makeStackItem(4)}) runVM(t, vm) @@ -1243,20 +1245,20 @@ func TestVALUESArray(t *testing.T) { } func TestVALUESNoArgument(t *testing.T) { - prog := makeProgram(VALUES) + prog := makeProgram(opcode.VALUES) vm := load(prog) checkVMFailed(t, vm) } func TestVALUESWrongType(t *testing.T) { - prog := makeProgram(VALUES) + prog := makeProgram(opcode.VALUES) vm := load(prog) vm.estack.PushVal(5) checkVMFailed(t, vm) } func TestHASKEYArrayTrue(t *testing.T) { - prog := makeProgram(PUSH5, NEWARRAY, PUSH4, HASKEY) + prog := makeProgram(opcode.PUSH5, opcode.NEWARRAY, opcode.PUSH4, opcode.HASKEY) vm := load(prog) runVM(t, vm) assert.Equal(t, 1, vm.estack.Len()) @@ -1264,7 +1266,7 @@ func TestHASKEYArrayTrue(t *testing.T) { } func TestHASKEYArrayFalse(t *testing.T) { - prog := makeProgram(PUSH5, NEWARRAY, PUSH5, HASKEY) + prog := makeProgram(opcode.PUSH5, opcode.NEWARRAY, opcode.PUSH5, opcode.HASKEY) vm := load(prog) runVM(t, vm) assert.Equal(t, 1, vm.estack.Len()) @@ -1272,7 +1274,7 @@ func TestHASKEYArrayFalse(t *testing.T) { } func TestHASKEYStructTrue(t *testing.T) { - prog := makeProgram(PUSH5, NEWSTRUCT, PUSH4, HASKEY) + prog := makeProgram(opcode.PUSH5, opcode.NEWSTRUCT, opcode.PUSH4, opcode.HASKEY) vm := load(prog) runVM(t, vm) assert.Equal(t, 1, vm.estack.Len()) @@ -1280,7 +1282,7 @@ func TestHASKEYStructTrue(t *testing.T) { } func TestHASKEYStructFalse(t *testing.T) { - prog := makeProgram(PUSH5, NEWSTRUCT, PUSH5, HASKEY) + prog := makeProgram(opcode.PUSH5, opcode.NEWSTRUCT, opcode.PUSH5, opcode.HASKEY) vm := load(prog) runVM(t, vm) assert.Equal(t, 1, vm.estack.Len()) @@ -1288,7 +1290,7 @@ func TestHASKEYStructFalse(t *testing.T) { } func TestHASKEYMapTrue(t *testing.T) { - prog := makeProgram(HASKEY) + prog := makeProgram(opcode.HASKEY) vm := load(prog) m := NewMapItem() m.Add(makeStackItem(5), makeStackItem(6)) @@ -1300,7 +1302,7 @@ func TestHASKEYMapTrue(t *testing.T) { } func TestHASKEYMapFalse(t *testing.T) { - prog := makeProgram(HASKEY) + prog := makeProgram(opcode.HASKEY) vm := load(prog) m := NewMapItem() m.Add(makeStackItem(5), makeStackItem(6)) @@ -1312,20 +1314,20 @@ func TestHASKEYMapFalse(t *testing.T) { } func TestHASKEYNoArguments(t *testing.T) { - prog := makeProgram(HASKEY) + prog := makeProgram(opcode.HASKEY) vm := load(prog) checkVMFailed(t, vm) } func TestHASKEY1Argument(t *testing.T) { - prog := makeProgram(HASKEY) + prog := makeProgram(opcode.HASKEY) vm := load(prog) vm.estack.PushVal(1) checkVMFailed(t, vm) } func TestHASKEYWrongKeyType(t *testing.T) { - prog := makeProgram(HASKEY) + prog := makeProgram(opcode.HASKEY) vm := load(prog) vm.estack.PushVal([]StackItem{}) vm.estack.PushVal([]StackItem{}) @@ -1333,7 +1335,7 @@ func TestHASKEYWrongKeyType(t *testing.T) { } func TestHASKEYWrongCollectionType(t *testing.T) { - prog := makeProgram(HASKEY) + prog := makeProgram(opcode.HASKEY) vm := load(prog) vm.estack.PushVal(1) vm.estack.PushVal(2) @@ -1341,20 +1343,20 @@ func TestHASKEYWrongCollectionType(t *testing.T) { } func TestSIGNNoArgument(t *testing.T) { - prog := makeProgram(SIGN) + prog := makeProgram(opcode.SIGN) vm := load(prog) checkVMFailed(t, vm) } func TestSIGNWrongType(t *testing.T) { - prog := makeProgram(SIGN) + prog := makeProgram(opcode.SIGN) vm := load(prog) vm.estack.PushVal([]StackItem{}) checkVMFailed(t, vm) } func TestSIGNBool(t *testing.T) { - prog := makeProgram(SIGN) + prog := makeProgram(opcode.SIGN) vm := load(prog) vm.estack.PushVal(false) runVM(t, vm) @@ -1363,7 +1365,7 @@ func TestSIGNBool(t *testing.T) { } func TestSIGNPositiveInt(t *testing.T) { - prog := makeProgram(SIGN) + prog := makeProgram(opcode.SIGN) vm := load(prog) vm.estack.PushVal(1) runVM(t, vm) @@ -1372,7 +1374,7 @@ func TestSIGNPositiveInt(t *testing.T) { } func TestSIGNNegativeInt(t *testing.T) { - prog := makeProgram(SIGN) + prog := makeProgram(opcode.SIGN) vm := load(prog) vm.estack.PushVal(-1) runVM(t, vm) @@ -1381,7 +1383,7 @@ func TestSIGNNegativeInt(t *testing.T) { } func TestSIGNZero(t *testing.T) { - prog := makeProgram(SIGN) + prog := makeProgram(opcode.SIGN) vm := load(prog) vm.estack.PushVal(0) runVM(t, vm) @@ -1390,7 +1392,7 @@ func TestSIGNZero(t *testing.T) { } func TestSIGNByteArray(t *testing.T) { - prog := makeProgram(SIGN) + prog := makeProgram(opcode.SIGN) vm := load(prog) vm.estack.PushVal([]byte{0, 1}) runVM(t, vm) @@ -1399,15 +1401,15 @@ func TestSIGNByteArray(t *testing.T) { } func TestAppCall(t *testing.T) { - prog := []byte{byte(APPCALL)} + prog := []byte{byte(opcode.APPCALL)} hash := util.Uint160{} prog = append(prog, hash.Bytes()...) - prog = append(prog, byte(RET)) + prog = append(prog, byte(opcode.RET)) vm := load(prog) vm.SetScriptGetter(func(in util.Uint160) []byte { if in.Equals(hash) { - return makeProgram(DEPTH) + return makeProgram(opcode.DEPTH) } return nil }) @@ -1432,7 +1434,7 @@ func TestSimpleCall(t *testing.T) { } func TestNZtrue(t *testing.T) { - prog := makeProgram(NZ) + prog := makeProgram(opcode.NZ) vm := load(prog) vm.estack.PushVal(1) runVM(t, vm) @@ -1440,7 +1442,7 @@ func TestNZtrue(t *testing.T) { } func TestNZfalse(t *testing.T) { - prog := makeProgram(NZ) + prog := makeProgram(opcode.NZ) vm := load(prog) vm.estack.PushVal(0) runVM(t, vm) @@ -1448,21 +1450,21 @@ func TestNZfalse(t *testing.T) { } func TestPICKbadNoitem(t *testing.T) { - prog := makeProgram(PICK) + prog := makeProgram(opcode.PICK) vm := load(prog) vm.estack.PushVal(1) checkVMFailed(t, vm) } func TestPICKbadNegative(t *testing.T) { - prog := makeProgram(PICK) + prog := makeProgram(opcode.PICK) vm := load(prog) vm.estack.PushVal(-1) checkVMFailed(t, vm) } func TestPICKgood(t *testing.T) { - prog := makeProgram(PICK) + prog := makeProgram(opcode.PICK) result := 2 vm := load(prog) vm.estack.PushVal(0) @@ -1477,7 +1479,7 @@ func TestPICKgood(t *testing.T) { } func TestROTBad(t *testing.T) { - prog := makeProgram(ROT) + prog := makeProgram(opcode.ROT) vm := load(prog) vm.estack.PushVal(1) vm.estack.PushVal(2) @@ -1485,7 +1487,7 @@ func TestROTBad(t *testing.T) { } func TestROTGood(t *testing.T) { - prog := makeProgram(ROT) + prog := makeProgram(opcode.ROT) vm := load(prog) vm.estack.PushVal(1) vm.estack.PushVal(2) @@ -1498,14 +1500,14 @@ func TestROTGood(t *testing.T) { } func TestXTUCKbadNoitem(t *testing.T) { - prog := makeProgram(XTUCK) + prog := makeProgram(opcode.XTUCK) vm := load(prog) vm.estack.PushVal(1) checkVMFailed(t, vm) } func TestXTUCKbadNoN(t *testing.T) { - prog := makeProgram(XTUCK) + prog := makeProgram(opcode.XTUCK) vm := load(prog) vm.estack.PushVal(1) vm.estack.PushVal(2) @@ -1513,14 +1515,14 @@ func TestXTUCKbadNoN(t *testing.T) { } func TestXTUCKbadNegative(t *testing.T) { - prog := makeProgram(XTUCK) + prog := makeProgram(opcode.XTUCK) vm := load(prog) vm.estack.PushVal(-1) checkVMFailed(t, vm) } func TestXTUCKbadZero(t *testing.T) { - prog := makeProgram(XTUCK) + prog := makeProgram(opcode.XTUCK) vm := load(prog) vm.estack.PushVal(1) vm.estack.PushVal(0) @@ -1528,7 +1530,7 @@ func TestXTUCKbadZero(t *testing.T) { } func TestXTUCKgood(t *testing.T) { - prog := makeProgram(XTUCK) + prog := makeProgram(opcode.XTUCK) topelement := 5 xtuckdepth := 3 vm := load(prog) @@ -1545,20 +1547,20 @@ func TestXTUCKgood(t *testing.T) { } func TestTUCKbadNoitems(t *testing.T) { - prog := makeProgram(TUCK) + prog := makeProgram(opcode.TUCK) vm := load(prog) checkVMFailed(t, vm) } func TestTUCKbadNoitem(t *testing.T) { - prog := makeProgram(TUCK) + prog := makeProgram(opcode.TUCK) vm := load(prog) vm.estack.PushVal(1) checkVMFailed(t, vm) } func TestTUCKgood(t *testing.T) { - prog := makeProgram(TUCK) + prog := makeProgram(opcode.TUCK) vm := load(prog) vm.estack.PushVal(42) vm.estack.PushVal(34) @@ -1569,7 +1571,7 @@ func TestTUCKgood(t *testing.T) { } func TestTUCKgood2(t *testing.T) { - prog := makeProgram(TUCK) + prog := makeProgram(opcode.TUCK) vm := load(prog) vm.estack.PushVal(11) vm.estack.PushVal(42) @@ -1582,7 +1584,7 @@ func TestTUCKgood2(t *testing.T) { } func TestOVERbadNoitem(t *testing.T) { - prog := makeProgram(OVER) + prog := makeProgram(opcode.OVER) vm := load(prog) vm.estack.PushVal(1) checkVMFailed(t, vm) @@ -1591,13 +1593,13 @@ func TestOVERbadNoitem(t *testing.T) { } func TestOVERbadNoitems(t *testing.T) { - prog := makeProgram(OVER) + prog := makeProgram(opcode.OVER) vm := load(prog) checkVMFailed(t, vm) } func TestOVERgood(t *testing.T) { - prog := makeProgram(OVER) + prog := makeProgram(opcode.OVER) vm := load(prog) vm.estack.PushVal(42) vm.estack.PushVal(34) @@ -1609,14 +1611,14 @@ func TestOVERgood(t *testing.T) { } func TestNIPBadNoItem(t *testing.T) { - prog := makeProgram(NIP) + prog := makeProgram(opcode.NIP) vm := load(prog) vm.estack.PushVal(1) checkVMFailed(t, vm) } func TestNIPGood(t *testing.T) { - prog := makeProgram(NIP) + prog := makeProgram(opcode.NIP) vm := load(prog) vm.estack.PushVal(1) vm.estack.PushVal(2) @@ -1626,13 +1628,13 @@ func TestNIPGood(t *testing.T) { } func TestDROPBadNoItem(t *testing.T) { - prog := makeProgram(DROP) + prog := makeProgram(opcode.DROP) vm := load(prog) checkVMFailed(t, vm) } func TestDROPGood(t *testing.T) { - prog := makeProgram(DROP) + prog := makeProgram(opcode.DROP) vm := load(prog) vm.estack.PushVal(1) runVM(t, vm) @@ -1640,13 +1642,13 @@ func TestDROPGood(t *testing.T) { } func TestXDROPbadNoitem(t *testing.T) { - prog := makeProgram(XDROP) + prog := makeProgram(opcode.XDROP) vm := load(prog) checkVMFailed(t, vm) } func TestXDROPbadNoN(t *testing.T) { - prog := makeProgram(XDROP) + prog := makeProgram(opcode.XDROP) vm := load(prog) vm.estack.PushVal(1) vm.estack.PushVal(2) @@ -1654,7 +1656,7 @@ func TestXDROPbadNoN(t *testing.T) { } func TestXDROPbadNegative(t *testing.T) { - prog := makeProgram(XDROP) + prog := makeProgram(opcode.XDROP) vm := load(prog) vm.estack.PushVal(1) vm.estack.PushVal(-1) @@ -1662,7 +1664,7 @@ func TestXDROPbadNegative(t *testing.T) { } func TestXDROPgood(t *testing.T) { - prog := makeProgram(XDROP) + prog := makeProgram(opcode.XDROP) vm := load(prog) vm.estack.PushVal(0) vm.estack.PushVal(1) @@ -1675,13 +1677,13 @@ func TestXDROPgood(t *testing.T) { } func TestINVERTbadNoitem(t *testing.T) { - prog := makeProgram(INVERT) + prog := makeProgram(opcode.INVERT) vm := load(prog) checkVMFailed(t, vm) } func TestINVERTgood1(t *testing.T) { - prog := makeProgram(INVERT) + prog := makeProgram(opcode.INVERT) vm := load(prog) vm.estack.PushVal(0) runVM(t, vm) @@ -1689,7 +1691,7 @@ func TestINVERTgood1(t *testing.T) { } func TestINVERTgood2(t *testing.T) { - prog := makeProgram(INVERT) + prog := makeProgram(opcode.INVERT) vm := load(prog) vm.estack.PushVal(-1) runVM(t, vm) @@ -1697,7 +1699,7 @@ func TestINVERTgood2(t *testing.T) { } func TestINVERTgood3(t *testing.T) { - prog := makeProgram(INVERT) + prog := makeProgram(opcode.INVERT) vm := load(prog) vm.estack.PushVal(0x69) runVM(t, vm) @@ -1705,20 +1707,20 @@ func TestINVERTgood3(t *testing.T) { } func TestCATBadNoArgs(t *testing.T) { - prog := makeProgram(CAT) + prog := makeProgram(opcode.CAT) vm := load(prog) checkVMFailed(t, vm) } func TestCATBadOneArg(t *testing.T) { - prog := makeProgram(CAT) + prog := makeProgram(opcode.CAT) vm := load(prog) vm.estack.PushVal([]byte("abc")) checkVMFailed(t, vm) } func TestCATBadBigItem(t *testing.T) { - prog := makeProgram(CAT) + prog := makeProgram(opcode.CAT) vm := load(prog) vm.estack.PushVal(make([]byte, MaxItemSize/2+1)) vm.estack.PushVal(make([]byte, MaxItemSize/2+1)) @@ -1727,7 +1729,7 @@ func TestCATBadBigItem(t *testing.T) { } func TestCATGood(t *testing.T) { - prog := makeProgram(CAT) + prog := makeProgram(opcode.CAT) vm := load(prog) vm.estack.PushVal([]byte("abc")) vm.estack.PushVal([]byte("def")) @@ -1737,7 +1739,7 @@ func TestCATGood(t *testing.T) { } func TestCATInt0ByteArray(t *testing.T) { - prog := makeProgram(CAT) + prog := makeProgram(opcode.CAT) vm := load(prog) vm.estack.PushVal(0) vm.estack.PushVal([]byte{}) @@ -1747,7 +1749,7 @@ func TestCATInt0ByteArray(t *testing.T) { } func TestCATByteArrayInt1(t *testing.T) { - prog := makeProgram(CAT) + prog := makeProgram(opcode.CAT) vm := load(prog) vm.estack.PushVal([]byte{}) vm.estack.PushVal(1) @@ -1757,20 +1759,20 @@ func TestCATByteArrayInt1(t *testing.T) { } func TestSUBSTRBadNoArgs(t *testing.T) { - prog := makeProgram(SUBSTR) + prog := makeProgram(opcode.SUBSTR) vm := load(prog) checkVMFailed(t, vm) } func TestSUBSTRBadOneArg(t *testing.T) { - prog := makeProgram(SUBSTR) + prog := makeProgram(opcode.SUBSTR) vm := load(prog) vm.estack.PushVal(1) checkVMFailed(t, vm) } func TestSUBSTRBadTwoArgs(t *testing.T) { - prog := makeProgram(SUBSTR) + prog := makeProgram(opcode.SUBSTR) vm := load(prog) vm.estack.PushVal(0) vm.estack.PushVal(2) @@ -1778,7 +1780,7 @@ func TestSUBSTRBadTwoArgs(t *testing.T) { } func TestSUBSTRGood(t *testing.T) { - prog := makeProgram(SUBSTR) + prog := makeProgram(opcode.SUBSTR) vm := load(prog) vm.estack.PushVal([]byte("abcdef")) vm.estack.PushVal(1) @@ -1789,7 +1791,7 @@ func TestSUBSTRGood(t *testing.T) { } func TestSUBSTRBadOffset(t *testing.T) { - prog := makeProgram(SUBSTR) + prog := makeProgram(opcode.SUBSTR) vm := load(prog) vm.estack.PushVal([]byte("abcdef")) vm.estack.PushVal(7) @@ -1803,7 +1805,7 @@ func TestSUBSTRBadOffset(t *testing.T) { } func TestSUBSTRBigLen(t *testing.T) { - prog := makeProgram(SUBSTR) + prog := makeProgram(opcode.SUBSTR) vm := load(prog) vm.estack.PushVal([]byte("abcdef")) vm.estack.PushVal(1) @@ -1814,7 +1816,7 @@ func TestSUBSTRBigLen(t *testing.T) { } func TestSUBSTRBad387(t *testing.T) { - prog := makeProgram(SUBSTR) + prog := makeProgram(opcode.SUBSTR) vm := load(prog) b := make([]byte, 6, 20) copy(b, "abcdef") @@ -1827,7 +1829,7 @@ func TestSUBSTRBad387(t *testing.T) { } func TestSUBSTRBadNegativeOffset(t *testing.T) { - prog := makeProgram(SUBSTR) + prog := makeProgram(opcode.SUBSTR) vm := load(prog) vm.estack.PushVal([]byte("abcdef")) vm.estack.PushVal(-1) @@ -1836,7 +1838,7 @@ func TestSUBSTRBadNegativeOffset(t *testing.T) { } func TestSUBSTRBadNegativeLen(t *testing.T) { - prog := makeProgram(SUBSTR) + prog := makeProgram(opcode.SUBSTR) vm := load(prog) vm.estack.PushVal([]byte("abcdef")) vm.estack.PushVal(3) @@ -1845,20 +1847,20 @@ func TestSUBSTRBadNegativeLen(t *testing.T) { } func TestLEFTBadNoArgs(t *testing.T) { - prog := makeProgram(LEFT) + prog := makeProgram(opcode.LEFT) vm := load(prog) checkVMFailed(t, vm) } func TestLEFTBadNoString(t *testing.T) { - prog := makeProgram(LEFT) + prog := makeProgram(opcode.LEFT) vm := load(prog) vm.estack.PushVal(2) checkVMFailed(t, vm) } func TestLEFTBadNegativeLen(t *testing.T) { - prog := makeProgram(LEFT) + prog := makeProgram(opcode.LEFT) vm := load(prog) vm.estack.PushVal([]byte("abcdef")) vm.estack.PushVal(-1) @@ -1866,7 +1868,7 @@ func TestLEFTBadNegativeLen(t *testing.T) { } func TestLEFTGood(t *testing.T) { - prog := makeProgram(LEFT) + prog := makeProgram(opcode.LEFT) vm := load(prog) vm.estack.PushVal([]byte("abcdef")) vm.estack.PushVal(2) @@ -1876,7 +1878,7 @@ func TestLEFTGood(t *testing.T) { } func TestLEFTGoodLen(t *testing.T) { - prog := makeProgram(LEFT) + prog := makeProgram(opcode.LEFT) vm := load(prog) vm.estack.PushVal([]byte("abcdef")) vm.estack.PushVal(8) @@ -1886,20 +1888,20 @@ func TestLEFTGoodLen(t *testing.T) { } func TestRIGHTBadNoArgs(t *testing.T) { - prog := makeProgram(RIGHT) + prog := makeProgram(opcode.RIGHT) vm := load(prog) checkVMFailed(t, vm) } func TestRIGHTBadNoString(t *testing.T) { - prog := makeProgram(RIGHT) + prog := makeProgram(opcode.RIGHT) vm := load(prog) vm.estack.PushVal(2) checkVMFailed(t, vm) } func TestRIGHTBadNegativeLen(t *testing.T) { - prog := makeProgram(RIGHT) + prog := makeProgram(opcode.RIGHT) vm := load(prog) vm.estack.PushVal([]byte("abcdef")) vm.estack.PushVal(-1) @@ -1907,7 +1909,7 @@ func TestRIGHTBadNegativeLen(t *testing.T) { } func TestRIGHTGood(t *testing.T) { - prog := makeProgram(RIGHT) + prog := makeProgram(opcode.RIGHT) vm := load(prog) vm.estack.PushVal([]byte("abcdef")) vm.estack.PushVal(2) @@ -1917,7 +1919,7 @@ func TestRIGHTGood(t *testing.T) { } func TestRIGHTBadLen(t *testing.T) { - prog := makeProgram(RIGHT) + prog := makeProgram(opcode.RIGHT) vm := load(prog) vm.estack.PushVal([]byte("abcdef")) vm.estack.PushVal(8) @@ -1925,14 +1927,14 @@ func TestRIGHTBadLen(t *testing.T) { } func TestPACKBadLen(t *testing.T) { - prog := makeProgram(PACK) + prog := makeProgram(opcode.PACK) vm := load(prog) vm.estack.PushVal(1) checkVMFailed(t, vm) } func TestPACKBigLen(t *testing.T) { - prog := makeProgram(PACK) + prog := makeProgram(opcode.PACK) vm := load(prog) for i := 0; i <= MaxArraySize; i++ { vm.estack.PushVal(0) @@ -1942,7 +1944,7 @@ func TestPACKBigLen(t *testing.T) { } func TestPACKGoodZeroLen(t *testing.T) { - prog := makeProgram(PACK) + prog := makeProgram(opcode.PACK) vm := load(prog) vm.estack.PushVal(0) runVM(t, vm) @@ -1951,7 +1953,7 @@ func TestPACKGoodZeroLen(t *testing.T) { } func TestPACKGood(t *testing.T) { - prog := makeProgram(PACK) + prog := makeProgram(opcode.PACK) elements := []int{55, 34, 42} vm := load(prog) // canary @@ -1972,14 +1974,14 @@ func TestPACKGood(t *testing.T) { } func TestUNPACKBadNotArray(t *testing.T) { - prog := makeProgram(UNPACK) + prog := makeProgram(opcode.UNPACK) vm := load(prog) vm.estack.PushVal(1) checkVMFailed(t, vm) } func TestUNPACKGood(t *testing.T) { - prog := makeProgram(UNPACK) + prog := makeProgram(opcode.UNPACK) elements := []int{55, 34, 42} vm := load(prog) // canary @@ -1995,18 +1997,18 @@ func TestUNPACKGood(t *testing.T) { } func TestREVERSEBadNotArray(t *testing.T) { - prog := makeProgram(REVERSE) + prog := makeProgram(opcode.REVERSE) vm := load(prog) vm.estack.PushVal(1) checkVMFailed(t, vm) } -func testREVERSEIssue437(t *testing.T, i1, i2 Instruction, reversed bool) { +func testREVERSEIssue437(t *testing.T, i1, i2 opcode.Opcode, reversed bool) { prog := makeProgram( - PUSH0, i1, - DUP, PUSH1, APPEND, - DUP, PUSH2, APPEND, - DUP, i2, REVERSE) + opcode.PUSH0, i1, + opcode.DUP, opcode.PUSH1, opcode.APPEND, + opcode.DUP, opcode.PUSH2, opcode.APPEND, + opcode.DUP, i2, opcode.REVERSE) vm := load(prog) vm.Run() @@ -2020,7 +2022,7 @@ func testREVERSEIssue437(t *testing.T, i1, i2 Instruction, reversed bool) { } assert.Equal(t, false, vm.HasFailed()) assert.Equal(t, 1, vm.estack.Len()) - if i1 == NEWARRAY { + if i1 == opcode.NEWARRAY { assert.Equal(t, &ArrayItem{arr}, vm.estack.Pop().value) } else { assert.Equal(t, &StructItem{arr}, vm.estack.Pop().value) @@ -2028,14 +2030,14 @@ func testREVERSEIssue437(t *testing.T, i1, i2 Instruction, reversed bool) { } func TestREVERSEIssue437(t *testing.T) { - t.Run("Array+Array", func(t *testing.T) { testREVERSEIssue437(t, NEWARRAY, NEWARRAY, true) }) - t.Run("Struct+Struct", func(t *testing.T) { testREVERSEIssue437(t, NEWSTRUCT, NEWSTRUCT, true) }) - t.Run("Array+Struct", func(t *testing.T) { testREVERSEIssue437(t, NEWARRAY, NEWSTRUCT, false) }) - t.Run("Struct+Array", func(t *testing.T) { testREVERSEIssue437(t, NEWSTRUCT, NEWARRAY, false) }) + t.Run("Array+Array", func(t *testing.T) { testREVERSEIssue437(t, opcode.NEWARRAY, opcode.NEWARRAY, true) }) + t.Run("Struct+Struct", func(t *testing.T) { testREVERSEIssue437(t, opcode.NEWSTRUCT, opcode.NEWSTRUCT, true) }) + t.Run("Array+Struct", func(t *testing.T) { testREVERSEIssue437(t, opcode.NEWARRAY, opcode.NEWSTRUCT, false) }) + t.Run("Struct+Array", func(t *testing.T) { testREVERSEIssue437(t, opcode.NEWSTRUCT, opcode.NEWARRAY, false) }) } func TestREVERSEGoodOneElem(t *testing.T) { - prog := makeProgram(DUP, REVERSE) + prog := makeProgram(opcode.DUP, opcode.REVERSE) elements := []int{22} vm := load(prog) vm.estack.PushVal(1) @@ -2054,7 +2056,7 @@ func TestREVERSEGoodStruct(t *testing.T) { eall := [][]int{eodd, even} for _, elements := range eall { - prog := makeProgram(DUP, REVERSE) + prog := makeProgram(opcode.DUP, opcode.REVERSE) vm := load(prog) vm.estack.PushVal(1) @@ -2082,7 +2084,7 @@ func TestREVERSEGood(t *testing.T) { eall := [][]int{eodd, even} for _, elements := range eall { - prog := makeProgram(DUP, REVERSE) + prog := makeProgram(opcode.DUP, opcode.REVERSE) vm := load(prog) vm.estack.PushVal(1) vm.estack.PushVal(elements) @@ -2099,20 +2101,20 @@ func TestREVERSEGood(t *testing.T) { } func TestREMOVEBadNoArgs(t *testing.T) { - prog := makeProgram(REMOVE) + prog := makeProgram(opcode.REMOVE) vm := load(prog) checkVMFailed(t, vm) } func TestREMOVEBadOneArg(t *testing.T) { - prog := makeProgram(REMOVE) + prog := makeProgram(opcode.REMOVE) vm := load(prog) vm.estack.PushVal(1) checkVMFailed(t, vm) } func TestREMOVEBadNotArray(t *testing.T) { - prog := makeProgram(REMOVE) + prog := makeProgram(opcode.REMOVE) vm := load(prog) vm.estack.PushVal(1) vm.estack.PushVal(1) @@ -2120,7 +2122,7 @@ func TestREMOVEBadNotArray(t *testing.T) { } func TestREMOVEBadIndex(t *testing.T) { - prog := makeProgram(REMOVE) + prog := makeProgram(opcode.REMOVE) elements := []int{22, 34, 42, 55, 81} vm := load(prog) vm.estack.PushVal(elements) @@ -2129,7 +2131,7 @@ func TestREMOVEBadIndex(t *testing.T) { } func TestREMOVEGood(t *testing.T) { - prog := makeProgram(DUP, PUSH2, REMOVE) + prog := makeProgram(opcode.DUP, opcode.PUSH2, opcode.REMOVE) elements := []int{22, 34, 42, 55, 81} reselements := []int{22, 34, 55, 81} vm := load(prog) @@ -2142,7 +2144,7 @@ func TestREMOVEGood(t *testing.T) { } func TestREMOVEMap(t *testing.T) { - prog := makeProgram(REMOVE, PUSH5, HASKEY) + prog := makeProgram(opcode.REMOVE, opcode.PUSH5, opcode.HASKEY) vm := load(prog) m := NewMapItem() @@ -2158,13 +2160,13 @@ func TestREMOVEMap(t *testing.T) { } func TestCHECKSIGNoArgs(t *testing.T) { - prog := makeProgram(CHECKSIG) + prog := makeProgram(opcode.CHECKSIG) vm := load(prog) checkVMFailed(t, vm) } func TestCHECKSIGOneArg(t *testing.T) { - prog := makeProgram(CHECKSIG) + prog := makeProgram(opcode.CHECKSIG) pk, err := keys.NewPrivateKey() assert.Nil(t, err) pbytes := pk.PublicKey().Bytes() @@ -2174,7 +2176,7 @@ func TestCHECKSIGOneArg(t *testing.T) { } func TestCHECKSIGNoSigLoaded(t *testing.T) { - prog := makeProgram(CHECKSIG) + prog := makeProgram(opcode.CHECKSIG) pk, err := keys.NewPrivateKey() assert.Nil(t, err) msg := "NEO - An Open Network For Smart Economy" @@ -2188,7 +2190,7 @@ func TestCHECKSIGNoSigLoaded(t *testing.T) { } func TestCHECKSIGBadKey(t *testing.T) { - prog := makeProgram(CHECKSIG) + prog := makeProgram(opcode.CHECKSIG) pk, err := keys.NewPrivateKey() assert.Nil(t, err) msg := []byte("NEO - An Open Network For Smart Economy") @@ -2203,7 +2205,7 @@ func TestCHECKSIGBadKey(t *testing.T) { } func TestCHECKSIGWrongSig(t *testing.T) { - prog := makeProgram(CHECKSIG) + prog := makeProgram(opcode.CHECKSIG) pk, err := keys.NewPrivateKey() assert.Nil(t, err) msg := []byte("NEO - An Open Network For Smart Economy") @@ -2220,7 +2222,7 @@ func TestCHECKSIGWrongSig(t *testing.T) { } func TestCHECKSIGGood(t *testing.T) { - prog := makeProgram(CHECKSIG) + prog := makeProgram(opcode.CHECKSIG) pk, err := keys.NewPrivateKey() assert.Nil(t, err) msg := []byte("NEO - An Open Network For Smart Economy") @@ -2237,7 +2239,7 @@ func TestCHECKSIGGood(t *testing.T) { } func TestVERIFYGood(t *testing.T) { - prog := makeProgram(VERIFY) + prog := makeProgram(opcode.VERIFY) pk, err := keys.NewPrivateKey() assert.Nil(t, err) msg := []byte("NEO - An Open Network For Smart Economy") @@ -2254,7 +2256,7 @@ func TestVERIFYGood(t *testing.T) { } func TestVERIFYBad(t *testing.T) { - prog := makeProgram(VERIFY) + prog := makeProgram(opcode.VERIFY) pk, err := keys.NewPrivateKey() assert.Nil(t, err) msg := []byte("NEO - An Open Network For Smart Economy") @@ -2271,13 +2273,13 @@ func TestVERIFYBad(t *testing.T) { } func TestCHECKMULTISIGNoArgs(t *testing.T) { - prog := makeProgram(CHECKMULTISIG) + prog := makeProgram(opcode.CHECKMULTISIG) vm := load(prog) checkVMFailed(t, vm) } func TestCHECKMULTISIGOneArg(t *testing.T) { - prog := makeProgram(CHECKMULTISIG) + prog := makeProgram(opcode.CHECKMULTISIG) pk, err := keys.NewPrivateKey() assert.Nil(t, err) vm := load(prog) @@ -2287,7 +2289,7 @@ func TestCHECKMULTISIGOneArg(t *testing.T) { } func TestCHECKMULTISIGNotEnoughKeys(t *testing.T) { - prog := makeProgram(CHECKMULTISIG) + prog := makeProgram(opcode.CHECKMULTISIG) pk1, err := keys.NewPrivateKey() assert.Nil(t, err) pk2, err := keys.NewPrivateKey() @@ -2306,7 +2308,7 @@ func TestCHECKMULTISIGNotEnoughKeys(t *testing.T) { } func TestCHECKMULTISIGNoHash(t *testing.T) { - prog := makeProgram(CHECKMULTISIG) + prog := makeProgram(opcode.CHECKMULTISIG) pk1, err := keys.NewPrivateKey() assert.Nil(t, err) pk2, err := keys.NewPrivateKey() @@ -2325,7 +2327,7 @@ func TestCHECKMULTISIGNoHash(t *testing.T) { } func TestCHECKMULTISIGBadKey(t *testing.T) { - prog := makeProgram(CHECKMULTISIG) + prog := makeProgram(opcode.CHECKMULTISIG) pk1, err := keys.NewPrivateKey() assert.Nil(t, err) pk2, err := keys.NewPrivateKey() @@ -2345,7 +2347,7 @@ func TestCHECKMULTISIGBadKey(t *testing.T) { } func TestCHECKMULTISIGBadSig(t *testing.T) { - prog := makeProgram(CHECKMULTISIG) + prog := makeProgram(opcode.CHECKMULTISIG) pk1, err := keys.NewPrivateKey() assert.Nil(t, err) pk2, err := keys.NewPrivateKey() @@ -2367,7 +2369,7 @@ func TestCHECKMULTISIGBadSig(t *testing.T) { } func TestCHECKMULTISIGGood(t *testing.T) { - prog := makeProgram(CHECKMULTISIG) + prog := makeProgram(opcode.CHECKMULTISIG) pk1, err := keys.NewPrivateKey() assert.Nil(t, err) pk2, err := keys.NewPrivateKey() @@ -2388,12 +2390,12 @@ func TestCHECKMULTISIGGood(t *testing.T) { assert.Equal(t, true, vm.estack.Pop().Bool()) } -func makeProgram(opcodes ...Instruction) []byte { +func makeProgram(opcodes ...opcode.Opcode) []byte { prog := make([]byte, len(opcodes)+1) // RET for i := 0; i < len(opcodes); i++ { prog[i] = byte(opcodes[i]) } - prog[len(prog)-1] = byte(RET) + prog[len(prog)-1] = byte(opcode.RET) return prog }