mirror of
https://github.com/btcsuite/btcd.git
synced 2025-01-19 05:33:36 +01:00
rpcclient: implement gettxoutsetinfo command
This commit is contained in:
parent
584c382334
commit
6519c04a6f
@ -9,6 +9,8 @@ import (
|
|||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
|
||||||
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
|
|
||||||
"github.com/btcsuite/btcd/wire"
|
"github.com/btcsuite/btcd/wire"
|
||||||
"github.com/btcsuite/btcutil"
|
"github.com/btcsuite/btcutil"
|
||||||
)
|
)
|
||||||
@ -435,6 +437,64 @@ type GetTxOutResult struct {
|
|||||||
Coinbase bool `json:"coinbase"`
|
Coinbase bool `json:"coinbase"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetTxOutSetInfoResult models the data from the gettxoutsetinfo command.
|
||||||
|
type GetTxOutSetInfoResult struct {
|
||||||
|
Height int64 `json:"height"`
|
||||||
|
BestBlock chainhash.Hash `json:"bestblock"`
|
||||||
|
Transactions int64 `json:"transactions"`
|
||||||
|
TxOuts int64 `json:"txouts"`
|
||||||
|
BogoSize int64 `json:"bogosize"`
|
||||||
|
HashSerialized chainhash.Hash `json:"hash_serialized_2"`
|
||||||
|
DiskSize int64 `json:"disk_size"`
|
||||||
|
TotalAmount btcutil.Amount `json:"total_amount"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON unmarshals the result of the gettxoutsetinfo JSON-RPC call
|
||||||
|
func (g *GetTxOutSetInfoResult) UnmarshalJSON(data []byte) error {
|
||||||
|
// Step 1: Create type aliases of the original struct.
|
||||||
|
type Alias GetTxOutSetInfoResult
|
||||||
|
|
||||||
|
// Step 2: Create an anonymous struct with raw replacements for the special
|
||||||
|
// fields.
|
||||||
|
aux := &struct {
|
||||||
|
BestBlock string `json:"bestblock"`
|
||||||
|
HashSerialized string `json:"hash_serialized_2"`
|
||||||
|
TotalAmount float64 `json:"total_amount"`
|
||||||
|
*Alias
|
||||||
|
}{
|
||||||
|
Alias: (*Alias)(g),
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 3: Unmarshal the data into the anonymous struct.
|
||||||
|
if err := json.Unmarshal(data, &aux); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 4: Convert the raw fields to the desired types
|
||||||
|
blockHash, err := chainhash.NewHashFromStr(aux.BestBlock)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
g.BestBlock = *blockHash
|
||||||
|
|
||||||
|
serializedHash, err := chainhash.NewHashFromStr(aux.HashSerialized)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
g.HashSerialized = *serializedHash
|
||||||
|
|
||||||
|
amount, err := btcutil.NewAmount(aux.TotalAmount)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
g.TotalAmount = amount
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// GetNetTotalsResult models the data returned from the getnettotals command.
|
// GetNetTotalsResult models the data returned from the getnettotals command.
|
||||||
type GetNetTotalsResult struct {
|
type GetNetTotalsResult struct {
|
||||||
TotalBytesRecv uint64 `json:"totalbytesrecv"`
|
TotalBytesRecv uint64 `json:"totalbytesrecv"`
|
||||||
|
@ -6,8 +6,13 @@ package btcjson_test
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
|
"github.com/btcsuite/btcutil"
|
||||||
|
"github.com/davecgh/go-spew/spew"
|
||||||
|
|
||||||
"github.com/btcsuite/btcd/btcjson"
|
"github.com/btcsuite/btcd/btcjson"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -86,3 +91,69 @@ func TestChainSvrCustomResults(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestGetTxOutSetInfoResult ensures that custom unmarshalling of
|
||||||
|
// GetTxOutSetInfoResult works as intended.
|
||||||
|
func TestGetTxOutSetInfoResult(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
result string
|
||||||
|
want btcjson.GetTxOutSetInfoResult
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "GetTxOutSetInfoResult - not scanning",
|
||||||
|
result: `{"height":123,"bestblock":"000000000000005f94116250e2407310463c0a7cf950f1af9ebe935b1c0687ab","transactions":1,"txouts":1,"bogosize":1,"hash_serialized_2":"9a0a561203ff052182993bc5d0cb2c620880bfafdbd80331f65fd9546c3e5c3e","disk_size":1,"total_amount":0.2}`,
|
||||||
|
want: btcjson.GetTxOutSetInfoResult{
|
||||||
|
Height: 123,
|
||||||
|
BestBlock: func() chainhash.Hash {
|
||||||
|
h, err := chainhash.NewHashFromStr("000000000000005f94116250e2407310463c0a7cf950f1af9ebe935b1c0687ab")
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return *h
|
||||||
|
}(),
|
||||||
|
Transactions: 1,
|
||||||
|
TxOuts: 1,
|
||||||
|
BogoSize: 1,
|
||||||
|
HashSerialized: func() chainhash.Hash {
|
||||||
|
h, err := chainhash.NewHashFromStr("9a0a561203ff052182993bc5d0cb2c620880bfafdbd80331f65fd9546c3e5c3e")
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return *h
|
||||||
|
}(),
|
||||||
|
DiskSize: 1,
|
||||||
|
TotalAmount: func() btcutil.Amount {
|
||||||
|
a, err := btcutil.NewAmount(0.2)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return a
|
||||||
|
}(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Logf("Running %d tests", len(tests))
|
||||||
|
for i, test := range tests {
|
||||||
|
var out btcjson.GetTxOutSetInfoResult
|
||||||
|
err := json.Unmarshal([]byte(test.result), &out)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Test #%d (%s) unexpected error: %v", i,
|
||||||
|
test.name, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if !reflect.DeepEqual(out, test.want) {
|
||||||
|
t.Errorf("Test #%d (%s) unexpected unmarshalled data - "+
|
||||||
|
"got %v, want %v", i, test.name, spew.Sdump(out),
|
||||||
|
spew.Sdump(test.want))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1026,6 +1026,44 @@ func (c *Client) GetTxOut(txHash *chainhash.Hash, index uint32, mempool bool) (*
|
|||||||
return c.GetTxOutAsync(txHash, index, mempool).Receive()
|
return c.GetTxOutAsync(txHash, index, mempool).Receive()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FutureGetTxOutSetInfoResult is a future promise to deliver the result of a
|
||||||
|
// GetTxOutSetInfoAsync RPC invocation (or an applicable error).
|
||||||
|
type FutureGetTxOutSetInfoResult chan *response
|
||||||
|
|
||||||
|
// Receive waits for the response promised by the future and returns the
|
||||||
|
// results of GetTxOutSetInfoAsync RPC invocation.
|
||||||
|
func (r FutureGetTxOutSetInfoResult) Receive() (*btcjson.GetTxOutSetInfoResult, error) {
|
||||||
|
res, err := receiveFuture(r)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unmarshal result as an gettxoutsetinfo result object.
|
||||||
|
var txOutSetInfo *btcjson.GetTxOutSetInfoResult
|
||||||
|
err = json.Unmarshal(res, &txOutSetInfo)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return txOutSetInfo, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetTxOutSetInfoAsync returns an instance of a type that can be used to get
|
||||||
|
// the result of the RPC at some future time by invoking the Receive function on
|
||||||
|
// the returned instance.
|
||||||
|
//
|
||||||
|
// See GetTxOutSetInfo for the blocking version and more details.
|
||||||
|
func (c *Client) GetTxOutSetInfoAsync() FutureGetTxOutSetInfoResult {
|
||||||
|
cmd := btcjson.NewGetTxOutSetInfoCmd()
|
||||||
|
return c.sendCmd(cmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetTxOutSetInfo returns the statistics about the unspent transaction output
|
||||||
|
// set.
|
||||||
|
func (c *Client) GetTxOutSetInfo() (*btcjson.GetTxOutSetInfoResult, error) {
|
||||||
|
return c.GetTxOutSetInfoAsync().Receive()
|
||||||
|
}
|
||||||
|
|
||||||
// FutureRescanBlocksResult is a future promise to deliver the result of a
|
// FutureRescanBlocksResult is a future promise to deliver the result of a
|
||||||
// RescanBlocksAsync RPC invocation (or an applicable error).
|
// RescanBlocksAsync RPC invocation (or an applicable error).
|
||||||
//
|
//
|
||||||
|
@ -116,3 +116,22 @@ func ExampleClient_GetWalletInfo() {
|
|||||||
fmt.Println(*info.HDSeedID) // eb44e4e9b864ef17e7ba947da746375b000f5d94
|
fmt.Println(*info.HDSeedID) // eb44e4e9b864ef17e7ba947da746375b000f5d94
|
||||||
fmt.Println(info.Scanning.Value) // false
|
fmt.Println(info.Scanning.Value) // false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ExampleClient_GetTxOutSetInfo() {
|
||||||
|
client, err := New(connCfg, nil)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
defer client.Shutdown()
|
||||||
|
|
||||||
|
r, err := client.GetTxOutSetInfo()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println(r.TotalAmount.String()) // 20947654.56996054 BTC
|
||||||
|
fmt.Println(r.BestBlock.String()) // 000000000000005f94116250e2407310463c0a7cf950f1af9ebe935b1c0687ab
|
||||||
|
fmt.Println(r.TxOuts) // 24280607
|
||||||
|
fmt.Println(r.Transactions) // 9285603
|
||||||
|
fmt.Println(r.DiskSize) // 1320871611
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user