6 "github.com/davecgh/go-spew/spew"
8 "github.com/bytom/errors"
9 "github.com/bytom/testutil"
12 func TestOutputIDAndNonceOp(t *testing.T) {
14 outputID := mustDecodeHex("0a60f9b12950c84c221012a808ef7782823b7e16b71fe2ba01811cda96a217df")
15 nonceID := mustDecodeHex("c4a6e6256debfca379595e444b91af56846397e8007ea87c40c622170dd13ff7")
17 prog := []byte{uint8(OP_OUTPUTID)}
18 vm := &virtualMachine{
21 context: &Context{SpentOutputID: &outputID},
29 expectedStack := [][]byte{outputID}
30 if !testutil.DeepEqual(gotVM.dataStack, expectedStack) {
31 t.Errorf("expected stack %v, got %v; vm is:\n%s", expectedStack, gotVM.dataStack, spew.Sdump(vm))
34 prog = []byte{uint8(OP_OUTPUTID)}
38 context: &Context{SpentOutputID: nil},
41 if err != ErrContext {
42 t.Errorf("expected ErrContext, got %v", err)
45 prog = []byte{uint8(OP_NONCE)}
49 context: &Context{AnchorID: nil},
52 if err != ErrContext {
53 t.Errorf("expected ErrContext, got %v", err)
56 prog = []byte{uint8(OP_NONCE)}
60 context: &Context{AnchorID: &nonceID},
68 expectedStack = [][]byte{nonceID}
69 if !testutil.DeepEqual(gotVM.dataStack, expectedStack) {
70 t.Errorf("expected stack %v, got %v", expectedStack, gotVM.dataStack)
74 func TestBlockHeight(t *testing.T) {
75 var blockHeight uint64 = 6666
77 prog, err := Assemble("BLOCKHEIGHT 6666 NUMEQUAL")
81 vm := &virtualMachine{
84 context: &Context{BlockHeight: &blockHeight},
88 t.Errorf("got error %s, expected none", err)
91 t.Error("result is false, want success")
94 prog, err = Assemble("BLOCKHEIGHT 7777 NUMEQUAL")
101 context: &Context{BlockHeight: &blockHeight},
104 if err == nil && vm.falseResult() {
105 err = ErrFalseVMResult
109 t.Error("got ok result, expected failure")
110 case ErrFalseVMResult:
113 t.Errorf("got error %s, expected ErrFalseVMResult", err)
117 func TestIntrospectionOps(t *testing.T) {
119 entryID := mustDecodeHex("2e68d78cdeaa98944c12512cf9c719eb4881e9afb61e4b766df5f369aee6392c")
120 entryData := mustDecodeHex("44be5e14ce216f4b2c35a5eb0b35d078bda55cf05b5d36ee0e7a01fbc6ef62b7")
121 assetID := mustDecodeHex("0100000000000000000000000000000000000000000000000000000000000000")
122 txData := mustDecodeHex("3e5190f2691e6d451c50edf9a9a66a7a6779c787676452810dbf4f6e4053682c")
124 type testStruct struct {
126 startVM *virtualMachine
128 wantVM *virtualMachine
130 cases := []testStruct{{
132 startVM: &virtualMachine{
137 append([]byte{9}, make([]byte, 31)...),
139 []byte("missingprog"),
142 CheckOutput: func(uint64, []byte, uint64, []byte, uint64, []byte, bool) (bool, error) {
147 wantVM: &virtualMachine{
150 dataStack: [][]byte{{}},
154 startVM: &virtualMachine{
157 mustDecodeHex("1f2a05f881ed9fa0c9068a84823677409f863891a2196eb55dbfbb677a566374"),
159 append([]byte{2}, make([]byte, 31)...),
161 []byte("controlprog"),
165 wantErr: ErrBadValue,
168 startVM: &virtualMachine{
171 mustDecodeHex("1f2a05f881ed9fa0c9068a84823677409f863891a2196eb55dbfbb677a566374"),
173 append([]byte{2}, make([]byte, 31)...),
175 []byte("controlprog"),
179 wantErr: ErrBadValue,
182 startVM: &virtualMachine{
185 mustDecodeHex("1f2a05f881ed9fa0c9068a84823677409f863891a2196eb55dbfbb677a566374"),
187 append([]byte{2}, make([]byte, 31)...),
189 []byte("controlprog"),
193 wantErr: ErrBadValue,
196 startVM: &virtualMachine{
199 mustDecodeHex("1f2a05f881ed9fa0c9068a84823677409f863891a2196eb55dbfbb677a566374"),
201 append([]byte{2}, make([]byte, 31)...),
203 []byte("controlprog"),
206 CheckOutput: func(uint64, []byte, uint64, []byte, uint64, []byte, bool) (bool, error) {
207 return false, ErrBadValue
211 wantErr: ErrBadValue,
214 startVM: &virtualMachine{
218 mustDecodeHex("1f2a05f881ed9fa0c9068a84823677409f863891a2196eb55dbfbb677a566374"),
220 append([]byte{2}, make([]byte, 31)...),
222 []byte("controlprog"),
226 wantErr: ErrRunLimitExceeded,
229 startVM: &virtualMachine{
230 context: &Context{AssetID: &assetID},
232 wantVM: &virtualMachine{
235 dataStack: [][]byte{assetID},
239 startVM: &virtualMachine{
240 context: &Context{Amount: uint64ptr(5)},
242 wantVM: &virtualMachine{
245 dataStack: [][]byte{{5}},
249 startVM: &virtualMachine{
250 program: []byte("spendprog"),
251 context: &Context{Code: []byte("spendprog")},
253 wantVM: &virtualMachine{
256 dataStack: [][]byte{[]byte("spendprog")},
260 startVM: &virtualMachine{
261 program: []byte("issueprog"),
263 context: &Context{Code: []byte("issueprog")},
265 wantVM: &virtualMachine{
268 dataStack: [][]byte{[]byte("issueprog")},
272 startVM: &virtualMachine{
273 context: &Context{TxData: &txData},
275 wantVM: &virtualMachine{
278 dataStack: [][]byte{txData},
282 startVM: &virtualMachine{
283 context: &Context{EntryData: &entryData},
285 wantVM: &virtualMachine{
288 dataStack: [][]byte{entryData},
292 startVM: &virtualMachine{
293 context: &Context{DestPos: new(uint64)},
295 wantVM: &virtualMachine{
298 dataStack: [][]byte{[]byte{}},
302 startVM: &virtualMachine{
303 context: &Context{EntryID: entryID},
305 wantVM: &virtualMachine{
308 dataStack: [][]byte{entryID},
313 OP_CHECKOUTPUT, OP_ASSET, OP_AMOUNT, OP_PROGRAM,
314 OP_TXDATA, OP_ENTRYDATA, OP_INDEX, OP_OUTPUTID,
317 for _, op := range txops {
318 cases = append(cases, testStruct{
320 startVM: &virtualMachine{
324 wantErr: ErrRunLimitExceeded,
328 for i, c := range cases {
330 prog := []byte{byte(c.op)}
332 if c.wantErr != ErrRunLimitExceeded {
337 switch errors.Root(err) {
341 t.Errorf("case %d, op %s: got no error, want %v", i, ops[c.op].name, c.wantErr)
343 t.Errorf("case %d, op %s: got err = %v want %v", i, ops[c.op].name, err, c.wantErr)
345 if c.wantErr != nil {
350 c.wantVM.program = prog
353 c.wantVM.context = gotVM.context
355 if !testutil.DeepEqual(gotVM, c.wantVM) {
356 t.Errorf("case %d, op %s: unexpected vm result\n\tgot: %+v\n\twant: %+v\nstartVM is:\n%s", i, ops[c.op].name, gotVM, c.wantVM, spew.Sdump(c.startVM))
361 func uint64ptr(n uint64) *uint64 { return &n }