@bsv/overlay 0.1.8 → 0.1.10

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 (80) hide show
  1. package/dist/cjs/package.json +2 -2
  2. package/dist/cjs/src/Engine.js +153 -493
  3. package/dist/cjs/src/Engine.js.map +1 -1
  4. package/dist/cjs/src/GASP/OverlayGASPRemote.js +6 -4
  5. package/dist/cjs/src/GASP/OverlayGASPRemote.js.map +1 -1
  6. package/dist/cjs/src/GASP/OverlayGASPStorage.js +152 -77
  7. package/dist/cjs/src/GASP/OverlayGASPStorage.js.map +1 -1
  8. package/dist/cjs/src/storage/knex/KnexStorage.js +106 -38
  9. package/dist/cjs/src/storage/knex/KnexStorage.js.map +1 -1
  10. package/dist/cjs/src/storage/knex/all-migrations.js +5 -1
  11. package/dist/cjs/src/storage/knex/all-migrations.js.map +1 -1
  12. package/dist/cjs/src/storage/knex/migrations/2024-07-17-001-transactions.js +39 -0
  13. package/dist/cjs/src/storage/knex/migrations/2024-07-17-001-transactions.js.map +1 -0
  14. package/dist/cjs/src/storage/knex/migrations/2024-07-18-001-indexes.js +34 -0
  15. package/dist/cjs/src/storage/knex/migrations/2024-07-18-001-indexes.js.map +1 -0
  16. package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
  17. package/dist/esm/src/Engine.js +151 -492
  18. package/dist/esm/src/Engine.js.map +1 -1
  19. package/dist/esm/src/GASP/OverlayGASPRemote.js +7 -4
  20. package/dist/esm/src/GASP/OverlayGASPRemote.js.map +1 -1
  21. package/dist/esm/src/GASP/OverlayGASPStorage.js +151 -77
  22. package/dist/esm/src/GASP/OverlayGASPStorage.js.map +1 -1
  23. package/dist/esm/src/storage/knex/KnexStorage.js +106 -38
  24. package/dist/esm/src/storage/knex/KnexStorage.js.map +1 -1
  25. package/dist/esm/src/storage/knex/all-migrations.js +5 -1
  26. package/dist/esm/src/storage/knex/all-migrations.js.map +1 -1
  27. package/dist/esm/src/storage/knex/migrations/2024-07-17-001-transactions.js +34 -0
  28. package/dist/esm/src/storage/knex/migrations/2024-07-17-001-transactions.js.map +1 -0
  29. package/dist/esm/src/storage/knex/migrations/2024-07-18-001-indexes.js +29 -0
  30. package/dist/esm/src/storage/knex/migrations/2024-07-18-001-indexes.js.map +1 -0
  31. package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
  32. package/dist/types/src/Engine.d.ts +10 -117
  33. package/dist/types/src/Engine.d.ts.map +1 -1
  34. package/dist/types/src/GASP/OverlayGASPRemote.d.ts +3 -2
  35. package/dist/types/src/GASP/OverlayGASPRemote.d.ts.map +1 -1
  36. package/dist/types/src/GASP/OverlayGASPStorage.d.ts +29 -3
  37. package/dist/types/src/GASP/OverlayGASPStorage.d.ts.map +1 -1
  38. package/dist/types/src/Output.d.ts +2 -2
  39. package/dist/types/src/Output.d.ts.map +1 -1
  40. package/dist/types/src/storage/Storage.d.ts +6 -8
  41. package/dist/types/src/storage/Storage.d.ts.map +1 -1
  42. package/dist/types/src/storage/knex/KnexStorage.d.ts +4 -4
  43. package/dist/types/src/storage/knex/KnexStorage.d.ts.map +1 -1
  44. package/dist/types/src/storage/knex/all-migrations.d.ts.map +1 -1
  45. package/dist/types/src/storage/knex/migrations/2024-07-17-001-transactions.d.ts +4 -0
  46. package/dist/types/src/storage/knex/migrations/2024-07-17-001-transactions.d.ts.map +1 -0
  47. package/dist/types/src/storage/knex/migrations/2024-07-18-001-indexes.d.ts +4 -0
  48. package/dist/types/src/storage/knex/migrations/2024-07-18-001-indexes.d.ts.map +1 -0
  49. package/dist/types/tsconfig.types.tsbuildinfo +1 -1
  50. package/package.json +2 -2
  51. package/src/Engine.ts +160 -552
  52. package/src/GASP/OverlayGASPRemote.ts +107 -0
  53. package/src/GASP/OverlayGASPStorage.ts +331 -0
  54. package/src/Output.ts +2 -2
  55. package/src/__tests/Engine.test.ts +27 -26
  56. package/src/__tests/OverlayGASPRemote.test.ts +1 -1
  57. package/src/__tests/OverlayGASPStorage.test.ts +4 -3
  58. package/src/storage/Storage.ts +6 -8
  59. package/src/storage/knex/KnexStorage.ts +119 -41
  60. package/src/storage/knex/all-migrations.ts +10 -6
  61. package/src/storage/knex/migrations/2024-07-17-001-transactions.ts +40 -0
  62. package/src/storage/knex/migrations/2024-07-18-001-indexes.ts +30 -0
  63. package/dist/cjs/src/GASP.js +0 -275
  64. package/dist/cjs/src/GASP.js.map +0 -1
  65. package/dist/cjs/src/SHIPAdvertisement.js +0 -3
  66. package/dist/cjs/src/SHIPAdvertisement.js.map +0 -1
  67. package/dist/cjs/src/SLAPAdvertisement.js +0 -3
  68. package/dist/cjs/src/SLAPAdvertisement.js.map +0 -1
  69. package/dist/esm/src/GASP.js +0 -279
  70. package/dist/esm/src/GASP.js.map +0 -1
  71. package/dist/esm/src/SHIPAdvertisement.js +0 -2
  72. package/dist/esm/src/SHIPAdvertisement.js.map +0 -1
  73. package/dist/esm/src/SLAPAdvertisement.js +0 -2
  74. package/dist/esm/src/SLAPAdvertisement.js.map +0 -1
  75. package/dist/types/src/GASP.d.ts +0 -215
  76. package/dist/types/src/GASP.d.ts.map +0 -1
  77. package/dist/types/src/SHIPAdvertisement.d.ts +0 -9
  78. package/dist/types/src/SHIPAdvertisement.d.ts.map +0 -1
  79. package/dist/types/src/SLAPAdvertisement.d.ts +0 -9
  80. package/dist/types/src/SLAPAdvertisement.d.ts.map +0 -1
