Correct getrawtransaction RPC handling and cleanup.
The getrawtransaction RPC call should return a hex-encoded string of the transaction when verbose is false instead of a TxRawResult object with the Hex field set to be compatible with the Sathoshi client. This commit, along with a recent commit to btcjson corrects this. Also, while here, do a bit of cleanup, finish a TODO to check for an invalid hash, and optimize the handling of non-verbose slightly.
This commit is contained in:
parent
af3609d861
commit
e0fab228a4
1 changed files with 35 additions and 23 deletions
58
rpcserver.go
58
rpcserver.go
|
@ -802,9 +802,11 @@ func handleGetBlock(s *rpcServer, cmd btcjson.Cmd, walletNotification chan []byt
|
||||||
txSha := tx.Sha().String()
|
txSha := tx.Sha().String()
|
||||||
mtx := tx.MsgTx()
|
mtx := tx.MsgTx()
|
||||||
|
|
||||||
rawTxn, err := createTxRawResult(s.server.btcnet, txSha, mtx, blk, maxidx, sha, true)
|
rawTxn, err := createTxRawResult(s.server.btcnet, txSha,
|
||||||
|
mtx, blk, maxidx, sha)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
rpcsLog.Errorf("Cannot create TxRawResult for txSha=%s: %v", txSha, err)
|
rpcsLog.Errorf("Cannot create TxRawResult for "+
|
||||||
|
"transaction %s: %v", txSha, err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
rawTxns[i] = *rawTxn
|
rawTxns[i] = *rawTxn
|
||||||
|
@ -946,9 +948,18 @@ func handleGetRawMempool(s *rpcServer, cmd btcjson.Cmd, walletNotification chan
|
||||||
func handleGetRawTransaction(s *rpcServer, cmd btcjson.Cmd, walletNotification chan []byte) (interface{}, error) {
|
func handleGetRawTransaction(s *rpcServer, cmd btcjson.Cmd, walletNotification chan []byte) (interface{}, error) {
|
||||||
c := cmd.(*btcjson.GetRawTransactionCmd)
|
c := cmd.(*btcjson.GetRawTransactionCmd)
|
||||||
|
|
||||||
// TODO: check error code. tx is not checked before
|
// Convert the provided transaction hash hex to a ShaHash.
|
||||||
// this point.
|
txSha, err := btcwire.NewShaHashFromStr(c.Txid)
|
||||||
txSha, _ := btcwire.NewShaHashFromStr(c.Txid)
|
if err != nil {
|
||||||
|
rpcsLog.Errorf("Error generating sha: %v", err)
|
||||||
|
return nil, btcjson.Error{
|
||||||
|
Code: btcjson.ErrBlockNotFound.Code,
|
||||||
|
Message: "Parameter 1 must be a hexaecimal string",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to fetch the transaction from the memory pool and if that fails,
|
||||||
|
// try the block database.
|
||||||
var mtx *btcwire.MsgTx
|
var mtx *btcwire.MsgTx
|
||||||
var blksha *btcwire.ShaHash
|
var blksha *btcwire.ShaHash
|
||||||
tx, err := s.server.txMemPool.FetchTransaction(txSha)
|
tx, err := s.server.txMemPool.FetchTransaction(txSha)
|
||||||
|
@ -967,9 +978,18 @@ func handleGetRawTransaction(s *rpcServer, cmd btcjson.Cmd, walletNotification c
|
||||||
mtx = tx.MsgTx()
|
mtx = tx.MsgTx()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// When the verbose flag isn't set, simply return the network-serialized
|
||||||
|
// transaction as a hex-encoded string.
|
||||||
|
if !c.Verbose {
|
||||||
|
mtxHex, err := messageToHex(mtx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return mtxHex, nil
|
||||||
|
}
|
||||||
|
|
||||||
var blk *btcutil.Block
|
var blk *btcutil.Block
|
||||||
var maxidx int64
|
var maxidx int64
|
||||||
|
|
||||||
if blksha != nil {
|
if blksha != nil {
|
||||||
blk, err = s.server.db.FetchBlockBySha(blksha)
|
blk, err = s.server.db.FetchBlockBySha(blksha)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -984,7 +1004,7 @@ func handleGetRawTransaction(s *rpcServer, cmd btcjson.Cmd, walletNotification c
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rawTxn, jsonErr := createTxRawResult(s.server.btcnet, c.Txid, mtx, blk, maxidx, blksha, c.Verbose)
|
rawTxn, jsonErr := createTxRawResult(s.server.btcnet, c.Txid, mtx, blk, maxidx, blksha)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
rpcsLog.Errorf("Cannot create TxRawResult for txSha=%s: %v", txSha, err)
|
rpcsLog.Errorf("Cannot create TxRawResult for txSha=%s: %v", txSha, err)
|
||||||
return nil, *jsonErr
|
return nil, *jsonErr
|
||||||
|
@ -992,25 +1012,17 @@ func handleGetRawTransaction(s *rpcServer, cmd btcjson.Cmd, walletNotification c
|
||||||
return *rawTxn, nil
|
return *rawTxn, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// createTxRawResult
|
// createTxRawResult converts the passed transaction and associated parameters
|
||||||
func createTxRawResult(net btcwire.BitcoinNet, txSha string, mtx *btcwire.MsgTx, blk *btcutil.Block, maxidx int64, blksha *btcwire.ShaHash, verbose bool) (*btcjson.TxRawResult, *btcjson.Error) {
|
// to a raw transaction JSON object.
|
||||||
|
func createTxRawResult(net btcwire.BitcoinNet, txSha string, mtx *btcwire.MsgTx, blk *btcutil.Block, maxidx int64, blksha *btcwire.ShaHash) (*btcjson.TxRawResult, *btcjson.Error) {
|
||||||
tx := btcutil.NewTx(mtx)
|
tx := btcutil.NewTx(mtx)
|
||||||
|
|
||||||
mtxHex, err := messageToHex(mtx)
|
mtxHex, err := messageToHex(mtx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if !verbose {
|
vinList := make([]btcjson.Vin, len(mtx.TxIn))
|
||||||
return &btcjson.TxRawResult{Hex: mtxHex}, nil
|
for i, v := range mtx.TxIn {
|
||||||
}
|
|
||||||
|
|
||||||
txOutList := mtx.TxOut
|
|
||||||
voutList := make([]btcjson.Vout, len(txOutList))
|
|
||||||
txInList := mtx.TxIn
|
|
||||||
vinList := make([]btcjson.Vin, len(txInList))
|
|
||||||
|
|
||||||
for i, v := range txInList {
|
|
||||||
if btcchain.IsCoinBase(tx) {
|
if btcchain.IsCoinBase(tx) {
|
||||||
vinList[i].Coinbase = hex.EncodeToString(v.SignatureScript)
|
vinList[i].Coinbase = hex.EncodeToString(v.SignatureScript)
|
||||||
} else {
|
} else {
|
||||||
|
@ -1024,7 +1036,8 @@ func createTxRawResult(net btcwire.BitcoinNet, txSha string, mtx *btcwire.MsgTx,
|
||||||
vinList[i].Sequence = float64(v.Sequence)
|
vinList[i].Sequence = float64(v.Sequence)
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, v := range txOutList {
|
voutList := make([]btcjson.Vout, len(mtx.TxOut))
|
||||||
|
for i, v := range mtx.TxOut {
|
||||||
voutList[i].N = i
|
voutList[i].N = i
|
||||||
voutList[i].Value = float64(v.Value) / float64(btcutil.SatoshiPerBitcoin)
|
voutList[i].Value = float64(v.Value) / float64(btcutil.SatoshiPerBitcoin)
|
||||||
|
|
||||||
|
@ -1060,8 +1073,7 @@ func createTxRawResult(net btcwire.BitcoinNet, txSha string, mtx *btcwire.MsgTx,
|
||||||
blockHeader := &blk.MsgBlock().Header
|
blockHeader := &blk.MsgBlock().Header
|
||||||
idx := blk.Height()
|
idx := blk.Height()
|
||||||
|
|
||||||
// This is not a typo, they are identical in
|
// This is not a typo, they are identical in bitcoind as well.
|
||||||
// bitcoind as well.
|
|
||||||
txReply.Time = blockHeader.Timestamp.Unix()
|
txReply.Time = blockHeader.Timestamp.Unix()
|
||||||
txReply.Blocktime = blockHeader.Timestamp.Unix()
|
txReply.Blocktime = blockHeader.Timestamp.Unix()
|
||||||
txReply.BlockHash = blksha.String()
|
txReply.BlockHash = blksha.String()
|
||||||
|
|
Loading…
Reference in a new issue