Skip to content

Commit 00ff075

Browse files
authored
Merge pull request #387 from SiaFoundation/nate/fix-tpool-race
Merge chain manager and tpool in SingleAddressWallet
2 parents f9c899f + bc2a34c commit 00ff075

File tree

18 files changed

+297
-208
lines changed

18 files changed

+297
-208
lines changed

cmd/hostd/node.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,12 +140,12 @@ func newNode(ctx context.Context, walletKey types.PrivateKey, ex *explorer.Explo
140140
// load the host identity
141141
hostKey := db.HostKey()
142142

143-
cm, err := chain.NewManager(cs)
143+
cm, err := chain.NewManager(cs, tp)
144144
if err != nil {
145145
return nil, types.PrivateKey{}, fmt.Errorf("failed to create chain manager: %w", err)
146146
}
147147

148-
w, err := wallet.NewSingleAddressWallet(walletKey, cm, tp, db, logger.Named("wallet"))
148+
w, err := wallet.NewSingleAddressWallet(walletKey, cm, db, logger.Named("wallet"))
149149
if err != nil {
150150
return nil, types.PrivateKey{}, fmt.Errorf("failed to create wallet: %w", err)
151151
}

host/accounts/accounts_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,13 +60,13 @@ func TestCredit(t *testing.T) {
6060
tp := chain.NewTPool(stp)
6161
defer tp.Close()
6262

63-
cm, err := chain.NewManager(cs)
63+
cm, err := chain.NewManager(cs, tp)
6464
if err != nil {
6565
t.Fatal(err)
6666
}
6767
defer cm.Close()
6868

69-
w, err := wallet.NewSingleAddressWallet(types.NewPrivateKeyFromSeed(frand.Bytes(32)), cm, tp, db, log.Named("wallet"))
69+
w, err := wallet.NewSingleAddressWallet(types.NewPrivateKeyFromSeed(frand.Bytes(32)), cm, db, log.Named("wallet"))
7070
if err != nil {
7171
t.Fatal(err)
7272
}

host/accounts/budget_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,13 +97,13 @@ func TestBudget(t *testing.T) {
9797
tp := chain.NewTPool(stp)
9898
defer tp.Close()
9999

100-
cm, err := chain.NewManager(cs)
100+
cm, err := chain.NewManager(cs, tp)
101101
if err != nil {
102102
t.Fatal(err)
103103
}
104104
defer cm.Close()
105105

106-
w, err := wallet.NewSingleAddressWallet(types.NewPrivateKeyFromSeed(frand.Bytes(32)), cm, tp, db, log.Named("wallet"))
106+
w, err := wallet.NewSingleAddressWallet(types.NewPrivateKeyFromSeed(frand.Bytes(32)), cm, db, log.Named("wallet"))
107107
if err != nil {
108108
t.Fatal(err)
109109
}

host/contracts/actions.go

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -158,16 +158,17 @@ func (cm *ContractManager) handleContractAction(id types.FileContractID, height
158158

159159
fee := cm.tpool.RecommendedFee().Mul64(1000)
160160
revisionTxn.MinerFees = append(revisionTxn.MinerFees, fee)
161-
toSign, discard, err := cm.wallet.FundTransaction(&revisionTxn, fee)
161+
toSign, release, err := cm.wallet.FundTransaction(&revisionTxn, fee)
162162
if err != nil {
163163
log.Error("failed to fund revision transaction", zap.Error(err))
164164
return
165165
}
166-
defer discard()
167166
if err := cm.wallet.SignTransaction(cs, &revisionTxn, toSign, types.CoveredFields{WholeTransaction: true}); err != nil {
167+
release()
168168
log.Error("failed to sign revision transaction", zap.Error(err))
169169
return
170170
} else if err := cm.tpool.AcceptTransactionSet([]types.Transaction{revisionTxn}); err != nil {
171+
release()
171172
log.Error("failed to broadcast revision transaction", zap.Error(err))
172173
return
173174
}
@@ -215,14 +216,12 @@ func (cm *ContractManager) handleContractAction(id types.FileContractID, height
215216
StorageProofs: []types.StorageProof{sp},
216217
},
217218
}
218-
intermediateToSign, discard, err := cm.wallet.FundTransaction(&resolutionTxnSet[0], fee)
219+
intermediateToSign, release, err := cm.wallet.FundTransaction(&resolutionTxnSet[0], fee)
219220
if err != nil {
220221
log.Error("failed to fund resolution transaction", zap.Error(err))
221222
registerContractAlert(alerts.SeverityError, "Failed to fund resolution transaction", err)
222223
return
223224
}
224-
defer discard()
225-
226225
// add the intermediate output to the proof transaction
227226
resolutionTxnSet[1].SiacoinInputs = append(resolutionTxnSet[1].SiacoinInputs, types.SiacoinInput{
228227
ParentID: resolutionTxnSet[0].SiacoinOutputID(0),
@@ -231,12 +230,15 @@ func (cm *ContractManager) handleContractAction(id types.FileContractID, height
231230
proofToSign := []types.Hash256{types.Hash256(resolutionTxnSet[1].SiacoinInputs[0].ParentID)}
232231
start = time.Now()
233232
if err := cm.wallet.SignTransaction(cs, &resolutionTxnSet[0], intermediateToSign, types.CoveredFields{WholeTransaction: true}); err != nil { // sign the intermediate transaction
233+
release()
234234
log.Error("failed to sign resolution intermediate transaction", zap.Error(err))
235235
return
236236
} else if err := cm.wallet.SignTransaction(cs, &resolutionTxnSet[1], proofToSign, types.CoveredFields{WholeTransaction: true}); err != nil { // sign the proof transaction
237+
release()
237238
log.Error("failed to sign resolution transaction", zap.Error(err))
238239
return
239240
} else if err := cm.tpool.AcceptTransactionSet(resolutionTxnSet); err != nil { // broadcast the transaction set
241+
release()
240242
buf, _ := json.Marshal(resolutionTxnSet)
241243
log.Error("failed to broadcast resolution transaction set", zap.Error(err), zap.ByteString("transactionSet", buf))
242244
registerContractAlert(alerts.SeverityError, "Failed to broadcast resolution transaction set", err)

host/contracts/manager_test.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,14 +44,15 @@ func formContract(renterKey, hostKey types.PrivateKey, start, end uint64, renter
4444
txn := types.Transaction{
4545
FileContracts: []types.FileContract{contract},
4646
}
47-
toSign, discard, err := w.FundTransaction(&txn, formationCost.Add(hostPayout)) // we're funding both sides of the payout
47+
toSign, release, err := w.FundTransaction(&txn, formationCost.Add(hostPayout)) // we're funding both sides of the payout
4848
if err != nil {
4949
return contracts.SignedRevision{}, fmt.Errorf("failed to fund transaction: %w", err)
5050
}
51-
defer discard()
5251
if err := w.SignTransaction(state, &txn, toSign, types.CoveredFields{WholeTransaction: true}); err != nil {
52+
release()
5353
return contracts.SignedRevision{}, fmt.Errorf("failed to sign transaction: %w", err)
5454
} else if err := tp.AcceptTransactionSet([]types.Transaction{txn}); err != nil {
55+
release()
5556
return contracts.SignedRevision{}, fmt.Errorf("failed to accept transaction set: %w", err)
5657
}
5758
revision := types.FileContractRevision{

host/settings/announce.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,15 +56,16 @@ func (m *ConfigManager) Announce() error {
5656
if err != nil {
5757
return fmt.Errorf("failed to fund transaction: %w", err)
5858
}
59-
defer release()
6059
// sign the transaction
6160
err = m.wallet.SignTransaction(m.cm.TipState(), &txn, toSign, types.CoveredFields{WholeTransaction: true})
6261
if err != nil {
62+
release()
6363
return fmt.Errorf("failed to sign transaction: %w", err)
6464
}
6565
// broadcast the transaction
6666
err = m.tp.AcceptTransactionSet([]types.Transaction{txn})
6767
if err != nil {
68+
release()
6869
return fmt.Errorf("failed to broadcast transaction: %w", err)
6970
}
7071
m.log.Debug("broadcast announcement", zap.String("transactionID", txn.ID().String()), zap.String("netaddress", settings.NetAddress), zap.String("cost", minerFee.ExactString()))

host/storage/storage_test.go

Lines changed: 113 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import (
1919
"go.sia.tech/hostd/webhooks"
2020
"go.sia.tech/siad/modules/consensus"
2121
"go.sia.tech/siad/modules/gateway"
22+
"go.sia.tech/siad/modules/transactionpool"
2223
"go.uber.org/zap/zaptest"
2324
"lukechampine.com/frand"
2425
)
@@ -60,11 +61,17 @@ func TestVolumeLoad(t *testing.T) {
6061
}
6162
default:
6263
}
63-
cm, err := chain.NewManager(cs)
64+
65+
tp, err := transactionpool.New(cs, g, filepath.Join(dir, "transactionpool"))
66+
if err != nil {
67+
t.Fatal(err)
68+
}
69+
defer tp.Close()
70+
71+
cm, err := chain.NewManager(cs, chain.NewTPool(tp))
6472
if err != nil {
6573
t.Fatal(err)
6674
}
67-
defer cm.Close()
6875
defer cm.Close()
6976

7077
webhookReporter, err := webhooks.NewManager(db, log.Named("webhooks"))
@@ -170,11 +177,17 @@ func TestAddVolume(t *testing.T) {
170177
}
171178
default:
172179
}
173-
cm, err := chain.NewManager(cs)
180+
181+
tp, err := transactionpool.New(cs, g, filepath.Join(dir, "transactionpool"))
182+
if err != nil {
183+
t.Fatal(err)
184+
}
185+
defer tp.Close()
186+
187+
cm, err := chain.NewManager(cs, chain.NewTPool(tp))
174188
if err != nil {
175189
t.Fatal(err)
176190
}
177-
defer cm.Close()
178191
defer cm.Close()
179192

180193
webhookReporter, err := webhooks.NewManager(db, log.Named("webhooks"))
@@ -243,11 +256,17 @@ func TestRemoveVolume(t *testing.T) {
243256
}
244257
default:
245258
}
246-
cm, err := chain.NewManager(cs)
259+
260+
tp, err := transactionpool.New(cs, g, filepath.Join(dir, "transactionpool"))
261+
if err != nil {
262+
t.Fatal(err)
263+
}
264+
defer tp.Close()
265+
266+
cm, err := chain.NewManager(cs, chain.NewTPool(tp))
247267
if err != nil {
248268
t.Fatal(err)
249269
}
250-
defer cm.Close()
251270
defer cm.Close()
252271

253272
// initialize the storage manager
@@ -411,11 +430,17 @@ func TestRemoveCorrupt(t *testing.T) {
411430
}
412431
default:
413432
}
414-
cm, err := chain.NewManager(cs)
433+
434+
tp, err := transactionpool.New(cs, g, filepath.Join(dir, "transactionpool"))
435+
if err != nil {
436+
t.Fatal(err)
437+
}
438+
defer tp.Close()
439+
440+
cm, err := chain.NewManager(cs, chain.NewTPool(tp))
415441
if err != nil {
416442
t.Fatal(err)
417443
}
418-
defer cm.Close()
419444
defer cm.Close()
420445

421446
// initialize the storage manager
@@ -611,12 +636,18 @@ func TestRemoveMissing(t *testing.T) {
611636
}
612637
default:
613638
}
614-
cm, err := chain.NewManager(cs)
639+
640+
tp, err := transactionpool.New(cs, g, filepath.Join(dir, "transactionpool"))
641+
if err != nil {
642+
t.Fatal(err)
643+
}
644+
defer tp.Close()
645+
646+
cm, err := chain.NewManager(cs, chain.NewTPool(tp))
615647
if err != nil {
616648
t.Fatal(err)
617649
}
618650
defer cm.Close()
619-
defer cm.Close()
620651

621652
// initialize the storage manager
622653
webhookReporter, err := webhooks.NewManager(db, log.Named("webhooks"))
@@ -788,11 +819,17 @@ func TestVolumeConcurrency(t *testing.T) {
788819
}
789820
default:
790821
}
791-
cm, err := chain.NewManager(cs)
822+
823+
tp, err := transactionpool.New(cs, g, filepath.Join(dir, "transactionpool"))
824+
if err != nil {
825+
t.Fatal(err)
826+
}
827+
defer tp.Close()
828+
829+
cm, err := chain.NewManager(cs, chain.NewTPool(tp))
792830
if err != nil {
793831
t.Fatal(err)
794832
}
795-
defer cm.Close()
796833
defer cm.Close()
797834

798835
// initialize the storage manager
@@ -948,11 +985,17 @@ func TestVolumeGrow(t *testing.T) {
948985
}
949986
default:
950987
}
951-
cm, err := chain.NewManager(cs)
988+
989+
tp, err := transactionpool.New(cs, g, filepath.Join(dir, "transactionpool"))
990+
if err != nil {
991+
t.Fatal(err)
992+
}
993+
defer tp.Close()
994+
995+
cm, err := chain.NewManager(cs, chain.NewTPool(tp))
952996
if err != nil {
953997
t.Fatal(err)
954998
}
955-
defer cm.Close()
956999
defer cm.Close()
9571000

9581001
// initialize the storage manager
@@ -1067,7 +1110,14 @@ func TestVolumeShrink(t *testing.T) {
10671110
}
10681111
default:
10691112
}
1070-
cm, err := chain.NewManager(cs)
1113+
1114+
tp, err := transactionpool.New(cs, g, filepath.Join(dir, "transactionpool"))
1115+
if err != nil {
1116+
t.Fatal(err)
1117+
}
1118+
defer tp.Close()
1119+
1120+
cm, err := chain.NewManager(cs, chain.NewTPool(tp))
10711121
if err != nil {
10721122
t.Fatal(err)
10731123
}
@@ -1229,7 +1279,14 @@ func TestVolumeManagerReadWrite(t *testing.T) {
12291279
}
12301280
default:
12311281
}
1232-
cm, err := chain.NewManager(cs)
1282+
1283+
tp, err := transactionpool.New(cs, g, filepath.Join(dir, "transactionpool"))
1284+
if err != nil {
1285+
t.Fatal(err)
1286+
}
1287+
defer tp.Close()
1288+
1289+
cm, err := chain.NewManager(cs, chain.NewTPool(tp))
12331290
if err != nil {
12341291
t.Fatal(err)
12351292
}
@@ -1348,7 +1405,14 @@ func TestSectorCache(t *testing.T) {
13481405
}
13491406
default:
13501407
}
1351-
cm, err := chain.NewManager(cs)
1408+
1409+
tp, err := transactionpool.New(cs, g, filepath.Join(dir, "transactionpool"))
1410+
if err != nil {
1411+
t.Fatal(err)
1412+
}
1413+
defer tp.Close()
1414+
1415+
cm, err := chain.NewManager(cs, chain.NewTPool(tp))
13521416
if err != nil {
13531417
t.Fatal(err)
13541418
}
@@ -1477,7 +1541,14 @@ func BenchmarkVolumeManagerWrite(b *testing.B) {
14771541
b.Fatal(err)
14781542
default:
14791543
}
1480-
cm, err := chain.NewManager(cs)
1544+
1545+
tp, err := transactionpool.New(cs, g, filepath.Join(dir, "transactionpool"))
1546+
if err != nil {
1547+
b.Fatal(err)
1548+
}
1549+
defer tp.Close()
1550+
1551+
cm, err := chain.NewManager(cs, chain.NewTPool(tp))
14811552
if err != nil {
14821553
b.Fatal(err)
14831554
}
@@ -1552,7 +1623,14 @@ func BenchmarkNewVolume(b *testing.B) {
15521623
b.Fatal(err)
15531624
default:
15541625
}
1555-
cm, err := chain.NewManager(cs)
1626+
1627+
tp, err := transactionpool.New(cs, g, filepath.Join(dir, "transactionpool"))
1628+
if err != nil {
1629+
b.Fatal(err)
1630+
}
1631+
defer tp.Close()
1632+
1633+
cm, err := chain.NewManager(cs, chain.NewTPool(tp))
15561634
if err != nil {
15571635
b.Fatal(err)
15581636
}
@@ -1610,7 +1688,14 @@ func BenchmarkVolumeManagerRead(b *testing.B) {
16101688
b.Fatal(err)
16111689
default:
16121690
}
1613-
cm, err := chain.NewManager(cs)
1691+
1692+
tp, err := transactionpool.New(cs, g, filepath.Join(dir, "transactionpool"))
1693+
if err != nil {
1694+
b.Fatal(err)
1695+
}
1696+
defer tp.Close()
1697+
1698+
cm, err := chain.NewManager(cs, chain.NewTPool(tp))
16141699
if err != nil {
16151700
b.Fatal(err)
16161701
}
@@ -1687,7 +1772,14 @@ func BenchmarkVolumeRemove(b *testing.B) {
16871772
b.Fatal(err)
16881773
default:
16891774
}
1690-
cm, err := chain.NewManager(cs)
1775+
1776+
tp, err := transactionpool.New(cs, g, filepath.Join(dir, "transactionpool"))
1777+
if err != nil {
1778+
b.Fatal(err)
1779+
}
1780+
defer tp.Close()
1781+
1782+
cm, err := chain.NewManager(cs, chain.NewTPool(tp))
16911783
if err != nil {
16921784
b.Fatal(err)
16931785
}

0 commit comments

Comments
 (0)