Skip to content

Commit 477e4f9

Browse files
committed
chore: update satoshi-mediator
1 parent 1ac4b3c commit 477e4f9

26 files changed

Lines changed: 880 additions & 335 deletions

doc/deployment/index.mdx

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -201,22 +201,23 @@ Following these initial Gatekeeper configuration variables, the file contains MD
201201

202202
WARNING: Changes to these variables are likely to **break** the Docker Compose functionality.
203203

204-
| Variable | Default Value | Description |
205-
|-----------------------------|---------------|----------------------------------------------------------------------------|
206-
| # Bitcoin testnet4 mediator | | |
207-
| `KC_TBTC_HOST` | `localhost` | Host name for the Bitcoin Testnet node |
208-
| `KC_TBTC_CHAIN` | `TBTC` | MDIP registry name for the Bitcoin Testnet network |
209-
| `KC_TBTC_NETWORK` | `testnet` | |
210-
| `KC_TBTC_START_BLOCK` | `38000` | |
211-
| `KC_TBTC_PORT` | `48332` | Bitcoin Testnet node RPC port |
212-
| `KC_TBTC_USER` | `testnet4` | Bitcoin Testnet node RPC user |
213-
| `KC_TBTC_PASS` | `testnet4` | Bitcoin Testnet node RPC password |
214-
| `KC_TBTC_WALLET` | `mdip` | Name of the Bitcoin Testnet wallet to draw funds from for transaction fees |
215-
| `KC_TBTC_IMPORT_INTERVAL` | `1` | MDIP Satoshi Mediator import loop wait interval (in minutes) |
216-
| `KC_TBTC_EXPORT_INTERVAL` | `1` | MDIP Satoshi Mediator export loop wait interval (in minutes) |
217-
| `KC_TBTC_FEE_MIN` | `0.00000200` | Bitcoin Testnet transaction minimum fee |
218-
| `KC_TBTC_FEE_MAX` | `0.00000600` | Bitcoin Testnet transaction maximum fee |
219-
| `KC_TBTC_FEE_INC` | `0` | |
204+
| Variable | Default Value | Description |
205+
|---------------------------------|---------------|----------------------------------------------------------------------------|
206+
| # Bitcoin testnet4 mediator | | |
207+
| `KC_TBTC_HOST` | `localhost` | Host name for the Bitcoin Testnet node |
208+
| `KC_TBTC_CHAIN` | `TBTC` | MDIP registry name for the Bitcoin Testnet network |
209+
| `KC_TBTC_NETWORK` | `testnet` | |
210+
| `KC_TBTC_START_BLOCK` | `38000` | |
211+
| `KC_TBTC_PORT` | `48332` | Bitcoin Testnet node RPC port |
212+
| `KC_TBTC_USER` | `testnet4` | Bitcoin Testnet node RPC user |
213+
| `KC_TBTC_PASS` | `testnet4` | Bitcoin Testnet node RPC password |
214+
| `KC_TBTC_WALLET` | `mdip` | Name of the Bitcoin Testnet wallet to draw funds from for transaction fees |
215+
| `KC_TBTC_IMPORT_INTERVAL` | `1` | MDIP Satoshi Mediator import loop wait interval (in minutes) |
216+
| `KC_TBTC_EXPORT_INTERVAL` | `1` | MDIP Satoshi Mediator export loop wait interval (in minutes) |
217+
| `KC_TBTC_FEE_BLOCK_TARGET` | `1` | Number of blocks to pass before Replace-By-Fee is used if enabled |
218+
| `KC_TBTC_FEE_FALLBACK_SAT_BYTE` | `10` | Fallback Sat/Byte if estimatesmartfee does not have enough data |
219+
| `KC_TBTC_FEE_MAX` | `0.00000600` | Bitcoin Testnet transaction maximum fee |
220+
| `KC_TBTC_RBF_ENABLED` | false | Whether Replace-By-Fee is enabled |
220221

221222
### Customizing the docker-compose.yml services
222223

