parent
845d54da55
commit
34b683b4aa
5 changed files with 121 additions and 1 deletions
24
account.go
24
account.go
|
@ -271,6 +271,30 @@ func (a *Account) CurrentAddress() (btcutil.Address, error) {
|
||||||
return addr, nil
|
return addr, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ListSinceBlock returns a slice of maps with details about transactions since
|
||||||
|
// the given block. If the block is -1 then all transactions are included.
|
||||||
|
// transaction. This is intended to be used for listsinceblock RPC
|
||||||
|
// replies.
|
||||||
|
func (a *Account) ListSinceBlock(since, curBlockHeight int32, minconf int) ([]map[string]interface{}, error) {
|
||||||
|
var txInfoList []map[string]interface{}
|
||||||
|
a.mtx.RLock()
|
||||||
|
defer a.mtx.RUnlock()
|
||||||
|
a.TxStore.RLock()
|
||||||
|
defer a.TxStore.RUnlock()
|
||||||
|
|
||||||
|
for _, tx := range a.TxStore.s {
|
||||||
|
// check block number.
|
||||||
|
if since != -1 && tx.Height() <= since {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
txInfoList = append(txInfoList,
|
||||||
|
tx.TxInfo(a.name, curBlockHeight, a.Net())...)
|
||||||
|
}
|
||||||
|
|
||||||
|
return txInfoList, nil
|
||||||
|
}
|
||||||
|
|
||||||
// ListTransactions returns a slice of maps with details about a recorded
|
// ListTransactions returns a slice of maps with details about a recorded
|
||||||
// transaction. This is intended to be used for listtransactions RPC
|
// transaction. This is intended to be used for listtransactions RPC
|
||||||
// replies.
|
// replies.
|
||||||
|
|
|
@ -405,6 +405,25 @@ func (store *AccountStore) ListAccounts(minconf int) map[string]float64 {
|
||||||
return pairs
|
return pairs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ListSinceBlock returns a slice of maps of strings to interface containing
|
||||||
|
// structures defining all transactions in the wallets since the given block.
|
||||||
|
// To be used for the listsinceblock command.
|
||||||
|
func (store *AccountStore) ListSinceBlock(since, curBlockHeight int32, minconf int) ([]map[string]interface{}, error) {
|
||||||
|
store.RLock()
|
||||||
|
defer store.RUnlock()
|
||||||
|
|
||||||
|
// Create and fill a map of account names and their balances.
|
||||||
|
txInfoList := []map[string]interface{}{}
|
||||||
|
for _, a := range store.accounts {
|
||||||
|
txTmp, err := a.ListSinceBlock(since, curBlockHeight, minconf)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
txInfoList = append(txInfoList, txTmp...)
|
||||||
|
}
|
||||||
|
return txInfoList, nil
|
||||||
|
}
|
||||||
|
|
||||||
// RescanActiveAddresses begins a rescan for all active addresses for
|
// RescanActiveAddresses begins a rescan for all active addresses for
|
||||||
// each account.
|
// each account.
|
||||||
//
|
//
|
||||||
|
|
|
@ -83,7 +83,7 @@ func (btcd *BtcdRPCConn) SendRequest(request *RPCRequest) chan *RPCResponse {
|
||||||
default:
|
default:
|
||||||
addRequest := &AddRPCRequest{
|
addRequest := &AddRPCRequest{
|
||||||
Request: request,
|
Request: request,
|
||||||
ResponseChan: make(chan chan *RPCResponse),
|
ResponseChan: make(chan chan *RPCResponse, 1),
|
||||||
}
|
}
|
||||||
btcd.addRequest <- addRequest
|
btcd.addRequest <- addRequest
|
||||||
return <-addRequest.ResponseChan
|
return <-addRequest.ResponseChan
|
||||||
|
|
64
cmdmgr.go
64
cmdmgr.go
|
@ -41,6 +41,7 @@ var rpcHandlers = map[string]cmdHandler{
|
||||||
"importprivkey": ImportPrivKey,
|
"importprivkey": ImportPrivKey,
|
||||||
"keypoolrefill": KeypoolRefill,
|
"keypoolrefill": KeypoolRefill,
|
||||||
"listaccounts": ListAccounts,
|
"listaccounts": ListAccounts,
|
||||||
|
"listsinceblock": ListSinceBlock,
|
||||||
"listtransactions": ListTransactions,
|
"listtransactions": ListTransactions,
|
||||||
"sendfrom": SendFrom,
|
"sendfrom": SendFrom,
|
||||||
"sendmany": SendMany,
|
"sendmany": SendMany,
|
||||||
|
@ -629,6 +630,69 @@ func ListAccounts(icmd btcjson.Cmd) (interface{}, *btcjson.Error) {
|
||||||
return accountstore.ListAccounts(cmd.MinConf), nil
|
return accountstore.ListAccounts(cmd.MinConf), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ListSinceBlock handles a listsinceblock request by returning an array of maps
|
||||||
|
// with details of sent and received wallet transactions since the given block.
|
||||||
|
func ListSinceBlock(icmd btcjson.Cmd) (interface{}, *btcjson.Error) {
|
||||||
|
cmd, ok := icmd.(*btcjson.ListSinceBlockCmd)
|
||||||
|
if !ok {
|
||||||
|
return nil, &btcjson.ErrInternal
|
||||||
|
}
|
||||||
|
|
||||||
|
height := int32(-1)
|
||||||
|
if cmd.BlockHash != "" {
|
||||||
|
br, err := GetBlock(CurrentRPCConn(), cmd.BlockHash)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
height = int32(br.Height)
|
||||||
|
}
|
||||||
|
|
||||||
|
bs, err := GetCurBlock()
|
||||||
|
if err != nil {
|
||||||
|
return nil, &btcjson.Error{
|
||||||
|
Code: btcjson.ErrWallet.Code,
|
||||||
|
Message: err.Error(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// For the result we need the block hash for the last block counted
|
||||||
|
// in the blockchain due to confirmations. We send this off now so that
|
||||||
|
// it can arrive asynchronously while we figure out the rest.
|
||||||
|
gbh, err := btcjson.NewGetBlockHashCmd(<-NewJSONID,
|
||||||
|
int64(bs.Height)+1-int64(cmd.TargetConfirmations))
|
||||||
|
if err != nil {
|
||||||
|
return nil, &btcjson.Error{
|
||||||
|
Code: btcjson.ErrWallet.Code,
|
||||||
|
Message: err.Error(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bhChan := CurrentRPCConn().SendRequest(NewRPCRequest(gbh, new(string)))
|
||||||
|
|
||||||
|
txInfoList, err := accountstore.ListSinceBlock(height, bs.Height,
|
||||||
|
cmd.TargetConfirmations)
|
||||||
|
if err != nil {
|
||||||
|
return nil, &btcjson.Error{
|
||||||
|
Code: btcjson.ErrWallet.Code,
|
||||||
|
Message: err.Error(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Done with work, get the response.
|
||||||
|
response := <-bhChan
|
||||||
|
if response.Err != nil {
|
||||||
|
return nil, response.Err
|
||||||
|
}
|
||||||
|
|
||||||
|
hash := response.Result.(*string)
|
||||||
|
|
||||||
|
res := make(map[string]interface{})
|
||||||
|
res["transactions"] = txInfoList
|
||||||
|
res["lastblock"] = *hash
|
||||||
|
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
|
||||||
// ListTransactions handles a listtransactions request by returning an
|
// ListTransactions handles a listtransactions request by returning an
|
||||||
// array of maps with details of sent and recevied wallet transactions.
|
// array of maps with details of sent and recevied wallet transactions.
|
||||||
func ListTransactions(icmd btcjson.Cmd) (interface{}, *btcjson.Error) {
|
func ListTransactions(icmd btcjson.Cmd) (interface{}, *btcjson.Error) {
|
||||||
|
|
13
tx/tx.go
13
tx/tx.go
|
@ -108,6 +108,7 @@ type Tx interface {
|
||||||
io.WriterTo
|
io.WriterTo
|
||||||
ReadFromVersion(uint32, io.Reader) (int64, error)
|
ReadFromVersion(uint32, io.Reader) (int64, error)
|
||||||
TxInfo(string, int32, btcwire.BitcoinNet) []map[string]interface{}
|
TxInfo(string, int32, btcwire.BitcoinNet) []map[string]interface{}
|
||||||
|
Height() int32
|
||||||
}
|
}
|
||||||
|
|
||||||
// TxStore is a slice holding RecvTx and SendTx pointers.
|
// TxStore is a slice holding RecvTx and SendTx pointers.
|
||||||
|
@ -1060,6 +1061,12 @@ func (tx *RecvTx) TxInfo(account string, curheight int32,
|
||||||
return []map[string]interface{}{txInfo}
|
return []map[string]interface{}{txInfo}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Height returns the current blockheight of the transaction, implementing the
|
||||||
|
// Tx interface.
|
||||||
|
func (tx *RecvTx) Height() int32 {
|
||||||
|
return tx.BlockHeight
|
||||||
|
}
|
||||||
|
|
||||||
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) {
|
||||||
var read int64
|
var read int64
|
||||||
|
|
||||||
|
@ -1197,3 +1204,9 @@ func (tx *SendTx) TxInfo(account string, curheight int32,
|
||||||
|
|
||||||
return reply
|
return reply
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Height returns the current blockheight of the transaction, implementing the
|
||||||
|
// Tx interface.
|
||||||
|
func (tx *SendTx) Height() int32 {
|
||||||
|
return tx.BlockHeight
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue