mirror of
https://github.com/btcsuite/btcd.git
synced 2025-01-19 05:33:36 +01:00
Implement gettxout rpc.
Use new error type defined in Roasbeef/btcjson@4dc9db809
This commit is contained in:
parent
8a7b73e62b
commit
293d71e9c3
93
rpcserver.go
93
rpcserver.go
@ -144,7 +144,7 @@ var rpcHandlersBeforeInit = map[string]commandHandler{
|
|||||||
"getpeerinfo": handleGetPeerInfo,
|
"getpeerinfo": handleGetPeerInfo,
|
||||||
"getrawmempool": handleGetRawMempool,
|
"getrawmempool": handleGetRawMempool,
|
||||||
"getrawtransaction": handleGetRawTransaction,
|
"getrawtransaction": handleGetRawTransaction,
|
||||||
"gettxout": handleUnimplemented,
|
"gettxout": handleGetTxOut,
|
||||||
"getwork": handleGetWork,
|
"getwork": handleGetWork,
|
||||||
"help": handleHelp,
|
"help": handleHelp,
|
||||||
"ping": handlePing,
|
"ping": handlePing,
|
||||||
@ -2434,6 +2434,97 @@ func reverseUint32Array(b []byte) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// handleGetTxOut handles gettxout commands.
|
||||||
|
func handleGetTxOut(s *rpcServer, cmd btcjson.Cmd, closeChan <-chan struct{}) (interface{}, error) {
|
||||||
|
c := cmd.(*btcjson.GetTxOutCmd)
|
||||||
|
|
||||||
|
// Convert the provided transaction hash hex to a ShaHash.
|
||||||
|
txSha, err := btcwire.NewShaHashFromStr(c.Txid)
|
||||||
|
if err != nil {
|
||||||
|
return nil, btcjson.Error{
|
||||||
|
Code: btcjson.ErrInvalidParameter.Code,
|
||||||
|
Message: fmt.Sprintf("argument must be hexadecimal "+
|
||||||
|
"string (not %q)", c.Txid),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If requested and the tx is available in the mempool try to fetch it from
|
||||||
|
// there, otherwise attempt to fetch from the block database.
|
||||||
|
var mtx *btcwire.MsgTx
|
||||||
|
var bestBlockSha string
|
||||||
|
var confirmations int64
|
||||||
|
if c.IncludeMempool && s.server.txMemPool.HaveTransaction(txSha) {
|
||||||
|
tx, err := s.server.txMemPool.FetchTransaction(txSha)
|
||||||
|
if err != nil {
|
||||||
|
rpcsLog.Errorf("Error fetching tx: %v", err)
|
||||||
|
return nil, btcjson.ErrNoTxInfo
|
||||||
|
}
|
||||||
|
mtx = tx.MsgTx()
|
||||||
|
confirmations = 0
|
||||||
|
bestBlockSha = ""
|
||||||
|
} else {
|
||||||
|
txList, err := s.server.db.FetchTxBySha(txSha)
|
||||||
|
if err != nil || len(txList) == 0 {
|
||||||
|
return nil, btcjson.ErrNoTxInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
lastTx := len(txList) - 1
|
||||||
|
mtx = txList[lastTx].Tx
|
||||||
|
blksha := txList[lastTx].BlkSha
|
||||||
|
txHeight := txList[lastTx].Height
|
||||||
|
|
||||||
|
_, bestHeight, err := s.server.db.NewestSha()
|
||||||
|
if err != nil {
|
||||||
|
rpcsLog.Errorf("Cannot get newest sha: %v", err)
|
||||||
|
return nil, btcjson.ErrBlockNotFound
|
||||||
|
}
|
||||||
|
|
||||||
|
confirmations = 1 + bestHeight - txHeight
|
||||||
|
bestBlockSha = blksha.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.Output < 0 || c.Output > len(mtx.TxOut)-1 {
|
||||||
|
return nil, btcjson.ErrInvalidTxVout
|
||||||
|
}
|
||||||
|
|
||||||
|
if mtx.TxOut[c.Output] == nil {
|
||||||
|
rpcsLog.Errorf("Output index: %d, for txid: %s does not exist.", c.Output, c.Txid)
|
||||||
|
return nil, btcjson.ErrInternal
|
||||||
|
}
|
||||||
|
|
||||||
|
// Disassemble script into single line printable format.
|
||||||
|
// The disassembled string will contain [error] inline if the script
|
||||||
|
// doesn't fully parse, so ignore the error here.
|
||||||
|
script := mtx.TxOut[c.Output].PkScript
|
||||||
|
disbuf, _ := btcscript.DisasmString(script)
|
||||||
|
|
||||||
|
// Get further info about the script.
|
||||||
|
// Ignore the error here since an error means the script couldn't parse
|
||||||
|
// and there is no additional information about it anyways.
|
||||||
|
net := s.server.netParams
|
||||||
|
scriptClass, addrs, reqSigs, _ := btcscript.ExtractPkScriptAddrs(script, net)
|
||||||
|
addresses := make([]string, len(addrs))
|
||||||
|
for i, addr := range addrs {
|
||||||
|
addresses[i] = addr.EncodeAddress()
|
||||||
|
}
|
||||||
|
|
||||||
|
txOutReply := &btcjson.GetTxOutResult{
|
||||||
|
BestBlock: bestBlockSha,
|
||||||
|
Confirmations: confirmations,
|
||||||
|
Value: btcutil.Amount(mtx.TxOut[c.Output].Value).ToUnit(btcutil.AmountBTC),
|
||||||
|
Version: mtx.Version,
|
||||||
|
ScriptPubKey: btcjson.ScriptPubKeyResult{
|
||||||
|
Asm: disbuf,
|
||||||
|
Hex: hex.EncodeToString(script),
|
||||||
|
ReqSigs: int32(reqSigs),
|
||||||
|
Type: scriptClass.String(),
|
||||||
|
Addresses: addresses,
|
||||||
|
},
|
||||||
|
Coinbase: btcchain.IsCoinBase(btcutil.NewTx(mtx)),
|
||||||
|
}
|
||||||
|
return txOutReply, nil
|
||||||
|
}
|
||||||
|
|
||||||
// handleGetWorkRequest is a helper for handleGetWork which deals with
|
// handleGetWorkRequest is a helper for handleGetWork which deals with
|
||||||
// generating and returning work to the caller.
|
// generating and returning work to the caller.
|
||||||
//
|
//
|
||||||
|
Loading…
Reference in New Issue
Block a user