@@ -322,9 +323,10 @@ In the example below, we use a generic bitcoin-code node configured to operate o
322323
- KC_SAT_WALLET=${KC_TBTC_WALLET}
323324
- KC_SAT_IMPORT_INTERVAL=${KC_TBTC_IMPORT_INTERVAL}
324325
- KC_SAT_EXPORT_INTERVAL=${KC_TBTC_EXPORT_INTERVAL}
325-
- KC_SAT_FEE_MIN=${KC_TBTC_FEE_MIN}
326+
- KC_SAT_FEE_BLOCK_TARGET=${KC_TBTC_FEE_BLOCK_TARGET}
327+
- KC_SAT_FEE_FALLBACK_SAT_BYTE=${KC_TBTC_FEE_FALLBACK_SAT_BYTE}
326328
- KC_SAT_FEE_MAX=${KC_TBTC_FEE_MAX}
327-
- KC_SAT_FEE_INC=${KC_TBTC_FEE_INC}
329+
- KC_SAT_RBF_ENABLED=${KC_TBTC_RBF_ENABLED}
328330
volumes:
329331
- ./data:/app/satoshi/data
330332
user: "${KC_UID}:${KC_GID}"

docker-compose.yml

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -123,9 +123,10 @@ services:
123123
- KC_SAT_WALLET=${KC_TFTC_WALLET}
124124
- KC_SAT_IMPORT_INTERVAL=${KC_TFTC_IMPORT_INTERVAL}
125125
- KC_SAT_EXPORT_INTERVAL=${KC_TFTC_EXPORT_INTERVAL}
126-
- KC_SAT_FEE_MIN=${KC_TFTC_FEE_MIN}
126+
- KC_SAT_FEE_BLOCK_TARGET=${KC_TFTC_FEE_BLOCK_TARGET}
127+
- KC_SAT_FEE_FALLBACK_SAT_BYTE=${KC_TFTC_FEE_FALLBACK_SAT_BYTE}
127128
- KC_SAT_FEE_MAX=${KC_TFTC_FEE_MAX}
128-
- KC_SAT_FEE_INC=${KC_TFTC_FEE_INC}
129+
- KC_SAT_RBF_ENABLED=${KC_TFTC_RBF_ENABLED}
129130
- KC_SAT_REIMPORT=${KC_TFTC_REIMPORT}
130131
- KC_SAT_DB=${KC_TFTC_DB}
131132
volumes:
@@ -162,9 +163,10 @@ services:
162163
- KC_SAT_WALLET=${KC_TBTC_WALLET}
163164
- KC_SAT_IMPORT_INTERVAL=${KC_TBTC_IMPORT_INTERVAL}
164165
- KC_SAT_EXPORT_INTERVAL=${KC_TBTC_EXPORT_INTERVAL}
165-
- KC_SAT_FEE_MIN=${KC_TBTC_FEE_MIN}
166+
- KC_SAT_FEE_BLOCK_TARGET=${KC_TBTC_FEE_BLOCK_TARGET}
167+
- KC_SAT_FEE_FALLBACK_SAT_BYTE=${KC_TBTC_FEE_FALLBACK_SAT_BYTE}
166168
- KC_SAT_FEE_MAX=${KC_TBTC_FEE_MAX}
167-
- KC_SAT_FEE_INC=${KC_TBTC_FEE_INC}
169+
- KC_SAT_RBF_ENABLED=${KC_TBTC_RBF_ENABLED}
168170
- KC_SAT_REIMPORT=${KC_TBTC_REIMPORT}
169171
- KC_SAT_DB=${KC_TBTC_DB}
170172
volumes:
@@ -203,9 +205,10 @@ services:
203205
- KC_SAT_WALLET=${KC_SIGNET_WALLET}
204206
- KC_SAT_IMPORT_INTERVAL=${KC_SIGNET_IMPORT_INTERVAL}
205207
- KC_SAT_EXPORT_INTERVAL=${KC_SIGNET_EXPORT_INTERVAL}
206-
- KC_SAT_FEE_MIN=${KC_SIGNET_FEE_MIN}
208+
- KC_SAT_FEE_BLOCK_TARGET=${KC_SIGNET_FEE_BLOCK_TARGET}
209+
- KC_SAT_FEE_FALLBACK_SAT_BYTE=${KC_SIGNET_FEE_FALLBACK_SAT_BYTE}
207210
- KC_SAT_FEE_MAX=${KC_SIGNET_FEE_MAX}
208-
- KC_SAT_FEE_INC=${KC_SIGNET_FEE_INC}
211+
- KC_SAT_RBF_ENABLED=${KC_SIGNET_RBF_ENABLED}
209212
- KC_SAT_REIMPORT=${KC_SIGNET_REIMPORT}
210213
- KC_SAT_DB=${KC_SIGNET_DB}
211214
volumes:
@@ -240,8 +243,8 @@ services:
240243
- KC_SAT_FEE_BLOCK_TARGET=${KC_SIGNET_INS_FEE_BLOCK_TARGET}
241244
- KC_SAT_FEE_FALLBACK_SAT_BYTE=${KC_SIGNET_INS_FEE_FALLBACK_SAT_BYTE}
242245
- KC_SAT_FEE_MAX=${KC_SIGNET_INS_FEE_MAX}
243-
- KC_SAT_REIMPORT=${KC_SIGNET_INS_REIMPORT}
244246
- KC_SAT_RBF_ENABLED=${KC_SIGNET_INS_RBF_ENABLED}
247+
- KC_SAT_REIMPORT=${KC_SIGNET_INS_REIMPORT}
245248
- KC_SAT_DB=${KC_SIGNET_INS_DB}
246249
volumes:
247250
- ./data:/app/satoshi/data

