make TxStore use generic interface

Means we can replace a bunch of type assertions with generic code.
This commit is contained in:
Owain G. Ainsworth 2014-01-23 00:00:10 +00:00
parent f1577a1718
commit ce2decb275
3 changed files with 20 additions and 27 deletions

View file

@ -247,15 +247,8 @@ func (a *Account) ListTransactions(from, count int) ([]map[string]interface{}, e
lastLookupIdx := len(a.TxStore.s) - count lastLookupIdx := len(a.TxStore.s) - count
// Search in reverse order: lookup most recently-added first. // Search in reverse order: lookup most recently-added first.
for i := len(a.TxStore.s) - 1; i >= from && i >= lastLookupIdx; i-- { for i := len(a.TxStore.s) - 1; i >= from && i >= lastLookupIdx; i-- {
switch e := a.TxStore.s[i].(type) { txInfoList = append(txInfoList,
case *tx.SendTx: a.TxStore.s[i].TxInfo(a.name, bs.Height, a.Net())...)
infos := e.TxInfo(a.name, bs.Height, a.Net())
txInfoList = append(txInfoList, infos...)
case *tx.RecvTx:
info := e.TxInfo(a.name, bs.Height, a.Net())
txInfoList = append(txInfoList, info)
}
} }
a.mtx.RUnlock() a.mtx.RUnlock()
a.TxStore.RUnlock() a.TxStore.RUnlock()
@ -287,7 +280,7 @@ func (a *Account) ListAddressTransactions(pkHashes map[string]struct{}) (
} }
if _, ok := pkHashes[string(rtx.ReceiverHash[:])]; ok { if _, ok := pkHashes[string(rtx.ReceiverHash[:])]; ok {
info := rtx.TxInfo(a.name, bs.Height, a.Net()) info := rtx.TxInfo(a.name, bs.Height, a.Net())
txInfoList = append(txInfoList, info) txInfoList = append(txInfoList, info...)
} }
} }
a.mtx.RUnlock() a.mtx.RUnlock()
@ -313,15 +306,8 @@ func (a *Account) ListAllTransactions() ([]map[string]interface{}, error) {
// Search in reverse order: lookup most recently-added first. // Search in reverse order: lookup most recently-added first.
for i := len(a.TxStore.s) - 1; i >= 0; i-- { for i := len(a.TxStore.s) - 1; i >= 0; i-- {
switch e := a.TxStore.s[i].(type) { txInfoList = append(txInfoList,
case *tx.SendTx: a.TxStore.s[i].TxInfo(a.name, bs.Height, a.Net())...)
infos := e.TxInfo(a.name, bs.Height, a.Net())
txInfoList = append(txInfoList, infos...)
case *tx.RecvTx:
info := e.TxInfo(a.name, bs.Height, a.Net())
txInfoList = append(txInfoList, info)
}
} }
a.mtx.RUnlock() a.mtx.RUnlock()
a.TxStore.RUnlock() a.TxStore.RUnlock()

View file

@ -389,7 +389,7 @@ func NtfnProcessedTx(n btcjson.Cmd, marshaled []byte) {
// Notify frontends of new recv tx and mark as notified. // Notify frontends of new recv tx and mark as notified.
NotifiedRecvTxChans.add <- *recvTxOP NotifiedRecvTxChans.add <- *recvTxOP
NotifyNewTxDetails(frontendNotificationMaster, a.Name(), t.TxInfo(a.Name(), NotifyNewTxDetails(frontendNotificationMaster, a.Name(), t.TxInfo(a.Name(),
ptn.BlockHeight, a.Wallet.Net())) ptn.BlockHeight, a.Wallet.Net())[0])
} }
if !ptn.Spent { if !ptn.Spent {

View file

@ -102,8 +102,15 @@ type OutPoint btcwire.OutPoint
// of variable length. // of variable length.
type PkScript []byte type PkScript []byte
// Tx is a generic type that can be used in place of either of the tx types in
// a TxStore.
type Tx interface {
io.WriterTo
ReadFromVersion(uint32, io.Reader) (int64, error)
TxInfo(string, int32, btcwire.BitcoinNet) []map[string]interface{}
}
// TxStore is a slice holding RecvTx and SendTx pointers. // TxStore is a slice holding RecvTx and SendTx pointers.
type TxStore []interface{} type TxStore []Tx
const ( const (
addressUnknown byte = iota addressUnknown byte = iota
@ -725,7 +732,7 @@ func (txs *TxStore) ReadFrom(r io.Reader) (int64, error) {
vers := binary.LittleEndian.Uint32(versionBytes) vers := binary.LittleEndian.Uint32(versionBytes)
read += int64(n) read += int64(n)
store := []interface{}{} store := []Tx{}
defer func() { defer func() {
*txs = store *txs = store
}() }()
@ -742,7 +749,7 @@ func (txs *TxStore) ReadFrom(r io.Reader) (int64, error) {
} }
read += n read += n
var tx io.ReaderFrom var tx Tx
// Read tx. // Read tx.
switch header { switch header {
case recvTxHeader: case recvTxHeader:
@ -788,7 +795,7 @@ func (txs *TxStore) WriteTo(w io.Writer) (int64, error) {
} }
written = int64(n) written = int64(n)
store := ([]interface{})(*txs) store := ([]Tx)(*txs)
for _, tx := range store { for _, tx := range store {
// Write header for tx. // Write header for tx.
var header byte var header byte
@ -861,7 +868,7 @@ func (txs *TxStore) InsertRecvTx(tx *RecvTx) {
// Correct results rely on txs being sorted by block height in // Correct results rely on txs being sorted by block height in
// increasing order. // increasing order.
func (txs *TxStore) Rollback(height int32, hash *btcwire.ShaHash) (modified bool) { func (txs *TxStore) Rollback(height int32, hash *btcwire.ShaHash) (modified bool) {
s := ([]interface{})(*txs) s := ([]Tx)(*txs)
// endlen specifies the final length of the rolled-back TxStore. // endlen specifies the final length of the rolled-back TxStore.
// Past endlen, array elements are nilled. We do this instead of // Past endlen, array elements are nilled. We do this instead of
@ -1023,7 +1030,7 @@ func (tx *RecvTx) WriteTo(w io.Writer) (n int64, err error) {
// TxInfo returns a slice of maps that may be marshaled as a JSON array // TxInfo returns a slice of maps that may be marshaled as a JSON array
// of JSON objects for a listtransactions RPC reply. // of JSON objects for a listtransactions RPC reply.
func (tx *RecvTx) TxInfo(account string, curheight int32, func (tx *RecvTx) TxInfo(account string, curheight int32,
net btcwire.BitcoinNet) map[string]interface{} { net btcwire.BitcoinNet) []map[string]interface{} {
address := "Unknown" address := "Unknown"
addr, err := btcutil.NewAddressPubKeyHash(tx.ReceiverHash, net) addr, err := btcutil.NewAddressPubKeyHash(tx.ReceiverHash, net)
@ -1049,7 +1056,7 @@ func (tx *RecvTx) TxInfo(account string, curheight int32,
txInfo["confirmations"] = 0 txInfo["confirmations"] = 0
} }
return txInfo return []map[string]interface{}{txInfo}
} }
func (tx *SendTx) ReadFromVersion(vers uint32, r io.Reader) (n int64, err error) { func (tx *SendTx) ReadFromVersion(vers uint32, r io.Reader) (n int64, err error) {