a59ac5b18f
This modifies the utxoset in the database and related UtxoViewpoint to store and work with unspent transaction outputs on a per-output basis instead of at a transaction level. This was inspired by similar recent changes in Bitcoin Core. The primary motivation is to simplify the code, pave the way for a utxo cache, and generally focus on optimizing runtime performance. The tradeoff is that this approach does somewhat increase the size of the serialized utxoset since it means that the transaction hash is duplicated for each output as a part of the key and some additional details such as whether the containing transaction is a coinbase and the block height it was a part of are duplicated in each output. However, in practice, the size difference isn't all that large, disk space is relatively cheap, certainly cheaper than memory, and it is much more important to provide more efficient runtime operation since that is the ultimate purpose of the daemon. While performing this conversion, it also simplifies the code to remove the transaction version information from the utxoset as well as the spend journal. The logic for only serializing it under certain circumstances is complicated and it isn't actually used anywhere aside from the gettxout RPC where it also isn't used by anything important either. Consequently, this also removes the version field of the gettxout RPC result. The utxos in the database are automatically migrated to the new format with this commit and it is possible to interrupt and resume the migration process. Finally, it also updates the tests for the new format and adds a new function to the tests to convert the old test data to the new format for convenience. The data has already been converted and updated in the commit. An overview of the changes are as follows: - Remove transaction version from both spent and unspent output entries - Update utxo serialization format to exclude the version - Modify the spend journal serialization format - The old version field is now reserved and always stores zero and ignores it when reading - This allows old entries to be used by new code without having to migrate the entire spend journal - Remove version field from gettxout RPC result - Convert UtxoEntry to represent a specific utxo instead of a transaction with all remaining utxos - Optimize for memory usage with an eye towards a utxo cache - Combine details such as whether the txout was contained in a coinbase, is spent, and is modified into a single packed field of bit flags - Align entry fields to eliminate extra padding since ultimately there will be a lot of these in memory - Introduce a free list for serializing an outpoint to the database key format to significantly reduce pressure on the GC - Update all related functions that previously dealt with transaction hashes to accept outpoints instead - Update all callers accordingly - Only add individually requested outputs from the mempool when constructing a mempool view - Modify the spend journal to always store the block height and coinbase information with every spent txout - Introduce code to handle fetching the missing information from another utxo from the same transaction in the event an old style entry is encountered - Make use of a database cursor with seek to do this much more efficiently than testing every possible output - Always decompress data loaded from the database now that a utxo entry only consists of a specific output - Introduce upgrade code to migrate the utxo set to the new format - Store versions of the utxoset and spend journal buckets - Allow migration process to be interrupted and resumed - Update all tests to expect the correct encodings, remove tests that no longer apply, and add new ones for the new expected behavior - Convert old tests for the legacy utxo format deserialization code to test the new function that is used during upgrade - Update the utxostore test data and add function that was used to convert it - Introduce a few new functions on UtxoViewpoint - AddTxOut for adding an individual txout versus all of them - addTxOut to handle the common code between the new AddTxOut and existing AddTxOuts - RemoveEntry for removing an individual txout - fetchEntryByHash for fetching any remaining utxo for a given transaction hash
550 lines
20 KiB
Go
550 lines
20 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 "encoding/json"
|
|
|
|
// 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 uint64 `json:"confirmations"`
|
|
Height int32 `json:"height"`
|
|
Version int32 `json:"version"`
|
|
VersionHex string `json:"versionHex"`
|
|
MerkleRoot string `json:"merkleroot"`
|
|
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"`
|
|
}
|
|
|
|
// GetBlockVerboseResult models the data from the getblock command when the
|
|
// verbose flag is set. When the verbose flag is not set, getblock returns a
|
|
// hex-encoded string.
|
|
type GetBlockVerboseResult struct {
|
|
Hash string `json:"hash"`
|
|
Confirmations uint64 `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"`
|
|
Tx []string `json:"tx,omitempty"`
|
|
RawTx []TxRawResult `json:"rawtx,omitempty"`
|
|
Time int64 `json:"time"`
|
|
Nonce uint32 `json:"nonce"`
|
|
Bits string `json:"bits"`
|
|
Difficulty float64 `json:"difficulty"`
|
|
PreviousHash string `json:"previousblockhash"`
|
|
NextHash string `json:"nextblockhash,omitempty"`
|
|
}
|
|
|
|
// 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"`
|
|
StartTime int64 `json:"startTime"`
|
|
Timeout int64 `json:"timeout"`
|
|
Since int32 `json:"since"`
|
|
}
|
|
|
|
// 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"`
|
|
Pruned bool `json:"pruned"`
|
|
PruneHeight int32 `json:"pruneheight,omitempty"`
|
|
ChainWork string `json:"chainwork,omitempty"`
|
|
SoftForks []*SoftForkDescription `json:"softforks"`
|
|
Bip9SoftForks map[string]*Bip9SoftForkDescription `json:"bip9_softforks"`
|
|
}
|
|
|
|
// GetBlockTemplateResultTx models the transactions field of the
|
|
// getblocktemplate command.
|
|
type GetBlockTemplateResultTx struct {
|
|
Data string `json:"data"`
|
|
Hash string `json:"hash"`
|
|
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"`
|
|
}
|
|
|
|
// GetMempoolEntryResult models the data returned from the getmempoolentry
|
|
// command.
|
|
type GetMempoolEntryResult struct {
|
|
Size int32 `json:"size"`
|
|
Fee float64 `json:"fee"`
|
|
ModifiedFee float64 `json:"modifiedfee"`
|
|
Time int64 `json:"time"`
|
|
Height int64 `json:"height"`
|
|
StartingPriority float64 `json:"startingpriority"`
|
|
CurrentPriority float64 `json:"currentpriority"`
|
|
DescendantCount int64 `json:"descendantcount"`
|
|
DescendantSize int64 `json:"descendantsize"`
|
|
DescendantFees float64 `json:"descendantfees"`
|
|
AncestorCount int64 `json:"ancestorcount"`
|
|
AncestorSize int64 `json:"ancestorsize"`
|
|
AncestorFees float64 `json:"ancestorfees"`
|
|
Depends []string `json:"depends"`
|
|
}
|
|
|
|
// 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"`
|
|
}
|
|
|
|
// 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"`
|
|
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"`
|
|
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"`
|
|
}
|
|
|
|
// 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"`
|
|
}
|
|
|
|
// 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 int64 `json:"hashespersec"`
|
|
NetworkHashPS int64 `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"`
|
|
Version int32 `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"`
|
|
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.
|
|
type ValidateAddressChainResult struct {
|
|
IsValid bool `json:"isvalid"`
|
|
Address string `json:"address,omitempty"`
|
|
}
|