Small changes to createVinList/createVoutList
Added error checking for script disassembley Changed vout to handle errors in processing the way bitcoind does: the type displayed is "nonstandard" when the calculated type is nonstandard or nulltype and also when there is an error getting the address. Still doesn't properly support multisig addresses, but now it should return "nonstandard" since since address lookup fails for those cases.
This commit is contained in:
parent
eb624acfd4
commit
28d08f8b16
1 changed files with 53 additions and 18 deletions
71
rpcserver.go
71
rpcserver.go
|
@ -35,7 +35,6 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
@ -700,7 +699,7 @@ func handleDebugLevel(s *rpcServer, cmd btcjson.Cmd,
|
||||||
|
|
||||||
// createVinList returns a slice of JSON objects for the inputs of the passed
|
// createVinList returns a slice of JSON objects for the inputs of the passed
|
||||||
// transaction.
|
// transaction.
|
||||||
func createVinList(mtx *btcwire.MsgTx) []btcjson.Vin {
|
func createVinList(mtx *btcwire.MsgTx) ([]btcjson.Vin, *btcjson.Error) {
|
||||||
tx := btcutil.NewTx(mtx)
|
tx := btcutil.NewTx(mtx)
|
||||||
vinList := make([]btcjson.Vin, len(mtx.TxIn))
|
vinList := make([]btcjson.Vin, len(mtx.TxIn))
|
||||||
for i, v := range mtx.TxIn {
|
for i, v := range mtx.TxIn {
|
||||||
|
@ -710,7 +709,13 @@ func createVinList(mtx *btcwire.MsgTx) []btcjson.Vin {
|
||||||
vinList[i].Txid = v.PreviousOutpoint.Hash.String()
|
vinList[i].Txid = v.PreviousOutpoint.Hash.String()
|
||||||
vinList[i].Vout = int(v.PreviousOutpoint.Index)
|
vinList[i].Vout = int(v.PreviousOutpoint.Index)
|
||||||
|
|
||||||
disbuf, _ := btcscript.DisasmString(v.SignatureScript)
|
disbuf, err := btcscript.DisasmString(v.SignatureScript)
|
||||||
|
if err != nil {
|
||||||
|
return nil, &btcjson.Error{
|
||||||
|
Code: btcjson.ErrInternal.Code,
|
||||||
|
Message: err.Error(),
|
||||||
|
}
|
||||||
|
}
|
||||||
vinList[i].ScriptSig = new(btcjson.ScriptSig)
|
vinList[i].ScriptSig = new(btcjson.ScriptSig)
|
||||||
vinList[i].ScriptSig.Asm = disbuf
|
vinList[i].ScriptSig.Asm = disbuf
|
||||||
vinList[i].ScriptSig.Hex = hex.EncodeToString(v.SignatureScript)
|
vinList[i].ScriptSig.Hex = hex.EncodeToString(v.SignatureScript)
|
||||||
|
@ -718,39 +723,51 @@ func createVinList(mtx *btcwire.MsgTx) []btcjson.Vin {
|
||||||
vinList[i].Sequence = v.Sequence
|
vinList[i].Sequence = v.Sequence
|
||||||
}
|
}
|
||||||
|
|
||||||
return vinList
|
return vinList, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// createVoutList returns a slice of JSON objects for the outputs of the passed
|
// createVoutList returns a slice of JSON objects for the outputs of the passed
|
||||||
// transaction.
|
// transaction.
|
||||||
func createVoutList(mtx *btcwire.MsgTx, net btcwire.BitcoinNet) []btcjson.Vout {
|
func createVoutList(mtx *btcwire.MsgTx, net btcwire.BitcoinNet) ([]btcjson.Vout, *btcjson.Error) {
|
||||||
voutList := make([]btcjson.Vout, len(mtx.TxOut))
|
voutList := make([]btcjson.Vout, len(mtx.TxOut))
|
||||||
for i, v := range 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)
|
||||||
|
|
||||||
|
disbuf, err := btcscript.DisasmString(v.PkScript)
|
||||||
|
if err != nil {
|
||||||
|
return nil, &btcjson.Error{
|
||||||
|
Code: btcjson.ErrInternal.Code,
|
||||||
|
Message: err.Error(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
voutList[i].ScriptPubKey.Asm = disbuf
|
||||||
|
voutList[i].ScriptPubKey.Hex = hex.EncodeToString(v.PkScript)
|
||||||
|
voutList[i].ScriptPubKey.Type = btcscript.NonStandardTy.String()
|
||||||
|
|
||||||
|
scriptType := btcscript.GetScriptClass(v.PkScript)
|
||||||
|
if scriptType == btcscript.NonStandardTy || scriptType == btcscript.NullDataTy {
|
||||||
|
continue
|
||||||
|
}
|
||||||
_, addrhash, err := btcscript.ScriptToAddrHash(v.PkScript)
|
_, addrhash, err := btcscript.ScriptToAddrHash(v.PkScript)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
txSha, _ := mtx.TxSha()
|
txSha, _ := mtx.TxSha()
|
||||||
// TODO: set and return error?
|
// TODO: set and return error?
|
||||||
rpcsLog.Errorf("Error getting address hash for %v: %v",
|
rpcsLog.Errorf("Error getting address hash for %v: %v", txSha, err)
|
||||||
txSha, err)
|
continue
|
||||||
}
|
}
|
||||||
if addr, err := btcutil.EncodeAddress(addrhash, net); err == nil {
|
if addr, err := btcutil.EncodeAddress(addrhash, net); err == nil {
|
||||||
// TODO: set and return error?
|
// TODO: set and return error?
|
||||||
addrList := make([]string, 1)
|
addrList := make([]string, 1)
|
||||||
addrList[0] = addr
|
addrList[0] = addr
|
||||||
|
voutList[i].ScriptPubKey.Type = scriptType.String()
|
||||||
voutList[i].ScriptPubKey.Addresses = addrList
|
voutList[i].ScriptPubKey.Addresses = addrList
|
||||||
|
// TODO: replace with proper multisig handling
|
||||||
|
voutList[i].ScriptPubKey.ReqSigs = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
disbuf, _ := btcscript.DisasmString(v.PkScript)
|
|
||||||
voutList[i].ScriptPubKey.Asm = disbuf
|
|
||||||
voutList[i].ScriptPubKey.Hex = hex.EncodeToString(v.PkScript)
|
|
||||||
voutList[i].ScriptPubKey.ReqSigs = strings.Count(disbuf, "OP_CHECKSIG")
|
|
||||||
voutList[i].ScriptPubKey.Type = btcscript.GetScriptClass(v.PkScript).String()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return voutList
|
return voutList, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// handleDecodeRawTransaction handles decoderawtransaction commands.
|
// handleDecodeRawTransaction handles decoderawtransaction commands.
|
||||||
|
@ -781,13 +798,22 @@ func handleDecodeRawTransaction(s *rpcServer, cmd btcjson.Cmd,
|
||||||
}
|
}
|
||||||
txSha, _ := mtx.TxSha()
|
txSha, _ := mtx.TxSha()
|
||||||
|
|
||||||
|
vin, err := createVinList(&mtx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
vout, err := createVoutList(&mtx, s.server.btcnet)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
// Create and return the result.
|
// Create and return the result.
|
||||||
txReply := btcjson.TxRawDecodeResult{
|
txReply := btcjson.TxRawDecodeResult{
|
||||||
Txid: txSha.String(),
|
Txid: txSha.String(),
|
||||||
Version: mtx.Version,
|
Version: mtx.Version,
|
||||||
Locktime: mtx.LockTime,
|
Locktime: mtx.LockTime,
|
||||||
Vin: createVinList(&mtx),
|
Vin: vin,
|
||||||
Vout: createVoutList(&mtx, s.server.btcnet),
|
Vout: vout,
|
||||||
}
|
}
|
||||||
return txReply, nil
|
return txReply, nil
|
||||||
}
|
}
|
||||||
|
@ -1107,11 +1133,20 @@ func createTxRawResult(net btcwire.BitcoinNet, txSha string, mtx *btcwire.MsgTx,
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vin, err := createVinList(mtx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
vout, err := createVoutList(mtx, net)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
txReply := &btcjson.TxRawResult{
|
txReply := &btcjson.TxRawResult{
|
||||||
Hex: mtxHex,
|
Hex: mtxHex,
|
||||||
Txid: txSha,
|
Txid: txSha,
|
||||||
Vout: createVoutList(mtx, net),
|
Vout: vout,
|
||||||
Vin: createVinList(mtx),
|
Vin: vin,
|
||||||
Version: mtx.Version,
|
Version: mtx.Version,
|
||||||
LockTime: mtx.LockTime,
|
LockTime: mtx.LockTime,
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue