Clean up replying to frontend commands.

This change moves the handlers to a map (instead of falling through a
switch statement), and updates each handler to use a btcjson.Cmd
instead of passing parameters in a btcjson.Message manually.

Plenty of comments were also added, which should also make the code
much more understandable.
This commit is contained in:
Josh Rickmar 2013-11-12 12:01:32 -05:00
parent e9b7fd2fcf
commit be26855266
3 changed files with 523 additions and 586 deletions

29
cmd.go
View file

@ -298,22 +298,23 @@ func GetCurBlock() (bs wallet.BlockStamp, err error) {
btcdMsgs <- mcmd btcdMsgs <- mcmd
// Block until reply is ready. // Block until reply is ready.
if reply := <-c; reply != nil { reply, ok := <-c
curBlock.Lock() if !ok || reply == nil {
if reply.height > curBlock.BlockStamp.Height { return wallet.BlockStamp{
bs = wallet.BlockStamp{ Height: int32(btcutil.BlockHeightUnknown),
Height: reply.height, }, errors.New("current block unavailable")
Hash: *reply.hash,
}
curBlock.BlockStamp = bs
}
curBlock.Unlock()
return bs, nil
} }
return wallet.BlockStamp{ curBlock.Lock()
Height: int32(btcutil.BlockHeightUnknown), if reply.height > curBlock.BlockStamp.Height {
}, errors.New("current block unavailable") bs = wallet.BlockStamp{
Height: reply.height,
Hash: *reply.hash,
}
curBlock.BlockStamp = bs
}
curBlock.Unlock()
return bs, nil
} }
// CalculateBalance sums the amounts of all unspent transaction // CalculateBalance sums the amounts of all unspent transaction

1048
cmdmgr.go

File diff suppressed because it is too large Load diff

View file

@ -23,6 +23,7 @@ import (
"github.com/conformal/btcscript" "github.com/conformal/btcscript"
"github.com/conformal/btcutil" "github.com/conformal/btcutil"
"github.com/conformal/btcwallet/tx" "github.com/conformal/btcwallet/tx"
"github.com/conformal/btcwallet/wallet"
"github.com/conformal/btcwire" "github.com/conformal/btcwire"
"sort" "sort"
"sync" "sync"
@ -37,6 +38,14 @@ var ErrInsufficientFunds = errors.New("insufficient funds")
// requested bitcoin network is invalid (neither mainnet nor testnet). // requested bitcoin network is invalid (neither mainnet nor testnet).
var ErrUnknownBitcoinNet = errors.New("unknown bitcoin network") var ErrUnknownBitcoinNet = errors.New("unknown bitcoin network")
// ErrNonPositiveAmount represents an error where a bitcoin amount is
// not positive (either negative, or zero).
var ErrNonPositiveAmount = errors.New("amount is not positive")
// ErrNegativeFee represents an error where a fee is erroneously
// negative.
var ErrNegativeFee = errors.New("fee is negative")
// TxFee represents the global transaction fee added to newly-created // TxFee represents the global transaction fee added to newly-created
// transactions and sent as a reward to the block miner. i is measured // transactions and sent as a reward to the block miner. i is measured
// in satoshis. // in satoshis.
@ -140,7 +149,7 @@ func selectInputs(s tx.UtxoStore, amt uint64, minconf int) (inputs []*tx.Utxo, b
// address, changeUtxo will point to a unconfirmed (height = -1, zeroed // address, changeUtxo will point to a unconfirmed (height = -1, zeroed
// block hash) Utxo. ErrInsufficientFunds is returned if there are not // block hash) Utxo. ErrInsufficientFunds is returned if there are not
// enough eligible unspent outputs to create the transaction. // enough eligible unspent outputs to create the transaction.
func (w *BtcWallet) txToPairs(pairs map[string]uint64, fee uint64, minconf int) (*CreatedTx, error) { func (w *BtcWallet) txToPairs(pairs map[string]int64, fee int64, minconf int) (*CreatedTx, error) {
// Recorded unspent transactions should not be modified until this // Recorded unspent transactions should not be modified until this
// finishes. // finishes.
w.UtxoStore.RLock() w.UtxoStore.RLock()
@ -150,13 +159,22 @@ func (w *BtcWallet) txToPairs(pairs map[string]uint64, fee uint64, minconf int)
msgtx := btcwire.NewMsgTx() msgtx := btcwire.NewMsgTx()
// Calculate minimum amount needed for inputs. // Calculate minimum amount needed for inputs.
var amt uint64 var amt int64
for _, v := range pairs { for _, v := range pairs {
// Error out if any amount is negative.
if v <= 0 {
return nil, ErrNonPositiveAmount
}
amt += v amt += v
} }
if fee < 0 {
return nil, ErrNegativeFee
}
// Select unspent outputs to be used in transaction. // Select unspent outputs to be used in transaction.
inputs, btcout, err := selectInputs(w.UtxoStore.s, amt+fee, minconf) inputs, btcout, err := selectInputs(w.UtxoStore.s, uint64(amt+fee),
minconf)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -181,7 +199,7 @@ func (w *BtcWallet) txToPairs(pairs map[string]uint64, fee uint64, minconf int)
// a new address we own. // a new address we own.
var changeUtxo *tx.Utxo var changeUtxo *tx.Utxo
var changeAddr string var changeAddr string
if btcout > amt+fee { if btcout > uint64(amt+fee) {
// Create a new address to spend leftover outputs to. // Create a new address to spend leftover outputs to.
// TODO(jrick): use the next chained address, not the next unused. // TODO(jrick): use the next chained address, not the next unused.
var err error var err error
@ -191,7 +209,7 @@ func (w *BtcWallet) txToPairs(pairs map[string]uint64, fee uint64, minconf int)
} }
// Spend change // Spend change
change := btcout - (amt + fee) change := btcout - uint64(amt+fee)
changeAddrHash, _, err := btcutil.DecodeAddress(changeAddr) changeAddrHash, _, err := btcutil.DecodeAddress(changeAddr)
if err != nil { if err != nil {
return nil, fmt.Errorf("cannot decode new address: %s", err) return nil, fmt.Errorf("cannot decode new address: %s", err)
@ -226,7 +244,9 @@ func (w *BtcWallet) txToPairs(pairs map[string]uint64, fee uint64, minconf int)
return nil, err return nil, err
} }
privkey, err := w.GetAddressKey(addrstr) privkey, err := w.GetAddressKey(addrstr)
if err != nil { if err == wallet.ErrWalletLocked {
return nil, wallet.ErrWalletLocked
} else if err != nil {
return nil, fmt.Errorf("cannot get address key: %v", err) return nil, fmt.Errorf("cannot get address key: %v", err)
} }
ai, err := w.GetAddressInfo(addrstr) ai, err := w.GetAddressInfo(addrstr)