@smartledger/bsv 9.13.0 → 9.15.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.
- package/CHANGELOG.md +125 -0
- package/README.md +19 -19
- package/bsv-gdaf.min.js +44 -44
- package/bsv-ltp.min.js +22 -22
- package/bsv-smartcontract.min.js +1 -1
- package/bsv.bundle.js +44 -44
- package/bsv.d.ts +26 -4
- package/bsv.min.js +44 -44
- package/docs/AUDIT_SCOPE.md +8 -8
- package/docs/MODULE_REFERENCE_COMPLETE.md +27 -27
- package/docs/advanced/UTXO_MANAGER_GUIDE.md +1 -1
- package/docs/audit-rfq/cure53.txt +2 -2
- package/docs/audit-rfq/ncc-group.txt +2 -2
- package/docs/audit-rfq/trail-of-bits.txt +2 -2
- package/docs/getting-started/INSTALLATION.md +23 -23
- package/docs/getting-started/QUICK_START.md +7 -7
- package/docs/migration/FROM_BSV_1_5_6.md +5 -5
- package/lib/notaryhash/index.js +8 -3
- package/lib/script/interpreter.js +93 -24
- package/lib/spv/merkleproof.js +63 -4
- package/package.json +1 -1
- package/tools/sv-vector-harness.js +11 -0
- package/version.js +1 -1
package/lib/spv/merkleproof.js
CHANGED
|
@@ -99,6 +99,50 @@ function targetLimit (powLimit) {
|
|
|
99
99
|
return target
|
|
100
100
|
}
|
|
101
101
|
|
|
102
|
+
/**
|
|
103
|
+
* A floor given in DIFFICULTY as the work it means: difficulty x 4,295,032,833, exactly.
|
|
104
|
+
*
|
|
105
|
+
* `minWork` counts hashes, and difficulty is the unit people actually quote — a real BSV
|
|
106
|
+
* header is "difficulty 2.6e10", not "1.1e20 hashes". Reading one as the other sets a floor
|
|
107
|
+
* 4.3 billion times too low and fails OPEN, which is why the unit is in the name. The
|
|
108
|
+
* multiplication is done on integers so a fractional difficulty keeps its digits instead of
|
|
109
|
+
* drifting through a float.
|
|
110
|
+
*/
|
|
111
|
+
function workFromDifficulty (difficulty) {
|
|
112
|
+
var text = typeof difficulty === 'number' ? numberToDecimal(difficulty) : String(difficulty)
|
|
113
|
+
// `1e19` is how a floor this size is written, by hand and by JSON, so both a Number and a
|
|
114
|
+
// string may arrive in exponent form. Expanded by moving the point, never through a float.
|
|
115
|
+
if (/^[0-9]+(\.[0-9]+)?[eE][+]?[0-9]+$/.test(text)) text = expandExponent(text)
|
|
116
|
+
if (!/^[0-9]+(\.[0-9]+)?$/.test(text)) {
|
|
117
|
+
throw new Error('minDifficulty must be a non-negative decimal number, not ' +
|
|
118
|
+
JSON.stringify(difficulty))
|
|
119
|
+
}
|
|
120
|
+
var parts = text.split('.')
|
|
121
|
+
var frac = parts[1] || ''
|
|
122
|
+
var scaled = new BN(parts[0] + frac, 10).mul(workFromTarget(targetFromBits(POW_LIMIT_BITS)))
|
|
123
|
+
return frac.length ? scaled.div(new BN(10).pow(new BN(frac.length))) : scaled
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/** `2.557e10` as `25570000000`, by moving the decimal point, with no float in the path. */
|
|
127
|
+
function expandExponent (text) {
|
|
128
|
+
var halves = text.split(/[eE]/)
|
|
129
|
+
var exp = parseInt(halves[1].replace('+', ''), 10)
|
|
130
|
+
var digits = halves[0].split('.')
|
|
131
|
+
var intPart = digits[0]
|
|
132
|
+
var frac = digits[1] || ''
|
|
133
|
+
if (exp >= frac.length) return intPart + frac + new Array(exp - frac.length + 1).join('0')
|
|
134
|
+
return intPart + frac.slice(0, exp) + '.' + frac.slice(exp)
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/** A Number as plain decimal digits, so 2.6e10 does not reach the parser as "2.6e+10". */
|
|
138
|
+
function numberToDecimal (n) {
|
|
139
|
+
if (!Number.isFinite(n) || n < 0) {
|
|
140
|
+
throw new Error('minDifficulty must be a non-negative finite number, not ' + String(n))
|
|
141
|
+
}
|
|
142
|
+
if (!/e/i.test(String(n))) return String(n)
|
|
143
|
+
return n.toLocaleString('en-US', { useGrouping: false, maximumFractionDigits: 20 })
|
|
144
|
+
}
|
|
145
|
+
|
|
102
146
|
/**
|
|
103
147
|
* `minWork` as a BN, refusing anything bn.js would read loosely. It parses `1e21` as
|
|
104
148
|
* 23521, `'4.3e9'` as 4 and `'abc'` as 1122, so a floor set from a Number near the
|
|
@@ -216,8 +260,10 @@ function verifyMerkleProof (proof) {
|
|
|
216
260
|
* header: a bsv.BlockHeader, an 80-byte Buffer, or 80-byte hex.
|
|
217
261
|
* powLimit: the easiest target a header may declare, as compact bits (number or hex
|
|
218
262
|
* string) or a BN target. Default 0x1d00ffff. Regtest needs 0x207fffff.
|
|
219
|
-
* minWork: minimum work the header must represent (number, decimal string or
|
|
220
|
-
* 2^256 / (target + 1). Difficulty 1 is about 4.295e9.
|
|
263
|
+
* minWork: minimum work the header must represent, in HASHES (number, decimal string or
|
|
264
|
+
* BN): 2^256 / (target + 1). Difficulty 1 is about 4.295e9.
|
|
265
|
+
* minDifficulty: the same floor in DIFFICULTY, which is the unit difficulty is quoted in
|
|
266
|
+
* (a real BSV header is about 2.6e10). Exactly one of the two, or neither.
|
|
221
267
|
* With `requirePow: false` the work checks are not performed at all: `targetAllowed` and
|
|
222
268
|
* `workSufficient` report true because nothing objected, and `powLimit`/`minWork` are not
|
|
223
269
|
* even read.
|
|
@@ -240,8 +286,20 @@ function verifyTxInclusion (params) {
|
|
|
240
286
|
// when the work checks are off.
|
|
241
287
|
var targetAllowed = target !== null &&
|
|
242
288
|
(!requirePow || target.cmp(targetLimit(params.powLimit)) <= 0)
|
|
243
|
-
var
|
|
244
|
-
|
|
289
|
+
var floor = null
|
|
290
|
+
if (requirePow) {
|
|
291
|
+
// One floor, named for its unit. Accepting both would leave the caller guessing which
|
|
292
|
+
// one bit, and the two are 4.3e9 apart.
|
|
293
|
+
if (params.minWork !== undefined && params.minWork !== null &&
|
|
294
|
+
params.minDifficulty !== undefined && params.minDifficulty !== null) {
|
|
295
|
+
throw new Error('pass minWork (hashes) or minDifficulty (difficulty), not both')
|
|
296
|
+
}
|
|
297
|
+
if (params.minWork !== undefined && params.minWork !== null) floor = minWorkBN(params.minWork)
|
|
298
|
+
else if (params.minDifficulty !== undefined && params.minDifficulty !== null) {
|
|
299
|
+
floor = workFromDifficulty(params.minDifficulty)
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
var workSufficient = floor === null || work.cmp(floor) >= 0
|
|
245
303
|
|
|
246
304
|
return {
|
|
247
305
|
valid: rootMatches && (!requirePow || (powValid && targetAllowed && workSufficient)),
|
|
@@ -262,6 +320,7 @@ module.exports = {
|
|
|
262
320
|
targetFromBits: targetFromBits,
|
|
263
321
|
targetLimit: targetLimit,
|
|
264
322
|
workFromTarget: workFromTarget,
|
|
323
|
+
workFromDifficulty: workFromDifficulty,
|
|
265
324
|
headerSnapshot: headerSnapshot,
|
|
266
325
|
merkleRootFromBranch: merkleRootFromBranch,
|
|
267
326
|
verifyMerkleProof: verifyMerkleProof,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@smartledger/bsv",
|
|
3
|
-
"version": "9.
|
|
3
|
+
"version": "9.15.0",
|
|
4
4
|
"description": "Bitcoin SV library with an interpreter-verified script engine: OP_PUSH_TX covenants, BIP-143 preimage tooling, and consensus flags that match what miners actually enforce. Also ships DID:web / W3C VC-JWT credentials and the Legal Token Protocol.",
|
|
5
5
|
"author": "SmartLedger Technology <hello@smartledger.technology> (https://smartledger.technology)",
|
|
6
6
|
"homepage": "https://github.com/codenlighten/smartledger-bsv#readme",
|
|
@@ -184,6 +184,17 @@ function classifyFlags (flagStr) {
|
|
|
184
184
|
* only the spending transaction carries the version under test.
|
|
185
185
|
*/
|
|
186
186
|
function evaluate (row, flags) {
|
|
187
|
+
// DoTest's one flag adjustment, which the rows themselves do not state:
|
|
188
|
+
//
|
|
189
|
+
// if(flags & SCRIPT_VERIFY_CLEANSTACK) flags |= SCRIPT_VERIFY_P2SH;
|
|
190
|
+
//
|
|
191
|
+
// Without it a row naming CLEANSTACK alone is verified under a flag set the node refuses
|
|
192
|
+
// outright, so it fails for the wrong reason and the row silently stops testing clean
|
|
193
|
+
// stacks at all.
|
|
194
|
+
if ((flags & Interpreter.SCRIPT_VERIFY_CLEANSTACK) !== 0) {
|
|
195
|
+
flags |= Interpreter.SCRIPT_VERIFY_P2SH
|
|
196
|
+
}
|
|
197
|
+
|
|
187
198
|
const scriptSig = fromBitcoindString(row.scriptSig)
|
|
188
199
|
const scriptPubKey = fromBitcoindString(row.scriptPubKey)
|
|
189
200
|
|
package/version.js
CHANGED