@bsv/wallet-toolbox 1.6.14 → 1.6.15

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bsv/wallet-toolbox",
3
- "version": "1.6.14",
3
+ "version": "1.6.15",
4
4
  "description": "BRC100 conforming wallet, wallet storage and wallet signer components",
5
5
  "main": "./out/src/index.js",
6
6
  "types": "./out/src/index.d.ts",
@@ -72,6 +72,81 @@ export class BulkFileDataManager {
72
72
  this.deleteBulkFilesNoLock()
73
73
  }
74
74
 
75
+ async deleteBulkFiles(): Promise<void> {
76
+ return this.lock.withWriteLock(async () => this.deleteBulkFilesNoLock())
77
+ }
78
+
79
+ private deleteBulkFilesNoLock(): void {
80
+ this.bfds = []
81
+ this.fileHashToIndex = {}
82
+
83
+ if (this.fromKnownSourceUrl) {
84
+ const vbhfs = validBulkHeaderFiles
85
+ const filtered = vbhfs.filter(f => f.sourceUrl === this.fromKnownSourceUrl)
86
+ const files = selectBulkHeaderFiles(filtered, this.chain, this.maxPerFile)
87
+ for (const file of files) {
88
+ this.add({ ...file, fileHash: file.fileHash!, mru: Date.now() })
89
+ }
90
+ }
91
+ }
92
+
93
+ /**
94
+ * If `bfds` are going to be backed by persistent storage,
95
+ * must be called before making storage available.
96
+ *
97
+ * Synchronizes bfds and storage files, after which this manager maintains sync.
98
+ * There should be no changes to bulk files by direct access to storage bulk file methods.
99
+ */
100
+ async setStorage(storage: ChaintracksStorageBulkFileApi, log: (...args: any[]) => void): Promise<void> {
101
+ return this.lock.withWriteLock(async () => this.setStorageNoLock(storage, log))
102
+ }
103
+
104
+ private async setStorageNoLock(storage: ChaintracksStorageBulkFileApi, log: (...args: any[]) => void): Promise<void> {
105
+ this.storage = storage
106
+ this.log = log
107
+
108
+ // Get files currently in persistent storage.
109
+ let sfs = await this.storage.getBulkFiles()
110
+
111
+ // Sync bfds with storage. Two scenarios supported:
112
+
113
+ const bfdsRanges = this.heightRangesFromBulkFiles(this.bfds)
114
+ const sfsRanges = this.heightRangesFromBulkFiles(sfs)
115
+
116
+ if (sfsRanges.cdn.length >= bfdsRanges.cdn.length) {
117
+ // Storage win if it has greater or equal CDN coverage
118
+ // Replace all bfds with sfs
119
+ this.bfds = []
120
+ for (const file of sfs) {
121
+ const vbf: BulkFileData = await this.validateFileInfo(file)
122
+ this.bfds.push(vbf)
123
+ }
124
+ } else {
125
+ // Bfds win if they have greater CDN coverage
126
+ // Replace all sfs with bfds
127
+ for (const s of sfs.reverse()) await this.storage.deleteBulkFile(s.fileId!)
128
+ for (const bfd of this.bfds) {
129
+ await this.ensureData(bfd)
130
+ bfd.fileId = await this.storage.insertBulkFile(bfdToInfo(bfd, true))
131
+ }
132
+ }
133
+ }
134
+
135
+ heightRangesFromBulkFiles(files: BulkHeaderFileInfo[]): {
136
+ all: HeightRange
137
+ cdn: HeightRange
138
+ incremental: HeightRange
139
+ } {
140
+ const ranges = { all: new HeightRange(0, -1), cdn: new HeightRange(0, -1), incremental: new HeightRange(0, -1) }
141
+ for (const file of files) {
142
+ const range = new HeightRange(file.firstHeight, file.firstHeight + file.count - 1)
143
+ ranges.all = ranges.all.union(range)
144
+ if (isBdfCdn(file)) ranges.cdn = ranges.cdn.union(range)
145
+ if (isBdfIncremental(file)) ranges.incremental = ranges.incremental.union(range)
146
+ }
147
+ return ranges
148
+ }
149
+
75
150
  async createReader(range?: HeightRange, maxBufferSize?: number): Promise<BulkFileDataReader> {
76
151
  range = range || (await this.getHeightRange())
77
152
  maxBufferSize = maxBufferSize || 1000000 * 80 // 100,000 headers, 8MB
@@ -114,56 +189,6 @@ export class BulkFileDataManager {
114
189
  this.log(log)
115
190
  }
116
191
 
117
- async setStorage(storage: ChaintracksStorageBulkFileApi, log: (...args: any[]) => void): Promise<void> {
118
- return this.lock.withWriteLock(async () => this.setStorageNoLock(storage, log))
119
- }
120
-
121
- private async setStorageNoLock(storage: ChaintracksStorageBulkFileApi, log: (...args: any[]) => void): Promise<void> {
122
- this.storage = storage
123
- this.log = log
124
- // Sync bfds with storage. Two scenarios supported:
125
- let sfs = await this.storage.getBulkFiles()
126
- const lastCdnBfd = this.bfds.filter(f => isBdfCdn(f)).slice(-1)[0]
127
- const lastCdnSfs = sfs.filter(f => isBdfCdn(f)).slice(-1)[0]
128
- if (
129
- lastCdnBfd &&
130
- lastCdnSfs &&
131
- lastCdnBfd.firstHeight + lastCdnBfd.count > lastCdnSfs.firstHeight + lastCdnSfs.count
132
- ) {
133
- // Storage has fewer cdn headers than bfds, clear them and try again.
134
- for (const s of sfs.reverse()) await this.storage.deleteBulkFile(s.fileId!)
135
- sfs = []
136
- }
137
- if (sfs.length === 0) {
138
- // 1. Storage has no files: Update storage to reflect bfds.
139
- for (const bfd of this.bfds) {
140
- await this.ensureData(bfd)
141
- bfd.fileId = await this.storage.insertBulkFile(bfdToInfo(bfd, true))
142
- }
143
- } else {
144
- // 2. bfds are a prefix of storage, including last bfd having same firstHeight but possibly fewer headers: Merge storage to bfds.
145
- const r = await this.mergeNoLock(sfs)
146
- }
147
- }
148
-
149
- async deleteBulkFiles(): Promise<void> {
150
- return this.lock.withWriteLock(async () => this.deleteBulkFilesNoLock())
151
- }
152
-
153
- private deleteBulkFilesNoLock(): void {
154
- this.bfds = []
155
- this.fileHashToIndex = {}
156
-
157
- if (this.fromKnownSourceUrl) {
158
- const vbhfs = validBulkHeaderFiles
159
- const filtered = vbhfs.filter(f => f.sourceUrl === this.fromKnownSourceUrl)
160
- const files = selectBulkHeaderFiles(filtered, this.chain, this.maxPerFile)
161
- for (const file of files) {
162
- this.add({ ...file, fileHash: file.fileHash!, mru: Date.now() })
163
- }
164
- }
165
- }
166
-
167
192
  async merge(files: BulkHeaderFileInfo[]): Promise<BulkFileDataManagerMergeResult> {
168
193
  return this.lock.withWriteLock(async () => this.mergeNoLock(files))
169
194
  }