forked from TrueCloudLab/neoneo-go
Merge pull request #932 from nspcc-dev/feature/abort
vm: implement ASSERT/ABORT opcodes
This commit is contained in:
commit
9afcd71be3
9 changed files with 104 additions and 106 deletions
|
@ -14,7 +14,6 @@ import (
|
|||
"github.com/nspcc-dev/neo-go/pkg/core/storage"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
"github.com/nspcc-dev/neo-go/pkg/internal/testchain"
|
||||
"github.com/nspcc-dev/neo-go/pkg/internal/testserdes"
|
||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||
|
@ -141,13 +140,6 @@ func newDumbBlock() *block.Block {
|
|||
}
|
||||
}
|
||||
|
||||
func getInvocationScript(data []byte, priv *keys.PrivateKey) []byte {
|
||||
signature := priv.Sign(data)
|
||||
buf := io.NewBufBinWriter()
|
||||
emit.Bytes(buf.BinWriter, signature)
|
||||
return buf.Bytes()
|
||||
}
|
||||
|
||||
// This function generates "../rpc/testdata/testblocks.acc" file which contains data
|
||||
// for RPC unit tests. It also is a nice integration test.
|
||||
// To generate new "../rpc/testdata/testblocks.acc", follow the steps:
|
||||
|
@ -424,7 +416,7 @@ func TestCreateBasicChain(t *testing.T) {
|
|||
func newNEP5Transfer(sc, from, to util.Uint160, amount int64) *transaction.Transaction {
|
||||
w := io.NewBufBinWriter()
|
||||
emit.AppCallWithOperationAndArgs(w.BinWriter, sc, "transfer", from, to, amount)
|
||||
emit.Opcode(w.BinWriter, opcode.THROWIFNOT)
|
||||
emit.Opcode(w.BinWriter, opcode.ASSERT)
|
||||
|
||||
script := w.Bytes()
|
||||
return transaction.NewInvocationTX(script, 0)
|
||||
|
|
|
@ -105,7 +105,7 @@ func (c *Client) TransferNEP5(acc *wallet.Account, to util.Uint160, token *walle
|
|||
// 2 round trips instead of one.
|
||||
w := io.NewBufBinWriter()
|
||||
emit.AppCallWithOperationAndArgs(w.BinWriter, token.Hash, "transfer", from, to, amount)
|
||||
emit.Opcode(w.BinWriter, opcode.THROWIFNOT)
|
||||
emit.Opcode(w.BinWriter, opcode.ASSERT)
|
||||
|
||||
tx := transaction.NewInvocationTX(w.Bytes(), gas)
|
||||
tx.Sender = from
|
||||
|
|
|
@ -48,18 +48,18 @@ type rpcTestCase struct {
|
|||
check func(t *testing.T, e *executor, result interface{})
|
||||
}
|
||||
|
||||
const testContractHash = "76751a2fdde4dc6c7489799a28bb539bc09d1f54"
|
||||
const testContractHash = "2077e1382aab3983aa342e68f7bbc94e69f204b9"
|
||||
|
||||
var rpcTestCases = map[string][]rpcTestCase{
|
||||
"getapplicationlog": {
|
||||
{
|
||||
name: "positive",
|
||||
params: `["113437bd8dfc44e3a6dfe77b750fcff246cbe933ca9667311f45d794cf0410cc"]`,
|
||||
params: `["16c26d67f06770a5b0cda4b1c5ccc28d12c0197c7239a7fe30c2eb523b58f54d"]`,
|
||||
result: func(e *executor) interface{} { return &result.ApplicationLog{} },
|
||||
check: func(t *testing.T, e *executor, acc interface{}) {
|
||||
res, ok := acc.(*result.ApplicationLog)
|
||||
require.True(t, ok)
|
||||
expectedTxHash, err := util.Uint256DecodeStringLE("113437bd8dfc44e3a6dfe77b750fcff246cbe933ca9667311f45d794cf0410cc")
|
||||
expectedTxHash, err := util.Uint256DecodeStringLE("16c26d67f06770a5b0cda4b1c5ccc28d12c0197c7239a7fe30c2eb523b58f54d")
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, expectedTxHash, res.TxHash)
|
||||
assert.Equal(t, 1, len(res.Executions))
|
||||
|
|
BIN
pkg/rpc/server/testdata/test_contract.avm
vendored
BIN
pkg/rpc/server/testdata/test_contract.avm
vendored
Binary file not shown.
BIN
pkg/rpc/server/testdata/testblocks.acc
vendored
BIN
pkg/rpc/server/testdata/testblocks.acc
vendored
Binary file not shown.
|
@ -65,6 +65,11 @@ const (
|
|||
CALL Opcode = 0x34
|
||||
CALLL Opcode = 0x35
|
||||
|
||||
// Exceptions
|
||||
ABORT Opcode = 0x37
|
||||
ASSERT Opcode = 0x38
|
||||
THROW Opcode = 0x3A
|
||||
|
||||
// Stack
|
||||
DEPTH Opcode = 0x43
|
||||
DROP Opcode = 0x45
|
||||
|
@ -158,8 +163,4 @@ const (
|
|||
ISNULL Opcode = 0xD8
|
||||
ISTYPE Opcode = 0xD9
|
||||
CONVERT Opcode = 0xDB
|
||||
|
||||
// Exceptions
|
||||
THROW Opcode = 0xF0
|
||||
THROWIFNOT Opcode = 0xF1
|
||||
)
|
||||
|
|
|
@ -59,6 +59,9 @@ func _() {
|
|||
_ = x[JMPLEL-51]
|
||||
_ = x[CALL-52]
|
||||
_ = x[CALLL-53]
|
||||
_ = x[ABORT-55]
|
||||
_ = x[ASSERT-56]
|
||||
_ = x[THROW-58]
|
||||
_ = x[DEPTH-67]
|
||||
_ = x[DROP-69]
|
||||
_ = x[NIP-70]
|
||||
|
@ -138,11 +141,9 @@ func _() {
|
|||
_ = x[ISNULL-216]
|
||||
_ = x[ISTYPE-217]
|
||||
_ = x[CONVERT-219]
|
||||
_ = x[THROW-240]
|
||||
_ = x[THROWIFNOT-241]
|
||||
}
|
||||
|
||||
const _Opcode_name = "PUSHINT8PUSHINT16PUSHINT32PUSHINT64PUSHINT128PUSHINT256PUSHNULLPUSHDATA1PUSHDATA2PUSHDATA4PUSHM1PUSH0PUSH1PUSH2PUSH3PUSH4PUSH5PUSH6PUSH7PUSH8PUSH9PUSH10PUSH11PUSH12PUSH13PUSH14PUSH15PUSH16NOPJMPJMPLJMPIFJMPIFLJMPIFNOTJMPIFNOTLJMPEQJMPEQLJMPNEJMPNELJMPGTJMPGTLJMPGEJMPGELJMPLTJMPLTLJMPLEJMPLELCALLCALLLDEPTHDROPNIPXDROPCLEARDUPOVERPICKTUCKSWAPOLDPUSH1ROLLREVERSE3REVERSE4REVERSENRETAPPCALLSYSCALLTAILCALLDUPFROMALTSTACKTOALTSTACKFROMALTSTACKCATSUBSTRLEFTRIGHTINVERTANDORXOREQUALNOTEQUALSIGNABSNEGATEINCDECADDSUBMULDIVMODSHLSHRNOTBOOLANDBOOLORNZNUMEQUALNUMNOTEQUALLTLTEGTGTEMINMAXWITHINPACKUNPACKNEWARRAY0NEWARRAYNEWARRAYTNEWSTRUCT0NEWSTRUCTNEWMAPSIZEHASKEYKEYSVALUESPICKITEMAPPENDSETITEMREVERSEITEMSREMOVECLEARITEMSISNULLISTYPECONVERTTHROWTHROWIFNOT"
|
||||
const _Opcode_name = "PUSHINT8PUSHINT16PUSHINT32PUSHINT64PUSHINT128PUSHINT256PUSHNULLPUSHDATA1PUSHDATA2PUSHDATA4PUSHM1PUSH0PUSH1PUSH2PUSH3PUSH4PUSH5PUSH6PUSH7PUSH8PUSH9PUSH10PUSH11PUSH12PUSH13PUSH14PUSH15PUSH16NOPJMPJMPLJMPIFJMPIFLJMPIFNOTJMPIFNOTLJMPEQJMPEQLJMPNEJMPNELJMPGTJMPGTLJMPGEJMPGELJMPLTJMPLTLJMPLEJMPLELCALLCALLLABORTASSERTTHROWDEPTHDROPNIPXDROPCLEARDUPOVERPICKTUCKSWAPOLDPUSH1ROLLREVERSE3REVERSE4REVERSENRETAPPCALLSYSCALLTAILCALLDUPFROMALTSTACKTOALTSTACKFROMALTSTACKCATSUBSTRLEFTRIGHTINVERTANDORXOREQUALNOTEQUALSIGNABSNEGATEINCDECADDSUBMULDIVMODSHLSHRNOTBOOLANDBOOLORNZNUMEQUALNUMNOTEQUALLTLTEGTGTEMINMAXWITHINPACKUNPACKNEWARRAY0NEWARRAYNEWARRAYTNEWSTRUCT0NEWSTRUCTNEWMAPSIZEHASKEYKEYSVALUESPICKITEMAPPENDSETITEMREVERSEITEMSREMOVECLEARITEMSISNULLISTYPECONVERT"
|
||||
|
||||
var _Opcode_map = map[Opcode]string{
|
||||
0: _Opcode_name[0:8],
|
||||
|
@ -194,86 +195,87 @@ var _Opcode_map = map[Opcode]string{
|
|||
51: _Opcode_name[286:292],
|
||||
52: _Opcode_name[292:296],
|
||||
53: _Opcode_name[296:301],
|
||||
67: _Opcode_name[301:306],
|
||||
69: _Opcode_name[306:310],
|
||||
70: _Opcode_name[310:313],
|
||||
72: _Opcode_name[313:318],
|
||||
73: _Opcode_name[318:323],
|
||||
74: _Opcode_name[323:326],
|
||||
75: _Opcode_name[326:330],
|
||||
77: _Opcode_name[330:334],
|
||||
78: _Opcode_name[334:338],
|
||||
80: _Opcode_name[338:342],
|
||||
81: _Opcode_name[342:350],
|
||||
82: _Opcode_name[350:354],
|
||||
83: _Opcode_name[354:362],
|
||||
84: _Opcode_name[362:370],
|
||||
85: _Opcode_name[370:378],
|
||||
102: _Opcode_name[378:381],
|
||||
103: _Opcode_name[381:388],
|
||||
104: _Opcode_name[388:395],
|
||||
105: _Opcode_name[395:403],
|
||||
106: _Opcode_name[403:418],
|
||||
107: _Opcode_name[418:428],
|
||||
108: _Opcode_name[428:440],
|
||||
126: _Opcode_name[440:443],
|
||||
127: _Opcode_name[443:449],
|
||||
128: _Opcode_name[449:453],
|
||||
129: _Opcode_name[453:458],
|
||||
144: _Opcode_name[458:464],
|
||||
145: _Opcode_name[464:467],
|
||||
146: _Opcode_name[467:469],
|
||||
147: _Opcode_name[469:472],
|
||||
151: _Opcode_name[472:477],
|
||||
152: _Opcode_name[477:485],
|
||||
153: _Opcode_name[485:489],
|
||||
154: _Opcode_name[489:492],
|
||||
155: _Opcode_name[492:498],
|
||||
156: _Opcode_name[498:501],
|
||||
157: _Opcode_name[501:504],
|
||||
158: _Opcode_name[504:507],
|
||||
159: _Opcode_name[507:510],
|
||||
160: _Opcode_name[510:513],
|
||||
161: _Opcode_name[513:516],
|
||||
162: _Opcode_name[516:519],
|
||||
168: _Opcode_name[519:522],
|
||||
169: _Opcode_name[522:525],
|
||||
170: _Opcode_name[525:528],
|
||||
171: _Opcode_name[528:535],
|
||||
172: _Opcode_name[535:541],
|
||||
177: _Opcode_name[541:543],
|
||||
179: _Opcode_name[543:551],
|
||||
180: _Opcode_name[551:562],
|
||||
181: _Opcode_name[562:564],
|
||||
182: _Opcode_name[564:567],
|
||||
183: _Opcode_name[567:569],
|
||||
184: _Opcode_name[569:572],
|
||||
185: _Opcode_name[572:575],
|
||||
186: _Opcode_name[575:578],
|
||||
187: _Opcode_name[578:584],
|
||||
192: _Opcode_name[584:588],
|
||||
193: _Opcode_name[588:594],
|
||||
194: _Opcode_name[594:603],
|
||||
195: _Opcode_name[603:611],
|
||||
196: _Opcode_name[611:620],
|
||||
197: _Opcode_name[620:630],
|
||||
198: _Opcode_name[630:639],
|
||||
200: _Opcode_name[639:645],
|
||||
202: _Opcode_name[645:649],
|
||||
203: _Opcode_name[649:655],
|
||||
204: _Opcode_name[655:659],
|
||||
205: _Opcode_name[659:665],
|
||||
206: _Opcode_name[665:673],
|
||||
207: _Opcode_name[673:679],
|
||||
208: _Opcode_name[679:686],
|
||||
209: _Opcode_name[686:698],
|
||||
210: _Opcode_name[698:704],
|
||||
211: _Opcode_name[704:714],
|
||||
216: _Opcode_name[714:720],
|
||||
217: _Opcode_name[720:726],
|
||||
219: _Opcode_name[726:733],
|
||||
240: _Opcode_name[733:738],
|
||||
241: _Opcode_name[738:748],
|
||||
55: _Opcode_name[301:306],
|
||||
56: _Opcode_name[306:312],
|
||||
58: _Opcode_name[312:317],
|
||||
67: _Opcode_name[317:322],
|
||||
69: _Opcode_name[322:326],
|
||||
70: _Opcode_name[326:329],
|
||||
72: _Opcode_name[329:334],
|
||||
73: _Opcode_name[334:339],
|
||||
74: _Opcode_name[339:342],
|
||||
75: _Opcode_name[342:346],
|
||||
77: _Opcode_name[346:350],
|
||||
78: _Opcode_name[350:354],
|
||||
80: _Opcode_name[354:358],
|
||||
81: _Opcode_name[358:366],
|
||||
82: _Opcode_name[366:370],
|
||||
83: _Opcode_name[370:378],
|
||||
84: _Opcode_name[378:386],
|
||||
85: _Opcode_name[386:394],
|
||||
102: _Opcode_name[394:397],
|
||||
103: _Opcode_name[397:404],
|
||||
104: _Opcode_name[404:411],
|
||||
105: _Opcode_name[411:419],
|
||||
106: _Opcode_name[419:434],
|
||||
107: _Opcode_name[434:444],
|
||||
108: _Opcode_name[444:456],
|
||||
126: _Opcode_name[456:459],
|
||||
127: _Opcode_name[459:465],
|
||||
128: _Opcode_name[465:469],
|
||||
129: _Opcode_name[469:474],
|
||||
144: _Opcode_name[474:480],
|
||||
145: _Opcode_name[480:483],
|
||||
146: _Opcode_name[483:485],
|
||||
147: _Opcode_name[485:488],
|
||||
151: _Opcode_name[488:493],
|
||||
152: _Opcode_name[493:501],
|
||||
153: _Opcode_name[501:505],
|
||||
154: _Opcode_name[505:508],
|
||||
155: _Opcode_name[508:514],
|
||||
156: _Opcode_name[514:517],
|
||||
157: _Opcode_name[517:520],
|
||||
158: _Opcode_name[520:523],
|
||||
159: _Opcode_name[523:526],
|
||||
160: _Opcode_name[526:529],
|
||||
161: _Opcode_name[529:532],
|
||||
162: _Opcode_name[532:535],
|
||||
168: _Opcode_name[535:538],
|
||||
169: _Opcode_name[538:541],
|
||||
170: _Opcode_name[541:544],
|
||||
171: _Opcode_name[544:551],
|
||||
172: _Opcode_name[551:557],
|
||||
177: _Opcode_name[557:559],
|
||||
179: _Opcode_name[559:567],
|
||||
180: _Opcode_name[567:578],
|
||||
181: _Opcode_name[578:580],
|
||||
182: _Opcode_name[580:583],
|
||||
183: _Opcode_name[583:585],
|
||||
184: _Opcode_name[585:588],
|
||||
185: _Opcode_name[588:591],
|
||||
186: _Opcode_name[591:594],
|
||||
187: _Opcode_name[594:600],
|
||||
192: _Opcode_name[600:604],
|
||||
193: _Opcode_name[604:610],
|
||||
194: _Opcode_name[610:619],
|
||||
195: _Opcode_name[619:627],
|
||||
196: _Opcode_name[627:636],
|
||||
197: _Opcode_name[636:646],
|
||||
198: _Opcode_name[646:655],
|
||||
200: _Opcode_name[655:661],
|
||||
202: _Opcode_name[661:665],
|
||||
203: _Opcode_name[665:671],
|
||||
204: _Opcode_name[671:675],
|
||||
205: _Opcode_name[675:681],
|
||||
206: _Opcode_name[681:689],
|
||||
207: _Opcode_name[689:695],
|
||||
208: _Opcode_name[695:702],
|
||||
209: _Opcode_name[702:714],
|
||||
210: _Opcode_name[714:720],
|
||||
211: _Opcode_name[720:730],
|
||||
216: _Opcode_name[730:736],
|
||||
217: _Opcode_name[736:742],
|
||||
219: _Opcode_name[742:749],
|
||||
}
|
||||
|
||||
func (i Opcode) String() string {
|
||||
|
|
|
@ -9,10 +9,10 @@ import (
|
|||
// Nothing more to test here, really.
|
||||
func TestStringer(t *testing.T) {
|
||||
tests := map[Opcode]string{
|
||||
ADD: "ADD",
|
||||
SUB: "SUB",
|
||||
THROWIFNOT: "THROWIFNOT",
|
||||
0xff: "Opcode(255)",
|
||||
ADD: "ADD",
|
||||
SUB: "SUB",
|
||||
ASSERT: "ASSERT",
|
||||
0xff: "Opcode(255)",
|
||||
}
|
||||
for o, s := range tests {
|
||||
assert.Equal(t, s, o.String())
|
||||
|
|
|
@ -1298,9 +1298,12 @@ func (v *VM) execute(ctx *Context, op opcode.Opcode, parameter []byte) (err erro
|
|||
case opcode.THROW:
|
||||
panic("THROW")
|
||||
|
||||
case opcode.THROWIFNOT:
|
||||
case opcode.ABORT:
|
||||
panic("ABORT")
|
||||
|
||||
case opcode.ASSERT:
|
||||
if !v.estack.Pop().Bool() {
|
||||
panic("THROWIFNOT")
|
||||
panic("ASSERT failed")
|
||||
}
|
||||
|
||||
default:
|
||||
|
|
Loading…
Reference in a new issue