@@ -9,38 +9,79 @@ export class KnexStorage implements Storage {
9
9
  this.knex = knex
10
10
  }
11
11
 
12
- async findOutput(txid: string, outputIndex: number, topic?: string, spent?: boolean): Promise<Output | null> {
12
+ async findOutput(txid: string, outputIndex: number, topic?: string, spent?: boolean, includeBEEF: boolean = false): Promise<Output | null> {
13
13
  const search: {
14
- txid: string
15
- outputIndex: number
16
- topic?: string
17
- spent?: boolean
14
+ 'outputs.txid': string
15
+ 'outputs.outputIndex': number
16
+ 'outputs.topic'?: string
17
+ 'outputs.spent'?: boolean
18
18
  } = {
19
- txid,
20
- outputIndex
19
+ 'outputs.txid': txid,
20
+ 'outputs.outputIndex': outputIndex
21
+ }
22
+ if (topic !== undefined) search['outputs.topic'] = topic
23
+ if (spent !== undefined) search['outputs.spent'] = spent
24
+
25
+ // Base query to get the output
26
+ const query = this.knex('outputs').where(search)
27
+
28
+ // Select necessary fields from outputs and conditionally include beef from transactions
29
+ const selectFields = [
30
+ 'outputs.txid',
31
+ 'outputs.outputIndex',
32
+ 'outputs.outputScript',
33
+ 'outputs.topic',
34
+ 'outputs.satoshis',
35
+ 'outputs.outputsConsumed',
36
+ 'outputs.spent',
37
+ 'outputs.consumedBy'
38
+ ]
39
+
40
+ if (includeBEEF) {
41
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
42
+ query.leftJoin('transactions', 'outputs.txid', 'transactions.txid')
43
+ selectFields.push('transactions.beef')
21
44
  }
22
- if (topic !== undefined) search.topic = topic
23
- if (spent !== undefined) search.spent = spent
24
- const [output] = await this.knex('outputs').where(search).select(
25
- 'txid', 'outputIndex', 'outputScript', 'topic', 'satoshis', 'beef', 'outputsConsumed', 'spent', 'consumedBy'
26
- )
45
+
46
+ const output = await query.select(selectFields).first()
47
+
27
48
  if (output === undefined || output === null) {
28
49
  return null
29
50
  }
51
+
30
52
  return {
31
53
  ...output,
32
54
  outputScript: [...output.outputScript],
33
- beef: [...output.beef],
55
+ beef: includeBEEF ? (output.beef !== undefined ? [...output.beef] : undefined) : undefined,
34
56
  spent: Boolean(output.spent),
35
57
  outputsConsumed: JSON.parse(output.outputsConsumed),
36
58
  consumedBy: JSON.parse(output.consumedBy)
37
59
  }
38
60
  }
39
61
 
40
- async findOutputsForTransaction(txid: string): Promise<Output[]> {
41
- const outputs = await this.knex('outputs').where({ txid }).select(
42
- 'txid', 'outputIndex', 'outputScript', 'topic', 'satoshis', 'beef', 'outputsConsumed', 'spent', 'consumedBy'
43
- )
62
+ async findOutputsForTransaction(txid: string, includeBEEF: boolean = false): Promise<Output[]> {
63
+ // Base query to get outputs
64
+ const query = this.knex('outputs').where({ 'outputs.txid': txid })
65
+
66
+ // Select necessary fields from outputs and conditionally include beef from transactions
67
+ const selectFields = [
68
+ 'outputs.txid',
69
+ 'outputs.outputIndex',
70
+ 'outputs.outputScript',
71
+ 'outputs.topic',
72
+ 'outputs.satoshis',
73
+ 'outputs.outputsConsumed',
74
+ 'outputs.spent',
75
+ 'outputs.consumedBy'
76
+ ]
77
+
78
+ if (includeBEEF) {
79
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
80
+ query.leftJoin('transactions', 'outputs.txid', 'transactions.txid')
81
+ selectFields.push('transactions.beef')
82
+ }
83
+
84
+ const outputs = await query.select(selectFields)
44
85
 
45
86
  if (outputs === undefined || outputs.length === 0) {
46
87
  return []
@@ -49,24 +90,42 @@ export class KnexStorage implements Storage {
49
90
  return outputs.map(output => ({
50
91
  ...output,
51
92
  outputScript: [...output.outputScript],
52
- beef: [...output.beef],
93
+ beef: includeBEEF ? (output.beef !== undefined ? [...output.beef] : undefined) : undefined,
53
94
  spent: Boolean(output.spent),
54
95
  outputsConsumed: JSON.parse(output.outputsConsumed),
55
96
  consumedBy: JSON.parse(output.consumedBy)
56
97
  }))
57
98
  }
58
99
 
59
- async findUTXOsForTopic(topic: string, since?: number): Promise<Output[]> {
60
- const query = this.knex('outputs').where({ topic, spent: false })
100
+ async findUTXOsForTopic(topic: string, since?: number, includeBEEF: boolean = false): Promise<Output[]> {
101
+ // Base query to get outputs
102
+ const query = this.knex('outputs').where({ 'outputs.topic': topic, 'outputs.spent': false })
61
103
 
62
104
  // If provided, additionally filters UTXOs by block height
63
105
  if (since !== undefined && since > 0) {
64
- await query.andWhere('blockHeight', '>=', since)
106
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
107
+ query.andWhere('outputs.blockHeight', '>=', since)
108
+ }
109
+
110
+ // Select necessary fields from outputs and conditionally include beef from transactions
111
+ const selectFields = [
112
+ 'outputs.txid',
113
+ 'outputs.outputIndex',
114
+ 'outputs.outputScript',
115
+ 'outputs.topic',
116
+ 'outputs.satoshis',
117
+ 'outputs.outputsConsumed',
118
+ 'outputs.spent',
119
+ 'outputs.consumedBy'
120
+ ]
121
+
122
+ if (includeBEEF) {
123
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
124
+ query.leftJoin('transactions', 'outputs.txid', 'transactions.txid')
125
+ selectFields.push('transactions.beef')
65
126
  }
66
127
 
67
- const outputs = await query.select(
68
- 'txid', 'outputIndex', 'outputScript', 'topic', 'satoshis', 'beef', 'outputsConsumed', 'spent', 'consumedBy'
69
- )
128
+ const outputs = await query.select(selectFields)
70
129
 
71
130
  if (outputs === undefined || outputs.length === 0) {
72
131
  return []
@@ -75,7 +134,7 @@ export class KnexStorage implements Storage {
75
134
  return outputs.map(output => ({
76
135
  ...output,
77
136
  outputScript: [...output.outputScript],
78
- beef: [...output.beef],
137
+ beef: includeBEEF ? (output.beef !== undefined ? [...output.beef] : undefined) : undefined,
79
138
  spent: Boolean(output.spent),
80
139
  outputsConsumed: JSON.parse(output.outputsConsumed),
81
140
  consumedBy: JSON.parse(output.consumedBy)
@@ -83,22 +142,42 @@ export class KnexStorage implements Storage {
83
142
  }
84
143
 
85
144
  async deleteOutput(txid: string, outputIndex: number, topic: string): Promise<void> {
86
- await this.knex('outputs').where({
87
- txid, outputIndex, topic
88
- }).del()
145
+ await this.knex.transaction(async trx => {
146
+ // Delete the specific output
147
+ await trx('outputs').where({ txid, outputIndex }).del()
148
+
149
+ // Check how many outputs reference the same transaction
150
+ const remainingOutputs = await trx('outputs').where({ txid }).count('* as count').first()
151
+
152
+ if (remainingOutputs !== undefined && Number(remainingOutputs.count) === 0) {
153
+ // If no more outputs reference the transaction, delete the beef
154
+ await trx('transactions').where({ txid }).del()
155
+ }
156
+ })
89
157
  }
90
158
 
91
159
  async insertOutput(output: Output): Promise<void> {
92
- await this.knex('outputs').insert({
160
+ const insertPromises = [this.knex('outputs').insert({
93
161
  txid: output.txid,
94
162
  outputIndex: Number(output.outputIndex),
95
163
  outputScript: Buffer.from(output.outputScript),
96
164
  topic: output.topic,
97
165
  satoshis: Number(output.satoshis),
98
- beef: Buffer.from(output.beef),
99
166
  outputsConsumed: JSON.stringify(output.outputsConsumed),
100
167
  consumedBy: JSON.stringify(output.consumedBy),
101
168
  spent: output.spent
169
+ })]
170
+
171
+ if (output.beef !== undefined) {
172
+ const insertTransactionPromise = this.knex('transactions').insert({
173
+ txid: output.txid,
174
+ beef: Buffer.from(output.beef)
175
+ }).onConflict('txid').ignore()
176
+ insertPromises.push(insertTransactionPromise)
177
+ }
178
+
179
+ await this.knex.transaction(async trx => {
180
+ await Promise.all(insertPromises.map(promise => promise.transacting(trx)))
102
181
  })
103
182
  }
104
183
 
@@ -118,11 +197,9 @@ export class KnexStorage implements Storage {
118
197
  }).update('consumedBy', consumedBy)
119
198
  }
120
199
 
121
- async updateOutputBeef(txid: string, outputIndex: number, topic: string, beef: number[]): Promise<void> {
122
- await this.knex('outputs').where({
123
- txid,
124
- outputIndex,
125
- topic
200
+ async updateTransactionBEEF(txid: string, beef: number[]): Promise<void> {
201
+ await this.knex('transactions').where({
202
+ txid
126
203
  }).update('beef', Buffer.from(beef))
127
204
  }
128
205
 
@@ -142,10 +219,11 @@ export class KnexStorage implements Storage {
142
219
  }
143
220
 
144
221
  async doesAppliedTransactionExist(tx: { txid: string, topic: string }): Promise<boolean> {
145
- const appliedTransactions = await this.knex('applied_transactions').where({
146
- txid: tx.txid,
147
- topic: tx.topic
148
- }).select('txid', 'topic')
149
- return appliedTransactions.length > 0
222
+ const result = await this.knex('applied_transactions')
223
+ .where({ txid: tx.txid, topic: tx.topic })
224
+ .select(this.knex.raw('1'))
225
+ .first()
226
+
227
+ return !!result
150
228
  }
151
- }
229
+ }
@@ -1,17 +1,21 @@
1
1
  import { Knex } from 'knex'
2
2
  import { up as initialSchemaUp, down as initialSchemaDown } from './migrations/2024-05-18-001-initial.js'
3
3
  import { up as addBlockHeightColumnUp, down as addBlockHeightColumnDown } from './migrations/2024-07-10-001-block-height.js'
4
+ import { up as addTransactionsTableUp, down as addTransactionsTableDown } from './migrations/2024-07-17-001-transactions.js'
5
+ import { up as addedIndexesUp, down as addedIndexesDown } from './migrations/2024-07-18-001-indexes.js'
4
6
 
5
7
  /**
6
8
  * An array of all migrations, in order.
7
9
  */
8
10
  type Migration = {
9
- up: (knex: Knex) => Promise<void>;
10
- down: (knex: Knex) => Promise<void>;
11
- };
11
+ up: (knex: Knex) => Promise<void>
12
+ down: (knex: Knex) => Promise<void>
13
+ }
12
14
 
13
15
  const allMigrations: Migration[] = [
14
16
  { up: initialSchemaUp, down: initialSchemaDown },
15
- { up: addBlockHeightColumnUp, down: addBlockHeightColumnDown }
16
- ];
17
- export default allMigrations
17
+ { up: addBlockHeightColumnUp, down: addBlockHeightColumnDown },
18
+ { up: addTransactionsTableUp, down: addTransactionsTableDown },
19
+ { up: addedIndexesUp, down: addedIndexesDown }
20
+ ]
21
+ export default allMigrations
@@ -0,0 +1,40 @@
1
+ import type { Knex } from 'knex'
2
+
3
+ export async function up(knex: Knex): Promise<void> {
4
+ // Create the new transactions table
5
+ await knex.schema.createTable('transactions', table => {
6
+ table.increments()
7
+ table.specificType('beef', 'longblob')
8
+ table.string('txid', 64).unique()
9
+ })
10
+
11
+ // Move data from outputs table to the new transactions table and ensure deduplication
12
+ await knex.raw(`
13
+ INSERT IGNORE INTO transactions (txid, beef)
14
+ SELECT txid, beef
15
+ FROM outputs
16
+ WHERE beef IS NOT NULL
17
+ `)
18
+
19
+ // Drop the beef column from the outputs table
20
+ await knex.schema.table('outputs', table => {
21
+ table.dropColumn('beef')
22
+ })
23
+ }
24
+
25
+ export async function down(knex: Knex): Promise<void> {
26
+ // Add the beef column back to the outputs table
27
+ await knex.schema.table('outputs', table => {
28
+ table.binary('beef')
29
+ })
30
+
31
+ // Move data back from the transactions table to the outputs table using a JOIN
32
+ await knex.raw(`
33
+ UPDATE outputs
34
+ JOIN transactions ON outputs.txid = transactions.txid
35
+ SET outputs.beef = transactions.beef
36
+ `)
37
+
38
+ // Drop the transactions table
39
+ await knex.schema.dropTable('transactions')
40
+ }
@@ -0,0 +1,30 @@
1
+ import type { Knex } from 'knex'
2
+ export async function up(knex: Knex): Promise<void> {
3
+ // Add index for applied_transactions table
4
+ await knex.schema.table('applied_transactions', function (table) {
5
+ table.index(['txid', 'topic'], 'idx_applied_transactions_txid_topic')
6
+ })
7
+ // Add index for transactions table
8
+ await knex.schema.table('transactions', function (table) {
9
+ table.index('txid', 'idx_transactions_txid')
10
+ })
11
+ // Add index for outputs table
12
+ await knex.schema.table('outputs', function (table) {
13
+ table.index(['txid', 'outputIndex', 'topic'], 'idx_outputs_txid_outputIndex_topic')
14
+ })
15
+ }
16
+
17
+ export async function down(knex: Knex): Promise<void> {
18
+ // Drop index for applied_transactions table
19
+ await knex.schema.table('applied_transactions', function (table) {
20
+ table.dropIndex(['txid', 'topic'], 'idx_applied_transactions_txid_topic')
21
+ })
22
+ // Drop index for transactions table
23
+ await knex.schema.table('transactions', function (table) {
24
+ table.dropIndex('txid', 'idx_transactions_txid')
25
+ })
26
+ // Drop index for outputs table
27
+ await knex.schema.table('outputs', function (table) {
28
+ table.dropIndex(['txid', 'outputIndex', 'topic'], 'idx_outputs_txid_outputIndex_topic')
29
+ })
30
+ }
@@ -1,275 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.GASP = exports.GASPVersionMismatchError = void 0;
4
- const sdk_1 = require("@bsv/sdk");
5
- class GASPVersionMismatchError extends Error {
6
- constructor(message, currentVersion, foreignVersion) {
7
- super(message);
8
- this.code = 'ERR_GASP_VERSION_MISMATCH';
9
- this.currentVersion = currentVersion;
10
- this.foreignVersion = foreignVersion;
11
- }
12
- }
13
- exports.GASPVersionMismatchError = GASPVersionMismatchError;
14
- /**
15
- * Main class implementing the Graph Aware Sync Protocol.
16
- */
17
- class GASP {
18
- /**
19
- *
20
- * @param storage The GASP Storage interface to use
21
- * @param remote The GASP Remote interface to use
22
- * @param lastInteraction The timestamp when we last interacted with this remote party
23
- */
24
- constructor(storage, remote, lastInteraction = 0, logPrefix = '[GASP] ', log = false) {
25
- this.storage = storage;
26
- this.remote = remote;
27
- this.lastInteraction = lastInteraction;
28
- this.version = 1;
29
- this.logPrefix = logPrefix;
30
- this.log = log;
31
- this.validateTimestamp(this.lastInteraction);
32
- this.logData(`GASP initialized with version: ${this.version}, lastInteraction: ${this.lastInteraction}`);
33
- }
34
- logData(...data) {
35
- if (this.log) {
36
- console.log(this.logPrefix, ...data);
37
- }
38
- }
39
- validateTimestamp(timestamp) {
40
- if (typeof timestamp !== 'number' || isNaN(timestamp) || timestamp < 0 || !Number.isInteger(timestamp)) {
41
- throw new Error('Invalid timestamp format');
42
- }
43
- }
44
- /**
45
- * Computes a 36-byte structure from a transaction ID and output index.
46
- * @param txid The transaction ID.
47
- * @param index The output index.
48
- * @returns A string representing the 36-byte structure.
49
- */
50
- compute36ByteStructure(txid, index) {
51
- const result = `${txid}.${index.toString()}`;
52
- this.logData(`Computed 36-byte structure: ${result} from txid: ${txid}, index: ${index}`);
53
- return result;
54
- }
55
- /**
56
- * Deconstructs a 36-byte structure into a transaction ID and output index.
57
- * @param outpoint The 36-byte structure.
58
- * @returns An object containing the transaction ID and output index.
59
- */
60
- deconstruct36ByteStructure(outpoint) {
61
- const [txid, index] = outpoint.split('.');
62
- const result = {
63
- txid,
64
- outputIndex: parseInt(index, 10)
65
- };
66
- this.logData(`Deconstructed 36-byte structure: ${outpoint} into txid: ${txid}, outputIndex: ${result.outputIndex}`);
67
- return result;
68
- }
69
- /**
70
- * Computes the transaction ID for a given transaction.
71
- * @param tx The transaction string.
72
- * @returns The computed transaction ID.
73
- */
74
- computeTXID(tx) {
75
- const txid = sdk_1.Transaction.fromHex(tx).id('hex');
76
- this.logData(`Computed TXID: ${txid} from transaction: ${tx}`);
77
- return txid;
78
- }
79
- /**
80
- * Synchronizes the transaction data between the local and remote participants.
81
- * TODO: Support stipulating upload, download, or bidirectional which should be default.
82
- */
83
- async sync() {
84
- this.logData(`Starting sync process. Last interaction timestamp: ${this.lastInteraction}`);
85
- debugger;
86
- const initialRequest = await this.buildInitialRequest(this.lastInteraction);
87
- const initialResponse = await this.remote.getInitialResponse(initialRequest);
88
- if (initialResponse.UTXOList.length > 0) {
89
- const foreignUTXOs = await this.storage.findKnownUTXOs(0);
90
- await Promise.all(initialResponse.UTXOList
91
- .filter(x => !foreignUTXOs.some(y => x.txid === y.txid && x.outputIndex === y.outputIndex))
92
- .map(async (UTXO) => {
93
- try {
94
- this.logData(`Requesting node for UTXO: ${JSON.stringify(UTXO)}`);
95
- const resolvedNode = await this.remote.requestNode(this.compute36ByteStructure(UTXO.txid, UTXO.outputIndex), UTXO.txid, UTXO.outputIndex, true);
96
- this.logData(`Received unspent graph node from remote: ${JSON.stringify(resolvedNode)}`);
97
- await this.processIncomingNode(resolvedNode);
98
- await this.completeGraph(resolvedNode.graphID);
99
- }
100
- catch (e) {
101
- this.logData(`Error with incoming UTXO ${UTXO.txid}.${UTXO.outputIndex}: ${e.message}`);
102
- }
103
- }));
104
- }
105
- // const initialReply = await this.getInitialReply(initialResponse)
106
- // this.logData(`Received initial reply: ${JSON.stringify(initialReply)}`)
107
- // if (initialReply.UTXOList.length > 0) {
108
- // await Promise.all(initialReply.UTXOList.map(async UTXO => {
109
- // try {
110
- // this.logData(`Hydrating GASP node for UTXO: ${JSON.stringify(UTXO)}`)
111
- // const outgoingNode = await this.storage.hydrateGASPNode(
112
- // this.compute36ByteStructure(UTXO.txid, UTXO.outputIndex),
113
- // UTXO.txid,
114
- // UTXO.outputIndex,
115
- // true
116
- // )
117
- // this.logData(`Sending unspent graph node for remote: ${JSON.stringify(outgoingNode)}`)
118
- // await this.processOutgoingNode(outgoingNode)
119
- // } catch (e) {
120
- // this.logData(`Error with outgoing UTXO ${UTXO.txid}.${UTXO.outputIndex}: ${(e as Error).message}`)
121
- // }
122
- // }))
123
- // }
124
- this.logData('Sync completed!');
125
- }
126
- /**
127
- * Builds the initial request for the sync process.
128
- * @returns A promise for the initial request object.
129
- */
130
- async buildInitialRequest(since) {
131
- const request = {
132
- version: this.version,
133
- since
134
- };
135
- this.logData(`Built initial request: ${JSON.stringify(request)}`);
136
- return request;
137
- }
138
- /**
139
- * Builds the initial response based on the received request.
140
- * @param request The initial request object.
141
- * @returns A promise for an initial response
142
- */
143
- async getInitialResponse(request) {
144
- this.logData(`Received initial request: ${JSON.stringify(request)}`);
145
- if (request.version !== this.version) {
146
- const error = new GASPVersionMismatchError(`GASP version mismatch. Current version: ${this.version}, foreign version: ${request.version}`, this.version, request.version);
147
- console.error(`GASP version mismatch error: ${error.message}`);
148
- throw error;
149
- }
150
- this.validateTimestamp(request.since);
151
- const response = {
152
- since: this.lastInteraction,
153
- UTXOList: await this.storage.findKnownUTXOs(request.since)
154
- };
155
- this.logData(`Built initial response: ${JSON.stringify(response)}`);
156
- return response;
157
- }
158
- /**
159
- * Builds the initial reply based on the received response.
160
- * @param response The initial response object.
161
- * @returns A promise for an initial reply
162
- */
163
- async getInitialReply(response) {
164
- this.logData(`Received initial response: ${JSON.stringify(response)}`);
165
- const knownUTXOs = await this.storage.findKnownUTXOs(response.since);
166
- const filteredUTXOs = knownUTXOs.filter(x => !response.UTXOList.some(y => y.txid === x.txid && y.outputIndex === x.outputIndex));
167
- const reply = {
168
- UTXOList: filteredUTXOs
169
- };
170
- this.logData(`Built initial reply: ${JSON.stringify(reply)}`);
171
- return reply;
172
- }
173
- /**
174
- * Provides a requested node to a foreign instance who requested it.
175
- */
176
- async requestNode(graphID, txid, outputIndex, metadata) {
177
- this.logData(`Remote is requesting node with graphID: ${graphID}, txid: ${txid}, outputIndex: ${outputIndex}, metadata: ${metadata}`);
178
- const node = await this.storage.hydrateGASPNode(graphID, txid, outputIndex, metadata);
179
- this.logData(`Returning node: ${JSON.stringify(node)}`);
180
- return node;
181
- }
182
- /**
183
- * Provides a set of inputs we care about after processing a new incoming node.
184
- * Also finalizes or discards a graph if no additional data is requested from the foreign instance.
185
- */
186
- async submitNode(node) {
187
- this.logData(`Remote party is submitting node: ${JSON.stringify(node)}`);
188
- await this.storage.appendToGraph(node);
189
- const requestedInputs = await this.storage.findNeededInputs(node);
190
- this.logData(`Requested inputs: ${JSON.stringify(requestedInputs)}`);
191
- if (!requestedInputs) {
192
- await this.completeGraph(node.graphID);
193
- }
194
- return requestedInputs;
195
- }
196
- /**
197
- * Handles the completion of a newly-synced graph
198
- * @param {string} graphID The ID of the newly-synced graph
199
- */
200
- async completeGraph(graphID) {
201
- this.logData(`Completing newly-synced graph: ${graphID}`);
202
- try {
203
- await this.storage.validateGraphAnchor(graphID);
204
- this.logData(`Graph validated for node: ${graphID}`);
205
- await this.storage.finalizeGraph(graphID);
206
- this.logData(`Graph finalized for node: ${graphID}`);
207
- }
208
- catch (e) {
209
- this.logData(`Error validating graph: ${e.message}. Discarding graph for node: ${graphID}`);
210
- await this.storage.discardGraph(graphID);
211
- }
212
- }
213
- /**
214
- * Processes an incoming node from the remote participant.
215
- * @param node The incoming GASP node.
216
- * @param spentBy The 36-byte structure of the node that spent this one, if applicable.
217
- */
218
- async processIncomingNode(node, spentBy, seenNodes = new Set()) {
219
- const nodeId = `${this.computeTXID(node.rawTx)}.${node.outputIndex}`;
220
- this.logData(`Processing incoming node: ${JSON.stringify(node)}, spentBy: ${spentBy}`);
221
- if (seenNodes.has(nodeId)) {
222
- this.logData(`Node ${nodeId} already processed, skipping.`);
223
- return; // Prevent infinite recursion
224
- }
225
- seenNodes.add(nodeId);
226
- await this.storage.appendToGraph(node, spentBy);
227
- const neededInputs = await this.storage.findNeededInputs(node);
228
- this.logData(`Needed inputs for node ${nodeId}: ${JSON.stringify(neededInputs)}`);
229
- if (neededInputs) {
230
- await Promise.all(Object.entries(neededInputs.requestedInputs).map(async ([outpoint, { metadata }]) => {
231
- const { txid, outputIndex } = this.deconstruct36ByteStructure(outpoint);
232
- this.logData(`Requesting new node for txid: ${txid}, outputIndex: ${outputIndex}, metadata: ${metadata}`);
233
- const newNode = await this.remote.requestNode(node.graphID, txid, outputIndex, metadata);
234
- this.logData(`Received new node: ${JSON.stringify(newNode)}`);
235
- await this.processIncomingNode(newNode, this.compute36ByteStructure(this.computeTXID(node.rawTx), node.outputIndex), seenNodes);
236
- }));
237
- }
238
- }
239
- /**
240
- * Processes an outgoing node to the remote participant.
241
- * @param node The outgoing GASP node.
242
- */
243
- async processOutgoingNode(node, seenNodes = new Set()) {
244
- const nodeId = `${this.computeTXID(node.rawTx)}.${node.outputIndex}`;
245
- this.logData(`Processing outgoing node: ${JSON.stringify(node)}`);
246
- if (seenNodes.has(nodeId)) {
247
- this.logData(`Node ${nodeId} already processed, skipping.`);
248
- return; // Prevent infinite recursion
249
- }
250
- seenNodes.add(nodeId);
251
- if (this.remote.submitNode === undefined) {
252
- throw new Error('Remote does not support GASP node submission!');
253
- }
254
- const response = await this.remote.submitNode(node);
255
- this.logData(`Received response for submitted node: ${JSON.stringify(response)}`);
256
- if (response) {
257
- await Promise.all(Object.entries(response.requestedInputs).map(async ([outpoint, { metadata }]) => {
258
- const { txid, outputIndex } = this.deconstruct36ByteStructure(outpoint);
259
- try {
260
- this.logData(`Hydrating node for txid: ${txid}, outputIndex: ${outputIndex}, metadata: ${metadata}`);
261
- const hydratedNode = await this.storage.hydrateGASPNode(node.graphID, txid, outputIndex, metadata);
262
- this.logData(`Hydrated node: ${JSON.stringify(hydratedNode)}`);
263
- await this.processOutgoingNode(hydratedNode, seenNodes);
264
- }
265
- catch (e) {
266
- this.logData(`Error hydrating node: ${e.message}`);
267
- // If we can't send the outgoing node, we just stop. The remote won't validate the anchor, and their temporary graph will be discarded.
268
- return;
269
- }
270
- }));
271
- }
272
- }
273
- }
274
- exports.GASP = GASP;
275
- //# sourceMappingURL=GASP.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"GASP.js","sourceRoot":"","sources":["../../../src/GASP.ts"],"names":[],"mappings":"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"}
@@ -1,3 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- //# sourceMappingURL=SHIPAdvertisement.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"SHIPAdvertisement.js","sourceRoot":"","sources":["../../../src/SHIPAdvertisement.ts"],"names":[],"mappings":""}
@@ -1,3 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- //# sourceMappingURL=SLAPAdvertisement.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"SLAPAdvertisement.js","sourceRoot":"","sources":["../../../src/SLAPAdvertisement.ts"],"names":[],"mappings":""}