Skip to content

Commit 7aeb668

Browse files
committed
Merge PR #845 from 'nodech/http-races'
2 parents 61ae19c + e49a8fc commit 7aeb668

File tree

4 files changed

+585
-56
lines changed

4 files changed

+585
-56
lines changed

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
11
# HSD Release Notes & Changelog
22

3+
## Unreleased
4+
5+
### Wallet API:
6+
7+
- HTTP Changes:
8+
- All transaction creating endpoints now accept `hardFee` for specifying the
9+
exact fee.
10+
- All transaction sending endpoints now fundlock/queue tx creation. (no more
11+
conflicting transactions)
12+
313
## v6.0.0
414

515
### Node and Wallet HTTP API

lib/wallet/http.js

Lines changed: 95 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -457,10 +457,9 @@ class HTTP extends Server {
457457
// Send TX
458458
this.post('/wallet/:id/send', async (req, res) => {
459459
const valid = Validator.fromRequest(req);
460-
const passphrase = valid.str('passphrase');
461460

462461
const options = TransactionOptions.fromValidator(valid);
463-
const tx = await req.wallet.send(options, passphrase);
462+
const tx = await req.wallet.send(options);
464463

465464
const details = await req.wallet.getDetails(tx.hash());
466465

@@ -470,14 +469,15 @@ class HTTP extends Server {
470469
// Create TX
471470
this.post('/wallet/:id/create', async (req, res) => {
472471
const valid = Validator.fromRequest(req);
473-
const passphrase = valid.str('passphrase');
474472
const sign = valid.bool('sign', true);
475473

474+
// TODO: Add create TX with locks for used Coins and/or
475+
// adds to the pending list.
476476
const options = TransactionOptions.fromValidator(valid);
477477
const tx = await req.wallet.createTX(options);
478478

479479
if (sign)
480-
await req.wallet.sign(tx, passphrase);
480+
await req.wallet.sign(tx, options.passphrase);
481481

482482
const json = tx.getJSON(this.network);
483483

@@ -1068,23 +1068,26 @@ class HTTP extends Server {
10681068
this.post('/wallet/:id/open', async (req, res) => {
10691069
const valid = Validator.fromRequest(req);
10701070
const name = valid.str('name');
1071-
const passphrase = valid.str('passphrase');
10721071
const broadcast = valid.bool('broadcast', true);
10731072
const sign = valid.bool('sign', true);
10741073

10751074
enforce(name, 'Name is required.');
10761075
enforce(broadcast ? sign : true, 'Must sign when broadcasting.');
10771076

10781077
const options = TransactionOptions.fromValidator(valid);
1079-
const mtx = await req.wallet.createOpen(name, options);
10801078

10811079
if (broadcast) {
1082-
const tx = await req.wallet.sendMTX(mtx, passphrase);
1080+
// TODO: Add abort signal to close when request closes.
1081+
const tx = await req.wallet.sendOpen(name, options);
10831082
return res.json(200, tx.getJSON(this.network));
10841083
}
10851084

1085+
// TODO: Add create TX with locks for used Coins and/or
1086+
// adds to the pending list.
1087+
const mtx = await req.wallet.createOpen(name, options);
1088+
10861089
if (sign)
1087-
await req.wallet.sign(mtx, passphrase);
1090+
await req.wallet.sign(mtx, options.passphrase);
10881091

10891092
const json = mtx.getJSON(this.network);
10901093

@@ -1100,7 +1103,6 @@ class HTTP extends Server {
11001103
const name = valid.str('name');
11011104
const bid = valid.u64('bid');
11021105
const lockup = valid.u64('lockup');
1103-
const passphrase = valid.str('passphrase');
11041106
const broadcast = valid.bool('broadcast', true);
11051107
const sign = valid.bool('sign', true);
11061108

@@ -1110,15 +1112,19 @@ class HTTP extends Server {
11101112
enforce(broadcast ? sign : true, 'Must sign when broadcasting.');
11111113

11121114
const options = TransactionOptions.fromValidator(valid);
1113-
const mtx = await req.wallet.createBid(name, bid, lockup, options);
11141115

11151116
if (broadcast) {
1116-
const tx = await req.wallet.sendMTX(mtx, passphrase);
1117+
// TODO: Add abort signal to close when request closes.
1118+
const tx = await req.wallet.sendBid(name, bid, lockup, options);
11171119
return res.json(200, tx.getJSON(this.network));
11181120
}
11191121

1122+
// TODO: Add create TX with locks for used Coins and/or
1123+
// adds to the pending list.
1124+
const mtx = await req.wallet.createBid(name, bid, lockup, options);
1125+
11201126
if (sign)
1121-
await req.wallet.sign(mtx, passphrase);
1127+
await req.wallet.sign(mtx, options.passphrase);
11221128

11231129
const json = mtx.getJSON(this.network);
11241130

@@ -1180,29 +1186,39 @@ class HTTP extends Server {
11801186
this.post('/wallet/:id/reveal', async (req, res) => {
11811187
const valid = Validator.fromRequest(req);
11821188
const name = valid.str('name');
1183-
const passphrase = valid.str('passphrase');
11841189
const broadcast = valid.bool('broadcast', true);
11851190
const sign = valid.bool('sign', true);
11861191

11871192
enforce(broadcast ? sign : true, 'Must sign when broadcasting.');
11881193

11891194
const options = TransactionOptions.fromValidator(valid);
11901195

1191-
let mtx;
1196+
if (broadcast) {
1197+
let tx;
11921198

1193-
if (!name) {
1194-
mtx = await req.wallet.createRevealAll(options);
1195-
} else {
1196-
mtx = await req.wallet.createReveal(name, options);
1197-
}
1199+
if (name) {
1200+
// TODO: Add abort signal to close when request closes.
1201+
tx = await req.wallet.sendReveal(name, options);
1202+
} else {
1203+
// TODO: Add abort signal to close when request closes.
1204+
tx = await req.wallet.sendRevealAll(options);
1205+
}
11981206

1199-
if (broadcast) {
1200-
const tx = await req.wallet.sendMTX(mtx, passphrase);
12011207
return res.json(200, tx.getJSON(this.network));
12021208
}
12031209

1210+
let mtx;
1211+
1212+
// TODO: Add create TX with locks for used Coins and/or
1213+
// adds to the pending list.
1214+
if (name) {
1215+
mtx = await req.wallet.createReveal(name, options);
1216+
} else {
1217+
mtx = await req.wallet.createRevealAll(options);
1218+
}
1219+
12041220
if (sign)
1205-
await req.wallet.sign(mtx, passphrase);
1221+
await req.wallet.sign(mtx, options.passphrase);
12061222

12071223
const json = mtx.getJSON(this.network);
12081224

@@ -1216,29 +1232,39 @@ class HTTP extends Server {
12161232
this.post('/wallet/:id/redeem', async (req, res) => {
12171233
const valid = Validator.fromRequest(req);
12181234
const name = valid.str('name');
1219-
const passphrase = valid.str('passphrase');
12201235
const broadcast = valid.bool('broadcast', true);
12211236
const sign = valid.bool('sign', true);
12221237

12231238
enforce(broadcast ? sign : true, 'Must sign when broadcasting.');
12241239

12251240
const options = TransactionOptions.fromValidator(valid);
12261241

1242+
if (broadcast) {
1243+
let tx;
1244+
1245+
if (name) {
1246+
// TODO: Add abort signal to close when request closes.
1247+
tx = await req.wallet.sendRedeem(name, options);
1248+
} else {
1249+
// TODO: Add abort signal to close when request closes.
1250+
tx = await req.wallet.sendRedeemAll(options);
1251+
}
1252+
1253+
return res.json(200, tx.getJSON(this.network));
1254+
}
1255+
12271256
let mtx;
12281257

1258+
// TODO: Add create TX with locks for used Coins and/or
1259+
// adds to the pending list.
12291260
if (!name) {
12301261
mtx = await req.wallet.createRedeemAll(options);
12311262
} else {
12321263
mtx = await req.wallet.createRedeem(name, options);
12331264
}
12341265

1235-
if (broadcast) {
1236-
const tx = await req.wallet.sendMTX(mtx, passphrase);
1237-
return res.json(200, tx.getJSON(this.network));
1238-
}
1239-
12401266
if (sign)
1241-
await req.wallet.sign(mtx, passphrase);
1267+
await req.wallet.sign(mtx, options.passphrase);
12421268

12431269
const json = mtx.getJSON(this.network);
12441270

@@ -1253,7 +1279,6 @@ class HTTP extends Server {
12531279
const valid = Validator.fromRequest(req);
12541280
const name = valid.str('name');
12551281
const data = valid.obj('data');
1256-
const passphrase = valid.str('passphrase');
12571282
const broadcast = valid.bool('broadcast', true);
12581283
const sign = valid.bool('sign', true);
12591284

@@ -1269,15 +1294,19 @@ class HTTP extends Server {
12691294
}
12701295

12711296
const options = TransactionOptions.fromValidator(valid);
1272-
const mtx = await req.wallet.createUpdate(name, resource, options);
12731297

12741298
if (broadcast) {
1275-
const tx = await req.wallet.sendMTX(mtx, passphrase);
1299+
// TODO: Add abort signal to close when request closes.
1300+
const tx = await req.wallet.sendUpdate(name, resource, options);
12761301
return res.json(200, tx.getJSON(this.network));
12771302
}
12781303

1304+
// TODO: Add create TX with locks for used Coins and/or
1305+
// adds to the pending list.
1306+
const mtx = await req.wallet.createUpdate(name, resource, options);
1307+
12791308
if (sign)
1280-
await req.wallet.sign(mtx, passphrase);
1309+
await req.wallet.sign(mtx, options.passphrase);
12811310

12821311
const json = mtx.getJSON(this.network);
12831312

@@ -1291,23 +1320,24 @@ class HTTP extends Server {
12911320
this.post('/wallet/:id/renewal', async (req, res) => {
12921321
const valid = Validator.fromRequest(req);
12931322
const name = valid.str('name');
1294-
const passphrase = valid.str('passphrase');
12951323
const broadcast = valid.bool('broadcast', true);
12961324
const sign = valid.bool('sign', true);
12971325

12981326
enforce(broadcast ? sign : true, 'Must sign when broadcasting.');
12991327
enforce(name, 'Must pass name.');
13001328

13011329
const options = TransactionOptions.fromValidator(valid);
1302-
const mtx = await req.wallet.createRenewal(name, options);
13031330

13041331
if (broadcast) {
1305-
const tx = await req.wallet.sendMTX(mtx, passphrase);
1332+
// TODO: Add abort signal to close when request closes.
1333+
const tx = await req.wallet.sendRenewal(name, options);
13061334
return res.json(200, tx.getJSON(this.network));
13071335
}
13081336

1337+
const mtx = await req.wallet.createRenewal(name, options);
1338+
13091339
if (sign)
1310-
await req.wallet.sign(mtx, passphrase);
1340+
await req.wallet.sign(mtx, options.passphrase);
13111341

13121342
const json = mtx.getJSON(this.network);
13131343

@@ -1322,7 +1352,6 @@ class HTTP extends Server {
13221352
const valid = Validator.fromRequest(req);
13231353
const name = valid.str('name');
13241354
const address = valid.str('address');
1325-
const passphrase = valid.str('passphrase');
13261355
const broadcast = valid.bool('broadcast', true);
13271356
const sign = valid.bool('sign', true);
13281357

@@ -1332,15 +1361,19 @@ class HTTP extends Server {
13321361

13331362
const addr = Address.fromString(address, this.network);
13341363
const options = TransactionOptions.fromValidator(valid);
1335-
const mtx = await req.wallet.createTransfer(name, addr, options);
13361364

13371365
if (broadcast) {
1338-
const tx = await req.wallet.sendMTX(mtx, passphrase);
1366+
// TODO: Add abort signal to close when request closes.
1367+
const tx = await req.wallet.sendTransfer(name, addr, options);
13391368
return res.json(200, tx.getJSON(this.network));
13401369
}
13411370

1371+
// TODO: Add create TX with locks for used Coins and/or
1372+
// adds to the pending list.
1373+
const mtx = await req.wallet.createTransfer(name, addr, options);
1374+
13421375
if (sign)
1343-
await req.wallet.sign(mtx, passphrase);
1376+
await req.wallet.sign(mtx, options.passphrase);
13441377

13451378
const json = mtx.getJSON(this.network);
13461379

@@ -1354,23 +1387,26 @@ class HTTP extends Server {
13541387
this.post('/wallet/:id/cancel', async (req, res) => {
13551388
const valid = Validator.fromRequest(req);
13561389
const name = valid.str('name');
1357-
const passphrase = valid.str('passphrase');
13581390
const broadcast = valid.bool('broadcast', true);
13591391
const sign = valid.bool('sign', true);
13601392

13611393
enforce(broadcast ? sign : true, 'Must sign when broadcasting.');
13621394
enforce(name, 'Must pass name.');
13631395

13641396
const options = TransactionOptions.fromValidator(valid);
1365-
const mtx = await req.wallet.createCancel(name, options);
13661397

13671398
if (broadcast) {
1368-
const tx = await req.wallet.sendMTX(mtx, passphrase);
1399+
// TODO: Add abort signal to close when request closes.
1400+
const tx = await req.wallet.sendCancel(name, options);
13691401
return res.json(200, tx.getJSON(this.network));
13701402
}
13711403

1404+
// TODO: Add create TX with locks for used Coins and/or
1405+
// adds to the pending list.
1406+
const mtx = await req.wallet.createCancel(name, options);
1407+
13721408
if (sign)
1373-
await req.wallet.sign(mtx, passphrase);
1409+
await req.wallet.sign(mtx, options.passphrase);
13741410

13751411
const json = mtx.getJSON(this.network);
13761412

@@ -1384,23 +1420,24 @@ class HTTP extends Server {
13841420
this.post('/wallet/:id/finalize', async (req, res) => {
13851421
const valid = Validator.fromRequest(req);
13861422
const name = valid.str('name');
1387-
const passphrase = valid.str('passphrase');
13881423
const broadcast = valid.bool('broadcast', true);
13891424
const sign = valid.bool('sign', true);
13901425

13911426
enforce(broadcast ? sign : true, 'Must sign when broadcasting.');
13921427
enforce(name, 'Must pass name.');
13931428

13941429
const options = TransactionOptions.fromValidator(valid);
1395-
const mtx = await req.wallet.createFinalize(name, options);
13961430

13971431
if (broadcast) {
1398-
const tx = await req.wallet.sendMTX(mtx, passphrase);
1432+
// TODO: Add abort signal to close when request closes.
1433+
const tx = await req.wallet.sendFinalize(name, options);
13991434
return res.json(200, tx.getJSON(this.network));
14001435
}
14011436

1437+
const mtx = await req.wallet.createFinalize(name, options);
1438+
14021439
if (sign)
1403-
await req.wallet.sign(mtx, passphrase);
1440+
await req.wallet.sign(mtx, options.passphrase);
14041441

14051442
const json = mtx.getJSON(this.network);
14061443

@@ -1414,23 +1451,26 @@ class HTTP extends Server {
14141451
this.post('/wallet/:id/revoke', async (req, res) => {
14151452
const valid = Validator.fromRequest(req);
14161453
const name = valid.str('name');
1417-
const passphrase = valid.str('passphrase');
14181454
const broadcast = valid.bool('broadcast', true);
14191455
const sign = valid.bool('sign', true);
14201456

14211457
enforce(broadcast ? sign : true, 'Must sign when broadcasting.');
14221458
enforce(name, 'Must pass name.');
14231459

14241460
const options = TransactionOptions.fromValidator(valid);
1425-
const mtx = await req.wallet.createRevoke(name, options);
14261461

14271462
if (broadcast) {
1428-
const tx = await req.wallet.sendMTX(mtx, passphrase);
1463+
// TODO: Add abort signal to close when request closes.
1464+
const tx = await req.wallet.sendRevoke(name, options);
14291465
return res.json(200, tx.getJSON(this.network));
14301466
}
14311467

1468+
// TODO: Add create TX with locks for used Coins and/or
1469+
// adds to the pending list.
1470+
const mtx = await req.wallet.createRevoke(name, options);
1471+
14321472
if (sign)
1433-
await req.wallet.sign(mtx, passphrase);
1473+
await req.wallet.sign(mtx, options.passphrase);
14341474

14351475
const json = mtx.getJSON(this.network);
14361476

@@ -1814,6 +1854,8 @@ class TransactionOptions {
18141854
this.subtractIndex = valid.i32('subtractIndex');
18151855
this.depth = valid.u32(['confirmations', 'depth']);
18161856
this.paths = valid.bool('paths');
1857+
this.passphrase = valid.str('passphrase');
1858+
this.hardFee = valid.u64('hardFee'),
18171859
this.outputs = [];
18181860

18191861
if (valid.has('outputs')) {

0 commit comments

Comments
 (0)