Skip to content

Commit

Permalink
Merge pull request #24 from SiaFoundation/pj/fund-txn-immature-outputs
Browse files Browse the repository at this point in the history
Don't use immature outputs when funding a transaction
  • Loading branch information
ChrisSchinnerl committed Feb 22, 2024
2 parents cf4be61 + 28f4ee4 commit c7d7289
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 15 deletions.
5 changes: 3 additions & 2 deletions wallet/wallet.go
Expand Up @@ -294,10 +294,11 @@ func (sw *SingleAddressWallet) FundTransaction(txn *types.Transaction, amount ty
sw.mu.Lock()
defer sw.mu.Unlock()

// remove locked and spent outputs
// remove immature, locked and spent outputs
cs := sw.cm.TipState()
utxos := make([]types.SiacoinElement, 0, len(elements))
for _, sce := range elements {
if time.Now().Before(sw.locked[sce.ID]) || tpoolSpent[sce.ID] {
if time.Now().Before(sw.locked[sce.ID]) || tpoolSpent[sce.ID] || cs.Index.Height < sce.MaturityHeight {
continue
}
utxos = append(utxos, sce.SiacoinElement)
Expand Down
32 changes: 19 additions & 13 deletions wallet/wallet_test.go
Expand Up @@ -79,10 +79,27 @@ func TestWallet(t *testing.T) {
}

// check that the wallet has an immature balance
if checkBalance(w, types.ZeroCurrency, types.ZeroCurrency, initialReward, types.ZeroCurrency); err != nil {
if err := checkBalance(w, types.ZeroCurrency, types.ZeroCurrency, initialReward, types.ZeroCurrency); err != nil {
t.Fatal(err)
}

// create a transaction that splits the wallet's balance into 20 outputs
txn := types.Transaction{
SiacoinOutputs: make([]types.SiacoinOutput, 20),
}
for i := range txn.SiacoinOutputs {
txn.SiacoinOutputs[i] = types.SiacoinOutput{
Value: initialReward.Div64(20),
Address: w.Address(),
}
}

// try funding the transaction, expect it to fail since the outputs are immature
_, err = w.FundTransaction(&txn, initialReward, false)
if err != wallet.ErrNotEnoughFunds {
t.Fatal("expected ErrNotEnoughFunds, got", err)
}

// mine until the payout matures
tip := cm.TipState()
target := tip.MaturityHeight() + 1
Expand All @@ -94,7 +111,7 @@ func TestWallet(t *testing.T) {
}

// check that one payout has matured
if checkBalance(w, initialReward, initialReward, types.ZeroCurrency, types.ZeroCurrency); err != nil {
if err := checkBalance(w, initialReward, initialReward, types.ZeroCurrency, types.ZeroCurrency); err != nil {
t.Fatal(err)
}

Expand All @@ -116,17 +133,6 @@ func TestWallet(t *testing.T) {
t.Fatalf("expected miner payout, got %v", events[0].Source)
}

// split the wallet's balance into 20 outputs
txn := types.Transaction{
SiacoinOutputs: make([]types.SiacoinOutput, 20),
}
for i := range txn.SiacoinOutputs {
txn.SiacoinOutputs[i] = types.SiacoinOutput{
Value: initialReward.Div64(20),
Address: w.Address(),
}
}

// fund and sign the transaction
toSign, err := w.FundTransaction(&txn, initialReward, false)
if err != nil {
Expand Down

0 comments on commit c7d7289

Please sign in to comment.