diff --git a/wallet/wallet.go b/wallet/wallet.go index f5ab36d..8c1d21f 100644 --- a/wallet/wallet.go +++ b/wallet/wallet.go @@ -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) diff --git a/wallet/wallet_test.go b/wallet/wallet_test.go index d2ecf5e..6c1ef6b 100644 --- a/wallet/wallet_test.go +++ b/wallet/wallet_test.go @@ -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 @@ -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) } @@ -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 {