Official Go implementation of the Bytom protocol
Revision | b4da11c495bc48b3026055e0bbc286f5a3615829 (tree) |
---|---|
Zeit | 2021-06-21 21:15:49 |
Autor | paladz <colt@Colt...> |
Commiter | paladz |
edit for elegant
@@ -17,7 +17,7 @@ func (a *API) createAsset(ctx context.Context, ins struct { | ||
17 | 17 | RootXPubs []chainkd.XPub `json:"root_xpubs"` |
18 | 18 | Quorum int `json:"quorum"` |
19 | 19 | Definition map[string]interface{} `json:"definition"` |
20 | - LimitHeight int64 `json:"limit_height"` | |
20 | + LimitHeight uint64 `json:"limit_height"` | |
21 | 21 | IssuanceProgram chainjson.HexBytes `json:"issuance_program"` |
22 | 22 | }) Response { |
23 | 23 | ass, err := a.wallet.AssetReg.Define( |
@@ -126,7 +126,7 @@ func (reg *Registry) getNextAssetIndex() uint64 { | ||
126 | 126 | } |
127 | 127 | |
128 | 128 | // Define defines a new Asset. |
129 | -func (reg *Registry) Define(xpubs []chainkd.XPub, quorum int, definition map[string]interface{}, limitHeight int64, alias string, issuanceProgram chainjson.HexBytes) (*Asset, error) { | |
129 | +func (reg *Registry) Define(xpubs []chainkd.XPub, quorum int, definition map[string]interface{}, limitHeight uint64, alias string, issuanceProgram chainjson.HexBytes) (*Asset, error) { | |
130 | 130 | var err error |
131 | 131 | var assetSigner *signers.Signer |
132 | 132 |
@@ -363,7 +363,7 @@ func serializeAssetDef(def map[string]interface{}) ([]byte, error) { | ||
363 | 363 | return json.MarshalIndent(def, "", " ") |
364 | 364 | } |
365 | 365 | |
366 | -func multisigIssuanceProgram(pubkeys []ed25519.PublicKey, nrequired int, blockHeight int64) (program []byte, vmversion uint64, err error) { | |
366 | +func multisigIssuanceProgram(pubkeys []ed25519.PublicKey, nrequired int, blockHeight uint64) (program []byte, vmversion uint64, err error) { | |
367 | 367 | issuanceProg, err := vmutil.P2SPMultiSigProgramWithHeight(pubkeys, nrequired, blockHeight) |
368 | 368 | if err != nil { |
369 | 369 | return nil, 0, err |
@@ -39,8 +39,8 @@ type payConstraint struct { | ||
39 | 39 | |
40 | 40 | func (p payConstraint) code() []byte { |
41 | 41 | builder := vmutil.NewBuilder() |
42 | - builder.AddInt64(int64(p.Index)) | |
43 | - builder.AddInt64(int64(p.Amount)).AddData(p.AssetId.Bytes()).AddInt64(1).AddData(p.Program) | |
42 | + builder.AddUint64(uint64(p.Index)) | |
43 | + builder.AddUint64(uint64(p.Amount)).AddData(p.AssetId.Bytes()).AddUint64(1).AddData(p.Program) | |
44 | 44 | builder.AddOp(vm.OP_CHECKOUTPUT) |
45 | 45 | prog, _ := builder.Build() // error is impossible |
46 | 46 | return prog |
@@ -139,13 +139,13 @@ func Instantiate(body []byte, params []*Param, recursive bool, args []ContractAr | ||
139 | 139 | a := args[i] |
140 | 140 | switch { |
141 | 141 | case a.B != nil: |
142 | - var n int64 | |
142 | + var n uint64 | |
143 | 143 | if *a.B { |
144 | 144 | n = 1 |
145 | 145 | } |
146 | - b.AddInt64(n) | |
146 | + b.AddUint64(n) | |
147 | 147 | case a.I != nil: |
148 | - b.AddInt64(*a.I) | |
148 | + b.AddUint64(uint64(*a.I)) | |
149 | 149 | case a.S != nil: |
150 | 150 | b.AddData(*a.S) |
151 | 151 | } |
@@ -160,7 +160,7 @@ func Instantiate(body []byte, params []*Param, recursive bool, args []ContractAr | ||
160 | 160 | b.AddOp(vm.OP_DEPTH) |
161 | 161 | b.AddData(body) |
162 | 162 | } |
163 | - b.AddInt64(0) | |
163 | + b.AddUint64(0) | |
164 | 164 | b.AddOp(vm.OP_CHECKPREDICATE) |
165 | 165 | return b.Build() |
166 | 166 | } |
@@ -50,7 +50,7 @@ func opAnd(vm *virtualMachine) error { | ||
50 | 50 | for i := 0; i < min; i++ { |
51 | 51 | res = append(res, a[i]&b[i]) |
52 | 52 | } |
53 | - return vm.push(res, true) | |
53 | + return vm.pushDataStack(res, true) | |
54 | 54 | } |
55 | 55 | |
56 | 56 | func opOr(vm *virtualMachine) error { |
@@ -103,7 +103,7 @@ func doOr(vm *virtualMachine, xor bool) error { | ||
103 | 103 | |
104 | 104 | res = append(res, resByte) |
105 | 105 | } |
106 | - return vm.push(res, true) | |
106 | + return vm.pushDataStack(res, true) | |
107 | 107 | } |
108 | 108 | |
109 | 109 | func opEqual(vm *virtualMachine) error { |
@@ -37,7 +37,7 @@ func doHash(vm *virtualMachine, hashFactory func() hash.Hash) error { | ||
37 | 37 | if err != nil { |
38 | 38 | return err |
39 | 39 | } |
40 | - return vm.push(h.Sum(nil), false) | |
40 | + return vm.pushDataStack(h.Sum(nil), false) | |
41 | 41 | } |
42 | 42 | |
43 | 43 | func opCheckSig(vm *virtualMachine) error { |
@@ -148,7 +148,7 @@ func opTxSigHash(vm *virtualMachine) error { | ||
148 | 148 | if vm.context.TxSigHash == nil { |
149 | 149 | return ErrContext |
150 | 150 | } |
151 | - return vm.push(vm.context.TxSigHash(), false) | |
151 | + return vm.pushDataStack(vm.context.TxSigHash(), false) | |
152 | 152 | } |
153 | 153 | |
154 | 154 | func opHash160(vm *virtualMachine) error { |
@@ -162,5 +162,5 @@ func opHash160(vm *virtualMachine) error { | ||
162 | 162 | return err |
163 | 163 | } |
164 | 164 | |
165 | - return vm.push(crypto.Ripemd160(data), false) | |
165 | + return vm.pushDataStack(crypto.Ripemd160(data), false) | |
166 | 166 | } |
@@ -58,7 +58,7 @@ func opAsset(vm *virtualMachine) error { | ||
58 | 58 | if vm.context.AssetID == nil { |
59 | 59 | return ErrContext |
60 | 60 | } |
61 | - return vm.push(*vm.context.AssetID, true) | |
61 | + return vm.pushDataStack(*vm.context.AssetID, true) | |
62 | 62 | } |
63 | 63 | |
64 | 64 | func opAmount(vm *virtualMachine) error { |
@@ -80,7 +80,7 @@ func opProgram(vm *virtualMachine) error { | ||
80 | 80 | return err |
81 | 81 | } |
82 | 82 | |
83 | - return vm.push(vm.context.Code, true) | |
83 | + return vm.pushDataStack(vm.context.Code, true) | |
84 | 84 | } |
85 | 85 | |
86 | 86 | func opIndex(vm *virtualMachine) error { |
@@ -100,7 +100,7 @@ func opEntryID(vm *virtualMachine) error { | ||
100 | 100 | if err != nil { |
101 | 101 | return err |
102 | 102 | } |
103 | - return vm.push(vm.context.EntryID, true) | |
103 | + return vm.pushDataStack(vm.context.EntryID, true) | |
104 | 104 | } |
105 | 105 | |
106 | 106 | func opOutputID(vm *virtualMachine) error { |
@@ -112,7 +112,7 @@ func opOutputID(vm *virtualMachine) error { | ||
112 | 112 | if vm.context.SpentOutputID == nil { |
113 | 113 | return ErrContext |
114 | 114 | } |
115 | - return vm.push(*vm.context.SpentOutputID, true) | |
115 | + return vm.pushDataStack(*vm.context.SpentOutputID, true) | |
116 | 116 | } |
117 | 117 | |
118 | 118 | func opBlockHeight(vm *virtualMachine) error { |
@@ -3,21 +3,21 @@ package vm | ||
3 | 3 | import "encoding/binary" |
4 | 4 | |
5 | 5 | func opFalse(vm *virtualMachine) error { |
6 | - err := vm.applyCost(1) | |
7 | - if err != nil { | |
6 | + if err := vm.applyCost(1); err != nil { | |
8 | 7 | return err |
9 | 8 | } |
9 | + | |
10 | 10 | return vm.pushBool(false, false) |
11 | 11 | } |
12 | 12 | |
13 | 13 | func opPushdata(vm *virtualMachine) error { |
14 | - err := vm.applyCost(1) | |
15 | - if err != nil { | |
14 | + if err := vm.applyCost(1); err != nil { | |
16 | 15 | return err |
17 | 16 | } |
17 | + | |
18 | 18 | d := make([]byte, len(vm.data)) |
19 | 19 | copy(d, vm.data) |
20 | - return vm.push(d, false) | |
20 | + return vm.pushDataStack(d, false) | |
21 | 21 | } |
22 | 22 | |
23 | 23 | func opNop(vm *virtualMachine) error { |
@@ -46,13 +46,15 @@ func PushDataBytes(in []byte) []byte { | ||
46 | 46 | return append([]byte{byte(OP_PUSHDATA4), b[0], b[1], b[2], b[3]}, in...) |
47 | 47 | } |
48 | 48 | |
49 | -// PushDataInt64 push int64 to stack | |
50 | -func PushDataInt64(n int64) []byte { | |
49 | +// PushDataUint64 push int64 to stack | |
50 | +func PushDataUint64(n uint64) []byte { | |
51 | 51 | if n == 0 { |
52 | 52 | return []byte{byte(OP_0)} |
53 | 53 | } |
54 | + | |
54 | 55 | if n >= 1 && n <= 16 { |
55 | 56 | return []byte{uint8(OP_1) + uint8(n) - 1} |
56 | 57 | } |
57 | - return PushDataBytes(Uint64Bytes(uint64(n))) | |
58 | + | |
59 | + return PushDataBytes(Uint64Bytes(n)) | |
58 | 60 | } |
@@ -140,7 +140,7 @@ func TestPushDataBytes(t *testing.T) { | ||
140 | 140 | |
141 | 141 | func TestPushdataInt64(t *testing.T) { |
142 | 142 | type test struct { |
143 | - num int64 | |
143 | + num uint64 | |
144 | 144 | want []byte |
145 | 145 | } |
146 | 146 | cases := []test{{ |
@@ -155,23 +155,17 @@ func TestPushdataInt64(t *testing.T) { | ||
155 | 155 | }, { |
156 | 156 | num: 256, |
157 | 157 | want: []byte{byte(OP_DATA_2), 0x00, 0x01}, |
158 | - }, { | |
159 | - num: -1, | |
160 | - want: []byte{byte(OP_DATA_8), 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, | |
161 | - }, { | |
162 | - num: -2, | |
163 | - want: []byte{byte(OP_DATA_8), 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, | |
164 | 158 | }} |
165 | 159 | |
166 | 160 | for i := 1; i <= 16; i++ { |
167 | 161 | cases = append(cases, test{ |
168 | - num: int64(i), | |
162 | + num: uint64(i), | |
169 | 163 | want: []byte{byte(OP_1) - 1 + byte(i)}, |
170 | 164 | }) |
171 | 165 | } |
172 | 166 | |
173 | 167 | for _, c := range cases { |
174 | - got := PushDataInt64(c.num) | |
168 | + got := PushDataUint64(c.num) | |
175 | 169 | |
176 | 170 | if !bytes.Equal(got, c.want) { |
177 | 171 | t.Errorf("PushDataInt64(%d) = %x want %x", c.num, got, c.want) |
@@ -7,29 +7,27 @@ import ( | ||
7 | 7 | ) |
8 | 8 | |
9 | 9 | func opCat(vm *virtualMachine) error { |
10 | - err := vm.applyCost(4) | |
11 | - if err != nil { | |
10 | + if err := vm.applyCost(4); err != nil { | |
12 | 11 | return err |
13 | 12 | } |
13 | + | |
14 | 14 | b, err := vm.pop(true) |
15 | 15 | if err != nil { |
16 | 16 | return err |
17 | 17 | } |
18 | + | |
18 | 19 | a, err := vm.pop(true) |
19 | 20 | if err != nil { |
20 | 21 | return err |
21 | 22 | } |
23 | + | |
22 | 24 | lens := int64(len(a) + len(b)) |
23 | - err = vm.applyCost(lens) | |
24 | - if err != nil { | |
25 | + if err = vm.applyCost(lens); err != nil { | |
25 | 26 | return err |
26 | 27 | } |
28 | + | |
27 | 29 | vm.deferCost(-lens) |
28 | - err = vm.push(append(a, b...), true) | |
29 | - if err != nil { | |
30 | - return err | |
31 | - } | |
32 | - return nil | |
30 | + return vm.pushDataStack(append(a, b...), true) | |
33 | 31 | } |
34 | 32 | |
35 | 33 | func opSubstr(vm *virtualMachine) error { |
@@ -72,7 +70,7 @@ func opSubstr(vm *virtualMachine) error { | ||
72 | 70 | return ErrBadValue |
73 | 71 | } |
74 | 72 | |
75 | - return vm.push(str[offset:end], true) | |
73 | + return vm.pushDataStack(str[offset:end], true) | |
76 | 74 | } |
77 | 75 | |
78 | 76 | func opLeft(vm *virtualMachine) error { |
@@ -104,7 +102,7 @@ func opLeft(vm *virtualMachine) error { | ||
104 | 102 | return ErrBadValue |
105 | 103 | } |
106 | 104 | |
107 | - return vm.push(str[:size], true) | |
105 | + return vm.pushDataStack(str[:size], true) | |
108 | 106 | } |
109 | 107 | |
110 | 108 | func opRight(vm *virtualMachine) error { |
@@ -131,12 +129,13 @@ func opRight(vm *virtualMachine) error { | ||
131 | 129 | if err != nil { |
132 | 130 | return err |
133 | 131 | } |
132 | + | |
134 | 133 | lstr := int64(len(str)) |
135 | 134 | if size > lstr { |
136 | 135 | return ErrBadValue |
137 | 136 | } |
138 | 137 | |
139 | - return vm.push(str[lstr-size:], true) | |
138 | + return vm.pushDataStack(str[lstr-size:], true) | |
140 | 139 | } |
141 | 140 | |
142 | 141 | func opSize(vm *virtualMachine) error { |
@@ -153,24 +152,25 @@ func opSize(vm *virtualMachine) error { | ||
153 | 152 | } |
154 | 153 | |
155 | 154 | func opCatpushdata(vm *virtualMachine) error { |
156 | - err := vm.applyCost(4) | |
157 | - if err != nil { | |
155 | + if err := vm.applyCost(4); err != nil { | |
158 | 156 | return err |
159 | 157 | } |
158 | + | |
160 | 159 | b, err := vm.pop(true) |
161 | 160 | if err != nil { |
162 | 161 | return err |
163 | 162 | } |
163 | + | |
164 | 164 | a, err := vm.pop(true) |
165 | 165 | if err != nil { |
166 | 166 | return err |
167 | 167 | } |
168 | - lb := len(b) | |
169 | - lens := int64(len(a) + lb) | |
170 | - err = vm.applyCost(lens) | |
171 | - if err != nil { | |
168 | + | |
169 | + lens := int64(len(a) + len(b)) | |
170 | + if err = vm.applyCost(lens); err != nil { | |
172 | 171 | return err |
173 | 172 | } |
173 | + | |
174 | 174 | vm.deferCost(-lens) |
175 | - return vm.push(append(a, PushDataBytes(b)...), true) | |
175 | + return vm.pushDataStack(append(a, PushDataBytes(b)...), true) | |
176 | 176 | } |
@@ -7,10 +7,10 @@ import ( | ||
7 | 7 | ) |
8 | 8 | |
9 | 9 | func opToAltStack(vm *virtualMachine) error { |
10 | - err := vm.applyCost(2) | |
11 | - if err != nil { | |
10 | + if err := vm.applyCost(2); err != nil { | |
12 | 11 | return err |
13 | 12 | } |
13 | + | |
14 | 14 | if len(vm.dataStack) == 0 { |
15 | 15 | return ErrDataStackUnderflow |
16 | 16 | } |
@@ -21,13 +21,14 @@ func opToAltStack(vm *virtualMachine) error { | ||
21 | 21 | } |
22 | 22 | |
23 | 23 | func opFromAltStack(vm *virtualMachine) error { |
24 | - err := vm.applyCost(2) | |
25 | - if err != nil { | |
24 | + if err := vm.applyCost(2); err != nil { | |
26 | 25 | return err |
27 | 26 | } |
27 | + | |
28 | 28 | if len(vm.altStack) == 0 { |
29 | 29 | return ErrAltStackUnderflow |
30 | 30 | } |
31 | + | |
31 | 32 | // no standard memory cost accounting here |
32 | 33 | vm.dataStack = append(vm.dataStack, vm.altStack[len(vm.altStack)-1]) |
33 | 34 | vm.altStack = vm.altStack[:len(vm.altStack)-1] |
@@ -35,13 +36,12 @@ func opFromAltStack(vm *virtualMachine) error { | ||
35 | 36 | } |
36 | 37 | |
37 | 38 | func op2Drop(vm *virtualMachine) error { |
38 | - err := vm.applyCost(2) | |
39 | - if err != nil { | |
39 | + if err := vm.applyCost(2); err != nil { | |
40 | 40 | return err |
41 | 41 | } |
42 | + | |
42 | 43 | for i := 0; i < 2; i++ { |
43 | - _, err = vm.pop(false) | |
44 | - if err != nil { | |
44 | + if _, err := vm.pop(false); err != nil { | |
45 | 45 | return err |
46 | 46 | } |
47 | 47 | } |
@@ -57,16 +57,16 @@ func op3Dup(vm *virtualMachine) error { | ||
57 | 57 | } |
58 | 58 | |
59 | 59 | func nDup(vm *virtualMachine, n int) error { |
60 | - err := vm.applyCost(int64(n)) | |
61 | - if err != nil { | |
60 | + if err := vm.applyCost(int64(n)); err != nil { | |
62 | 61 | return err |
63 | 62 | } |
63 | + | |
64 | 64 | if len(vm.dataStack) < n { |
65 | 65 | return ErrDataStackUnderflow |
66 | 66 | } |
67 | + | |
67 | 68 | for i := 0; i < n; i++ { |
68 | - err = vm.push(vm.dataStack[len(vm.dataStack)-n], false) | |
69 | - if err != nil { | |
69 | + if err := vm.pushDataStack(vm.dataStack[len(vm.dataStack)-n], false); err != nil { | |
70 | 70 | return err |
71 | 71 | } |
72 | 72 | } |
@@ -74,16 +74,16 @@ func nDup(vm *virtualMachine, n int) error { | ||
74 | 74 | } |
75 | 75 | |
76 | 76 | func op2Over(vm *virtualMachine) error { |
77 | - err := vm.applyCost(2) | |
78 | - if err != nil { | |
77 | + if err := vm.applyCost(2); err != nil { | |
79 | 78 | return err |
80 | 79 | } |
80 | + | |
81 | 81 | if len(vm.dataStack) < 4 { |
82 | 82 | return ErrDataStackUnderflow |
83 | 83 | } |
84 | + | |
84 | 85 | for i := 0; i < 2; i++ { |
85 | - err = vm.push(vm.dataStack[len(vm.dataStack)-4], false) | |
86 | - if err != nil { | |
86 | + if err := vm.pushDataStack(vm.dataStack[len(vm.dataStack)-4], false); err != nil { | |
87 | 87 | return err |
88 | 88 | } |
89 | 89 | } |
@@ -91,13 +91,14 @@ func op2Over(vm *virtualMachine) error { | ||
91 | 91 | } |
92 | 92 | |
93 | 93 | func op2Rot(vm *virtualMachine) error { |
94 | - err := vm.applyCost(2) | |
95 | - if err != nil { | |
94 | + if err := vm.applyCost(2); err != nil { | |
96 | 95 | return err |
97 | 96 | } |
97 | + | |
98 | 98 | if len(vm.dataStack) < 6 { |
99 | 99 | return ErrDataStackUnderflow |
100 | 100 | } |
101 | + | |
101 | 102 | newStack := make([][]byte, 0, len(vm.dataStack)) |
102 | 103 | newStack = append(newStack, vm.dataStack[:len(vm.dataStack)-6]...) |
103 | 104 | newStack = append(newStack, vm.dataStack[len(vm.dataStack)-4:]...) |
@@ -108,13 +109,14 @@ func op2Rot(vm *virtualMachine) error { | ||
108 | 109 | } |
109 | 110 | |
110 | 111 | func op2Swap(vm *virtualMachine) error { |
111 | - err := vm.applyCost(2) | |
112 | - if err != nil { | |
112 | + if err := vm.applyCost(2); err != nil { | |
113 | 113 | return err |
114 | 114 | } |
115 | + | |
115 | 116 | if len(vm.dataStack) < 4 { |
116 | 117 | return ErrDataStackUnderflow |
117 | 118 | } |
119 | + | |
118 | 120 | newStack := make([][]byte, 0, len(vm.dataStack)) |
119 | 121 | newStack = append(newStack, vm.dataStack[:len(vm.dataStack)-4]...) |
120 | 122 | newStack = append(newStack, vm.dataStack[len(vm.dataStack)-2:]...) |
@@ -125,19 +127,17 @@ func op2Swap(vm *virtualMachine) error { | ||
125 | 127 | } |
126 | 128 | |
127 | 129 | func opIfDup(vm *virtualMachine) error { |
128 | - err := vm.applyCost(1) | |
129 | - if err != nil { | |
130 | + if err := vm.applyCost(1); err != nil { | |
130 | 131 | return err |
131 | 132 | } |
133 | + | |
132 | 134 | item, err := vm.top() |
133 | 135 | if err != nil { |
134 | 136 | return err |
135 | 137 | } |
138 | + | |
136 | 139 | if AsBool(item) { |
137 | - err = vm.push(item, false) | |
138 | - if err != nil { | |
139 | - return err | |
140 | - } | |
140 | + return vm.pushDataStack(item, false) | |
141 | 141 | } |
142 | 142 | return nil |
143 | 143 | } |
@@ -151,15 +151,12 @@ func opDepth(vm *virtualMachine) error { | ||
151 | 151 | } |
152 | 152 | |
153 | 153 | func opDrop(vm *virtualMachine) error { |
154 | - err := vm.applyCost(1) | |
155 | - if err != nil { | |
156 | - return err | |
157 | - } | |
158 | - _, err = vm.pop(false) | |
159 | - if err != nil { | |
154 | + if err := vm.applyCost(1); err != nil { | |
160 | 155 | return err |
161 | 156 | } |
162 | - return nil | |
157 | + | |
158 | + _, err := vm.pop(false) | |
159 | + return err | |
163 | 160 | } |
164 | 161 | |
165 | 162 | func opDup(vm *virtualMachine) error { |
@@ -167,18 +164,18 @@ func opDup(vm *virtualMachine) error { | ||
167 | 164 | } |
168 | 165 | |
169 | 166 | func opNip(vm *virtualMachine) error { |
170 | - err := vm.applyCost(1) | |
171 | - if err != nil { | |
167 | + if err := vm.applyCost(1); err != nil { | |
172 | 168 | return err |
173 | 169 | } |
170 | + | |
174 | 171 | top, err := vm.top() |
175 | 172 | if err != nil { |
176 | 173 | return err |
177 | 174 | } |
175 | + | |
178 | 176 | // temporarily pop off the top value with no standard memory accounting |
179 | 177 | vm.dataStack = vm.dataStack[:len(vm.dataStack)-1] |
180 | - _, err = vm.pop(false) | |
181 | - if err != nil { | |
178 | + if _, err = vm.pop(false); err != nil { | |
182 | 179 | return err |
183 | 180 | } |
184 | 181 | // now put the top item back |
@@ -187,18 +184,15 @@ func opNip(vm *virtualMachine) error { | ||
187 | 184 | } |
188 | 185 | |
189 | 186 | func opOver(vm *virtualMachine) error { |
190 | - err := vm.applyCost(1) | |
191 | - if err != nil { | |
187 | + if err := vm.applyCost(1); err != nil { | |
192 | 188 | return err |
193 | 189 | } |
190 | + | |
194 | 191 | if len(vm.dataStack) < 2 { |
195 | 192 | return ErrDataStackUnderflow |
196 | 193 | } |
197 | - err = vm.push(vm.dataStack[len(vm.dataStack)-2], false) | |
198 | - if err != nil { | |
199 | - return err | |
200 | - } | |
201 | - return nil | |
194 | + | |
195 | + return vm.pushDataStack(vm.dataStack[len(vm.dataStack)-2], false) | |
202 | 196 | } |
203 | 197 | |
204 | 198 | func opPick(vm *virtualMachine) error { |
@@ -216,11 +210,12 @@ func opPick(vm *virtualMachine) error { | ||
216 | 210 | return ErrBadValue |
217 | 211 | } |
218 | 212 | |
219 | - if int64(len(vm.dataStack)) < off { | |
213 | + dataStackSize := int64(len(vm.dataStack)) | |
214 | + if dataStackSize < off { | |
220 | 215 | return ErrDataStackUnderflow |
221 | 216 | } |
222 | 217 | |
223 | - return vm.push(vm.dataStack[int64(len(vm.dataStack))-(off)], false) | |
218 | + return vm.pushDataStack(vm.dataStack[dataStackSize-off], false) | |
224 | 219 | } |
225 | 220 | |
226 | 221 | func opRoll(vm *virtualMachine) error { |
@@ -242,24 +237,22 @@ func opRoll(vm *virtualMachine) error { | ||
242 | 237 | } |
243 | 238 | |
244 | 239 | func opRot(vm *virtualMachine) error { |
245 | - err := vm.applyCost(2) | |
246 | - if err != nil { | |
247 | - return err | |
248 | - } | |
249 | - err = rot(vm, 3) | |
250 | - if err != nil { | |
240 | + if err := vm.applyCost(2); err != nil { | |
251 | 241 | return err |
252 | 242 | } |
253 | - return nil | |
243 | + | |
244 | + return rot(vm, 3) | |
254 | 245 | } |
255 | 246 | |
256 | 247 | func rot(vm *virtualMachine, n int64) error { |
257 | 248 | if n < 1 { |
258 | 249 | return ErrBadValue |
259 | 250 | } |
251 | + | |
260 | 252 | if int64(len(vm.dataStack)) < n { |
261 | 253 | return ErrDataStackUnderflow |
262 | 254 | } |
255 | + | |
263 | 256 | index := int64(len(vm.dataStack)) - n |
264 | 257 | newStack := make([][]byte, 0, len(vm.dataStack)) |
265 | 258 | newStack = append(newStack, vm.dataStack[:index]...) |
@@ -270,34 +263,36 @@ func rot(vm *virtualMachine, n int64) error { | ||
270 | 263 | } |
271 | 264 | |
272 | 265 | func opSwap(vm *virtualMachine) error { |
273 | - err := vm.applyCost(1) | |
274 | - if err != nil { | |
266 | + if err := vm.applyCost(1); err != nil { | |
275 | 267 | return err |
276 | 268 | } |
269 | + | |
277 | 270 | l := len(vm.dataStack) |
278 | 271 | if l < 2 { |
279 | 272 | return ErrDataStackUnderflow |
280 | 273 | } |
274 | + | |
281 | 275 | vm.dataStack[l-1], vm.dataStack[l-2] = vm.dataStack[l-2], vm.dataStack[l-1] |
282 | 276 | return nil |
283 | 277 | } |
284 | 278 | |
285 | 279 | func opTuck(vm *virtualMachine) error { |
286 | - err := vm.applyCost(1) | |
287 | - if err != nil { | |
280 | + if err := vm.applyCost(1); err != nil { | |
288 | 281 | return err |
289 | 282 | } |
283 | + | |
290 | 284 | if len(vm.dataStack) < 2 { |
291 | 285 | return ErrDataStackUnderflow |
292 | 286 | } |
287 | + | |
293 | 288 | top2 := make([][]byte, 2) |
294 | 289 | copy(top2, vm.dataStack[len(vm.dataStack)-2:]) |
295 | 290 | // temporarily remove the top two items without standard memory accounting |
296 | 291 | vm.dataStack = vm.dataStack[:len(vm.dataStack)-2] |
297 | - err = vm.push(top2[1], false) | |
298 | - if err != nil { | |
292 | + if err := vm.pushDataStack(top2[1], false); err != nil { | |
299 | 293 | return err |
300 | 294 | } |
295 | + | |
301 | 296 | vm.dataStack = append(vm.dataStack, top2...) |
302 | 297 | return nil |
303 | 298 | } |
@@ -61,13 +61,13 @@ func Verify(context *Context, gasLimit int64) (gasLeft int64, err error) { | ||
61 | 61 | } |
62 | 62 | |
63 | 63 | for i, state := range context.StateData { |
64 | - if err = vm.pushAlt(state, false); err != nil { | |
64 | + if err = vm.pushAltStack(state, false); err != nil { | |
65 | 65 | return vm.runLimit, errors.Wrapf(err, "pushing initial statedata %d", i) |
66 | 66 | } |
67 | 67 | } |
68 | 68 | |
69 | 69 | for i, arg := range context.Arguments { |
70 | - if err = vm.push(arg, false); err != nil { | |
70 | + if err = vm.pushDataStack(arg, false); err != nil { | |
71 | 71 | return vm.runLimit, errors.Wrapf(err, "pushing initial argument %d", i) |
72 | 72 | } |
73 | 73 | } |
@@ -115,6 +115,7 @@ func (vm *virtualMachine) step() error { | ||
115 | 115 | if vm.expansionReserved { |
116 | 116 | return ErrDisallowedOpcode |
117 | 117 | } |
118 | + | |
118 | 119 | vm.pc = vm.nextPC |
119 | 120 | return vm.applyCost(1) |
120 | 121 | } |
@@ -139,7 +140,7 @@ func (vm *virtualMachine) step() error { | ||
139 | 140 | return nil |
140 | 141 | } |
141 | 142 | |
142 | -func (vm *virtualMachine) push(data []byte, deferred bool) error { | |
143 | +func (vm *virtualMachine) pushDataStack(data []byte, deferred bool) error { | |
143 | 144 | cost := 8 + int64(len(data)) |
144 | 145 | if deferred { |
145 | 146 | vm.deferCost(cost) |
@@ -151,7 +152,7 @@ func (vm *virtualMachine) push(data []byte, deferred bool) error { | ||
151 | 152 | return nil |
152 | 153 | } |
153 | 154 | |
154 | -func (vm *virtualMachine) pushAlt(data []byte, deferred bool) error { | |
155 | +func (vm *virtualMachine) pushAltStack(data []byte, deferred bool) error { | |
155 | 156 | cost := 8 + int64(len(data)) |
156 | 157 | if deferred { |
157 | 158 | vm.deferCost(cost) |
@@ -164,11 +165,11 @@ func (vm *virtualMachine) pushAlt(data []byte, deferred bool) error { | ||
164 | 165 | } |
165 | 166 | |
166 | 167 | func (vm *virtualMachine) pushBool(b bool, deferred bool) error { |
167 | - return vm.push(BoolBytes(b), deferred) | |
168 | + return vm.pushDataStack(BoolBytes(b), deferred) | |
168 | 169 | } |
169 | 170 | |
170 | 171 | func (vm *virtualMachine) pushBigInt(n *uint256.Int, deferred bool) error { |
171 | - return vm.push(BigIntBytes(n), deferred) | |
172 | + return vm.pushDataStack(BigIntBytes(n), deferred) | |
172 | 173 | } |
173 | 174 | |
174 | 175 | func (vm *virtualMachine) pop(deferred bool) ([]byte, error) { |
@@ -27,8 +27,8 @@ func NewBuilder() *Builder { | ||
27 | 27 | } |
28 | 28 | |
29 | 29 | // AddInt64 adds a pushdata instruction for an integer value. |
30 | -func (b *Builder) AddInt64(n int64) *Builder { | |
31 | - b.program = append(b.program, vm.PushDataInt64(n)...) | |
30 | +func (b *Builder) AddUint64(n uint64) *Builder { | |
31 | + b.program = append(b.program, vm.PushDataUint64(n)...) | |
32 | 32 | return b |
33 | 33 | } |
34 | 34 |
@@ -28,9 +28,9 @@ func (b *Builder) addP2SPMultiSig(pubkeys []ed25519.PublicKey, nrequired int) er | ||
28 | 28 | for _, p := range pubkeys { |
29 | 29 | b.AddData(p) |
30 | 30 | } |
31 | - b.AddInt64(int64(nrequired)) // stack is now [... SIG SIG SIG PREDICATEHASH PUB PUB PUB M] | |
32 | - b.AddInt64(int64(len(pubkeys))) // stack is now [... SIG SIG SIG PREDICATEHASH PUB PUB PUB M N] | |
33 | - b.AddOp(vm.OP_CHECKMULTISIG) // stack is now [... NARGS] | |
31 | + b.AddUint64(uint64(nrequired)) // stack is now [... SIG SIG SIG PREDICATEHASH PUB PUB PUB M] | |
32 | + b.AddUint64(uint64(len(pubkeys))) // stack is now [... SIG SIG SIG PREDICATEHASH PUB PUB PUB M N] | |
33 | + b.AddOp(vm.OP_CHECKMULTISIG) // stack is now [... NARGS] | |
34 | 34 | return nil |
35 | 35 | } |
36 | 36 |
@@ -44,7 +44,7 @@ func DefaultCoinbaseProgram() ([]byte, error) { | ||
44 | 44 | // P2WPKHProgram return the segwit pay to public key hash |
45 | 45 | func P2WPKHProgram(hash []byte) ([]byte, error) { |
46 | 46 | builder := NewBuilder() |
47 | - builder.AddInt64(0) | |
47 | + builder.AddUint64(0) | |
48 | 48 | builder.AddData(hash) |
49 | 49 | return builder.Build() |
50 | 50 | } |
@@ -52,7 +52,7 @@ func P2WPKHProgram(hash []byte) ([]byte, error) { | ||
52 | 52 | // P2WSHProgram return the segwit pay to script hash |
53 | 53 | func P2WSHProgram(hash []byte) ([]byte, error) { |
54 | 54 | builder := NewBuilder() |
55 | - builder.AddInt64(0) | |
55 | + builder.AddUint64(0) | |
56 | 56 | builder.AddData(hash) |
57 | 57 | return builder.Build() |
58 | 58 | } |
@@ -111,9 +111,9 @@ func P2SHProgram(scriptHash []byte) ([]byte, error) { | ||
111 | 111 | builder.AddOp(vm.OP_SHA3) |
112 | 112 | builder.AddData(scriptHash) |
113 | 113 | builder.AddOp(vm.OP_EQUALVERIFY) |
114 | - builder.AddInt64(0) | |
114 | + builder.AddUint64(0) | |
115 | 115 | builder.AddOp(vm.OP_SWAP) |
116 | - builder.AddInt64(0) | |
116 | + builder.AddUint64(0) | |
117 | 117 | builder.AddOp(vm.OP_CHECKPREDICATE) |
118 | 118 | return builder.Build() |
119 | 119 | } |
@@ -128,10 +128,10 @@ func P2SPMultiSigProgram(pubkeys []ed25519.PublicKey, nrequired int) ([]byte, er | ||
128 | 128 | } |
129 | 129 | |
130 | 130 | // P2SPMultiSigProgramWithHeight generates the script with block height for control transaction output |
131 | -func P2SPMultiSigProgramWithHeight(pubkeys []ed25519.PublicKey, nrequired int, blockHeight int64) ([]byte, error) { | |
131 | +func P2SPMultiSigProgramWithHeight(pubkeys []ed25519.PublicKey, nrequired int, blockHeight uint64) ([]byte, error) { | |
132 | 132 | builder := NewBuilder() |
133 | 133 | if blockHeight > 0 { |
134 | - builder.AddInt64(blockHeight) | |
134 | + builder.AddUint64(blockHeight) | |
135 | 135 | builder.AddOp(vm.OP_BLOCKHEIGHT) |
136 | 136 | builder.AddOp(vm.OP_GREATERTHAN) |
137 | 137 | builder.AddOp(vm.OP_VERIFY) |
@@ -107,7 +107,7 @@ func TestP2SPMultiSigProgramWithHeight(t *testing.T) { | ||
107 | 107 | tests := []struct { |
108 | 108 | pubkeys []ed25519.PublicKey |
109 | 109 | nrequired int |
110 | - height int64 | |
110 | + height uint64 | |
111 | 111 | wantProgram string |
112 | 112 | wantErr error |
113 | 113 | }{ |
@@ -127,12 +127,6 @@ func TestP2SPMultiSigProgramWithHeight(t *testing.T) { | ||
127 | 127 | wantProgram: "ae20988650ff921c82d47a953527894f792572ba63197c56e5fe79e5df0c444d6bb6207192bf4eac0789ee19c88dfa87861cf59e215820f7bdb7be02761d9ed92e6c62208bcd251d9f4e03877130b6e6f1d577eda562375f07c3cdfad8f1d541002fd1a35253ad", |
128 | 128 | }, |
129 | 129 | { |
130 | - pubkeys: []ed25519.PublicKey{pub1}, | |
131 | - nrequired: 1, | |
132 | - height: -1, | |
133 | - wantErr: errors.WithDetail(ErrBadValue, "negative blockHeight"), | |
134 | - }, | |
135 | - { | |
136 | 130 | pubkeys: []ed25519.PublicKey{pub1}, |
137 | 131 | nrequired: 1, |
138 | 132 | height: 0, |