Return nil for some spent gettxout outputs.
This change modifies the behavior of the gettxout RPC to match the behavior of the reference client. If a transaction output is spent by a mined transaction, the handler will now return nil (JSON null). While here, avoid indexing some slices multiple times, by creating a local variable instead.
This commit is contained in:
parent
764893c400
commit
790a4f5a6e
1 changed files with 19 additions and 7 deletions
26
rpcserver.go
26
rpcserver.go
|
@ -2453,6 +2453,7 @@ func handleGetTxOut(s *rpcServer, cmd btcjson.Cmd, closeChan <-chan struct{}) (i
|
||||||
var mtx *btcwire.MsgTx
|
var mtx *btcwire.MsgTx
|
||||||
var bestBlockSha string
|
var bestBlockSha string
|
||||||
var confirmations int64
|
var confirmations int64
|
||||||
|
var dbSpentInfo []bool
|
||||||
if c.IncludeMempool && s.server.txMemPool.HaveTransaction(txSha) {
|
if c.IncludeMempool && s.server.txMemPool.HaveTransaction(txSha) {
|
||||||
tx, err := s.server.txMemPool.FetchTransaction(txSha)
|
tx, err := s.server.txMemPool.FetchTransaction(txSha)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -2468,10 +2469,11 @@ func handleGetTxOut(s *rpcServer, cmd btcjson.Cmd, closeChan <-chan struct{}) (i
|
||||||
return nil, btcjson.ErrNoTxInfo
|
return nil, btcjson.ErrNoTxInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
lastTx := len(txList) - 1
|
lastTx := txList[len(txList)-1]
|
||||||
mtx = txList[lastTx].Tx
|
mtx = lastTx.Tx
|
||||||
blksha := txList[lastTx].BlkSha
|
blksha := lastTx.BlkSha
|
||||||
txHeight := txList[lastTx].Height
|
txHeight := lastTx.Height
|
||||||
|
dbSpentInfo = lastTx.TxSpent
|
||||||
|
|
||||||
_, bestHeight, err := s.server.db.NewestSha()
|
_, bestHeight, err := s.server.db.NewestSha()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -2487,15 +2489,25 @@ func handleGetTxOut(s *rpcServer, cmd btcjson.Cmd, closeChan <-chan struct{}) (i
|
||||||
return nil, btcjson.ErrInvalidTxVout
|
return nil, btcjson.ErrInvalidTxVout
|
||||||
}
|
}
|
||||||
|
|
||||||
if mtx.TxOut[c.Output] == nil {
|
txOut := mtx.TxOut[c.Output]
|
||||||
|
if txOut == nil {
|
||||||
rpcsLog.Errorf("Output index: %d, for txid: %s does not exist.", c.Output, c.Txid)
|
rpcsLog.Errorf("Output index: %d, for txid: %s does not exist.", c.Output, c.Txid)
|
||||||
return nil, btcjson.ErrInternal
|
return nil, btcjson.ErrInternal
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// To match the behavior of the reference client, this handler returns
|
||||||
|
// nil (JSON null) if the transaction output is spent by another
|
||||||
|
// transaction already in the database. Unspent transaction outputs
|
||||||
|
// from transactions in mempool, as well as mined transactions that are
|
||||||
|
// spent by a mempool transaction, are not affected by this.
|
||||||
|
if dbSpentInfo != nil && dbSpentInfo[c.Output] {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
// Disassemble script into single line printable format.
|
// Disassemble script into single line printable format.
|
||||||
// The disassembled string will contain [error] inline if the script
|
// The disassembled string will contain [error] inline if the script
|
||||||
// doesn't fully parse, so ignore the error here.
|
// doesn't fully parse, so ignore the error here.
|
||||||
script := mtx.TxOut[c.Output].PkScript
|
script := txOut.PkScript
|
||||||
disbuf, _ := btcscript.DisasmString(script)
|
disbuf, _ := btcscript.DisasmString(script)
|
||||||
|
|
||||||
// Get further info about the script.
|
// Get further info about the script.
|
||||||
|
@ -2511,7 +2523,7 @@ func handleGetTxOut(s *rpcServer, cmd btcjson.Cmd, closeChan <-chan struct{}) (i
|
||||||
txOutReply := &btcjson.GetTxOutResult{
|
txOutReply := &btcjson.GetTxOutResult{
|
||||||
BestBlock: bestBlockSha,
|
BestBlock: bestBlockSha,
|
||||||
Confirmations: confirmations,
|
Confirmations: confirmations,
|
||||||
Value: btcutil.Amount(mtx.TxOut[c.Output].Value).ToUnit(btcutil.AmountBTC),
|
Value: btcutil.Amount(txOut.Value).ToUnit(btcutil.AmountBTC),
|
||||||
Version: mtx.Version,
|
Version: mtx.Version,
|
||||||
ScriptPubKey: btcjson.ScriptPubKeyResult{
|
ScriptPubKey: btcjson.ScriptPubKeyResult{
|
||||||
Asm: disbuf,
|
Asm: disbuf,
|
||||||
|
|
Loading…
Reference in a new issue