btcjson/rpcserver: Encode witness stack as slice.

The modifies the encoding of witness stacks in JSON responses to use a
slice of strings instead of a single space-separated string for
compatibility with Core.
This commit is contained in:
Dave Collins 2017-08-29 20:40:19 -05:00
parent 9bd7bcfff6
commit 0b50802d52
No known key found for this signature in database
GPG key ID: B8904D9D9C93D1F2
2 changed files with 27 additions and 26 deletions

View file

@ -317,7 +317,7 @@ type Vin struct {
Vout uint32 `json:"vout"`
ScriptSig *ScriptSig `json:"scriptSig"`
Sequence uint32 `json:"sequence"`
Witness string `json:"txinwitness"`
Witness []string `json:"txinwitness"`
}
// IsCoinBase returns a bool to show if a Vin is a Coinbase one or not.
@ -335,9 +335,9 @@ func (v *Vin) HasWitness() bool {
func (v *Vin) MarshalJSON() ([]byte, error) {
if v.IsCoinBase() {
coinbaseStruct := struct {
Coinbase string `json:"coinbase"`
Sequence uint32 `json:"sequence"`
Witness string `json:"witness,omitempty"`
Coinbase string `json:"coinbase"`
Sequence uint32 `json:"sequence"`
Witness []string `json:"witness,omitempty"`
}{
Coinbase: v.Coinbase,
Sequence: v.Sequence,
@ -351,7 +351,7 @@ func (v *Vin) MarshalJSON() ([]byte, error) {
Txid string `json:"txid"`
Vout uint32 `json:"vout"`
ScriptSig *ScriptSig `json:"scriptSig"`
Witness string `json:"txinwitness"`
Witness []string `json:"txinwitness"`
Sequence uint32 `json:"sequence"`
}{
Txid: v.Txid,
@ -389,7 +389,7 @@ type VinPrevOut struct {
Txid string `json:"txid"`
Vout uint32 `json:"vout"`
ScriptSig *ScriptSig `json:"scriptSig"`
Witness string `json:"txinwitness"`
Witness []string `json:"txinwitness"`
PrevOut *PrevOut `json:"prevOut"`
Sequence uint32 `json:"sequence"`
}
@ -423,7 +423,7 @@ func (v *VinPrevOut) MarshalJSON() ([]byte, error) {
Txid string `json:"txid"`
Vout uint32 `json:"vout"`
ScriptSig *ScriptSig `json:"scriptSig"`
Witness string `json:"txinwitness"`
Witness []string `json:"txinwitness"`
PrevOut *PrevOut `json:"prevOut,omitempty"`
Sequence uint32 `json:"sequence"`
}{

View file

@ -629,6 +629,23 @@ func handleDebugLevel(s *rpcServer, cmd interface{}, closeChan <-chan struct{})
return "Done.", nil
}
// witnessToHex formats the passed witness stack as a slice of hex-encoded
// strings to be used in a JSON response.
func witnessToHex(witness wire.TxWitness) []string {
// Ensure nil is returned when there are no entries versus an empty
// slice so it can properly be omitted as necessary.
if len(witness) == 0 {
return nil
}
result := make([]string, 0, len(witness))
for _, wit := range witness {
result = append(result, hex.EncodeToString(wit))
}
return result
}
// createVinList returns a slice of JSON objects for the inputs of the passed
// transaction.
func createVinList(mtx *wire.MsgTx) []btcjson.Vin {
@ -638,7 +655,7 @@ func createVinList(mtx *wire.MsgTx) []btcjson.Vin {
txIn := mtx.TxIn[0]
vinList[0].Coinbase = hex.EncodeToString(txIn.SignatureScript)
vinList[0].Sequence = txIn.Sequence
vinList[0].Witness = witnessToSring(txIn.Witness)
vinList[0].Witness = witnessToHex(txIn.Witness)
return vinList
}
@ -658,29 +675,13 @@ func createVinList(mtx *wire.MsgTx) []btcjson.Vin {
}
if mtx.HasWitness() {
vinEntry.Witness = witnessToSring(txIn.Witness)
vinEntry.Witness = witnessToHex(txIn.Witness)
}
}
return vinList
}
// witnessToSring formats the passed witness stack as a string to be used
// within a JSON response. The witness is encoded as a single string with
// spaces separating each witness element.
func witnessToSring(witness wire.TxWitness) string {
var b bytes.Buffer
for i, wit := range witness {
if i > 0 {
b.WriteString(" ")
}
b.WriteString(hex.EncodeToString(wit))
}
return b.String()
}
// createVoutList returns a slice of JSON objects for the outputs of the passed
// transaction.
func createVoutList(mtx *wire.MsgTx, chainParams *chaincfg.Params, filterAddrMap map[string]struct{}) []btcjson.Vout {
@ -2852,7 +2853,7 @@ func createVinListPrevOut(s *rpcServer, mtx *wire.MsgTx, chainParams *chaincfg.P
}
if len(txIn.Witness) != 0 {
vinEntry.Witness = witnessToSring(txIn.Witness)
vinEntry.Witness = witnessToHex(txIn.Witness)
}
// Add the entry to the list now if it already passed the filter