Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 4 additions & 5 deletions blockchain/txlookup.go
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ func (b *BlockChain) fetchInputTransactions(node *blockNode, block *btcutil.Bloc
// passed transaction from the point of view of the end of the main chain. It
// also attempts to fetch the transaction itself so the returned TxStore can be
// examined for duplicate transactions.
func (b *BlockChain) FetchTransactionStore(tx *btcutil.Tx) (TxStore, error) {
func (b *BlockChain) FetchTransactionStore(tx *btcutil.Tx, includeSpent bool) (TxStore, error) {
// Create a set of needed transactions from the transactions referenced
// by the inputs of the passed transaction. Also, add the passed
// transaction itself as a way for the caller to detect duplicates.
Expand All @@ -311,9 +311,8 @@ func (b *BlockChain) FetchTransactionStore(tx *btcutil.Tx) (TxStore, error) {
}

// Request the input transactions from the point of view of the end of
// the main chain without including fully spent trasactions in the
// results. Fully spent transactions are only needed for chain
// reorganization which does not apply here.
txStore := fetchTxStoreMain(b.db, txNeededSet, false)
// the main chain with or without without including fully spent transactions
// in the results.
txStore := fetchTxStoreMain(b.db, txNeededSet, includeSpent)
return txStore, nil
}
2 changes: 1 addition & 1 deletion blockmanager.go
Original file line number Diff line number Diff line change
Expand Up @@ -1119,7 +1119,7 @@ out:
}

case fetchTransactionStoreMsg:
txStore, err := b.blockChain.FetchTransactionStore(msg.tx)
txStore, err := b.blockChain.FetchTransactionStore(msg.tx, false)
msg.reply <- fetchTransactionStoreResponse{
TxStore: txStore,
err: err,
Expand Down
20 changes: 11 additions & 9 deletions btcjson/chainsvrcmds.go
Original file line number Diff line number Diff line change
Expand Up @@ -545,23 +545,25 @@ func NewReconsiderBlockCmd(blockHash string) *ReconsiderBlockCmd {

// SearchRawTransactionsCmd defines the searchrawtransactions JSON-RPC command.
type SearchRawTransactionsCmd struct {
Address string
Verbose *int `jsonrpcdefault:"1"`
Skip *int `jsonrpcdefault:"0"`
Count *int `jsonrpcdefault:"100"`
Address string
Verbose *int `jsonrpcdefault:"1"`
Skip *int `jsonrpcdefault:"0"`
Count *int `jsonrpcdefault:"100"`
VinExtra *int `jsonrpcdefault:"0"`
}

// NewSearchRawTransactionsCmd returns a new instance which can be used to issue a
// sendrawtransaction JSON-RPC command.
//
// The parameters which are pointers indicate they are optional. Passing nil
// for optional parameters will use the default value.
func NewSearchRawTransactionsCmd(address string, verbose, skip, count *int) *SearchRawTransactionsCmd {
func NewSearchRawTransactionsCmd(address string, verbose, skip, count *int, vinExtra *int) *SearchRawTransactionsCmd {
return &SearchRawTransactionsCmd{
Address: address,
Verbose: verbose,
Skip: skip,
Count: count,
Address: address,
Verbose: verbose,
Skip: skip,
Count: count,
VinExtra: vinExtra,
}
}

Expand Down
62 changes: 42 additions & 20 deletions btcjson/chainsvrcmds_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -679,14 +679,15 @@ func TestChainSvrCmds(t *testing.T) {
return btcjson.NewCmd("searchrawtransactions", "1Address")
},
staticCmd: func() interface{} {
return btcjson.NewSearchRawTransactionsCmd("1Address", nil, nil, nil)
return btcjson.NewSearchRawTransactionsCmd("1Address", nil, nil, nil, nil)
},
marshalled: `{"jsonrpc":"1.0","method":"searchrawtransactions","params":["1Address"],"id":1}`,
unmarshalled: &btcjson.SearchRawTransactionsCmd{
Address: "1Address",
Verbose: btcjson.Int(1),
Skip: btcjson.Int(0),
Count: btcjson.Int(100),
Address: "1Address",
Verbose: btcjson.Int(1),
Skip: btcjson.Int(0),
Count: btcjson.Int(100),
VinExtra: btcjson.Int(0),
},
},
{
Expand All @@ -696,14 +697,15 @@ func TestChainSvrCmds(t *testing.T) {
},
staticCmd: func() interface{} {
return btcjson.NewSearchRawTransactionsCmd("1Address",
btcjson.Int(0), nil, nil)
btcjson.Int(0), nil, nil, nil)
},
marshalled: `{"jsonrpc":"1.0","method":"searchrawtransactions","params":["1Address",0],"id":1}`,
unmarshalled: &btcjson.SearchRawTransactionsCmd{
Address: "1Address",
Verbose: btcjson.Int(0),
Skip: btcjson.Int(0),
Count: btcjson.Int(100),
Address: "1Address",
Verbose: btcjson.Int(0),
Skip: btcjson.Int(0),
Count: btcjson.Int(100),
VinExtra: btcjson.Int(0),
},
},
{
Expand All @@ -713,14 +715,15 @@ func TestChainSvrCmds(t *testing.T) {
},
staticCmd: func() interface{} {
return btcjson.NewSearchRawTransactionsCmd("1Address",
btcjson.Int(0), btcjson.Int(5), nil)
btcjson.Int(0), btcjson.Int(5), nil, nil)
},
marshalled: `{"jsonrpc":"1.0","method":"searchrawtransactions","params":["1Address",0,5],"id":1}`,
unmarshalled: &btcjson.SearchRawTransactionsCmd{
Address: "1Address",
Verbose: btcjson.Int(0),
Skip: btcjson.Int(5),
Count: btcjson.Int(100),
Address: "1Address",
Verbose: btcjson.Int(0),
Skip: btcjson.Int(5),
Count: btcjson.Int(100),
VinExtra: btcjson.Int(0),
},
},
{
Expand All @@ -730,14 +733,33 @@ func TestChainSvrCmds(t *testing.T) {
},
staticCmd: func() interface{} {
return btcjson.NewSearchRawTransactionsCmd("1Address",
btcjson.Int(0), btcjson.Int(5), btcjson.Int(10))
btcjson.Int(0), btcjson.Int(5), btcjson.Int(10), nil)
},
marshalled: `{"jsonrpc":"1.0","method":"searchrawtransactions","params":["1Address",0,5,10],"id":1}`,
unmarshalled: &btcjson.SearchRawTransactionsCmd{
Address: "1Address",
Verbose: btcjson.Int(0),
Skip: btcjson.Int(5),
Count: btcjson.Int(10),
Address: "1Address",
Verbose: btcjson.Int(0),
Skip: btcjson.Int(5),
Count: btcjson.Int(10),
VinExtra: btcjson.Int(0),
},
},
{
name: "searchrawtransactions",
newCmd: func() (interface{}, error) {
return btcjson.NewCmd("searchrawtransactions", "1Address", 0, 5, 10, 1)
},
staticCmd: func() interface{} {
return btcjson.NewSearchRawTransactionsCmd("1Address",
btcjson.Int(0), btcjson.Int(5), btcjson.Int(10), btcjson.Int(1))
},
marshalled: `{"jsonrpc":"1.0","method":"searchrawtransactions","params":["1Address",0,5,10,1],"id":1}`,
unmarshalled: &btcjson.SearchRawTransactionsCmd{
Address: "1Address",
Verbose: btcjson.Int(0),
Skip: btcjson.Int(5),
Count: btcjson.Int(10),
VinExtra: btcjson.Int(1),
},
},
{
Expand Down
68 changes: 66 additions & 2 deletions btcjson/chainsvrresults.go
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,56 @@ func (v *Vin) MarshalJSON() ([]byte, error) {
return json.Marshal(txStruct)
}

// PrevOut represents previous output for an input Vin.
type PrevOut struct {
Addresses []string `json:"addresses,omitempty"`
Value float64 `json:"value"`
}

// VinPrevOut is like Vin except it includes PrevOut. It is used by searchrawtransaction
type VinPrevOut struct {
Coinbase string `json:"coinbase"`
Txid string `json:"txid"`
Vout uint32 `json:"vout"`
ScriptSig *ScriptSig `json:"scriptSig"`
PrevOut *PrevOut `json:"prevOut"`
Sequence uint32 `json:"sequence"`
}

// IsCoinBase returns a bool to show if a Vin is a Coinbase one or not.
func (v *VinPrevOut) IsCoinBase() bool {
return len(v.Coinbase) > 0
}

// MarshalJSON provides a custom Marshal method for VinPrevOut.
func (v *VinPrevOut) MarshalJSON() ([]byte, error) {
if v.IsCoinBase() {
coinbaseStruct := struct {
Coinbase string `json:"coinbase"`
Sequence uint32 `json:"sequence"`
}{
Coinbase: v.Coinbase,
Sequence: v.Sequence,
}
return json.Marshal(coinbaseStruct)
}

txStruct := struct {
Txid string `json:"txid"`
Vout uint32 `json:"vout"`
ScriptSig *ScriptSig `json:"scriptSig"`
PrevOut *PrevOut `json:"prevOut,omitempty"`
Sequence uint32 `json:"sequence"`
}{
Txid: v.Txid,
Vout: v.Vout,
ScriptSig: v.ScriptSig,
PrevOut: v.PrevOut,
Sequence: v.Sequence,
}
return json.Marshal(txStruct)
}

// Vout models parts of the tx data. It is defined seperately since both
// getrawtransaction and decoderawtransaction use the same structure.
type Vout struct {
Expand Down Expand Up @@ -332,8 +382,7 @@ type NetworksResult struct {
Proxy string `json:"proxy"`
}

// TxRawResult models the data from the getrawtransaction and
// searchrawtransaction commands.
// TxRawResult models the data from the getrawtransaction command.
type TxRawResult struct {
Hex string `json:"hex"`
Txid string `json:"txid"`
Expand All @@ -347,6 +396,21 @@ type TxRawResult struct {
Blocktime int64 `json:"blocktime,omitempty"`
}

// SearchRawTransactionsResult models the data from the searchrawtransaction
// command.
type SearchRawTransactionsResult struct {
Hex string `json:"hex"`
Txid string `json:"txid"`
Version int32 `json:"version"`
LockTime uint32 `json:"locktime"`
Vin []VinPrevOut `json:"vin"`
Vout []Vout `json:"vout"`
BlockHash string `json:"blockhash,omitempty"`
Confirmations uint64 `json:"confirmations,omitempty"`
Time int64 `json:"time,omitempty"`
Blocktime int64 `json:"blocktime,omitempty"`
}

// TxRawDecodeResult models the data from the decoderawtransaction command.
type TxRawDecodeResult struct {
Txid string `json:"txid"`
Expand Down
25 changes: 25 additions & 0 deletions btcjson/chainsvrresults_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,31 @@ func TestChainSvrCustomResults(t *testing.T) {
},
expected: `{"txid":"123","vout":1,"scriptSig":{"asm":"0","hex":"00"},"sequence":4294967295}`,
},
{
name: "custom vinprevout marshal with coinbase",
result: &btcjson.VinPrevOut{
Coinbase: "021234",
Sequence: 4294967295,
},
expected: `{"coinbase":"021234","sequence":4294967295}`,
},
{
name: "custom vinprevout marshal without coinbase",
result: &btcjson.VinPrevOut{
Txid: "123",
Vout: 1,
ScriptSig: &btcjson.ScriptSig{
Asm: "0",
Hex: "00",
},
PrevOut: &btcjson.PrevOut{
Addresses: []string{"addr1"},
Value: 0,
},
Sequence: 4294967295,
},
expected: `{"txid":"123","vout":1,"scriptSig":{"asm":"0","hex":"00"},"prevOut":{"addresses":["addr1"],"value":0},"sequence":4294967295}`,
},
}

t.Logf("Running %d tests", len(tests))
Expand Down
Loading