@smartledger/bsv 9.0.0 → 9.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (155) hide show
  1. package/CHANGELOG.md +137 -0
  2. package/README.md +152 -1041
  3. package/STABILITY.md +134 -0
  4. package/bsv-gdaf.min.js +53 -48
  5. package/bsv-ltp.min.js +23 -18
  6. package/bsv-smartcontract.min.js +18 -18
  7. package/bsv.bundle.js +53 -48
  8. package/bsv.min.js +53 -48
  9. package/docs/MODULE_REFERENCE_COMPLETE.md +27 -27
  10. package/docs/advanced/UTXO_MANAGER_GUIDE.md +1 -1
  11. package/docs/getting-started/INSTALLATION.md +23 -23
  12. package/docs/getting-started/QUICK_START.md +7 -7
  13. package/docs/migration/FROM_BSV_1_5_6.md +5 -5
  14. package/docs/proposals/10.0.0-package-split.md +131 -0
  15. package/index.js +5 -0
  16. package/lib/block/merkleblock.js +19 -5
  17. package/lib/hdprivatekey.js +15 -0
  18. package/lib/script/interpreter.js +109 -1
  19. package/lib/smart_contract/builder.js +14 -0
  20. package/lib/util/deprecate.js +159 -0
  21. package/package.json +19 -82
  22. package/version.js +1 -1
  23. package/.mocharc.json +0 -5
  24. package/test/address.js +0 -629
  25. package/test/block/block.js +0 -239
  26. package/test/block/blockheader.js +0 -270
  27. package/test/block/merkleblock.js +0 -207
  28. package/test/build/bundle_crypto_shim.js +0 -104
  29. package/test/build/bundle_externals.js +0 -125
  30. package/test/build/bundle_smoke.js +0 -55
  31. package/test/build/esbuild_main.js +0 -65
  32. package/test/build/esm_wrapper.js +0 -97
  33. package/test/build/exports_resolution.js +0 -84
  34. package/test/build/version_sync.js +0 -14
  35. package/test/cli/smoke.js +0 -261
  36. package/test/consensus/base58-vectors.js +0 -120
  37. package/test/consensus/sv-script-vectors.js +0 -81
  38. package/test/consensus/sv-sighash-vectors.js +0 -51
  39. package/test/consensus/sv-tx-vectors.js +0 -48
  40. package/test/credentials-test.js +0 -332
  41. package/test/crypto/backend_selection.js +0 -126
  42. package/test/crypto/bn.js +0 -168
  43. package/test/crypto/ecdsa.js +0 -426
  44. package/test/crypto/elliptic-fixed.js +0 -61
  45. package/test/crypto/hash.browser.js +0 -121
  46. package/test/crypto/hash.js +0 -122
  47. package/test/crypto/point.js +0 -193
  48. package/test/crypto/random.js +0 -105
  49. package/test/crypto/security.js +0 -176
  50. package/test/crypto/shamir.js +0 -177
  51. package/test/crypto/shamir_rngcap.js +0 -29
  52. package/test/crypto/signature.js +0 -399
  53. package/test/data/bip69.json +0 -215
  54. package/test/data/bitcoin-sv/README.md +0 -170
  55. package/test/data/bitcoin-sv/base58_encode_decode.json +0 -14
  56. package/test/data/bitcoin-sv/base58_keys_invalid.json +0 -152
  57. package/test/data/bitcoin-sv/base58_keys_valid.json +0 -452
  58. package/test/data/bitcoin-sv/script_tests.json +0 -2591
  59. package/test/data/bitcoin-sv/sighash.json +0 -1003
  60. package/test/data/bitcoin-sv/tx_invalid.json +0 -285
  61. package/test/data/bitcoin-sv/tx_valid.json +0 -367
  62. package/test/data/bitcoind/base58_keys_invalid.json +0 -152
  63. package/test/data/bitcoind/base58_keys_valid.json +0 -452
  64. package/test/data/bitcoind/blocks.json +0 -27
  65. package/test/data/bitcoind/script_tests.json +0 -2244
  66. package/test/data/bitcoind/sig_canonical.json +0 -7
  67. package/test/data/bitcoind/sig_noncanonical.json +0 -22
  68. package/test/data/bitcoind/tx_invalid.json +0 -177
  69. package/test/data/bitcoind/tx_valid.json +0 -224
  70. package/test/data/blk86756-testnet.dat +0 -0
  71. package/test/data/blk86756-testnet.js +0 -12
  72. package/test/data/blk86756-testnet.json +0 -684
  73. package/test/data/brc220-batch-vector.json +0 -129
  74. package/test/data/ecdsa.json +0 -230
  75. package/test/data/merkleblocks.js +0 -486
  76. package/test/data/messages.json +0 -22
  77. package/test/data/sighash.json +0 -1004
  78. package/test/data/tx_creation.json +0 -85
  79. package/test/didweb/relationships.js +0 -144
  80. package/test/ecies/bitcore-ecies.js +0 -178
  81. package/test/ecies/electrum-ecies.js +0 -206
  82. package/test/encoding/base58.js +0 -131
  83. package/test/encoding/base58check.js +0 -145
  84. package/test/encoding/bufferreader.js +0 -328
  85. package/test/encoding/bufferwriter.js +0 -160
  86. package/test/encoding/varint.js +0 -104
  87. package/test/gdaf/anchor_no_key_leak.js +0 -146
  88. package/test/gdaf/anchor_spv.js +0 -163
  89. package/test/gdaf/canonicalization.js +0 -106
  90. package/test/gdaf/canonicalize.js +0 -140
  91. package/test/gdaf/zk_prover.js +0 -204
  92. package/test/hdkeys.js +0 -365
  93. package/test/hdprivatekey.js +0 -339
  94. package/test/hdpublickey.js +0 -293
  95. package/test/index.js +0 -16
  96. package/test/ltp/ids.js +0 -74
  97. package/test/ltp/right.js +0 -198
  98. package/test/ltp/verify_failclosed.js +0 -134
  99. package/test/message/message.js +0 -190
  100. package/test/mnemonic/data/fixtures.json +0 -300
  101. package/test/mnemonic/mnemonic.js +0 -277
  102. package/test/mnemonic/mocha.opts +0 -1
  103. package/test/mnemonic/pbkdf2.test.js +0 -43
  104. package/test/networks.js +0 -207
  105. package/test/notaryhash/batch_leaf.js +0 -140
  106. package/test/notaryhash/batch_vector.js +0 -282
  107. package/test/notaryhash/certificate.js +0 -249
  108. package/test/notaryhash/encoding.js +0 -186
  109. package/test/notaryhash/interop.js +0 -112
  110. package/test/notaryhash/merkle.js +0 -181
  111. package/test/notaryhash/script.js +0 -270
  112. package/test/notaryhash/verify.js +0 -342
  113. package/test/opcode.js +0 -186
  114. package/test/ordinals/bsv20.js +0 -337
  115. package/test/ordinals/inscription.js +0 -329
  116. package/test/ordinals/ordlock.js +0 -567
  117. package/test/privatekey.js +0 -540
  118. package/test/publickey.js +0 -411
  119. package/test/regressions.js +0 -215
  120. package/test/script/chronicle.js +0 -543
  121. package/test/script/defaults.js +0 -160
  122. package/test/script/genesis_limits.js +0 -203
  123. package/test/script/interpreter.js +0 -776
  124. package/test/script/script.js +0 -1259
  125. package/test/script/string_ops.js +0 -88
  126. package/test/security/fail_closed_contracts.js +0 -104
  127. package/test/security/threat_model_coverage.js +0 -31
  128. package/test/smart_contract/covenants.js +0 -207
  129. package/test/smart_contract/dsl_debugger.js +0 -92
  130. package/test/smart_contract/extract_field.js +0 -61
  131. package/test/smart_contract/nonenforcing_guard.js +0 -44
  132. package/test/smart_contract/ordinal_transfer.js +0 -71
  133. package/test/smart_contract/preimage.js +0 -98
  134. package/test/smart_contract/sighash_marketplace.js +0 -98
  135. package/test/smart_contract/token_generalized.js +0 -175
  136. package/test/spv/headerchain.js +0 -86
  137. package/test/spv/merkleproof.js +0 -133
  138. package/test/statuslist/failclosed.js +0 -78
  139. package/test/transaction/deserialize.js +0 -33
  140. package/test/transaction/input/input.js +0 -92
  141. package/test/transaction/input/multisig.js +0 -174
  142. package/test/transaction/input/multisigscripthash.js +0 -111
  143. package/test/transaction/input/publickey.js +0 -68
  144. package/test/transaction/input/publickeyhash.js +0 -59
  145. package/test/transaction/output.js +0 -185
  146. package/test/transaction/sighash.js +0 -91
  147. package/test/transaction/signature.js +0 -127
  148. package/test/transaction/transaction.js +0 -1299
  149. package/test/transaction/unspentoutput.js +0 -97
  150. package/test/types/dts_drift.js +0 -124
  151. package/test/types/surface_honesty.js +0 -102
  152. package/test/util/id.js +0 -72
  153. package/test/util/js.js +0 -76
  154. package/test/util/preconditions.js +0 -79
  155. package/test/vcjwt/interop.js +0 -126
