parent
9aa27517eb
commit
b978c7e059
4 changed files with 188 additions and 10 deletions
|
@ -198,7 +198,7 @@ func (a *Account) ListSinceBlock(since, curBlockHeight int32, minconf int) ([]ma
|
|||
var txInfoList []map[string]interface{}
|
||||
for _, tx := range a.TxStore {
|
||||
// check block number.
|
||||
if since != -1 && tx.Height() <= since {
|
||||
if since != -1 && tx.GetBlockHeight() <= since {
|
||||
continue
|
||||
}
|
||||
|
||||
|
@ -629,7 +629,7 @@ func (a *Account) TotalReceived(confirms int) (float64, error) {
|
|||
}
|
||||
|
||||
// Tally if the appropiate number of block confirmations have passed.
|
||||
if confirmed(confirms, recvtx.Height(), bs.Height) {
|
||||
if confirmed(confirms, recvtx.GetBlockHeight(), bs.Height) {
|
||||
totalSatoshis += recvtx.Amount
|
||||
}
|
||||
}
|
||||
|
|
29
acctmgr.go
29
acctmgr.go
|
@ -472,6 +472,35 @@ func (am *AccountManager) ListSinceBlock(since, curBlockHeight int32, minconf in
|
|||
return txInfoList, nil
|
||||
}
|
||||
|
||||
// accountTx represents an account/transaction pair to be used by
|
||||
// GetTransaction().
|
||||
type accountTx struct {
|
||||
Account string
|
||||
Tx tx.Tx
|
||||
}
|
||||
|
||||
// GetTransaction returns an array of accountTx to fully represent the effect of
|
||||
// a transaction on locally known wallets. If we know nothing about a
|
||||
// transaction an empty array will be returned.
|
||||
func (am *AccountManager) GetTransaction(txid string) []accountTx {
|
||||
accumulatedTxen := []accountTx{}
|
||||
|
||||
for _, a := range am.AllAccounts() {
|
||||
for _, t := range a.TxStore {
|
||||
if t.GetTxID().String() != txid {
|
||||
continue
|
||||
}
|
||||
accumulatedTxen = append(accumulatedTxen,
|
||||
accountTx{
|
||||
Account: a.name,
|
||||
Tx: t.Copy(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return accumulatedTxen
|
||||
}
|
||||
|
||||
// RescanActiveAddresses begins a rescan for all active addresses for
|
||||
// each account.
|
||||
//
|
||||
|
|
84
rpcserver.go
84
rpcserver.go
|
@ -41,6 +41,7 @@ var rpcHandlers = map[string]cmdHandler{
|
|||
"getnewaddress": GetNewAddress,
|
||||
"getrawchangeaddress": GetRawChangeAddress,
|
||||
"getreceivedbyaccount": GetReceivedByAccount,
|
||||
"gettransaction": GetTransaction,
|
||||
"importprivkey": ImportPrivKey,
|
||||
"keypoolrefill": KeypoolRefill,
|
||||
"listaccounts": ListAccounts,
|
||||
|
@ -60,7 +61,6 @@ var rpcHandlers = map[string]cmdHandler{
|
|||
"dumpwallet": Unimplemented,
|
||||
"getblocktemplate": Unimplemented,
|
||||
"getreceivedbyaddress": Unimplemented,
|
||||
"gettransaction": Unimplemented,
|
||||
"gettxout": Unimplemented,
|
||||
"gettxoutsetinfo": Unimplemented,
|
||||
"getwork": Unimplemented,
|
||||
|
@ -782,6 +782,88 @@ func GetReceivedByAccount(icmd btcjson.Cmd) (interface{}, *btcjson.Error) {
|
|||
return amt, nil
|
||||
}
|
||||
|
||||
func GetTransaction(icmd btcjson.Cmd) (interface{}, *btcjson.Error) {
|
||||
// Type assert icmd to access parameters.
|
||||
cmd, ok := icmd.(*btcjson.GetTransactionCmd)
|
||||
if !ok {
|
||||
return nil, &btcjson.ErrInternal
|
||||
}
|
||||
|
||||
accumulatedTxen := AcctMgr.GetTransaction(cmd.Txid)
|
||||
if len(accumulatedTxen) == 0 {
|
||||
return nil, &btcjson.ErrNoTxInfo
|
||||
}
|
||||
|
||||
details := []map[string]interface{}{}
|
||||
totalAmount := int64(0)
|
||||
for _, e := range accumulatedTxen {
|
||||
switch t := e.Tx.(type) {
|
||||
case *tx.SendTx:
|
||||
var amount int64
|
||||
for i := range t.Receivers {
|
||||
if t.Receivers[i].Change {
|
||||
continue
|
||||
}
|
||||
amount += t.Receivers[i].Amount
|
||||
}
|
||||
totalAmount -= amount
|
||||
details = append(details, map[string]interface{}{
|
||||
"account": e.Account,
|
||||
"category": "send",
|
||||
// negative since it is a send
|
||||
"amount": -amount,
|
||||
"fee": t.Fee,
|
||||
})
|
||||
case *tx.RecvTx:
|
||||
totalAmount += t.Amount
|
||||
details = append(details, map[string]interface{}{
|
||||
"account": e.Account,
|
||||
// TODO(oga) We don't mine for now so there
|
||||
// won't be any special coinbase types. If the
|
||||
// tx is a coinbase then we should handle it
|
||||
// specially with the category depending on
|
||||
// whether it is an orphan or in the blockchain.
|
||||
"category": "receive",
|
||||
"amount": t.Amount,
|
||||
"address": hex.EncodeToString(t.ReceiverHash),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Generic information should be the same, so just use the first one.
|
||||
first := accumulatedTxen[0]
|
||||
ret := map[string]interface{}{
|
||||
// "amount"
|
||||
// "confirmations
|
||||
"amount": totalAmount,
|
||||
|
||||
"txid": first.Tx.GetTxID().String(),
|
||||
// TODO(oga) technically we have different time and
|
||||
// timereceived depending on if a transaction was send or
|
||||
// receive. We ideally should provide the correct numbers for
|
||||
// both. Right now they will always be the same
|
||||
"time": first.Tx.GetTime(),
|
||||
"timereceived": first.Tx.GetTime(),
|
||||
"details": details,
|
||||
}
|
||||
if first.Tx.GetBlockHeight() != -1 {
|
||||
ret["blockindex"] = first.Tx.GetBlockHeight()
|
||||
ret["blockhash"] = first.Tx.GetBlockHash().String()
|
||||
ret["blocktime"] = first.Tx.GetBlockTime()
|
||||
bs, err := GetCurBlock()
|
||||
if err != nil {
|
||||
return nil, &btcjson.Error{
|
||||
Code: btcjson.ErrWallet.Code,
|
||||
Message: err.Error(),
|
||||
}
|
||||
}
|
||||
ret["confirmations"] = bs.Height - first.Tx.GetBlockHeight() + 1
|
||||
}
|
||||
// TODO(oga) if the tx is a coinbase we should set "generated" to true.
|
||||
// Since we do not mine this currently is never the case.
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
// ListAccounts handles a listaccounts request by returning a map of account
|
||||
// names to their balances.
|
||||
func ListAccounts(icmd btcjson.Cmd) (interface{}, *btcjson.Error) {
|
||||
|
|
81
tx/tx.go
81
tx/tx.go
|
@ -108,7 +108,12 @@ type Tx interface {
|
|||
io.WriterTo
|
||||
ReadFromVersion(uint32, io.Reader) (int64, error)
|
||||
TxInfo(string, int32, btcwire.BitcoinNet) []map[string]interface{}
|
||||
Height() int32
|
||||
GetBlockHeight() int32
|
||||
GetBlockHash() *btcwire.ShaHash
|
||||
GetBlockTime() int64
|
||||
GetTime() int64
|
||||
GetTxID() *btcwire.ShaHash
|
||||
Copy() Tx
|
||||
}
|
||||
|
||||
// TxStore is a slice holding RecvTx and SendTx pointers.
|
||||
|
@ -1061,12 +1066,43 @@ func (tx *RecvTx) TxInfo(account string, curheight int32,
|
|||
return []map[string]interface{}{txInfo}
|
||||
}
|
||||
|
||||
// Height returns the current blockheight of the transaction, implementing the
|
||||
// Tx interface.
|
||||
func (tx *RecvTx) Height() int32 {
|
||||
// GetBlockHeight returns the current blockheight of the transaction,
|
||||
// implementing the Tx interface.
|
||||
func (tx *RecvTx) GetBlockHeight() int32 {
|
||||
return tx.BlockHeight
|
||||
}
|
||||
|
||||
// GetBlockHash return the current blockhash of thet transaction, implementing
|
||||
// the Tx interface.
|
||||
func (tx *RecvTx) GetBlockHash() *btcwire.ShaHash {
|
||||
return &tx.BlockHash
|
||||
}
|
||||
|
||||
// GetBlockTime returns the current block time of the transaction, implementing
|
||||
// the Tx interface.
|
||||
func (tx *RecvTx) GetBlockTime() int64 {
|
||||
return tx.BlockTime
|
||||
}
|
||||
|
||||
// GetTime returns the current ID of the transaction, implementing the Tx
|
||||
// interface.
|
||||
func (tx *RecvTx) GetTime() int64 {
|
||||
return tx.TimeReceived
|
||||
}
|
||||
|
||||
// GetTxID returns the current ID of the transaction, implementing the Tx
|
||||
// interface.
|
||||
func (tx *RecvTx) GetTxID() *btcwire.ShaHash {
|
||||
return &tx.TxID
|
||||
}
|
||||
|
||||
// Copy returns a deep copy of the structure, implementing the Tx interface..
|
||||
func (tx *RecvTx) Copy() Tx {
|
||||
copyTx := *tx
|
||||
|
||||
return ©Tx
|
||||
}
|
||||
|
||||
func (tx *SendTx) ReadFromVersion(vers uint32, r io.Reader) (n int64, err error) {
|
||||
var read int64
|
||||
|
||||
|
@ -1205,8 +1241,39 @@ func (tx *SendTx) TxInfo(account string, curheight int32,
|
|||
return reply
|
||||
}
|
||||
|
||||
// Height returns the current blockheight of the transaction, implementing the
|
||||
// Tx interface.
|
||||
func (tx *SendTx) Height() int32 {
|
||||
// GetBlockHeight returns the current blockheight of the transaction,
|
||||
// implementing the Tx interface.
|
||||
func (tx *SendTx) GetBlockHeight() int32 {
|
||||
return tx.BlockHeight
|
||||
}
|
||||
|
||||
// GetBlockHash return the current blockhash of thet transaction, implementing
|
||||
// the Tx interface.
|
||||
func (tx *SendTx) GetBlockHash() *btcwire.ShaHash {
|
||||
return &tx.BlockHash
|
||||
}
|
||||
|
||||
// GetBlockTime returns the current block time of the transaction, implementing
|
||||
// the Tx interface.
|
||||
func (tx *SendTx) GetBlockTime() int64 {
|
||||
return tx.BlockTime
|
||||
}
|
||||
|
||||
// GetTime returns the current ID of the transaction, implementing the Tx
|
||||
// interface.
|
||||
func (tx *SendTx) GetTime() int64 {
|
||||
return tx.Time
|
||||
}
|
||||
|
||||
// GetTxID returns the current ID of the transaction, implementing the Tx
|
||||
// interface.
|
||||
func (tx *SendTx) GetTxID() *btcwire.ShaHash {
|
||||
return &tx.TxID
|
||||
}
|
||||
|
||||
// Copy returns a deep copy of the structure, implementing the Tx interface..
|
||||
func (tx *SendTx) Copy() Tx {
|
||||
copyTx := *tx
|
||||
|
||||
return ©Tx
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue