Implement gettxout rpc.
Use new error type defined in Roasbeef/btcjson@4dc9db809
This commit is contained in:
parent
8a7b73e62b
commit
293d71e9c3
1 changed files with 92 additions and 1 deletions
93
rpcserver.go
93
rpcserver.go
|
@ -144,7 +144,7 @@ var rpcHandlersBeforeInit = map[string]commandHandler{
|
|||
"getpeerinfo": handleGetPeerInfo,
|
||||
"getrawmempool": handleGetRawMempool,
|
||||
"getrawtransaction": handleGetRawTransaction,
|
||||
"gettxout": handleUnimplemented,
|
||||
"gettxout": handleGetTxOut,
|
||||
"getwork": handleGetWork,
|
||||
"help": handleHelp,
|
||||
"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
|
||||
// generating and returning work to the caller.
|
||||
//
|
||||
|
|
Loading…
Add table
Reference in a new issue