1bab29aa69
TODO:: 1. Populate Ancestor and decsendent related fields instead of mocking. 2. Move and refator the implementation of getmempoolentry to the mempool package.
854 lines
30 KiB
Go
854 lines
30 KiB
Go
// Copyright (c) 2014-2017 The btcsuite developers
|
|
// Use of this source code is governed by an ISC
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package btcjson
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/hex"
|
|
"encoding/json"
|
|
|
|
"github.com/lbryio/lbcd/chaincfg/chainhash"
|
|
|
|
"github.com/lbryio/lbcd/wire"
|
|
btcutil "github.com/lbryio/lbcutil"
|
|
)
|
|
|
|
// GetBlockHeaderVerboseResult models the data from the getblockheader command when
|
|
// the verbose flag is set. When the verbose flag is not set, getblockheader
|
|
// returns a hex-encoded string.
|
|
type GetBlockHeaderVerboseResult struct {
|
|
Hash string `json:"hash"`
|
|
Confirmations int64 `json:"confirmations"`
|
|
Height int32 `json:"height"`
|
|
Version int32 `json:"version"`
|
|
VersionHex string `json:"versionHex"`
|
|
MerkleRoot string `json:"merkleroot"`
|
|
ClaimTrie string `json:"nameclaimroot,omitempty"`
|
|
Time int64 `json:"time"`
|
|
Nonce uint64 `json:"nonce"`
|
|
Bits string `json:"bits"`
|
|
Difficulty float64 `json:"difficulty"`
|
|
PreviousHash string `json:"previousblockhash,omitempty"`
|
|
NextHash string `json:"nextblockhash,omitempty"`
|
|
}
|
|
|
|
// GetBlockStatsResult models the data from the getblockstats command.
|
|
type GetBlockStatsResult struct {
|
|
AverageFee int64 `json:"avgfee"`
|
|
AverageFeeRate int64 `json:"avgfeerate"`
|
|
AverageTxSize int64 `json:"avgtxsize"`
|
|
FeeratePercentiles []int64 `json:"feerate_percentiles"`
|
|
Hash string `json:"blockhash"`
|
|
Height int64 `json:"height"`
|
|
Ins int64 `json:"ins"`
|
|
MaxFee int64 `json:"maxfee"`
|
|
MaxFeeRate int64 `json:"maxfeerate"`
|
|
MaxTxSize int64 `json:"maxtxsize"`
|
|
MedianFee int64 `json:"medianfee"`
|
|
MedianTime int64 `json:"mediantime"`
|
|
MedianTxSize int64 `json:"mediantxsize"`
|
|
MinFee int64 `json:"minfee"`
|
|
MinFeeRate int64 `json:"minfeerate"`
|
|
MinTxSize int64 `json:"mintxsize"`
|
|
Outs int64 `json:"outs"`
|
|
SegWitTotalSize int64 `json:"swtotal_size"`
|
|
SegWitTotalWeight int64 `json:"swtotal_weight"`
|
|
SegWitTxs int64 `json:"swtxs"`
|
|
Subsidy int64 `json:"subsidy"`
|
|
Time int64 `json:"time"`
|
|
TotalOut int64 `json:"total_out"`
|
|
TotalSize int64 `json:"total_size"`
|
|
TotalWeight int64 `json:"total_weight"`
|
|
Txs int64 `json:"txs"`
|
|
UTXOIncrease int64 `json:"utxo_increase"`
|
|
UTXOSizeIncrease int64 `json:"utxo_size_inc"`
|
|
}
|
|
|
|
type GetBlockVerboseResultBase struct {
|
|
Hash string `json:"hash"`
|
|
Confirmations int64 `json:"confirmations"`
|
|
StrippedSize int32 `json:"strippedsize"`
|
|
Size int32 `json:"size"`
|
|
Weight int32 `json:"weight"`
|
|
Height int64 `json:"height"`
|
|
Version int32 `json:"version"`
|
|
VersionHex string `json:"versionHex"`
|
|
MerkleRoot string `json:"merkleroot"`
|
|
Time int64 `json:"time"`
|
|
Nonce uint32 `json:"nonce"`
|
|
Bits string `json:"bits"`
|
|
Difficulty float64 `json:"difficulty"`
|
|
PreviousHash string `json:"previousblockhash,omitempty"`
|
|
NextHash string `json:"nextblockhash,omitempty"`
|
|
|
|
ClaimTrie string `json:"nameclaimroot,omitempty"`
|
|
TxCount int `json:"nTx"` // For backwards compatibility only
|
|
}
|
|
|
|
// GetBlockVerboseResult models the data from the getblock command when the
|
|
// verbose flag is set to 1. When the verbose flag is set to 0, getblock returns a
|
|
// hex-encoded string. When the verbose flag is set to 1, getblock returns an object
|
|
// whose tx field is an array of transaction hashes. When the verbose flag is set to 2,
|
|
// getblock returns an object whose tx field is an array of raw transactions.
|
|
// Use GetBlockVerboseTxResult to unmarshal data received from passing verbose=2 to getblock.
|
|
type GetBlockVerboseResult struct {
|
|
GetBlockVerboseResultBase
|
|
Tx []string `json:"tx"`
|
|
}
|
|
|
|
// GetBlockVerboseTxResult models the data from the getblock command when the
|
|
// verbose flag is set to 2. When the verbose flag is set to 0, getblock returns a
|
|
// hex-encoded string. When the verbose flag is set to 1, getblock returns an object
|
|
// whose tx field is an array of transaction hashes. When the verbose flag is set to 2,
|
|
// getblock returns an object whose tx field is an array of raw transactions.
|
|
// Use GetBlockVerboseResult to unmarshal data received from passing verbose=1 to getblock.
|
|
type GetBlockVerboseTxResult struct {
|
|
GetBlockVerboseResultBase
|
|
Tx []TxRawResult `json:"tx"`
|
|
}
|
|
|
|
// GetChainTxStatsResult models the data from the getchaintxstats command.
|
|
type GetChainTxStatsResult struct {
|
|
Time int64 `json:"time"`
|
|
TxCount int64 `json:"txcount"`
|
|
WindowFinalBlockHash string `json:"window_final_block_hash"`
|
|
WindowFinalBlockHeight int32 `json:"window_final_block_height"`
|
|
WindowBlockCount int32 `json:"window_block_count"`
|
|
WindowTxCount int32 `json:"window_tx_count"`
|
|
WindowInterval int32 `json:"window_interval"`
|
|
TxRate float64 `json:"txrate"`
|
|
}
|
|
|
|
// CreateMultiSigResult models the data returned from the createmultisig
|
|
// command.
|
|
type CreateMultiSigResult struct {
|
|
Address string `json:"address"`
|
|
RedeemScript string `json:"redeemScript"`
|
|
}
|
|
|
|
// DecodeScriptResult models the data returned from the decodescript command.
|
|
type DecodeScriptResult struct {
|
|
Asm string `json:"asm"`
|
|
ReqSigs int32 `json:"reqSigs,omitempty"`
|
|
Type string `json:"type"`
|
|
Addresses []string `json:"addresses,omitempty"`
|
|
P2sh string `json:"p2sh,omitempty"`
|
|
}
|
|
|
|
// GetAddedNodeInfoResultAddr models the data of the addresses portion of the
|
|
// getaddednodeinfo command.
|
|
type GetAddedNodeInfoResultAddr struct {
|
|
Address string `json:"address"`
|
|
Connected string `json:"connected"`
|
|
}
|
|
|
|
// GetAddedNodeInfoResult models the data from the getaddednodeinfo command.
|
|
type GetAddedNodeInfoResult struct {
|
|
AddedNode string `json:"addednode"`
|
|
Connected *bool `json:"connected,omitempty"`
|
|
Addresses *[]GetAddedNodeInfoResultAddr `json:"addresses,omitempty"`
|
|
}
|
|
|
|
// SoftForkDescription describes the current state of a soft-fork which was
|
|
// deployed using a super-majority block signalling.
|
|
type SoftForkDescription struct {
|
|
ID string `json:"id"`
|
|
Version uint32 `json:"version"`
|
|
Reject struct {
|
|
Status bool `json:"status"`
|
|
} `json:"reject"`
|
|
}
|
|
|
|
// Bip9SoftForkDescription describes the current state of a defined BIP0009
|
|
// version bits soft-fork.
|
|
type Bip9SoftForkDescription struct {
|
|
Status string `json:"status"`
|
|
Bit uint8 `json:"bit"`
|
|
StartTime1 int64 `json:"startTime"`
|
|
StartTime2 int64 `json:"start_time"`
|
|
Timeout int64 `json:"timeout"`
|
|
Since int32 `json:"since"`
|
|
}
|
|
|
|
// StartTime returns the starting time of the softfork as a Unix epoch.
|
|
func (d *Bip9SoftForkDescription) StartTime() int64 {
|
|
if d.StartTime1 != 0 {
|
|
return d.StartTime1
|
|
}
|
|
return d.StartTime2
|
|
}
|
|
|
|
// SoftForks describes the current softforks enabled by the backend. Softforks
|
|
// activated through BIP9 are grouped together separate from any other softforks
|
|
// with different activation types.
|
|
type SoftForks struct {
|
|
SoftForks []*SoftForkDescription `json:"softforks"`
|
|
Bip9SoftForks map[string]*Bip9SoftForkDescription `json:"bip9_softforks"`
|
|
}
|
|
|
|
// UnifiedSoftForks describes a softforks in a general manner, irrespective of
|
|
// its activation type. This was a format introduced by bitcoind v0.19.0
|
|
type UnifiedSoftFork struct {
|
|
Type string `json:"type"`
|
|
BIP9SoftForkDescription *Bip9SoftForkDescription `json:"bip9"`
|
|
Height int32 `json:"height"`
|
|
Active bool `json:"active"`
|
|
}
|
|
|
|
// UnifiedSoftForks describes the current softforks enabled the by the backend
|
|
// in a unified manner, i.e, softforks with different activation types are
|
|
// grouped together. This was a format introduced by bitcoind v0.19.0
|
|
type UnifiedSoftForks struct {
|
|
SoftForks map[string]*UnifiedSoftFork `json:"softforks"`
|
|
}
|
|
|
|
// GetBlockChainInfoResult models the data returned from the getblockchaininfo
|
|
// command.
|
|
type GetBlockChainInfoResult struct {
|
|
Chain string `json:"chain"`
|
|
Blocks int32 `json:"blocks"`
|
|
Headers int32 `json:"headers"`
|
|
BestBlockHash string `json:"bestblockhash"`
|
|
Difficulty float64 `json:"difficulty"`
|
|
MedianTime int64 `json:"mediantime"`
|
|
VerificationProgress float64 `json:"verificationprogress,omitempty"`
|
|
InitialBlockDownload bool `json:"initialblockdownload,omitempty"`
|
|
Pruned bool `json:"pruned"`
|
|
PruneHeight int32 `json:"pruneheight,omitempty"`
|
|
ChainWork string `json:"chainwork,omitempty"`
|
|
SizeOnDisk int64 `json:"size_on_disk,omitempty"`
|
|
*SoftForks
|
|
*UnifiedSoftForks
|
|
}
|
|
|
|
// GetBlockFilterResult models the data returned from the getblockfilter
|
|
// command.
|
|
type GetBlockFilterResult struct {
|
|
Filter string `json:"filter"` // the hex-encoded filter data
|
|
Header string `json:"header"` // the hex-encoded filter header
|
|
}
|
|
|
|
// GetBlockTemplateResultTx models the transactions field of the
|
|
// getblocktemplate command.
|
|
type GetBlockTemplateResultTx struct {
|
|
Data string `json:"data"`
|
|
Hash string `json:"hash"`
|
|
TxID string `json:"txid"`
|
|
Depends []int64 `json:"depends"`
|
|
Fee int64 `json:"fee"`
|
|
SigOps int64 `json:"sigops"`
|
|
Weight int64 `json:"weight"`
|
|
}
|
|
|
|
// GetBlockTemplateResultAux models the coinbaseaux field of the
|
|
// getblocktemplate command.
|
|
type GetBlockTemplateResultAux struct {
|
|
Flags string `json:"flags"`
|
|
}
|
|
|
|
// GetBlockTemplateResult models the data returned from the getblocktemplate
|
|
// command.
|
|
type GetBlockTemplateResult struct {
|
|
// Base fields from BIP 0022. CoinbaseAux is optional. One of
|
|
// CoinbaseTxn or CoinbaseValue must be specified, but not both.
|
|
Bits string `json:"bits"`
|
|
CurTime int64 `json:"curtime"`
|
|
Height int64 `json:"height"`
|
|
PreviousHash string `json:"previousblockhash"`
|
|
SigOpLimit int64 `json:"sigoplimit,omitempty"`
|
|
SizeLimit int64 `json:"sizelimit,omitempty"`
|
|
WeightLimit int64 `json:"weightlimit,omitempty"`
|
|
Transactions []GetBlockTemplateResultTx `json:"transactions"`
|
|
Version int32 `json:"version"`
|
|
CoinbaseAux *GetBlockTemplateResultAux `json:"coinbaseaux,omitempty"`
|
|
CoinbaseTxn *GetBlockTemplateResultTx `json:"coinbasetxn,omitempty"`
|
|
CoinbaseValue *int64 `json:"coinbasevalue,omitempty"`
|
|
WorkID string `json:"workid,omitempty"`
|
|
|
|
// Witness commitment defined in BIP 0141.
|
|
DefaultWitnessCommitment string `json:"default_witness_commitment,omitempty"`
|
|
|
|
// Optional long polling from BIP 0022.
|
|
LongPollID string `json:"longpollid,omitempty"`
|
|
LongPollURI string `json:"longpolluri,omitempty"`
|
|
SubmitOld *bool `json:"submitold,omitempty"`
|
|
|
|
// Basic pool extension from BIP 0023.
|
|
Target string `json:"target,omitempty"`
|
|
Expires int64 `json:"expires,omitempty"`
|
|
|
|
// Mutations from BIP 0023.
|
|
MaxTime int64 `json:"maxtime,omitempty"`
|
|
MinTime int64 `json:"mintime,omitempty"`
|
|
Mutable []string `json:"mutable,omitempty"`
|
|
NonceRange string `json:"noncerange,omitempty"`
|
|
|
|
// Block proposal from BIP 0023.
|
|
Capabilities []string `json:"capabilities,omitempty"`
|
|
RejectReasion string `json:"reject-reason,omitempty"`
|
|
|
|
ClaimTrieHash string `json:"claimtrie"`
|
|
|
|
Rules []string `json:"rules,omitempty"`
|
|
}
|
|
|
|
// GetMempoolEntryResult models the data returned from the getmempoolentry's
|
|
// fee field
|
|
|
|
type MempoolFees struct {
|
|
Base float64 `json:"base"`
|
|
Modified float64 `json:"modified"`
|
|
Ancestor float64 `json:"ancestor"`
|
|
Descendant float64 `json:"descendant"`
|
|
}
|
|
|
|
// GetMempoolEntryResult models the data returned from the getmempoolentry
|
|
// command.
|
|
type GetMempoolEntryResult struct {
|
|
VSize int32 `json:"vsize"`
|
|
Size int32 `json:"size"`
|
|
Weight int64 `json:"weight"`
|
|
Fee float64 `json:"fee"`
|
|
ModifiedFee float64 `json:"modifiedfee"`
|
|
Time int64 `json:"time"`
|
|
Height int64 `json:"height"`
|
|
DescendantCount int64 `json:"descendantcount"`
|
|
DescendantSize int64 `json:"descendantsize"`
|
|
DescendantFees float64 `json:"descendantfees"`
|
|
AncestorCount int64 `json:"ancestorcount"`
|
|
AncestorSize int64 `json:"ancestorsize"`
|
|
AncestorFees float64 `json:"ancestorfees"`
|
|
WTxId string `json:"wtxid"`
|
|
Fees MempoolFees `json:"fees"`
|
|
Depends []string `json:"depends"`
|
|
SpentBy []string `json:"spentby"`
|
|
}
|
|
|
|
// GetChainTipsResult models the data returns from the getchaintips command.
|
|
type GetChainTipsResult struct {
|
|
Height int64 `json:"height"`
|
|
Hash string `json:"hash"`
|
|
BranchLen int64 `json:"branchlen"`
|
|
Status string `json:"status"`
|
|
}
|
|
|
|
// GetMempoolInfoResult models the data returned from the getmempoolinfo
|
|
// command.
|
|
type GetMempoolInfoResult struct {
|
|
Size int64 `json:"size"`
|
|
Bytes int64 `json:"bytes"`
|
|
}
|
|
|
|
// NetworksResult models the networks data from the getnetworkinfo command.
|
|
type NetworksResult struct {
|
|
Name string `json:"name"`
|
|
Limited bool `json:"limited"`
|
|
Reachable bool `json:"reachable"`
|
|
Proxy string `json:"proxy"`
|
|
ProxyRandomizeCredentials bool `json:"proxy_randomize_credentials"`
|
|
}
|
|
|
|
// LocalAddressesResult models the localaddresses data from the getnetworkinfo
|
|
// command.
|
|
type LocalAddressesResult struct {
|
|
Address string `json:"address"`
|
|
Port uint16 `json:"port"`
|
|
Score int32 `json:"score"`
|
|
}
|
|
|
|
// GetNetworkInfoResult models the data returned from the getnetworkinfo
|
|
// command.
|
|
type GetNetworkInfoResult struct {
|
|
Version int32 `json:"version"`
|
|
SubVersion string `json:"subversion"`
|
|
ProtocolVersion int32 `json:"protocolversion"`
|
|
LocalServices string `json:"localservices"`
|
|
LocalRelay bool `json:"localrelay"`
|
|
TimeOffset int64 `json:"timeoffset"`
|
|
Connections int32 `json:"connections"`
|
|
NetworkActive bool `json:"networkactive"`
|
|
Networks []NetworksResult `json:"networks"`
|
|
RelayFee float64 `json:"relayfee"`
|
|
IncrementalFee float64 `json:"incrementalfee"`
|
|
LocalAddresses []LocalAddressesResult `json:"localaddresses"`
|
|
Warnings string `json:"warnings"`
|
|
}
|
|
|
|
// GetNodeAddressesResult models the data returned from the getnodeaddresses
|
|
// command.
|
|
type GetNodeAddressesResult struct {
|
|
// Timestamp in seconds since epoch (Jan 1 1970 GMT) keeping track of when the node was last seen
|
|
Time int64 `json:"time"`
|
|
Services uint64 `json:"services"` // The services offered
|
|
Address string `json:"address"` // The address of the node
|
|
Port uint16 `json:"port"` // The port of the node
|
|
}
|
|
|
|
// GetPeerInfoResult models the data returned from the getpeerinfo command.
|
|
type GetPeerInfoResult struct {
|
|
ID int32 `json:"id"`
|
|
Addr string `json:"addr"`
|
|
AddrLocal string `json:"addrlocal,omitempty"`
|
|
Services string `json:"services"`
|
|
RelayTxes bool `json:"relaytxes"`
|
|
LastSend int64 `json:"lastsend"`
|
|
LastRecv int64 `json:"lastrecv"`
|
|
BytesSent uint64 `json:"bytessent"`
|
|
BytesRecv uint64 `json:"bytesrecv"`
|
|
ConnTime int64 `json:"conntime"`
|
|
TimeOffset int64 `json:"timeoffset"`
|
|
PingTime float64 `json:"pingtime"`
|
|
PingWait float64 `json:"pingwait,omitempty"`
|
|
Version uint32 `json:"version"`
|
|
SubVer string `json:"subver"`
|
|
Inbound bool `json:"inbound"`
|
|
StartingHeight int32 `json:"startingheight"`
|
|
CurrentHeight int32 `json:"currentheight,omitempty"`
|
|
BanScore int32 `json:"banscore"`
|
|
FeeFilter int64 `json:"feefilter"`
|
|
SyncNode bool `json:"syncnode"`
|
|
}
|
|
|
|
// GetRawMempoolVerboseResult models the data returned from the getrawmempool
|
|
// command when the verbose flag is set. When the verbose flag is not set,
|
|
// getrawmempool returns an array of transaction hashes.
|
|
type GetRawMempoolVerboseResult struct {
|
|
Size int32 `json:"size"`
|
|
Vsize int32 `json:"vsize"`
|
|
Weight int32 `json:"weight"`
|
|
Fee float64 `json:"fee"`
|
|
Time int64 `json:"time"`
|
|
Height int64 `json:"height"`
|
|
StartingPriority float64 `json:"startingpriority"`
|
|
CurrentPriority float64 `json:"currentpriority"`
|
|
Depends []string `json:"depends"`
|
|
}
|
|
|
|
// ScriptPubKeyResult models the scriptPubKey data of a tx script. It is
|
|
// defined separately since it is used by multiple commands.
|
|
type ScriptPubKeyResult struct {
|
|
Asm string `json:"asm"`
|
|
Hex string `json:"hex,omitempty"`
|
|
ReqSigs int32 `json:"reqSigs,omitempty"`
|
|
Type string `json:"type"`
|
|
SubType string `json:"subtype"`
|
|
IsClaim bool `json:"isclaim"`
|
|
IsSupport bool `json:"issupport"`
|
|
Addresses []string `json:"addresses,omitempty"`
|
|
}
|
|
|
|
// GetTxOutResult models the data from the gettxout command.
|
|
type GetTxOutResult struct {
|
|
BestBlock string `json:"bestblock"`
|
|
Confirmations int64 `json:"confirmations"`
|
|
Value float64 `json:"value"`
|
|
ScriptPubKey ScriptPubKeyResult `json:"scriptPubKey"`
|
|
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.
|
|
type GetNetTotalsResult struct {
|
|
TotalBytesRecv uint64 `json:"totalbytesrecv"`
|
|
TotalBytesSent uint64 `json:"totalbytessent"`
|
|
TimeMillis int64 `json:"timemillis"`
|
|
}
|
|
|
|
// ScriptSig models a signature script. It is defined separately since it only
|
|
// applies to non-coinbase. Therefore the field in the Vin structure needs
|
|
// to be a pointer.
|
|
type ScriptSig struct {
|
|
Asm string `json:"asm"`
|
|
Hex string `json:"hex"`
|
|
}
|
|
|
|
// Vin models parts of the tx data. It is defined separately since
|
|
// getrawtransaction, decoderawtransaction, and searchrawtransaction use the
|
|
// same structure.
|
|
type Vin struct {
|
|
Coinbase string `json:"coinbase"`
|
|
Txid string `json:"txid"`
|
|
Vout uint32 `json:"vout"`
|
|
ScriptSig *ScriptSig `json:"scriptSig"`
|
|
Sequence uint32 `json:"sequence"`
|
|
Witness []string `json:"txinwitness"`
|
|
}
|
|
|
|
// IsCoinBase returns a bool to show if a Vin is a Coinbase one or not.
|
|
func (v *Vin) IsCoinBase() bool {
|
|
return len(v.Coinbase) > 0
|
|
}
|
|
|
|
// HasWitness returns a bool to show if a Vin has any witness data associated
|
|
// with it or not.
|
|
func (v *Vin) HasWitness() bool {
|
|
return len(v.Witness) > 0
|
|
}
|
|
|
|
// MarshalJSON provides a custom Marshal method for Vin.
|
|
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: v.Coinbase,
|
|
Sequence: v.Sequence,
|
|
Witness: v.Witness,
|
|
}
|
|
return json.Marshal(coinbaseStruct)
|
|
}
|
|
|
|
if v.HasWitness() {
|
|
txStruct := struct {
|
|
Txid string `json:"txid"`
|
|
Vout uint32 `json:"vout"`
|
|
ScriptSig *ScriptSig `json:"scriptSig"`
|
|
Witness []string `json:"txinwitness"`
|
|
Sequence uint32 `json:"sequence"`
|
|
}{
|
|
Txid: v.Txid,
|
|
Vout: v.Vout,
|
|
ScriptSig: v.ScriptSig,
|
|
Witness: v.Witness,
|
|
Sequence: v.Sequence,
|
|
}
|
|
return json.Marshal(txStruct)
|
|
}
|
|
|
|
txStruct := struct {
|
|
Txid string `json:"txid"`
|
|
Vout uint32 `json:"vout"`
|
|
ScriptSig *ScriptSig `json:"scriptSig"`
|
|
Sequence uint32 `json:"sequence"`
|
|
}{
|
|
Txid: v.Txid,
|
|
Vout: v.Vout,
|
|
ScriptSig: v.ScriptSig,
|
|
Sequence: v.Sequence,
|
|
}
|
|
return json.Marshal(txStruct)
|
|
}
|
|
|
|
// PrevOut represents previous output for an input Vin.
|
|
type PrevOut struct {
|
|
Addresses []string `json:"addresses,omitempty"`
|
|
Value float64 `json:"value"`
|
|
IsClaim bool `json:"isclaim"`
|
|
IsSupport bool `json:"issupport"`
|
|
}
|
|
|
|
// 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"`
|
|
Witness []string `json:"txinwitness"`
|
|
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
|
|
}
|
|
|
|
// HasWitness returns a bool to show if a Vin has any witness data associated
|
|
// with it or not.
|
|
func (v *VinPrevOut) HasWitness() bool {
|
|
return len(v.Witness) > 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)
|
|
}
|
|
|
|
if v.HasWitness() {
|
|
txStruct := struct {
|
|
Txid string `json:"txid"`
|
|
Vout uint32 `json:"vout"`
|
|
ScriptSig *ScriptSig `json:"scriptSig"`
|
|
Witness []string `json:"txinwitness"`
|
|
PrevOut *PrevOut `json:"prevOut,omitempty"`
|
|
Sequence uint32 `json:"sequence"`
|
|
}{
|
|
Txid: v.Txid,
|
|
Vout: v.Vout,
|
|
ScriptSig: v.ScriptSig,
|
|
Witness: v.Witness,
|
|
PrevOut: v.PrevOut,
|
|
Sequence: v.Sequence,
|
|
}
|
|
return json.Marshal(txStruct)
|
|
}
|
|
|
|
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 separately since both
|
|
// getrawtransaction and decoderawtransaction use the same structure.
|
|
type Vout struct {
|
|
Value float64 `json:"value"`
|
|
N uint32 `json:"n"`
|
|
ScriptPubKey ScriptPubKeyResult `json:"scriptPubKey"`
|
|
}
|
|
|
|
// GetMiningInfoResult models the data from the getmininginfo command.
|
|
type GetMiningInfoResult struct {
|
|
Blocks int64 `json:"blocks"`
|
|
CurrentBlockSize uint64 `json:"currentblocksize"`
|
|
CurrentBlockWeight uint64 `json:"currentblockweight"`
|
|
CurrentBlockTx uint64 `json:"currentblocktx"`
|
|
Difficulty float64 `json:"difficulty"`
|
|
Errors string `json:"errors"`
|
|
Generate bool `json:"generate"`
|
|
GenProcLimit int32 `json:"genproclimit"`
|
|
HashesPerSec float64 `json:"hashespersec"`
|
|
NetworkHashPS float64 `json:"networkhashps"`
|
|
PooledTx uint64 `json:"pooledtx"`
|
|
TestNet bool `json:"testnet"`
|
|
}
|
|
|
|
// GetWorkResult models the data from the getwork command.
|
|
type GetWorkResult struct {
|
|
Data string `json:"data"`
|
|
Hash1 string `json:"hash1"`
|
|
Midstate string `json:"midstate"`
|
|
Target string `json:"target"`
|
|
}
|
|
|
|
// InfoChainResult models the data returned by the chain server getinfo command.
|
|
type InfoChainResult struct {
|
|
Version int32 `json:"version"`
|
|
ProtocolVersion int32 `json:"protocolversion"`
|
|
Blocks int32 `json:"blocks"`
|
|
TimeOffset int64 `json:"timeoffset"`
|
|
Connections int32 `json:"connections"`
|
|
Proxy string `json:"proxy"`
|
|
Difficulty float64 `json:"difficulty"`
|
|
TestNet bool `json:"testnet"`
|
|
RelayFee float64 `json:"relayfee"`
|
|
Errors string `json:"errors"`
|
|
}
|
|
|
|
// TxRawResult models the data from the getrawtransaction command.
|
|
type TxRawResult struct {
|
|
Hex string `json:"hex"`
|
|
Txid string `json:"txid"`
|
|
Hash string `json:"hash,omitempty"`
|
|
Size int32 `json:"size,omitempty"`
|
|
Vsize int32 `json:"vsize,omitempty"`
|
|
Weight int32 `json:"weight,omitempty"`
|
|
Version uint32 `json:"version"`
|
|
LockTime uint32 `json:"locktime"`
|
|
Vin []Vin `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"`
|
|
}
|
|
|
|
// SearchRawTransactionsResult models the data from the searchrawtransaction
|
|
// command.
|
|
type SearchRawTransactionsResult struct {
|
|
Hex string `json:"hex,omitempty"`
|
|
Txid string `json:"txid"`
|
|
Hash string `json:"hash"`
|
|
Size string `json:"size"`
|
|
Vsize string `json:"vsize"`
|
|
Weight string `json:"weight"`
|
|
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"`
|
|
Version int32 `json:"version"`
|
|
Locktime uint32 `json:"locktime"`
|
|
Vin []Vin `json:"vin"`
|
|
Vout []Vout `json:"vout"`
|
|
}
|
|
|
|
// ValidateAddressChainResult models the data returned by the chain server
|
|
// validateaddress command.
|
|
//
|
|
// Compared to the Bitcoin Core version, this struct lacks the scriptPubKey
|
|
// field since it requires wallet access, which is outside the scope of btcd.
|
|
// Ref: https://bitcoincore.org/en/doc/0.20.0/rpc/util/validateaddress/
|
|
type ValidateAddressChainResult struct {
|
|
IsValid bool `json:"isvalid"`
|
|
Address string `json:"address,omitempty"`
|
|
IsScript *bool `json:"isscript,omitempty"`
|
|
IsWitness *bool `json:"iswitness,omitempty"`
|
|
WitnessVersion *int32 `json:"witness_version,omitempty"`
|
|
WitnessProgram *string `json:"witness_program,omitempty"`
|
|
}
|
|
|
|
// EstimateSmartFeeResult models the data returned buy the chain server
|
|
// estimatesmartfee command
|
|
type EstimateSmartFeeResult struct {
|
|
FeeRate *float64 `json:"feerate,omitempty"`
|
|
Errors []string `json:"errors,omitempty"`
|
|
Blocks int64 `json:"blocks"`
|
|
}
|
|
|
|
var _ json.Unmarshaler = &FundRawTransactionResult{}
|
|
|
|
type rawFundRawTransactionResult struct {
|
|
Transaction string `json:"hex"`
|
|
Fee float64 `json:"fee"`
|
|
ChangePosition int `json:"changepos"`
|
|
}
|
|
|
|
// FundRawTransactionResult is the result of the fundrawtransaction JSON-RPC call
|
|
type FundRawTransactionResult struct {
|
|
Transaction *wire.MsgTx
|
|
Fee btcutil.Amount
|
|
ChangePosition int // the position of the added change output, or -1
|
|
}
|
|
|
|
// UnmarshalJSON unmarshals the result of the fundrawtransaction JSON-RPC call
|
|
func (f *FundRawTransactionResult) UnmarshalJSON(data []byte) error {
|
|
var rawRes rawFundRawTransactionResult
|
|
if err := json.Unmarshal(data, &rawRes); err != nil {
|
|
return err
|
|
}
|
|
|
|
txBytes, err := hex.DecodeString(rawRes.Transaction)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
var msgTx wire.MsgTx
|
|
witnessErr := msgTx.Deserialize(bytes.NewReader(txBytes))
|
|
if witnessErr != nil {
|
|
legacyErr := msgTx.DeserializeNoWitness(bytes.NewReader(txBytes))
|
|
if legacyErr != nil {
|
|
return legacyErr
|
|
}
|
|
}
|
|
|
|
fee, err := btcutil.NewAmount(rawRes.Fee)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
f.Transaction = &msgTx
|
|
f.Fee = fee
|
|
f.ChangePosition = rawRes.ChangePosition
|
|
return nil
|
|
}
|
|
|
|
// GetDescriptorInfoResult models the data from the getdescriptorinfo command.
|
|
type GetDescriptorInfoResult struct {
|
|
Descriptor string `json:"descriptor"` // descriptor in canonical form, without private keys
|
|
Checksum string `json:"checksum"` // checksum for the input descriptor
|
|
IsRange bool `json:"isrange"` // whether the descriptor is ranged
|
|
IsSolvable bool `json:"issolvable"` // whether the descriptor is solvable
|
|
HasPrivateKeys bool `json:"hasprivatekeys"` // whether the descriptor has at least one private key
|
|
}
|
|
|
|
// DeriveAddressesResult models the data from the deriveaddresses command.
|
|
type DeriveAddressesResult []string
|
|
|
|
// LoadWalletResult models the data from the loadwallet command
|
|
type LoadWalletResult struct {
|
|
Name string `json:"name"`
|
|
Warning string `json:"warning"`
|
|
}
|
|
|
|
// DumpWalletResult models the data from the dumpwallet command
|
|
type DumpWalletResult struct {
|
|
Filename string `json:"filename"`
|
|
}
|