sample.env

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,10 @@ KC_TBTC_PASS=testnet4
4040
KC_TBTC_WALLET=mdip
4141
KC_TBTC_IMPORT_INTERVAL=1
4242
KC_TBTC_EXPORT_INTERVAL=1
43-
KC_TBTC_FEE_MIN=0.00000200
44-
KC_TBTC_FEE_MAX=0.00000600
45-
KC_TBTC_FEE_INC=0
43+
KC_TBTC_FEE_BLOCK_TARGET=1
44+
KC_TBTC_FEE_FALLBACK_SAT_BYTE=10
45+
KC_TBTC_FEE_MAX=0.00200000
46+
KC_TBTC_RBF_ENABLED=false
4647
KC_TBTC_REIMPORT=true
4748
KC_TBTC_DB=json
4849

@@ -55,9 +56,10 @@ KC_TFTC_PASS=feathercoin
5556
KC_TFTC_WALLET=mdip
5657
KC_TFTC_IMPORT_INTERVAL=1
5758
KC_TFTC_EXPORT_INTERVAL=1
58-
KC_TFTC_FEE_MIN=0.00000300
59-
KC_TFTC_FEE_MAX=0.00003000
60-
KC_TFTC_FEE_INC=0
59+
KC_TFTC_FEE_BLOCK_TARGET=1
60+
KC_TFTC_FEE_FALLBACK_SAT_BYTE=10
61+
KC_TFTC_FEE_MAX=0.00200000
62+
KC_TFTC_RBF_ENABLED=false
6163
KC_TFTC_REIMPORT=true
6264
KC_TFTC_DB=json
6365

@@ -70,9 +72,10 @@ KC_SIGNET_PASS=signet
7072
KC_SIGNET_WALLET=mdip
7173
KC_SIGNET_IMPORT_INTERVAL=1
7274
KC_SIGNET_EXPORT_INTERVAL=1
73-
KC_SIGNET_FEE_MIN=0.00000300
75+
KC_SIGNET_FEE_BLOCK_TARGET=1
76+
KC_SIGNET_FEE_FALLBACK_SAT_BYTE=10
7477
KC_SIGNET_FEE_MAX=0.00003000
75-
KC_SIGNET_FEE_INC=0
78+
KC_SIGNET_RBF_ENABLED=false
7679
KC_SIGNET_REIMPORT=true
7780
KC_SIGNET_DB=json
7881

@@ -86,10 +89,10 @@ KC_SIGNET_INS_WALLET=mdip
8689
KC_SIGNET_INS_IMPORT_INTERVAL=1
8790
KC_SIGNET_INS_EXPORT_INTERVAL=1
8891
KC_SIGNET_INS_FEE_BLOCK_TARGET=1
89-
KC_SIGNET_INS_FEE_MAX=0.00200000
9092
KC_SIGNET_INS_FEE_FALLBACK_SAT_BYTE=10
91-
KC_SIGNET_INS_REIMPORT=true
93+
KC_SIGNET_INS_FEE_MAX=0.00200000
9294
KC_SIGNET_INS_RBF_ENABLED=false
95+
KC_SIGNET_INS_REIMPORT=true
9396
KC_SIGNET_INS_DB=json
9497

