From be60ce48907a2eaa10166c3320148d70884ed149 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ian=20Desc=C3=B4teaux?= Date: Tue, 9 Apr 2019 01:21:07 -0400 Subject: [PATCH 1/8] Refactor RPC call function name for uniformity --- electrum/block.go | 12 ++++++------ electrum/misc.go | 12 ++++++------ electrum/transaction.go | 30 +++++++++++++++--------------- 3 files changed, 27 insertions(+), 27 deletions(-) diff --git a/electrum/block.go b/electrum/block.go index cd58fd7..1988827 100644 --- a/electrum/block.go +++ b/electrum/block.go @@ -7,16 +7,16 @@ var ( ErrCheckpointHeight = errors.New("checkpoint height must be greater or equal than block height") ) -// BlockHeaderResp represents the response to BlockHeader(). +// BlockHeaderResp represents the response to GetBlockHeader(). type BlockHeaderResp struct { Branch []string `json:"branch"` Header string `json:"header"` Root string `json:"root"` } -// BlockHeader returns the block header at a specific height. +// GetBlockHeader returns the block header at a specific height. // https://electrumx.readthedocs.io/en/latest/protocol-methods.html#blockchain-block-header -func (s *Server) BlockHeader(height uint32, checkpointHeight ...uint32) (*BlockHeaderResp, error) { +func (s *Server) GetBlockHeader(height uint32, checkpointHeight ...uint32) (*BlockHeaderResp, error) { if checkpointHeight != nil { if height > checkpointHeight[0] { return nil, ErrCheckpointHeight @@ -45,7 +45,7 @@ func (s *Server) BlockHeader(height uint32, checkpointHeight ...uint32) (*BlockH return result, err } -// BlockHeadersResp represents the response to BlockHeaders(). +// BlockHeadersResp represents the response to GetBlockHeaders(). type BlockHeadersResp struct { Count uint32 `json:"count"` Headers string `json:"hex"` @@ -54,9 +54,9 @@ type BlockHeadersResp struct { Root string `json:"root,omitempty"` } -// BlockHeaders return a concatenated chunk of block headers. +// GetBlockHeaders return a concatenated chunk of block headers. // https://electrumx.readthedocs.io/en/latest/protocol-methods.html#blockchain-block-headers -func (s *Server) BlockHeaders(startHeight, count uint32, checkpointHeight ...uint32) (*BlockHeadersResp, error) { +func (s *Server) GetBlockHeaders(startHeight, count uint32, checkpointHeight ...uint32) (*BlockHeadersResp, error) { resp := &struct { Result *BlockHeadersResp `json:"result"` }{} diff --git a/electrum/misc.go b/electrum/misc.go index 35c2dbb..7610f08 100644 --- a/electrum/misc.go +++ b/electrum/misc.go @@ -11,10 +11,10 @@ type basicResp struct { Result string `json:"result"` } -// EstimateFee returns the estimated transaction fee per kilobytes for a transaction +// GetFee returns the estimated transaction fee per kilobytes for a transaction // to be confirmed within a target number of blocks. // https://electrumx.readthedocs.io/en/latest/protocol-methods.html#blockchain-estimatefee -func (s *Server) EstimateFee(target uint32) (float32, error) { +func (s *Server) GetFee(target uint32) (float32, error) { resp := &struct { Result float32 `json:"result"` }{} @@ -27,10 +27,10 @@ func (s *Server) EstimateFee(target uint32) (float32, error) { return resp.Result, err } -// RelayFee returns the minimum fee a transaction must pay to be accepted into the +// GetRelayFee returns the minimum fee a transaction must pay to be accepted into the // remote server memory pool. // https://electrumx.readthedocs.io/en/latest/protocol-methods.html#blockchain-relayfee -func (s *Server) RelayFee() (float32, error) { +func (s *Server) GetRelayFee() (float32, error) { resp := &struct { Result float32 `json:"result"` }{} @@ -43,10 +43,10 @@ func (s *Server) RelayFee() (float32, error) { return resp.Result, err } -// FeeHistogram returns a histogram of the fee rates paid by transactions in the +// GetFeeHistogram returns a histogram of the fee rates paid by transactions in the // memory pool, weighted by transacation size. // https://electrumx.readthedocs.io/en/latest/protocol-methods.html#mempool-get-fee-histogram -func (s *Server) FeeHistogram() (map[uint32]uint32, error) { +func (s *Server) GetFeeHistogram() (map[uint32]uint32, error) { resp := &struct { Result map[uint32]uint32 `json:"result"` }{} diff --git a/electrum/transaction.go b/electrum/transaction.go index c2de267..03c22d0 100644 --- a/electrum/transaction.go +++ b/electrum/transaction.go @@ -1,9 +1,9 @@ package electrum -// TransactionBroadcast sends a raw transaction to the remote server to +// BroadcastTransaction sends a raw transaction to the remote server to // be broadcasted on the server network. // https://electrumx.readthedocs.io/en/latest/protocol-methods.html#blockchain-transaction-broadcast -func (s *Server) TransactionBroadcast(rawTx string) (string, error) { +func (s *Server) BroadcastTransaction(rawTx string) (string, error) { resp := &basicResp{} err := s.request("blockchain.transaction.broadcast", []interface{}{rawTx}, resp) if err != nil { @@ -13,7 +13,7 @@ func (s *Server) TransactionBroadcast(rawTx string) (string, error) { return resp.Result, nil } -// TransactionResp represents the response to TransactionGet(). +// TransactionResp represents the response to GetTransaction(). type TransactionResp struct { Blockhash string `json:"blockhash"` Blocktime uint64 `json:"blocktime"` @@ -60,9 +60,9 @@ type ScriptPubkey struct { Type string `json:"type"` } -// TransactionGet gets the detailed information for a transaction. +// GetTransaction gets the detailed information for a transaction. // https://electrumx.readthedocs.io/en/latest/protocol-methods.html#blockchain-transaction-get -func (s *Server) TransactionGet(txHash string) (*TransactionResp, error) { +func (s *Server) GetTransaction(txHash string) (*TransactionResp, error) { resp := &struct { Result TransactionResp `json:"result"` }{} @@ -74,9 +74,9 @@ func (s *Server) TransactionGet(txHash string) (*TransactionResp, error) { return &resp.Result, nil } -// TransactionGetRaw gets a raw encoded transaction. +// GetRawTransaction gets a raw encoded transaction. // https://electrumx.readthedocs.io/en/latest/protocol-methods.html#blockchain-transaction-get -func (s *Server) TransactionGetRaw(txHash string) (string, error) { +func (s *Server) GetRawTransaction(txHash string) (string, error) { resp := &basicResp{} err := s.request("blockchain.transaction.get", []interface{}{txHash, false}, resp) if err != nil { @@ -86,16 +86,16 @@ func (s *Server) TransactionGetRaw(txHash string) (string, error) { return resp.Result, nil } -// MerkleResp represents the response TransactionGetMerkle(). +// MerkleResp represents the response GetMerkleProof(). type MerkleResp struct { Merkle []string `json:"merkle"` Height uint32 `json:"block_height"` Position uint32 `json:"pos"` } -// TransactionGetMerkle returns the merkle proof for a confirmed transaction. +// GetMerkleProof returns the merkle proof for a confirmed transaction. // https://electrumx.readthedocs.io/en/latest/protocol-methods.html#blockchain-transaction-get-merkle -func (s *Server) TransactionGetMerkle(txHash string, height uint32) (*MerkleResp, error) { +func (s *Server) GetMerkleProof(txHash string, height uint32) (*MerkleResp, error) { resp := &struct { Result MerkleResp `json:"result"` }{} @@ -107,9 +107,9 @@ func (s *Server) TransactionGetMerkle(txHash string, height uint32) (*MerkleResp return &resp.Result, err } -// TransactionHashFromPosition returns the transaction hash for a specific position in a block. +// GetHashFromPosition returns the transaction hash for a specific position in a block. // https://electrumx.readthedocs.io/en/latest/protocol-methods.html#blockchain-transaction-id-from-pos -func (s *Server) TransactionHashFromPosition(height, position uint32) (string, error) { +func (s *Server) GetHashFromPosition(height, position uint32) (string, error) { resp := &basicResp{} err := s.request("blockchain.transaction.id_from_pos", []interface{}{height, position, false}, resp) if err != nil { @@ -119,15 +119,15 @@ func (s *Server) TransactionHashFromPosition(height, position uint32) (string, e return resp.Result, err } -// MerkleFromPosResp represents the response to TransactionMerkleFromPosition(). +// MerkleFromPosResp represents the response to GetMerkleProofFromPosition(). type MerkleFromPosResp struct { Hash string `json:"tx_hash"` Merkle []string `json:"merkle"` } -// TransactionMerkleFromPosition returns the merkle proof for a specific position in a block. +// GetMerkleProofFromPosition returns the merkle proof for a specific position in a block. // https://electrumx.readthedocs.io/en/latest/protocol-methods.html#blockchain-transaction-id-from-pos -func (s *Server) TransactionMerkleFromPosition(height, position uint32) (*MerkleFromPosResp, error) { +func (s *Server) GetMerkleProofFromPosition(height, position uint32) (*MerkleFromPosResp, error) { resp := struct { Result MerkleFromPosResp `json:"result"` }{} From 05dbd73ea1a6d81b3e485127fbb060a3232fda7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ian=20Desc=C3=B4teaux?= Date: Tue, 9 Apr 2019 01:28:11 -0400 Subject: [PATCH 2/8] Remove TODO comments --- electrum/misc.go | 7 ------- electrum/scripthash.go | 5 ----- 2 files changed, 12 deletions(-) diff --git a/electrum/misc.go b/electrum/misc.go index 7610f08..97f3648 100644 --- a/electrum/misc.go +++ b/electrum/misc.go @@ -1,12 +1,5 @@ package electrum -/* TODO: - * - masternode.announce.broadcast - * - masternode.list - * - protx.diff - * - protx.info - */ - type basicResp struct { Result string `json:"result"` } diff --git a/electrum/scripthash.go b/electrum/scripthash.go index 80fee94..c5954b1 100644 --- a/electrum/scripthash.go +++ b/electrum/scripthash.go @@ -1,10 +1,5 @@ package electrum -/* TODO: - * - blockchain.scripthash.utxos (version 1.5) - * - blockchain.scripthash.history (version 1.5) - */ - // BalanceResp represents the response to GetBalance(). type BalanceResp struct { Confirmed float64 `json:"confirmed"` From e17304e3501d5811023362bbe9300a04d258000e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ian=20Desc=C3=B4teaux?= Date: Tue, 9 Apr 2019 01:42:08 -0400 Subject: [PATCH 3/8] Add documentation to network.go --- electrum/network.go | 42 +++++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/electrum/network.go b/electrum/network.go index 1341074..d7e8114 100644 --- a/electrum/network.go +++ b/electrum/network.go @@ -14,48 +14,52 @@ import ( ) const ( - // ClientVersion ... + // ClientVersion identifies the client version/name to the remote server ClientVersion = "go-electrum1.0" - // ProtocolVersion ... + // ProtocolVersion identifies the support protocol version to the remote server ProtocolVersion = "1.4" + // TCP connection and server request timeout duration. connTimeout = 30 * time.Second nl = byte('\n') ) var ( - // DebugMode ... + // DebugMode provides debug output on communications with the remote server if enabled. DebugMode bool - // ErrServerConnected ... + // ErrServerConnected throws an error if remote server is already connected. ErrServerConnected = errors.New("server is already connected") - // ErrServerShutdown ... + // ErrServerShutdown throws an error if remote server has shutdown. ErrServerShutdown = errors.New("server has shutdown") - // ErrTimeout ... + // ErrTimeout throws an error if request has timed out ErrTimeout = errors.New("request timeout") - // ErrNotImplemented ... - ErrNotImplemented = errors.New("API call is not implemented") + // ErrNotImplemented throws an error if this RPC call has not been implemented yet. + ErrNotImplemented = errors.New("RPC call is not implemented") + + // ErrDeprecated throws an error if this RPC call is deprecated. + ErrDeprecated = errors.New("RPC call has been deprecated") ) -// Transport ... +// Transport provides interface to server transport. type Transport interface { SendMessage([]byte) error Responses() <-chan []byte Errors() <-chan error } -// TCPTransport ... +// TCPTransport store informations about the TCP transport. type TCPTransport struct { conn net.Conn responses chan []byte errors chan error } -// NewTCPTransport ... +// NewTCPTransport opens a new TCP connection to the remote server. func NewTCPTransport(addr string) (*TCPTransport, error) { conn, err := net.DialTimeout("tcp", addr, connTimeout) if err != nil { @@ -73,7 +77,7 @@ func NewTCPTransport(addr string) (*TCPTransport, error) { return tcp, nil } -// NewSSLTransport ... +// NewSSLTransport opens a new SSL connection to the remote server. func NewSSLTransport(addr string, config *tls.Config) (*TCPTransport, error) { dialer := net.Dialer{ Timeout: connTimeout, @@ -112,7 +116,7 @@ func (t *TCPTransport) listen() { } } -// SendMessage ... +// SendMessage sends a message to the remote server through the TCP transport. func (t *TCPTransport) SendMessage(body []byte) error { if DebugMode { log.Printf("%s [debug] %s <- %s", time.Now().Format("2006-01-02 15:04:05"), t.conn.RemoteAddr(), body) @@ -122,12 +126,12 @@ func (t *TCPTransport) SendMessage(body []byte) error { return err } -// Responses ... +// Responses returns chan to TCP transport responses. func (t *TCPTransport) Responses() <-chan []byte { return t.responses } -// Errors ... +// Errors returns chan to TCP transport errors. func (t *TCPTransport) Errors() <-chan error { return t.errors } @@ -137,7 +141,7 @@ type container struct { err error } -// Server ... +// Server stores information about the remote server. type Server struct { transport Transport @@ -153,7 +157,7 @@ type Server struct { nextID uint64 } -// NewServer ... +// NewServer initialize a new remote server. func NewServer() *Server { s := &Server{ handlers: make(map[uint64]chan *container), @@ -166,7 +170,7 @@ func NewServer() *Server { return s } -// ConnectTCP ... +// ConnectTCP connects to the remote server using TCP. func (s *Server) ConnectTCP(addr string) error { if s.transport != nil { return ErrServerConnected @@ -183,7 +187,7 @@ func (s *Server) ConnectTCP(addr string) error { return nil } -// ConnectSSL ... +// ConnectSSL connects to the remote server using SSL. func (s *Server) ConnectSSL(addr string, config *tls.Config) error { if s.transport != nil { return ErrServerConnected From 83a648a5de0664b5252147ce6cc904b6db23ad97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ian=20Desc=C3=B4teaux?= Date: Wed, 10 Apr 2019 02:06:51 -0400 Subject: [PATCH 4/8] Fix checkpointHeight usage when requesting block headers --- electrum/block.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/electrum/block.go b/electrum/block.go index 1988827..d5ca4ab 100644 --- a/electrum/block.go +++ b/electrum/block.go @@ -25,7 +25,7 @@ func (s *Server) GetBlockHeader(height uint32, checkpointHeight ...uint32) (*Blo resp := &struct { Result *BlockHeaderResp `json:"result"` }{} - err := s.request("blockchain.block.header", []interface{}{height, checkpointHeight}, resp) + err := s.request("blockchain.block.header", []interface{}{height, checkpointHeight[0]}, resp) return resp.Result, err } @@ -65,7 +65,7 @@ func (s *Server) GetBlockHeaders(startHeight, count uint32, checkpointHeight ... if (startHeight + (count - 1)) > checkpointHeight[0] { return nil, ErrCheckpointHeight } - err := s.request("blockchain.block.headers", []interface{}{startHeight, count, checkpointHeight}, resp) + err := s.request("blockchain.block.headers", []interface{}{startHeight, count, checkpointHeight[0]}, resp) if err != nil { return nil, err } @@ -73,7 +73,7 @@ func (s *Server) GetBlockHeaders(startHeight, count uint32, checkpointHeight ... return resp.Result, err } - err := s.request("blockchain.block.headers", []interface{}{startHeight, count, checkpointHeight}, resp) + err := s.request("blockchain.block.headers", []interface{}{startHeight, count}, resp) if err != nil { return nil, err } From 1be998a66b9e038adb8df36c54e99737ae0a7b15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ian=20Desc=C3=B4teaux?= Date: Wed, 10 Apr 2019 02:44:02 -0400 Subject: [PATCH 5/8] Fix returned map for GetFeeHistogram() --- electrum/misc.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/electrum/misc.go b/electrum/misc.go index 97f3648..479f7ad 100644 --- a/electrum/misc.go +++ b/electrum/misc.go @@ -39,9 +39,9 @@ func (s *Server) GetRelayFee() (float32, error) { // GetFeeHistogram returns a histogram of the fee rates paid by transactions in the // memory pool, weighted by transacation size. // https://electrumx.readthedocs.io/en/latest/protocol-methods.html#mempool-get-fee-histogram -func (s *Server) GetFeeHistogram() (map[uint32]uint32, error) { +func (s *Server) GetFeeHistogram() ([]*map[uint32]uint64, error) { resp := &struct { - Result map[uint32]uint32 `json:"result"` + Result []*map[uint32]uint64 `json:"result"` }{} err := s.request("mempool.get_fee_histogram", []interface{}{}, resp) From 60c984b5f35e72453a7133db44ea33f046730b49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ian=20Desc=C3=B4teaux?= Date: Thu, 11 Apr 2019 01:21:18 -0400 Subject: [PATCH 6/8] Refactor use of bare struct in functions --- electrum/block.go | 52 +++++++++++++------------ electrum/misc.go | 26 +++++++------ electrum/scripthash.go | 42 +++++++++++--------- electrum/server.go | 37 +++++++++++------- electrum/subscribe.go | 41 ++++++++++++-------- electrum/transaction.go | 85 ++++++++++++++++++++++++----------------- 6 files changed, 167 insertions(+), 116 deletions(-) diff --git a/electrum/block.go b/electrum/block.go index d5ca4ab..e05fb1c 100644 --- a/electrum/block.go +++ b/electrum/block.go @@ -4,11 +4,16 @@ import "errors" var ( // ErrCheckpointHeight is thrown if the checkpoint height is smaller than the block height. - ErrCheckpointHeight = errors.New("checkpoint height must be greater or equal than block height") + ErrCheckpointHeight = errors.New("checkpoint height must be greater than or equal to block height") ) -// BlockHeaderResp represents the response to GetBlockHeader(). -type BlockHeaderResp struct { +// GetBlockHeaderResp represents the response to GetBlockHeader(). +type GetBlockHeaderResp struct { + Result *GetBlockHeaderResult `json:"result"` +} + +// GetBlockHeaderResult represents the content of the result field in the response to GetBlockHeader(). +type GetBlockHeaderResult struct { Branch []string `json:"branch"` Header string `json:"header"` Root string `json:"root"` @@ -16,27 +21,25 @@ type BlockHeaderResp struct { // GetBlockHeader returns the block header at a specific height. // https://electrumx.readthedocs.io/en/latest/protocol-methods.html#blockchain-block-header -func (s *Server) GetBlockHeader(height uint32, checkpointHeight ...uint32) (*BlockHeaderResp, error) { - if checkpointHeight != nil { +func (s *Server) GetBlockHeader(height uint32, checkpointHeight ...uint32) (*GetBlockHeaderResult, error) { + if checkpointHeight != nil && checkpointHeight[0] != 0 { if height > checkpointHeight[0] { return nil, ErrCheckpointHeight } - resp := &struct { - Result *BlockHeaderResp `json:"result"` - }{} + var resp GetBlockHeaderResp err := s.request("blockchain.block.header", []interface{}{height, checkpointHeight[0]}, resp) return resp.Result, err } - resp := &basicResp{} - err := s.request("blockchain.block.header", []interface{}{height}, resp) + var resp basicResp + err := s.request("blockchain.block.header", []interface{}{height, 0}, resp) if err != nil { return nil, err } - result := &BlockHeaderResp{ + result := &GetBlockHeaderResult{ Branch: nil, Header: resp.Result, Root: "", @@ -45,8 +48,13 @@ func (s *Server) GetBlockHeader(height uint32, checkpointHeight ...uint32) (*Blo return result, err } -// BlockHeadersResp represents the response to GetBlockHeaders(). -type BlockHeadersResp struct { +// GetBlockHeadersResp represents the response to GetBlockHeaders(). +type GetBlockHeadersResp struct { + Result *GetBlockHeadersResult `json:"result"` +} + +// GetBlockHeadersResult represents the content of the result field in the response to GetBlockHeaders(). +type GetBlockHeadersResult struct { Count uint32 `json:"count"` Headers string `json:"hex"` Max uint32 `json:"max"` @@ -56,24 +64,20 @@ type BlockHeadersResp struct { // GetBlockHeaders return a concatenated chunk of block headers. // https://electrumx.readthedocs.io/en/latest/protocol-methods.html#blockchain-block-headers -func (s *Server) GetBlockHeaders(startHeight, count uint32, checkpointHeight ...uint32) (*BlockHeadersResp, error) { - resp := &struct { - Result *BlockHeadersResp `json:"result"` - }{} +func (s *Server) GetBlockHeaders(startHeight, count uint32, checkpointHeight ...uint32) (*GetBlockHeadersResult, error) { + var resp GetBlockHeadersResp + var err error - if checkpointHeight != nil { + if checkpointHeight != nil && checkpointHeight[0] != 0 { if (startHeight + (count - 1)) > checkpointHeight[0] { return nil, ErrCheckpointHeight } - err := s.request("blockchain.block.headers", []interface{}{startHeight, count, checkpointHeight[0]}, resp) - if err != nil { - return nil, err - } - return resp.Result, err + err = s.request("blockchain.block.headers", []interface{}{startHeight, count, checkpointHeight[0]}, resp) + } else { + err = s.request("blockchain.block.headers", []interface{}{startHeight, count, 0}, resp) } - err := s.request("blockchain.block.headers", []interface{}{startHeight, count}, resp) if err != nil { return nil, err } diff --git a/electrum/misc.go b/electrum/misc.go index 479f7ad..ad619a3 100644 --- a/electrum/misc.go +++ b/electrum/misc.go @@ -4,13 +4,16 @@ type basicResp struct { Result string `json:"result"` } +// GetFeeResp represents the response to GetFee(). +type GetFeeResp struct { + Result float32 `json:"result"` +} + // GetFee returns the estimated transaction fee per kilobytes for a transaction // to be confirmed within a target number of blocks. // https://electrumx.readthedocs.io/en/latest/protocol-methods.html#blockchain-estimatefee func (s *Server) GetFee(target uint32) (float32, error) { - resp := &struct { - Result float32 `json:"result"` - }{} + var resp GetFeeResp err := s.request("blockchain.estimatefee", []interface{}{target}, resp) if err != nil { @@ -24,9 +27,7 @@ func (s *Server) GetFee(target uint32) (float32, error) { // remote server memory pool. // https://electrumx.readthedocs.io/en/latest/protocol-methods.html#blockchain-relayfee func (s *Server) GetRelayFee() (float32, error) { - resp := &struct { - Result float32 `json:"result"` - }{} + var resp GetFeeResp err := s.request("blockchain.relayfee", []interface{}{}, resp) if err != nil { @@ -36,15 +37,18 @@ func (s *Server) GetRelayFee() (float32, error) { return resp.Result, err } +// GetFeeHistogramResp represents the response to GetFee(). +type GetFeeHistogramResp struct { + Result map[uint32]uint64 `json:"result"` +} + // GetFeeHistogram returns a histogram of the fee rates paid by transactions in the // memory pool, weighted by transacation size. // https://electrumx.readthedocs.io/en/latest/protocol-methods.html#mempool-get-fee-histogram -func (s *Server) GetFeeHistogram() ([]*map[uint32]uint64, error) { - resp := &struct { - Result []*map[uint32]uint64 `json:"result"` - }{} +func (s *Server) GetFeeHistogram() (map[uint32]uint64, error) { + var resp GetFeeHistogramResp - err := s.request("mempool.get_fee_histogram", []interface{}{}, resp) + err := s.request("mempool.get_fee_histogram", []interface{}{}, &resp) if err != nil { return nil, err } diff --git a/electrum/scripthash.go b/electrum/scripthash.go index c5954b1..fafdb06 100644 --- a/electrum/scripthash.go +++ b/electrum/scripthash.go @@ -1,37 +1,46 @@ package electrum -// BalanceResp represents the response to GetBalance(). -type BalanceResp struct { +// GetBalanceResp represents the response to GetBalance(). +type GetBalanceResp struct { + Result GetBalanceResult `json:"result"` +} + +// GetBalanceResult represents the content of the result field in the response to GetBalance(). +type GetBalanceResult struct { Confirmed float64 `json:"confirmed"` Unconfirmed float64 `json:"unconfirmed"` } // GetBalance returns the confirmed and unconfirmed balance for a scripthash. // https://electrumx.readthedocs.io/en/latest/protocol-methods.html#blockchain-scripthash-get-balance -func (s *Server) GetBalance(scripthash string) (BalanceResp, error) { - resp := &struct { - Result BalanceResp `json:"result"` - }{} +func (s *Server) GetBalance(scripthash string) (GetBalanceResult, error) { + var resp GetBalanceResp + err := s.request("blockchain.scripthash.get_balance", []interface{}{scripthash}, resp) if err != nil { - return BalanceResp{}, err + return GetBalanceResult{}, err } return resp.Result, err } -// MempoolResp represents the reponse to GetHistory() and GetMempool(). -type MempoolResp struct { +// GetMempoolResp represents the response to GetHistory() and GetMempool(). +type GetMempoolResp struct { + Result []*GetMempoolResult `json:"result"` +} + +// GetMempoolResult represents the content of the result field in the response +// to GetHistory() and GetMempool(). +type GetMempoolResult struct { Hash string `json:"tx_hash"` Height int32 `json:"height"` Fee uint32 `json:"fee,omitempty"` } // GetHistory returns the confirmed and unconfirmed history for a scripthash. -func (s *Server) GetHistory(scripthash string) ([]*MempoolResp, error) { - resp := &struct { - Result []*MempoolResp `json:"result"` - }{} +func (s *Server) GetHistory(scripthash string) ([]*GetMempoolResult, error) { + var resp GetMempoolResp + err := s.request("blockchain.scripthash.get_history", []interface{}{scripthash}, resp) if err != nil { return nil, err @@ -41,10 +50,9 @@ func (s *Server) GetHistory(scripthash string) ([]*MempoolResp, error) { } // GetMempool returns the unconfirmed transacations of a scripthash. -func (s *Server) GetMempool(scripthash string) ([]*MempoolResp, error) { - resp := &struct { - Result []*MempoolResp `json:"result"` - }{} +func (s *Server) GetMempool(scripthash string) ([]*GetMempoolResult, error) { + var resp GetMempoolResp + err := s.request("blockchain.scripthash.get_mempool", []interface{}{scripthash}, resp) if err != nil { return nil, err diff --git a/electrum/server.go b/electrum/server.go index 03e30e1..1e0010d 100644 --- a/electrum/server.go +++ b/electrum/server.go @@ -12,8 +12,9 @@ func (s *Server) Ping() error { // ServerAddPeer adds your new server into the remote server own peers list. // This should not be used if you are a client. // https://electrumx.readthedocs.io/en/latest/protocol-methods.html#server-add-peer -func (s *Server) ServerAddPeer(features *FeaturesResp) error { - resp := &basicResp{} +func (s *Server) ServerAddPeer(features *ServerFeaturesResult) error { + var resp basicResp + err := s.request("server.add_peer", []interface{}{features}, resp) return err @@ -22,7 +23,8 @@ func (s *Server) ServerAddPeer(features *FeaturesResp) error { // ServerBanner returns the banner for this remote server. // https://electrumx.readthedocs.io/en/latest/protocol-methods.html#server-banner func (s *Server) ServerBanner() (string, error) { - resp := &basicResp{} + var resp basicResp + err := s.request("server.banner", []interface{}{}, resp) return resp.Result, err @@ -31,7 +33,8 @@ func (s *Server) ServerBanner() (string, error) { // ServerDonation returns the donation address for this remote server // https://electrumx.readthedocs.io/en/latest/protocol-methods.html#server-donation-address func (s *Server) ServerDonation() (string, error) { - resp := &basicResp{} + var resp basicResp + err := s.request("server.donation_address", []interface{}{}, resp) return resp.Result, err @@ -42,9 +45,14 @@ type host struct { SSLPort uint16 `json:"ssl_port,omitempty"` } -// FeaturesResp represent the data sent or receive in RPC call "server.features" and +// ServerFeaturesResp represent the response to GetFeatures(). +type ServerFeaturesResp struct { + Result *ServerFeaturesResult `json:"result"` +} + +// ServerFeaturesResult represent the data sent or receive in RPC call "server.features" and // "server.add_peer". -type FeaturesResp struct { +type ServerFeaturesResult struct { GenesisHash string `json:"genesis_hash"` Hosts map[string]host `json:"hosts"` ProtocolMax string `json:"protocol_max"` @@ -56,10 +64,9 @@ type FeaturesResp struct { // ServerFeatures returns a list of features and services supported by the remote server. // https://electrumx.readthedocs.io/en/latest/protocol-methods.html#server-features -func (s *Server) ServerFeatures() (*FeaturesResp, error) { - resp := &struct { - Result *FeaturesResp `json:"result"` - }{} +func (s *Server) ServerFeatures() (*ServerFeaturesResult, error) { + var resp ServerFeaturesResp + err := s.request("server.features", []interface{}{}, resp) return resp.Result, err @@ -76,13 +83,17 @@ func (s *Server) ServerPeers() (interface{}, error) { return resp.Result, err } +// ServerVersionResp represent the response to ServerVersion(). +type ServerVersionResp struct { + Result [2]string `json:"result"` +} + // ServerVersion identify the client to the server, and negotiate the protocol version. // This call must be sent first, or the server will default to an older protocol version. // https://electrumx.readthedocs.io/en/latest/protocol-methods.html#server-version func (s *Server) ServerVersion() (serverVer, protocolVer string, err error) { - resp := &struct { - Result []string `json:"result"` - }{} + var resp ServerVersionResp + err = s.request("server.version", []interface{}{ClientVersion, ProtocolVersion}, resp) if err != nil { serverVer = "" diff --git a/electrum/subscribe.go b/electrum/subscribe.go index fb077f5..cd834c2 100644 --- a/electrum/subscribe.go +++ b/electrum/subscribe.go @@ -4,23 +4,31 @@ import "encoding/json" // SubscribeHeadersResp represent the response to SubscribeHeaders(). type SubscribeHeadersResp struct { + Result *SubscribeHeadersResult `json:"result"` +} + +// SubscribeHeadersNotif represent the notification to SubscribeHeaders(). +type SubscribeHeadersNotif struct { + Params []*SubscribeHeadersResult `json:"params"` +} + +// SubscribeHeadersResult rrepresents the content of the result field in the response to SubscribeHeaders(). +type SubscribeHeadersResult struct { Height int32 `json:"height"` Hex string `json:"hex"` } // SubscribeHeaders subscribes to receive block headers notifications when new blocks are found. // https://electrumx.readthedocs.io/en/latest/protocol-methods.html#blockchain-headers-subscribe -func (s *Server) SubscribeHeaders() (<-chan *SubscribeHeadersResp, error) { - resp := &struct { - Result *SubscribeHeadersResp `json:"result"` - }{} +func (s *Server) SubscribeHeaders() (<-chan *SubscribeHeadersResult, error) { + var resp SubscribeHeadersResp err := s.request("blockchain.headers.subscribe", []interface{}{}, resp) if err != nil { return nil, err } - respChan := make(chan *SubscribeHeadersResp, 1) + respChan := make(chan *SubscribeHeadersResult, 1) respChan <- resp.Result go func() { @@ -29,9 +37,7 @@ func (s *Server) SubscribeHeaders() (<-chan *SubscribeHeadersResp, error) { return } - resp := &struct { - Params []*SubscribeHeadersResp `json:"params"` - }{} + var resp SubscribeHeadersNotif err := json.Unmarshal(msg.content, resp) if err != nil { @@ -47,11 +53,17 @@ func (s *Server) SubscribeHeaders() (<-chan *SubscribeHeadersResp, error) { return respChan, nil } +// SubscribeNotif represent the notification to SubscribeScripthash() and SubscribeMasternode(). +type SubscribeNotif struct { + Params [2]string `json:"params"` +} + // SubscribeScripthash subscribes to receive notifications when new transactions are received // for that scripthash. // https://electrumx.readthedocs.io/en/latest/protocol-methods.html#blockchain-headers-subscribe func (s *Server) SubscribeScripthash(scripthash string) (<-chan string, error) { - resp := &basicResp{} + var resp basicResp + err := s.request("blockchain.scripthash.subscribe", []interface{}{scripthash}, resp) if err != nil { return nil, err @@ -68,9 +80,7 @@ func (s *Server) SubscribeScripthash(scripthash string) (<-chan string, error) { return } - resp := &struct { - Params []string `json:"params"` - }{} + var resp SubscribeNotif err := json.Unmarshal(msg.content, resp) if err != nil { @@ -89,7 +99,8 @@ func (s *Server) SubscribeScripthash(scripthash string) (<-chan string, error) { // SubscribeMasternode subscribes to receive notifications when a masternode status changes. // https://electrumx.readthedocs.io/en/latest/protocol-methods.html#blockchain-headers-subscribe func (s *Server) SubscribeMasternode(collateral string) (<-chan string, error) { - resp := &basicResp{} + var resp basicResp + err := s.request("blockchain.masternode.subscribe", []interface{}{collateral}, resp) if err != nil { return nil, err @@ -106,9 +117,7 @@ func (s *Server) SubscribeMasternode(collateral string) (<-chan string, error) { return } - resp := &struct { - Params []string `json:"params"` - }{} + var resp SubscribeNotif err := json.Unmarshal(msg.content, resp) if err != nil { diff --git a/electrum/transaction.go b/electrum/transaction.go index 03c22d0..606f292 100644 --- a/electrum/transaction.go +++ b/electrum/transaction.go @@ -13,20 +13,25 @@ func (s *Server) BroadcastTransaction(rawTx string) (string, error) { return resp.Result, nil } -// TransactionResp represents the response to GetTransaction(). -type TransactionResp struct { - Blockhash string `json:"blockhash"` - Blocktime uint64 `json:"blocktime"` - Confirmations int32 `json:"confirmations"` - Hash string `json:"hash"` - Hex string `json:"hex"` - Locktime uint32 `json:"locktime"` - Size uint32 `json:"size"` - Time uint64 `json:"time"` - Version uint32 `json:"version"` - Vin []Vin `json:"vin"` - Vout []Vout `json:"vout"` - Merkle MerkleResp `json:"merkle,omitempty"` // For protocol v1.5 and up. +// GetTransactionResp represents the response to GetTransaction(). +type GetTransactionResp struct { + Result *GetTransactionResult `json:"result"` +} + +// GetTransactionResult represents the content of the result field in the response to GetTransaction(). +type GetTransactionResult struct { + Blockhash string `json:"blockhash"` + Blocktime uint64 `json:"blocktime"` + Confirmations int32 `json:"confirmations"` + Hash string `json:"hash"` + Hex string `json:"hex"` + Locktime uint32 `json:"locktime"` + Size uint32 `json:"size"` + Time uint64 `json:"time"` + Version uint32 `json:"version"` + Vin []Vin `json:"vin"` + Vout []Vout `json:"vout"` + Merkle GetMerkleProofResult `json:"merkle,omitempty"` // For protocol v1.5 and up. } // Vin represents the input side of a transaction. @@ -62,22 +67,22 @@ type ScriptPubkey struct { // GetTransaction gets the detailed information for a transaction. // https://electrumx.readthedocs.io/en/latest/protocol-methods.html#blockchain-transaction-get -func (s *Server) GetTransaction(txHash string) (*TransactionResp, error) { - resp := &struct { - Result TransactionResp `json:"result"` - }{} +func (s *Server) GetTransaction(txHash string) (*GetTransactionResult, error) { + var resp GetTransactionResp + err := s.request("blockchain.transaction.get", []interface{}{txHash, true}, resp) if err != nil { return nil, err } - return &resp.Result, nil + return resp.Result, nil } // GetRawTransaction gets a raw encoded transaction. // https://electrumx.readthedocs.io/en/latest/protocol-methods.html#blockchain-transaction-get func (s *Server) GetRawTransaction(txHash string) (string, error) { - resp := &basicResp{} + var resp basicResp + err := s.request("blockchain.transaction.get", []interface{}{txHash, false}, resp) if err != nil { return "", err @@ -86,8 +91,13 @@ func (s *Server) GetRawTransaction(txHash string) (string, error) { return resp.Result, nil } -// MerkleResp represents the response GetMerkleProof(). -type MerkleResp struct { +// GetMerkleProofResp represents the response to GetMerkleProof(). +type GetMerkleProofResp struct { + Result *GetMerkleProofResult `json:"result"` +} + +// GetMerkleProofResult represents the content of the result field in the response to GetMerkleProof(). +type GetMerkleProofResult struct { Merkle []string `json:"merkle"` Height uint32 `json:"block_height"` Position uint32 `json:"pos"` @@ -95,22 +105,22 @@ type MerkleResp struct { // GetMerkleProof returns the merkle proof for a confirmed transaction. // https://electrumx.readthedocs.io/en/latest/protocol-methods.html#blockchain-transaction-get-merkle -func (s *Server) GetMerkleProof(txHash string, height uint32) (*MerkleResp, error) { - resp := &struct { - Result MerkleResp `json:"result"` - }{} +func (s *Server) GetMerkleProof(txHash string, height uint32) (*GetMerkleProofResult, error) { + var resp GetMerkleProofResp + err := s.request("blockchain.transaction.get_merkle", []interface{}{txHash, height}, resp) if err != nil { return nil, err } - return &resp.Result, err + return resp.Result, err } // GetHashFromPosition returns the transaction hash for a specific position in a block. // https://electrumx.readthedocs.io/en/latest/protocol-methods.html#blockchain-transaction-id-from-pos func (s *Server) GetHashFromPosition(height, position uint32) (string, error) { - resp := &basicResp{} + var resp basicResp + err := s.request("blockchain.transaction.id_from_pos", []interface{}{height, position, false}, resp) if err != nil { return "", err @@ -119,22 +129,27 @@ func (s *Server) GetHashFromPosition(height, position uint32) (string, error) { return resp.Result, err } -// MerkleFromPosResp represents the response to GetMerkleProofFromPosition(). -type MerkleFromPosResp struct { +// GetMerkleProofFromPosResp represents the response to GetMerkleProofFromPosition(). +type GetMerkleProofFromPosResp struct { + Result *GetMerkleProofFromPosResult `json:"result"` +} + +// GetMerkleProofFromPosResult represents the content of the result field in the response +// to GetMerkleProofFromPosition(). +type GetMerkleProofFromPosResult struct { Hash string `json:"tx_hash"` Merkle []string `json:"merkle"` } // GetMerkleProofFromPosition returns the merkle proof for a specific position in a block. // https://electrumx.readthedocs.io/en/latest/protocol-methods.html#blockchain-transaction-id-from-pos -func (s *Server) GetMerkleProofFromPosition(height, position uint32) (*MerkleFromPosResp, error) { - resp := struct { - Result MerkleFromPosResp `json:"result"` - }{} +func (s *Server) GetMerkleProofFromPosition(height, position uint32) (*GetMerkleProofFromPosResult, error) { + var resp GetMerkleProofFromPosResp + err := s.request("blockchain.transaction.id_from_pos", []interface{}{height, position, true}, resp) if err != nil { return nil, err } - return &resp.Result, err + return resp.Result, err } From fcdd59887bbbc2e366498a13832a0de3390398b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ian=20Desc=C3=B4teaux?= Date: Thu, 11 Apr 2019 01:49:11 -0400 Subject: [PATCH 7/8] Refactor use of bare struct in functions, part 2 --- electrum/block.go | 12 +++++++----- electrum/misc.go | 6 +++--- electrum/scripthash.go | 24 ++++++++++++++---------- electrum/server.go | 12 ++++++------ electrum/subscribe.go | 8 ++++---- electrum/transaction.go | 12 ++++++------ 6 files changed, 40 insertions(+), 34 deletions(-) diff --git a/electrum/block.go b/electrum/block.go index e05fb1c..1d74aa7 100644 --- a/electrum/block.go +++ b/electrum/block.go @@ -28,13 +28,13 @@ func (s *Server) GetBlockHeader(height uint32, checkpointHeight ...uint32) (*Get } var resp GetBlockHeaderResp - err := s.request("blockchain.block.header", []interface{}{height, checkpointHeight[0]}, resp) + err := s.request("blockchain.block.header", []interface{}{height, checkpointHeight[0]}, &resp) return resp.Result, err } var resp basicResp - err := s.request("blockchain.block.header", []interface{}{height, 0}, resp) + err := s.request("blockchain.block.header", []interface{}{height, 0}, &resp) if err != nil { return nil, err } @@ -64,7 +64,9 @@ type GetBlockHeadersResult struct { // GetBlockHeaders return a concatenated chunk of block headers. // https://electrumx.readthedocs.io/en/latest/protocol-methods.html#blockchain-block-headers -func (s *Server) GetBlockHeaders(startHeight, count uint32, checkpointHeight ...uint32) (*GetBlockHeadersResult, error) { +func (s *Server) GetBlockHeaders(startHeight, count uint32, + checkpointHeight ...uint32) (*GetBlockHeadersResult, error) { + var resp GetBlockHeadersResp var err error @@ -73,9 +75,9 @@ func (s *Server) GetBlockHeaders(startHeight, count uint32, checkpointHeight ... return nil, ErrCheckpointHeight } - err = s.request("blockchain.block.headers", []interface{}{startHeight, count, checkpointHeight[0]}, resp) + err = s.request("blockchain.block.headers", []interface{}{startHeight, count, checkpointHeight[0]}, &resp) } else { - err = s.request("blockchain.block.headers", []interface{}{startHeight, count, 0}, resp) + err = s.request("blockchain.block.headers", []interface{}{startHeight, count, 0}, &resp) } if err != nil { diff --git a/electrum/misc.go b/electrum/misc.go index ad619a3..d6f7000 100644 --- a/electrum/misc.go +++ b/electrum/misc.go @@ -15,7 +15,7 @@ type GetFeeResp struct { func (s *Server) GetFee(target uint32) (float32, error) { var resp GetFeeResp - err := s.request("blockchain.estimatefee", []interface{}{target}, resp) + err := s.request("blockchain.estimatefee", []interface{}{target}, &resp) if err != nil { return -1, err } @@ -29,7 +29,7 @@ func (s *Server) GetFee(target uint32) (float32, error) { func (s *Server) GetRelayFee() (float32, error) { var resp GetFeeResp - err := s.request("blockchain.relayfee", []interface{}{}, resp) + err := s.request("blockchain.relayfee", []interface{}{}, &resp) if err != nil { return -1, err } @@ -39,7 +39,7 @@ func (s *Server) GetRelayFee() (float32, error) { // GetFeeHistogramResp represents the response to GetFee(). type GetFeeHistogramResp struct { - Result map[uint32]uint64 `json:"result"` + Result map[uint32]uint64 `json:"result,omitempty"` } // GetFeeHistogram returns a histogram of the fee rates paid by transactions in the diff --git a/electrum/scripthash.go b/electrum/scripthash.go index fafdb06..e75fa3e 100644 --- a/electrum/scripthash.go +++ b/electrum/scripthash.go @@ -16,7 +16,7 @@ type GetBalanceResult struct { func (s *Server) GetBalance(scripthash string) (GetBalanceResult, error) { var resp GetBalanceResp - err := s.request("blockchain.scripthash.get_balance", []interface{}{scripthash}, resp) + err := s.request("blockchain.scripthash.get_balance", []interface{}{scripthash}, &resp) if err != nil { return GetBalanceResult{}, err } @@ -41,7 +41,7 @@ type GetMempoolResult struct { func (s *Server) GetHistory(scripthash string) ([]*GetMempoolResult, error) { var resp GetMempoolResp - err := s.request("blockchain.scripthash.get_history", []interface{}{scripthash}, resp) + err := s.request("blockchain.scripthash.get_history", []interface{}{scripthash}, &resp) if err != nil { return nil, err } @@ -53,7 +53,7 @@ func (s *Server) GetHistory(scripthash string) ([]*GetMempoolResult, error) { func (s *Server) GetMempool(scripthash string) ([]*GetMempoolResult, error) { var resp GetMempoolResp - err := s.request("blockchain.scripthash.get_mempool", []interface{}{scripthash}, resp) + err := s.request("blockchain.scripthash.get_mempool", []interface{}{scripthash}, &resp) if err != nil { return nil, err } @@ -61,8 +61,13 @@ func (s *Server) GetMempool(scripthash string) ([]*GetMempoolResult, error) { return resp.Result, err } -// UnspentResp represents the response to ListUnspent() -type UnspentResp struct { +// ListUnspentResp represents the response to ListUnspent() +type ListUnspentResp struct { + Result []*ListUnspentResult `json:"result"` +} + +// ListUnspentResult represents the content of the result field in the response to ListUnspent() +type ListUnspentResult struct { Height uint32 `json:"height"` Position uint32 `json:"tx_pos"` Hash string `json:"tx_hash"` @@ -70,11 +75,10 @@ type UnspentResp struct { } // ListUnspent returns an ordered list of UTXOs for a scripthash. -func (s *Server) ListUnspent(scripthash string) ([]*UnspentResp, error) { - resp := &struct { - Result []*UnspentResp `json:"result"` - }{} - err := s.request("blockchain.scripthash.listunspent", []interface{}{scripthash}, resp) +func (s *Server) ListUnspent(scripthash string) ([]*ListUnspentResult, error) { + var resp ListUnspentResp + + err := s.request("blockchain.scripthash.listunspent", []interface{}{scripthash}, &resp) if err != nil { return nil, err } diff --git a/electrum/server.go b/electrum/server.go index 1e0010d..1a48db8 100644 --- a/electrum/server.go +++ b/electrum/server.go @@ -15,7 +15,7 @@ func (s *Server) Ping() error { func (s *Server) ServerAddPeer(features *ServerFeaturesResult) error { var resp basicResp - err := s.request("server.add_peer", []interface{}{features}, resp) + err := s.request("server.add_peer", []interface{}{features}, &resp) return err } @@ -25,7 +25,7 @@ func (s *Server) ServerAddPeer(features *ServerFeaturesResult) error { func (s *Server) ServerBanner() (string, error) { var resp basicResp - err := s.request("server.banner", []interface{}{}, resp) + err := s.request("server.banner", []interface{}{}, &resp) return resp.Result, err } @@ -35,7 +35,7 @@ func (s *Server) ServerBanner() (string, error) { func (s *Server) ServerDonation() (string, error) { var resp basicResp - err := s.request("server.donation_address", []interface{}{}, resp) + err := s.request("server.donation_address", []interface{}{}, &resp) return resp.Result, err } @@ -67,7 +67,7 @@ type ServerFeaturesResult struct { func (s *Server) ServerFeatures() (*ServerFeaturesResult, error) { var resp ServerFeaturesResp - err := s.request("server.features", []interface{}{}, resp) + err := s.request("server.features", []interface{}{}, &resp) return resp.Result, err } @@ -78,7 +78,7 @@ func (s *Server) ServerPeers() (interface{}, error) { resp := &struct { Result [][]interface{} `json:"result"` }{} - err := s.request("server.peers.subscribe", []interface{}{}, resp) + err := s.request("server.peers.subscribe", []interface{}{}, &resp) return resp.Result, err } @@ -94,7 +94,7 @@ type ServerVersionResp struct { func (s *Server) ServerVersion() (serverVer, protocolVer string, err error) { var resp ServerVersionResp - err = s.request("server.version", []interface{}{ClientVersion, ProtocolVersion}, resp) + err = s.request("server.version", []interface{}{ClientVersion, ProtocolVersion}, &resp) if err != nil { serverVer = "" protocolVer = "" diff --git a/electrum/subscribe.go b/electrum/subscribe.go index cd834c2..af78255 100644 --- a/electrum/subscribe.go +++ b/electrum/subscribe.go @@ -14,7 +14,7 @@ type SubscribeHeadersNotif struct { // SubscribeHeadersResult rrepresents the content of the result field in the response to SubscribeHeaders(). type SubscribeHeadersResult struct { - Height int32 `json:"height"` + Height int32 `json:"height,omitempty"` Hex string `json:"hex"` } @@ -23,7 +23,7 @@ type SubscribeHeadersResult struct { func (s *Server) SubscribeHeaders() (<-chan *SubscribeHeadersResult, error) { var resp SubscribeHeadersResp - err := s.request("blockchain.headers.subscribe", []interface{}{}, resp) + err := s.request("blockchain.headers.subscribe", []interface{}{}, &resp) if err != nil { return nil, err } @@ -64,7 +64,7 @@ type SubscribeNotif struct { func (s *Server) SubscribeScripthash(scripthash string) (<-chan string, error) { var resp basicResp - err := s.request("blockchain.scripthash.subscribe", []interface{}{scripthash}, resp) + err := s.request("blockchain.scripthash.subscribe", []interface{}{scripthash}, &resp) if err != nil { return nil, err } @@ -101,7 +101,7 @@ func (s *Server) SubscribeScripthash(scripthash string) (<-chan string, error) { func (s *Server) SubscribeMasternode(collateral string) (<-chan string, error) { var resp basicResp - err := s.request("blockchain.masternode.subscribe", []interface{}{collateral}, resp) + err := s.request("blockchain.masternode.subscribe", []interface{}{collateral}, &resp) if err != nil { return nil, err } diff --git a/electrum/transaction.go b/electrum/transaction.go index 606f292..019f8f3 100644 --- a/electrum/transaction.go +++ b/electrum/transaction.go @@ -5,7 +5,7 @@ package electrum // https://electrumx.readthedocs.io/en/latest/protocol-methods.html#blockchain-transaction-broadcast func (s *Server) BroadcastTransaction(rawTx string) (string, error) { resp := &basicResp{} - err := s.request("blockchain.transaction.broadcast", []interface{}{rawTx}, resp) + err := s.request("blockchain.transaction.broadcast", []interface{}{rawTx}, &resp) if err != nil { return "", err } @@ -70,7 +70,7 @@ type ScriptPubkey struct { func (s *Server) GetTransaction(txHash string) (*GetTransactionResult, error) { var resp GetTransactionResp - err := s.request("blockchain.transaction.get", []interface{}{txHash, true}, resp) + err := s.request("blockchain.transaction.get", []interface{}{txHash, true}, &resp) if err != nil { return nil, err } @@ -83,7 +83,7 @@ func (s *Server) GetTransaction(txHash string) (*GetTransactionResult, error) { func (s *Server) GetRawTransaction(txHash string) (string, error) { var resp basicResp - err := s.request("blockchain.transaction.get", []interface{}{txHash, false}, resp) + err := s.request("blockchain.transaction.get", []interface{}{txHash, false}, &resp) if err != nil { return "", err } @@ -108,7 +108,7 @@ type GetMerkleProofResult struct { func (s *Server) GetMerkleProof(txHash string, height uint32) (*GetMerkleProofResult, error) { var resp GetMerkleProofResp - err := s.request("blockchain.transaction.get_merkle", []interface{}{txHash, height}, resp) + err := s.request("blockchain.transaction.get_merkle", []interface{}{txHash, height}, &resp) if err != nil { return nil, err } @@ -121,7 +121,7 @@ func (s *Server) GetMerkleProof(txHash string, height uint32) (*GetMerkleProofRe func (s *Server) GetHashFromPosition(height, position uint32) (string, error) { var resp basicResp - err := s.request("blockchain.transaction.id_from_pos", []interface{}{height, position, false}, resp) + err := s.request("blockchain.transaction.id_from_pos", []interface{}{height, position, false}, &resp) if err != nil { return "", err } @@ -146,7 +146,7 @@ type GetMerkleProofFromPosResult struct { func (s *Server) GetMerkleProofFromPosition(height, position uint32) (*GetMerkleProofFromPosResult, error) { var resp GetMerkleProofFromPosResp - err := s.request("blockchain.transaction.id_from_pos", []interface{}{height, position, true}, resp) + err := s.request("blockchain.transaction.id_from_pos", []interface{}{height, position, true}, &resp) if err != nil { return nil, err } From d55f6465f87e205c5b4a0fef440d3ba20b778a15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ian=20Desc=C3=B4teaux?= Date: Thu, 11 Apr 2019 03:35:38 -0400 Subject: [PATCH 8/8] Fix GetFeeHistogram() JSON unmarshaling to map[uint32]uint64 --- electrum/misc.go | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/electrum/misc.go b/electrum/misc.go index d6f7000..ecd5a47 100644 --- a/electrum/misc.go +++ b/electrum/misc.go @@ -38,20 +38,25 @@ func (s *Server) GetRelayFee() (float32, error) { } // GetFeeHistogramResp represents the response to GetFee(). -type GetFeeHistogramResp struct { - Result map[uint32]uint64 `json:"result,omitempty"` +type getFeeHistogramResp struct { + Result [][2]uint64 `json:"result"` } // GetFeeHistogram returns a histogram of the fee rates paid by transactions in the // memory pool, weighted by transacation size. // https://electrumx.readthedocs.io/en/latest/protocol-methods.html#mempool-get-fee-histogram func (s *Server) GetFeeHistogram() (map[uint32]uint64, error) { - var resp GetFeeHistogramResp + var resp getFeeHistogramResp err := s.request("mempool.get_fee_histogram", []interface{}{}, &resp) if err != nil { return nil, err } - return resp.Result, err + feeMap := make(map[uint32]uint64) + for i := 0; i < len(resp.Result); i++ { + feeMap[uint32(resp.Result[i][0])] = resp.Result[i][1] + } + + return feeMap, err }