@@ -1,543 +0,0 @@
1
- 'use strict'
2
-
3
- /* global describe, it, beforeEach, afterEach */
4
-
5
- // The BSV Chronicle script surface: OP_2MUL/OP_2DIV restored, OP_VER/OP_VERIF/
6
- // OP_VERNOTIF given meaning, and SIGHASH_CHRONICLE selecting the Original
7
- // Transaction Digest Algorithm. All of it sits behind SCRIPT_ENABLE_CHRONICLE.
8
- //
9
- // The default (flag off) behaviour is pinned just as carefully as the enabled
10
- // behaviour. Enabling an opcode by accident is a consensus change, and the
11
- // pre-Chronicle rules are what every existing signature and script was written
12
- // against.
13
-
14
- require('chai').should()
15
- var bsv = require('../..')
16
- var Interpreter = bsv.Script.Interpreter
17
- var Opcode = bsv.Opcode
18
- var Script = bsv.Script
19
- var BN = bsv.crypto.BN
20
- var Signature = bsv.crypto.Signature
21
-
22
- var CHRONICLE = Interpreter.SCRIPT_ENABLE_CHRONICLE
23
-
24
- /** Evaluate `build`ed script against a tx of `version`, returning the outcome. */
25
- function run (build, opts) {
26
- opts = opts || {}
27
- var tx = new bsv.Transaction()
28
- if (opts.version != null) tx.version = opts.version
29
- var script = new Script()
30
- build(script)
31
- var interp = new Interpreter()
32
- var verified = interp.verify(
33
- new Script(), script, tx, 0, opts.flags == null ? CHRONICLE : opts.flags, new BN(0)
34
- )
35
- return {
36
- verified: verified,
37
- errstr: interp.errstr || '',
38
- // Read with the era's width, not BN's four-byte default: post-Genesis
39
- // results are routinely wider than that, and a default-width read throws
40
- // on them rather than reporting the value.
41
- stack: (interp.stack || []).map(function (b) {
42
- return BN.fromScriptNumBuffer(b, false, Math.max(b.length, 4)).toString()
43
- }),
44
- // The raw bytes as well: several Chronicle behaviours are about WIDTH, not
45
- // value, and a script-number reading collapses that distinction.
46
- raw: (interp.stack || []).map(function (b) { return Buffer.from(b) })
47
- }
48
- }
49
-
50
- describe('Chronicle script surface', function () {
51
- describe('SCRIPT_ENABLE_CHRONICLE flag', function () {
52
- it('is a distinct bit that does not collide with the other opcode flags', function () {
53
- CHRONICLE.should.be.a('number')
54
- ;[
55
- Interpreter.SCRIPT_ENABLE_MONOLITH_OPCODES,
56
- Interpreter.SCRIPT_ENABLE_MAGNETIC_OPCODES,
57
- Interpreter.SCRIPT_ENABLE_SIGHASH_FORKID,
58
- Interpreter.SCRIPT_ENABLE_REPLAY_PROTECTION
59
- ].forEach(function (other) {
60
- (CHRONICLE & other).should.equal(0)
61
- })
62
- })
63
-
64
- // This assertion used to read `(Interpreter.DEFAULT_FLAGS & CHRONICLE).should.equal(0)`
65
- // — and Interpreter.DEFAULT_FLAGS does not exist, so it evaluated `undefined & n`,
66
- // which is 0 for every n. A tautology, written by me, in the same change that added
67
- // the flag. What it MEANT to assert is that verify() enables nothing on its own.
68
- // The intent inverted in 8.0.0. It used to assert that verify() enables nothing on
69
- // its own, which was true and was the bug: a BSV library whose default described
70
- // Bitcoin in 2015 accepted scripts the network rejects. The default is now current
71
- // mainnet, so the assertion is that Chronicle IS on without being asked for.
72
- it('is enabled by default, because mainnet has it', function () {
73
- // Deliberately NOT via run(): that helper passes CHRONICLE explicitly, so it would
74
- // measure the helper rather than the library. Omit the argument entirely.
75
- var script = new Script().add(Opcode.OP_VER)
76
- var interp = new Interpreter()
77
- interp.verify(new Script(), script, new bsv.Transaction(), 0)
78
- // OP_VER is meaningful under Chronicle; BAD_OPCODE would mean it was not enabled.
79
- ;(interp.errstr || '').should.not.match(/BAD_OPCODE/)
80
- ;(Interpreter.currentConsensusFlags() & CHRONICLE).should.equal(CHRONICLE)
81
- })
82
-
83
- it('can still be turned off for a pre-activation UTXO', function () {
84
- var script = new Script().add(Opcode.OP_VER)
85
- var interp = new Interpreter()
86
- var verified = interp.verify(new Script(), script, new bsv.Transaction(), 0, 0)
87
- verified.should.equal(false)
88
- interp.errstr.should.match(/BAD_OPCODE/)
89
- })
90
-
91
- it('mainnetFlags() opts in, and can opt out for a pre-activation UTXO', function () {
92
- // Chronicle gates PER UTXO in the node (`utxo_after_chronicle`), so the library
93
- // cannot decide this globally — it can only make both answers easy to express.
94
- (Interpreter.mainnetFlags() & CHRONICLE).should.not.equal(0)
95
- ;(Interpreter.mainnetFlags({ afterChronicle: false }) & CHRONICLE).should.equal(0)
96
- Interpreter.CHRONICLE_ACTIVATION_HEIGHT.should.equal(943816)
97
- })
98
-
99
- it('mainnetFlags() actually evaluates a Chronicle script', function () {
100
- var r = run(function (s) { s.add(Opcode.OP_VER) },
101
- { flags: Interpreter.mainnetFlags(), version: 7 })
102
- r.stack[r.stack.length - 1].should.equal('7')
103
-
104
- var pre = run(function (s) { s.add(Opcode.OP_VER) },
105
- { flags: Interpreter.mainnetFlags({ afterChronicle: false }), version: 7 })
106
- pre.verified.should.equal(false)
107
- pre.errstr.should.match(/BAD_OPCODE/)
108
- })
109
- })
110
-
111
- describe('OP_2MUL / OP_2DIV', function () {
112
- it('stay DISABLED without the flag, even in an unexecuted branch', function () {
113
- // "Disabled" is stronger than "unimplemented": a disabled opcode fails the
114
- // script even where it is never executed. That is why the gate lives in
115
- // isOpcodeDisabled rather than in the evaluation switch — losing this
116
- // distinction would silently loosen consensus.
117
- var r = run(function (s) {
118
- s.add(Opcode.OP_0).add(Opcode.OP_IF).add(Opcode.OP_2MUL).add(Opcode.OP_ENDIF).add(Opcode.OP_1)
119
- }, { flags: 0 })
120
- r.verified.should.equal(false)
121
- r.errstr.should.match(/DISABLED_OPCODE/)
122
- })
123
-
124
- it('are usable in an unexecuted branch once enabled', function () {
125
- var r = run(function (s) {
126
- s.add(Opcode.OP_0).add(Opcode.OP_IF).add(Opcode.OP_2MUL).add(Opcode.OP_ENDIF).add(Opcode.OP_1)
127
- })
128
- r.verified.should.equal(true)
129
- })
130
-
131
- it('OP_2MUL doubles, over positive, negative and zero', function () {
132
- ;[[0, '0'], [1, '2'], [7, '14'], [-3, '-6'], [-1, '-2']].forEach(function (t) {
133
- var r = run(function (s) { s.add(new BN(t[0]).toScriptNumBuffer()).add(Opcode.OP_2MUL) })
134
- r.stack[r.stack.length - 1].should.equal(t[1])
135
- })
136
- })
137
-
138
- it('OP_2DIV truncates toward zero, so it agrees with OP_DIV by 2', function () {
139
- // -5 OP_2DIV is -2, not -3. A shift would give -3; bn.js `shrn` also asserts
140
- // on negatives. This is the case where a rounding change would hide.
141
- ;[0, 1, 5, -5, 7, -7, -1, 1000, -1000].forEach(function (v) {
142
- var viaOp = run(function (s) { s.add(new BN(v).toScriptNumBuffer()).add(Opcode.OP_2DIV) })
143
- var viaDiv = run(function (s) {
144
- s.add(new BN(v).toScriptNumBuffer()).add(new BN(2).toScriptNumBuffer()).add(Opcode.OP_DIV)
145
- })
146
- viaOp.stack[viaOp.stack.length - 1].should.equal(viaDiv.stack[viaDiv.stack.length - 1])
147
- })
148
- })
149
- })
150
-
151
- describe('OP_VER', function () {
152
- it('is BAD_OPCODE without the flag', function () {
153
- var r = run(function (s) { s.add(Opcode.OP_VER) }, { flags: 0 })
154
- r.verified.should.equal(false)
155
- r.errstr.should.match(/BAD_OPCODE/)
156
- })
157
-
158
- it('pushes the executing transaction version', function () {
159
- ;[1, 2, 10].forEach(function (v) {
160
- var r = run(function (s) { s.add(Opcode.OP_VER) }, { version: v })
161
- r.stack[r.stack.length - 1].should.equal(String(v))
162
- // LENGTH too, not just the numeric reading. `01000000` and `01` both read
163
- // as 1, so the value check alone passes whether OP_VER pushes four
164
- // little-endian bytes or a minimally-encoded script number — and pushing
165
- // the script number was the bug fixed in #95.
166
- r.raw[r.raw.length - 1].length.should.equal(4)
167
- })
168
- })
169
- })
170
-
171
- describe('OP_VERIF / OP_VERNOTIF', function () {
172
- it('after Genesis, errors only in an EXECUTED branch', function () {
173
- // Core treats OP_VERIF as illegal everywhere, including unexecuted
174
- // branches — a rule it applies to no other opcode. BSV dropped that at
175
- // Genesis, and the node is explicit:
176
- //
177
- // if(!utxo_after_chronicle) {
178
- // if(utxo_after_genesis && !fExec) break;
179
- // else return SCRIPT_ERR_BAD_OPCODE;
180
- // }
181
- //
182
- // Note the condition includes utxo_after_genesis, so the era has to be
183
- // stated. Run without it, this is a pre-Genesis output, and then Core's
184
- // rule is also BSV's: illegal everywhere, which the node's own corpus
185
- // confirms for exactly these scripts.
186
- var unexecuted = run(function (s) {
187
- s.add(Opcode.OP_0).add(Opcode.OP_IF).add(Opcode.OP_VERIF).add(Opcode.OP_ENDIF).add(Opcode.OP_1)
188
- }, { flags: Interpreter.SCRIPT_UTXO_AFTER_GENESIS })
189
- unexecuted.verified.should.equal(true)
190
-
191
- // Pre-Genesis the same script is invalid, unexecuted branch or not.
192
- var preGenesis = run(function (s) {
193
- s.add(Opcode.OP_0).add(Opcode.OP_IF).add(Opcode.OP_VERIF).add(Opcode.OP_ENDIF).add(Opcode.OP_1)
194
- }, { flags: 0 })
195
- preGenesis.verified.should.equal(false)
196
- preGenesis.errstr.should.match(/BAD_OPCODE/)
197
-
198
- var executed = run(function (s) {
199
- s.add(Opcode.OP_1).add(Opcode.OP_VERIF).add(Opcode.OP_ENDIF)
200
- }, { flags: 0 })
201
- executed.verified.should.equal(false)
202
- executed.errstr.should.match(/BAD_OPCODE/)
203
- })
204
-
205
- // The comparison is BYTE-WISE against the four little-endian version
206
- // bytes, not numeric:
207
- //
208
- // if(vch.size() == 4) { to_le(checker.Version(), val.data());
209
- // fValue = std::ranges::equal(val, vch); }
210
- //
211
- // So a 1-byte script number never matches, however equal it looks
212
- // numerically, and the idiomatic form is `OP_VER OP_VERIF`.
213
- var LE = function (v) {
214
- var b = Buffer.alloc(4)
215
- b.writeInt32LE(v, 0)
216
- return b
217
- }
218
-
219
- it('OP_VERIF takes the branch on a 4-byte little-endian version match', function () {
220
- var taken = run(function (s) {
221
- s.add(LE(2)).add(Opcode.OP_VERIF).add(Opcode.OP_1).add(Opcode.OP_ENDIF)
222
- }, { version: 2 })
223
- taken.verified.should.equal(true)
224
-
225
- var notTaken = run(function (s) {
226
- s.add(LE(9)).add(Opcode.OP_VERIF).add(Opcode.OP_1).add(Opcode.OP_ENDIF).add(Opcode.OP_1)
227
- }, { version: 2 })
228
- notTaken.verified.should.equal(true)
229
- notTaken.stack.length.should.equal(1) // only the trailing OP_1
230
- })
231
-
232
- it('a numerically-equal operand of the wrong LENGTH does not match', function () {
233
- var r = run(function (s) {
234
- s.add(new BN(2).toScriptNumBuffer()).add(Opcode.OP_VERIF).add(Opcode.OP_1).add(Opcode.OP_ENDIF).add(Opcode.OP_1)
235
- }, { version: 2 })
236
- r.verified.should.equal(true)
237
- r.stack.length.should.equal(1) // branch NOT taken
238
- })
239
-
240
- it('OP_VER feeds OP_VERIF directly', function () {
241
- var r = run(function (s) {
242
- s.add(Opcode.OP_VER).add(Opcode.OP_VERIF).add(Opcode.OP_1).add(Opcode.OP_ENDIF)
243
- }, { version: 2 })
244
- r.verified.should.equal(true)
245
- })
246
-
247
- it('OP_VERNOTIF is its negation', function () {
248
- var r = run(function (s) {
249
- s.add(LE(9)).add(Opcode.OP_VERNOTIF).add(Opcode.OP_1).add(Opcode.OP_ENDIF)
250
- }, { version: 2 })
251
- r.verified.should.equal(true)
252
- })
253
-
254
- it('CONSUMES its operand, mirroring OP_IF', function () {
255
- // The spec describes the comparison but not the stack effect. An IF that left
256
- // its condition behind would unbalance every script using it, so this pops.
257
- // Pinned so a correction shows up as a failure rather than silently.
258
- var r = run(function (s) {
259
- s.add(Opcode.OP_7).add(Opcode.OP_2).add(Opcode.OP_VERIF).add(Opcode.OP_ENDIF)
260
- }, { version: 2 })
261
- r.verified.should.equal(true)
262
- r.stack.should.deep.equal(['7']) // the 2 was consumed, the 7 remains
263
- })
264
-
265
- it('fails on an empty stack rather than reading past it', function () {
266
- var r = run(function (s) {
267
- s.add(Opcode.OP_VERIF).add(Opcode.OP_ENDIF).add(Opcode.OP_1)
268
- }, { version: 2 })
269
- r.verified.should.equal(false)
270
- r.errstr.should.match(/UNBALANCED_CONDITIONAL/)
271
- })
272
- })
273
-
274
- // Ported from SV Node src/script/interpreter.cpp (OP_LSHIFTNUM / OP_RSHIFTNUM) and
275
- // the CScriptNum / bsv::bint arithmetic behind it. Each case below corresponds to a
276
- // specific line of that implementation, so a divergence shows up as a named failure.
277
- describe('OP_LSHIFTNUM / OP_RSHIFTNUM', function () {
278
- // Push x then n then the opcode: the node's comment is literally `(x n -- out)`,
279
- // so the COUNT is on top.
280
- function shift (x, n, op, flags) {
281
- return run(function (s) {
282
- s.add(new BN(x).toScriptNumBuffer()).add(new BN(n).toScriptNumBuffer()).add(op)
283
- }, { flags: flags == null ? CHRONICLE : flags })
284
- }
285
- function value (x, n, op) {
286
- var r = shift(x, n, op)
287
- return r.stack[r.stack.length - 1]
288
- }
289
- // A zero result makes the script fail EVAL_FALSE, so compare against OP_0 instead.
290
- function isZero (x, n, op) {
291
- return run(function (s) {
292
- s.add(new BN(x).toScriptNumBuffer()).add(new BN(n).toScriptNumBuffer()).add(op)
293
- .add(Opcode.OP_0).add(Opcode.OP_EQUAL)
294
- }).verified
295
- }
296
-
297
- it('are upgradable NOPs before Chronicle, as the node has them', function () {
298
- // if(!utxo_after_chronicle) { ... else break; } — a no-op, NOT an error.
299
- // Rejecting here would refuse scripts the network accepts.
300
- var r = shift(8, 1, Opcode.OP_LSHIFTNUM, 0)
301
- r.verified.should.equal(true)
302
- r.stack.should.deep.equal(['8', '1']) // untouched: no shift, nothing popped
303
- })
304
-
305
- it('honour DISCOURAGE_UPGRADABLE_NOPS before Chronicle', function () {
306
- var r = shift(8, 1, Opcode.OP_LSHIFTNUM, Interpreter.SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS)
307
- r.verified.should.equal(false)
308
- r.errstr.should.match(/DISCOURAGE_UPGRADABLE_NOPS/)
309
- })
310
-
311
- it('left shift multiplies by 2^n, carrying the sign', function () {
312
- value(1, 4, Opcode.OP_LSHIFTNUM).should.equal('16')
313
- value(3, 3, Opcode.OP_LSHIFTNUM).should.equal('24')
314
- value(1, 0, Opcode.OP_LSHIFTNUM).should.equal('1')
315
- value(-1, 4, Opcode.OP_LSHIFTNUM).should.equal('-16')
316
- value(-3, 3, Opcode.OP_LSHIFTNUM).should.equal('-24')
317
- })
318
-
319
- it('right shift TRUNCATES TOWARD ZERO, which is the whole of "preserving sign"', function () {
320
- // The node spells this out: "Mathematical division by 2^bit_shift, rounding
321
- // toward zero ... For negative values: n / 2^k = -((-n) >> k)". A two's
322
- // complement arithmetic shift would FLOOR instead, giving -3 and -4 here.
323
- value(-5, 1, Opcode.OP_RSHIFTNUM).should.equal('-2')
324
- value(-7, 1, Opcode.OP_RSHIFTNUM).should.equal('-3')
325
- value(5, 1, Opcode.OP_RSHIFTNUM).should.equal('2')
326
- value(-1000, 3, Opcode.OP_RSHIFTNUM).should.equal('-125')
327
- })
328
-
329
- it('agrees with OP_DIV by 2^n, the same convention as OP_2DIV', function () {
330
- [5, -5, 7, -7, 1000, -1000].forEach(function (x) {
331
- var viaShift = value(x, 1, Opcode.OP_RSHIFTNUM)
332
- var viaDiv = run(function (s) {
333
- s.add(new BN(x).toScriptNumBuffer()).add(new BN(2).toScriptNumBuffer()).add(Opcode.OP_DIV)
334
- })
335
- viaShift.should.equal(viaDiv.stack[viaDiv.stack.length - 1])
336
- })
337
- })
338
-
339
- it('rejects a negative shift count', function () {
340
- // if(n < 0) return SCRIPT_ERR_INVALID_NUMBER_RANGE
341
- ;[Opcode.OP_LSHIFTNUM, Opcode.OP_RSHIFTNUM].forEach(function (op) {
342
- var r = shift(8, -1, op)
343
- r.verified.should.equal(false)
344
- r.errstr.should.match(/INVALID_NUMBER_RANGE/)
345
- })
346
- })
347
-
348
- it('right shift past the bit length is zero, not an error', function () {
349
- isZero(5, 1000, Opcode.OP_RSHIFTNUM).should.equal(true)
350
- isZero(-5, 1000, Opcode.OP_RSHIFTNUM).should.equal(true) // and no negative zero
351
- isZero(1, 1, Opcode.OP_RSHIFTNUM).should.equal(true)
352
- isZero(-1, 1, Opcode.OP_RSHIFTNUM).should.equal(true)
353
- })
354
-
355
- it('left shift overflows rather than growing without bound', function () {
356
- // CScriptNum bounds this BEFORE shifting (current_size + shift_bytes >
357
- // max_length), so a huge count cannot allocate a huge number first.
358
- //
359
- // The count has to exceed the real bound to test that. Chronicle's
360
- // max_length is 32,000,000 bytes, so 1000 bits — 125 bytes — is a
361
- // perfectly valid post-Chronicle number and overflows only against the
362
- // pre-Genesis four. This used to pass because the bound was four
363
- // whatever the era.
364
- var r = shift(5, 8 * Interpreter.MAX_SCRIPT_NUM_LENGTH_AFTER_CHRONICLE,
365
- Opcode.OP_LSHIFTNUM)
366
- r.verified.should.equal(false)
367
- r.errstr.should.match(/OVERFLOW/)
368
- })
369
-
370
- it('leaves a shift inside the bound alone', function () {
371
- // The counterpart: 1000 bits is valid post-Chronicle, and was not before.
372
- var r = shift(5, 1000, Opcode.OP_LSHIFTNUM)
373
- r.verified.should.equal(true)
374
- r.raw[0].length.should.equal(126)
375
- })
376
-
377
- it('fails on a short stack', function () {
378
- var r = run(function (s) { s.add(new BN(1).toScriptNumBuffer()).add(Opcode.OP_LSHIFTNUM) })
379
- r.verified.should.equal(false)
380
- r.errstr.should.match(/INVALID_STACK_OPERATION/)
381
- })
382
- })
383
-
384
- describe('SIGHASH_CHRONICLE selects the original digest algorithm', function () {
385
- function fixture () {
386
- var key = bsv.PrivateKey.fromBuffer(Buffer.alloc(32, 5))
387
- var sub = Script.buildPublicKeyHashOut(key.toAddress())
388
- var tx = new bsv.Transaction()
389
- tx.uncheckedAddInput(new bsv.Transaction.Input({
390
- prevTxId: 'aa'.repeat(32), outputIndex: 0, script: Script.empty()
391
- }))
392
- tx.addOutput(new bsv.Transaction.Output({ script: sub, satoshis: 1000 }))
393
- return { tx: tx, sub: sub, amt: new BN(2000) }
394
- }
395
-
396
- it('has the constant at 0x20', function () {
397
- Signature.SIGHASH_CHRONICLE.should.equal(0x20)
398
- })
399
-
400
- it('routes to OTDA when the bit is set AND the flag is enabled', function () {
401
- var f = fixture()
402
- var type = Signature.SIGHASH_ALL | Signature.SIGHASH_FORKID | Signature.SIGHASH_CHRONICLE
403
- var enabled = bsv.Transaction.sighash.sighash(
404
- f.tx, type, 0, f.sub, f.amt,
405
- Interpreter.SCRIPT_ENABLE_SIGHASH_FORKID | CHRONICLE
406
- )
407
- var forcedOtda = bsv.Transaction.sighash.sighash(f.tx, type, 0, f.sub, f.amt, 0)
408
- enabled.toString('hex').should.equal(forcedOtda.toString('hex'))
409
- })
410
-
411
- it('OVERRIDES FORKID — otherwise the bit could never select OTDA in practice', function () {
412
- // FORKID is set on essentially every BSV signature written since 2018, so a
413
- // CHRONICLE bit that only applied when FORKID was absent would mean nothing.
414
- //
415
- // Stated against the algorithm rather than against the flag: the node
416
- // routes on the bit alone, so with the bit set, enabling forkid makes no
417
- // difference and the result is the original digest either way.
418
- var f = fixture()
419
- var type = Signature.SIGHASH_ALL | Signature.SIGHASH_FORKID | Signature.SIGHASH_CHRONICLE
420
- var withForkId = bsv.Transaction.sighash.sighash(
421
- f.tx, type, 0, f.sub, f.amt, Interpreter.SCRIPT_ENABLE_SIGHASH_FORKID
422
- )
423
- var forcedOtda = bsv.Transaction.sighash.sighash(f.tx, type, 0, f.sub, f.amt, 0)
424
- withForkId.toString('hex').should.equal(forcedOtda.toString('hex'))
425
-
426
- // And it does override: without the bit the same transaction takes BIP-143.
427
- var withoutBit = Signature.SIGHASH_ALL | Signature.SIGHASH_FORKID
428
- var bip143 = bsv.Transaction.sighash.sighash(
429
- f.tx, withoutBit, 0, f.sub, f.amt, Interpreter.SCRIPT_ENABLE_SIGHASH_FORKID
430
- )
431
- bip143.toString('hex').should.not.equal(withForkId.toString('hex'))
432
- })
433
-
434
- it('cannot be used outside Chronicle, so old BIP-143 signatures are unaffected', function () {
435
- // Before the upgrade the 0x20 bit means nothing, so signatures already exist
436
- // whose type byte happens to set it. Reinterpreting those as OTDA would be
437
- // a silent validity change on historic data.
438
- //
439
- // The node prevents that in CheckSignatureEncoding rather than in the
440
- // digest function: a signature carrying the bit outside Chronicle is
441
- // REJECTED, not reinterpreted, so it never reaches a digest at all. That
442
- // is what lets SignatureHash() route on the bit alone, and gating the
443
- // digest instead made 260 of the node's 1000 vectors disagree.
444
- var priv = new bsv.PrivateKey()
445
- var hashbuf = bsv.crypto.Hash.sha256(Buffer.from('chronicle bit'))
446
- var type = Signature.SIGHASH_ALL | Signature.SIGHASH_FORKID | Signature.SIGHASH_CHRONICLE
447
- var sig = bsv.crypto.ECDSA.sign(hashbuf, priv)
448
- sig.nhashtype = type
449
-
450
- var interp = new Interpreter()
451
- interp.set({ flags: Interpreter.SCRIPT_ENABLE_SIGHASH_FORKID | Interpreter.SCRIPT_VERIFY_STRICTENC })
452
- interp.checkSignatureEncoding(sig.toTxFormat()).should.equal(false)
453
- interp.errstr.should.equal('SCRIPT_ERR_ILLEGAL_CHRONICLE')
454
-
455
- // With Chronicle in force it is allowed.
456
- var ok = new Interpreter()
457
- ok.set({
458
- flags: Interpreter.SCRIPT_ENABLE_SIGHASH_FORKID |
459
- Interpreter.SCRIPT_VERIFY_STRICTENC | Interpreter.SCRIPT_CHRONICLE
460
- })
461
- ok.checkSignatureEncoding(sig.toTxFormat()).should.equal(true)
462
- })
463
- })
464
-
465
- describe('mainnet consensus helpers', function () {
466
- var BN2 = bsv.crypto.BN
467
-
468
- // useMainnetConsensus() mutates process-wide statics, so the limits are saved
469
- // and restored around every case here. Without this the raised caps leak into
470
- // every later test in the run — 27 of them, when it was first written.
471
- var savedLimits
472
- beforeEach(function () { savedLimits = Interpreter.getLimits() })
473
- afterEach(function () { Interpreter.setLimits(savedLimits) })
474
-
475
- // Genesis reverted CLTV/CSV to OP_NOP2/OP_NOP3, and the node ignores their flags
476
- // once the UTXO is post-Genesis:
477
- // if (!(flags & SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY) || utxo_after_genesis)
478
- // Including them made mainnetFlags() reject scripts mainnet accepts.
479
- it('mainnetFlags omits CLTV and CSV', function () {
480
- var f = Interpreter.mainnetFlags()
481
- ;(f & Interpreter.SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY).should.equal(0)
482
- ;(f & Interpreter.SCRIPT_VERIFY_CHECKSEQUENCEVERIFY).should.equal(0)
483
- })
484
-
485
- it('mainnetFlags accepts a CLTV script, as mainnet does', function () {
486
- var lock = new Script()
487
- .add(new BN2(500000000).toScriptNumBuffer())
488
- .add(Opcode.OP_CHECKLOCKTIMEVERIFY)
489
- .add(Opcode.OP_DROP)
490
- .add(Opcode.OP_1)
491
- var tx = new bsv.Transaction()
492
- tx.version = 2
493
- var interp = new Interpreter()
494
- interp.verify(new Script(), lock, tx, 0, Interpreter.mainnetFlags(), new BN2(0))
495
- .should.equal(true)
496
- interp.errstr.should.equal('')
497
- })
498
-
499
- it('mainnetFlags accepts a CSV script, as mainnet does', function () {
500
- var lock = new Script()
501
- .add(new BN2(1000).toScriptNumBuffer())
502
- .add(Opcode.OP_CHECKSEQUENCEVERIFY)
503
- .add(Opcode.OP_DROP)
504
- .add(Opcode.OP_1)
505
- var tx = new bsv.Transaction()
506
- tx.version = 2
507
- var interp = new Interpreter()
508
- interp.verify(new Script(), lock, tx, 0, Interpreter.mainnetFlags(), new BN2(0))
509
- .should.equal(true)
510
- })
511
-
512
- // The flags still exist for pre-Genesis emulation — that capability is retained,
513
- // it is simply not what mainnet does.
514
- it('the CLTV flag still enforces when a caller asks for it', function () {
515
- var lock = new Script()
516
- .add(new BN2(500000000).toScriptNumBuffer())
517
- .add(Opcode.OP_CHECKLOCKTIMEVERIFY)
518
- .add(Opcode.OP_DROP)
519
- .add(Opcode.OP_1)
520
- var tx = new bsv.Transaction()
521
- tx.version = 2
522
- var interp = new Interpreter()
523
- interp.verify(new Script(), lock, tx, 0,
524
- Interpreter.SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY, new BN2(0)).should.equal(false)
525
- interp.errstr.should.match(/UNSATISFIED_LOCKTIME/)
526
- })
527
-
528
- // Flags and limits are separate mechanisms; mainnetFlags() cannot set the statics.
529
- // A script over the pre-Genesis 10,000-byte cap is valid on mainnet.
530
- it('useMainnetConsensus lifts the limits that mainnetFlags cannot', function () {
531
- var big = new Script()
532
- for (var i = 0; i < 400; i++) big.add(Buffer.alloc(30, 1)).add(Opcode.OP_DROP)
533
- big.add(Opcode.OP_1)
534
- big.toBuffer().length.should.be.above(10000)
535
-
536
- var flags = Interpreter.useMainnetConsensus()
537
- var interp = new Interpreter()
538
- interp.verify(new Script(), big, new bsv.Transaction(), 0, flags, new BN2(0))
539
- .should.equal(true)
540
- Interpreter.MAX_SCRIPT_SIZE.should.be.above(10000)
541
- })
542
- })
543
- })