9598
# IPFS mediator
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { MediatorDb, MediatorDbInterface } from '../types.js';
2+
3+
export default abstract class AbstractDB implements MediatorDbInterface {
4+
private lock: Promise<void> = Promise.resolve();
5+
6+
abstract loadDb(): Promise<MediatorDb | null>;
7+
abstract saveDb(db: MediatorDb): Promise<boolean>;
8+
9+
async updateDb(mutator: (db: MediatorDb) => void | Promise<void>): Promise<void> {
10+
const run = async () => {
11+
const db = (await this.loadDb()) ?? this.defaultDb();
12+
await mutator(db);
13+
await this.saveDb(db);
14+
};
15+
const chained = this.lock.then(run, run);
16+
this.lock = chained.catch(() => {}); // keep chain alive on errors
17+
return chained;
18+
}
19+
20+
protected defaultDb(): MediatorDb {
21+
return {
22+
height: 0,
23+
time: '',
24+
blockCount: 0,
25+
blocksScanned: 0,
26+
blocksPending: 0,
27+
txnsScanned: 0,
28+
discovered: [],
29+
};
30+
}
31+
}

services/mediators/satoshi-inscription/src/db/jsonfile.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
import fs from 'fs';
2-
import { MediatorDb, MediatorDbInterface } from '../types.js';
2+
import { MediatorDb } from '../types.js';
3+
import AbstractDB from "./abstract-db.js";
34

4-
export default class JsonFile implements MediatorDbInterface {
5+
export default class JsonFile extends AbstractDB {
56
private readonly dataFolder: string;
67
private readonly fileName: string;
78

89
constructor(registry: string, dataFolder = 'data') {
10+
super();
911
this.dataFolder = dataFolder;
1012
this.fileName = `${dataFolder}/${registry}-mediator.json`;
1113
}
@@ -15,7 +17,9 @@ export default class JsonFile implements MediatorDbInterface {
1517
fs.mkdirSync(this.dataFolder, { recursive: true });
1618
}
1719

18-
fs.writeFileSync(this.fileName, JSON.stringify(data, null, 4));
20+
const tmp = this.fileName + '.tmp';
21+
fs.writeFileSync(tmp, JSON.stringify(data, null, 4));
22+
fs.renameSync(tmp, this.fileName);
1923
return true;
2024
}
2125

services/mediators/satoshi-inscription/src/db/mongo.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import { MongoClient, Db, Collection } from 'mongodb';
2-
import { MediatorDb, MediatorDbInterface } from '../types.js';
2+
import { MediatorDb } from '../types.js';
3+
import AbstractDB from "./abstract-db.js";
34

4-
export default class JsonMongo implements MediatorDbInterface {
5+
export default class JsonMongo extends AbstractDB {
56
private client: MongoClient;
67
private readonly dbName: string;
78
private readonly collectionName: string;
@@ -15,6 +16,7 @@ export default class JsonMongo implements MediatorDbInterface {
1516
}
1617

1718
constructor(registry: string) {
19+
super();
1820
const url = process.env.KC_MONGODB_URL || 'mongodb://localhost:27017';
1921
this.client = new MongoClient(url);
2022
this.dbName = 'sat-mediator';

services/mediators/satoshi-inscription/src/db/redis.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import { Redis } from 'ioredis'
2-
import { MediatorDb, MediatorDbInterface } from '../types.js';
2+
import { MediatorDb } from '../types.js';
3+
import AbstractDB from "./abstract-db.js";
34

4-
export default class JsonRedis implements MediatorDbInterface {
5+
export default class JsonRedis extends AbstractDB {
56
private readonly url: string;
67
private readonly dbKey: string;
78
private redis?: Redis;
@@ -13,6 +14,7 @@ export default class JsonRedis implements MediatorDbInterface {
1314
}
1415

1516
constructor(registry: string) {
17+
super();
1618
this.url = process.env.KC_REDIS_URL || 'redis://localhost:6379';
1719
this.dbKey = `sat-mediator/${registry}`;
1820
}

services/mediators/satoshi-inscription/src/db/sqlite.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import sqlite3 from 'sqlite3';
22
import { open, Database } from 'sqlite';
3-
import { MediatorDb, MediatorDbInterface } from '../types.js';
3+
import { MediatorDb } from '../types.js';
4+
import AbstractDB from "./abstract-db.js";
45

5-
export default class JsonSQLite implements MediatorDbInterface {
6+
export default class JsonSQLite extends AbstractDB {
67
private readonly fileName: string;
78
private db?: Database;
89

@@ -13,6 +14,7 @@ export default class JsonSQLite implements MediatorDbInterface {
1314
}
1415

1516
constructor(registry: string, dataFolder = 'data') {
17+
super();
1618
this.fileName = `${dataFolder}/${registry}-mediator.db`;
1719
}
1820

0 commit comments

Comments
 (0)