Fix and simplify RPC server error handling.
This change rewrites much of the error handling for the RPC server components to match a more idiomatic Go error handling style as well as fix several issues regarding error equality checks. Closes #94.
This commit is contained in:
parent
0cba485793
commit
d863c75be7
8 changed files with 446 additions and 824 deletions
23
account.go
23
account.go
|
@ -439,21 +439,19 @@ func (a *Account) Track() {
|
||||||
// Request notifications for transactions sending to all wallet
|
// Request notifications for transactions sending to all wallet
|
||||||
// addresses.
|
// addresses.
|
||||||
addrs := a.ActiveAddresses()
|
addrs := a.ActiveAddresses()
|
||||||
addrstrs := make([]string, len(addrs))
|
addrstrs := make([]string, 0, len(addrs))
|
||||||
i := 0
|
|
||||||
for addr := range addrs {
|
for addr := range addrs {
|
||||||
addrstrs[i] = addr.EncodeAddress()
|
addrstrs = append(addrstrs, addr.EncodeAddress())
|
||||||
i++
|
|
||||||
}
|
}
|
||||||
|
|
||||||
jsonErr := NotifyReceived(CurrentServerConn(), addrstrs)
|
if err := NotifyReceived(CurrentServerConn(), addrstrs); err != nil {
|
||||||
if jsonErr != nil {
|
|
||||||
log.Error("Unable to request transaction updates for address.")
|
log.Error("Unable to request transaction updates for address.")
|
||||||
}
|
}
|
||||||
|
|
||||||
unspent, err := a.TxStore.UnspentOutputs()
|
unspent, err := a.TxStore.UnspentOutputs()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("Unable to access unspent outputs: %v", err)
|
log.Errorf("Unable to access unspent outputs: %v", err)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
ReqSpentUtxoNtfns(unspent)
|
ReqSpentUtxoNtfns(unspent)
|
||||||
}
|
}
|
||||||
|
@ -621,11 +619,11 @@ func (a *Account) RecoverAddresses(n int) error {
|
||||||
|
|
||||||
// Run a goroutine to rescan blockchain for recovered addresses.
|
// Run a goroutine to rescan blockchain for recovered addresses.
|
||||||
go func(addrs []string) {
|
go func(addrs []string) {
|
||||||
jsonErr := Rescan(CurrentServerConn(), lastInfo.FirstBlock(),
|
err := Rescan(CurrentServerConn(), lastInfo.FirstBlock(),
|
||||||
addrs, nil)
|
addrs, nil)
|
||||||
if jsonErr != nil {
|
if err != nil {
|
||||||
log.Errorf("Rescanning for recovered addresses failed: %v",
|
log.Errorf("Rescanning for recovered addresses "+
|
||||||
jsonErr.Message)
|
"failed: %v", err)
|
||||||
}
|
}
|
||||||
}(addrStrs)
|
}(addrStrs)
|
||||||
|
|
||||||
|
@ -660,7 +658,10 @@ func ReqSpentUtxoNtfns(credits []*txstore.Credit) {
|
||||||
ops = append(ops, op)
|
ops = append(ops, op)
|
||||||
}
|
}
|
||||||
|
|
||||||
NotifySpent(CurrentServerConn(), ops)
|
if err := NotifySpent(CurrentServerConn(), ops); err != nil {
|
||||||
|
log.Errorf("Cannot request notifications for spent outputs: %v",
|
||||||
|
err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TotalReceived iterates through an account's transaction history, returning the
|
// TotalReceived iterates through an account's transaction history, returning the
|
||||||
|
|
|
@ -473,7 +473,7 @@ func (am *AccountManager) rescanListener() {
|
||||||
|
|
||||||
case *RescanFinishedMsg:
|
case *RescanFinishedMsg:
|
||||||
if e.Error != nil {
|
if e.Error != nil {
|
||||||
log.Errorf("Rescan failed: %v", e.Error.Message)
|
log.Errorf("Rescan failed: %v", e.Error)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
11
cmd.go
11
cmd.go
|
@ -54,11 +54,12 @@ func GetCurBlock() (wallet.BlockStamp, error) {
|
||||||
return bs, nil
|
return bs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
bb, jsonErr := GetBestBlock(CurrentServerConn())
|
bb, err := GetBestBlock(CurrentServerConn())
|
||||||
if jsonErr != nil {
|
if err != nil {
|
||||||
return wallet.BlockStamp{
|
unknown := wallet.BlockStamp{
|
||||||
Height: int32(btcutil.BlockHeightUnknown),
|
Height: int32(btcutil.BlockHeightUnknown),
|
||||||
}, jsonErr
|
}
|
||||||
|
return unknown, err
|
||||||
}
|
}
|
||||||
|
|
||||||
hash, err := btcwire.NewShaHashFromStr(bb.Hash)
|
hash, err := btcwire.NewShaHashFromStr(bb.Hash)
|
||||||
|
@ -210,7 +211,7 @@ func main() {
|
||||||
// Perform handshake.
|
// Perform handshake.
|
||||||
if err := Handshake(btcd); err != nil {
|
if err := Handshake(btcd); err != nil {
|
||||||
var message string
|
var message string
|
||||||
if jsonErr, ok := err.(*btcjson.Error); ok {
|
if jsonErr, ok := err.(btcjson.Error); ok {
|
||||||
message = jsonErr.Message
|
message = jsonErr.Message
|
||||||
} else {
|
} else {
|
||||||
message = err.Error()
|
message = err.Error()
|
||||||
|
|
11
rescan.go
11
rescan.go
|
@ -17,7 +17,6 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/conformal/btcjson"
|
|
||||||
"github.com/conformal/btcutil"
|
"github.com/conformal/btcutil"
|
||||||
"github.com/conformal/btcwire"
|
"github.com/conformal/btcwire"
|
||||||
)
|
)
|
||||||
|
@ -51,7 +50,7 @@ func (r *RescanProgressMsg) ImplementsRescanMsg() {}
|
||||||
// possibly-finished rescan, or an error if the rescan failed.
|
// possibly-finished rescan, or an error if the rescan failed.
|
||||||
type RescanFinishedMsg struct {
|
type RescanFinishedMsg struct {
|
||||||
Addresses map[*Account][]btcutil.Address
|
Addresses map[*Account][]btcutil.Address
|
||||||
Error *btcjson.Error
|
Error error
|
||||||
}
|
}
|
||||||
|
|
||||||
// ImplementsRescanMsg is implemented to satisify the RescanMsg
|
// ImplementsRescanMsg is implemented to satisify the RescanMsg
|
||||||
|
@ -143,7 +142,7 @@ func (b *rescanBatch) merge(job *RescanJob) {
|
||||||
|
|
||||||
// Status types for the handler.
|
// Status types for the handler.
|
||||||
type rescanProgress int32
|
type rescanProgress int32
|
||||||
type rescanFinished *btcjson.Error
|
type rescanFinished error
|
||||||
|
|
||||||
// jobHandler runs the RescanManager's for-select loop to manage rescan jobs
|
// jobHandler runs the RescanManager's for-select loop to manage rescan jobs
|
||||||
// and dispatch requests.
|
// and dispatch requests.
|
||||||
|
@ -191,7 +190,7 @@ func (m *RescanManager) jobHandler() {
|
||||||
if m.msgs != nil {
|
if m.msgs != nil {
|
||||||
m.msgs <- &RescanFinishedMsg{
|
m.msgs <- &RescanFinishedMsg{
|
||||||
Addresses: curBatch.addrs,
|
Addresses: curBatch.addrs,
|
||||||
Error: (*btcjson.Error)(s),
|
Error: error(s),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
curBatch.done()
|
curBatch.done()
|
||||||
|
@ -223,8 +222,8 @@ func (m *RescanManager) rpcHandler() {
|
||||||
}
|
}
|
||||||
|
|
||||||
c := CurrentServerConn()
|
c := CurrentServerConn()
|
||||||
jsonErr := Rescan(c, job.StartHeight, addrStrs, job.OutPoints)
|
err := Rescan(c, job.StartHeight, addrStrs, job.OutPoints)
|
||||||
m.status <- rescanFinished(jsonErr)
|
m.status <- rescanFinished(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
10
rpc.go
10
rpc.go
|
@ -34,13 +34,15 @@ type RawRPCResponse struct {
|
||||||
// to by the interface rather than using the rules in the encoding/json
|
// to by the interface rather than using the rules in the encoding/json
|
||||||
// package to allocate a new variable for the result. The final result
|
// package to allocate a new variable for the result. The final result
|
||||||
// and JSON-RPC error is returned.
|
// and JSON-RPC error is returned.
|
||||||
func (r *RawRPCResponse) FinishUnmarshal(v interface{}) (interface{}, *btcjson.Error) {
|
//
|
||||||
|
// If the returned error is non-nil, it will be a btcjson.Error.
|
||||||
|
func (r *RawRPCResponse) FinishUnmarshal(v interface{}) (interface{}, error) {
|
||||||
// JSON-RPC spec makes this handling easier-ish because both result and
|
// JSON-RPC spec makes this handling easier-ish because both result and
|
||||||
// error cannot be non-nil.
|
// error cannot be non-nil.
|
||||||
var jsonErr *btcjson.Error
|
|
||||||
if r.Error != nil {
|
if r.Error != nil {
|
||||||
|
var jsonErr btcjson.Error
|
||||||
if err := json.Unmarshal([]byte(*r.Error), &jsonErr); err != nil {
|
if err := json.Unmarshal([]byte(*r.Error), &jsonErr); err != nil {
|
||||||
return nil, &btcjson.Error{
|
return nil, btcjson.Error{
|
||||||
Code: btcjson.ErrParse.Code,
|
Code: btcjson.ErrParse.Code,
|
||||||
Message: err.Error(),
|
Message: err.Error(),
|
||||||
}
|
}
|
||||||
|
@ -49,7 +51,7 @@ func (r *RawRPCResponse) FinishUnmarshal(v interface{}) (interface{}, *btcjson.E
|
||||||
}
|
}
|
||||||
if r.Result != nil {
|
if r.Result != nil {
|
||||||
if err := json.Unmarshal([]byte(*r.Result), &v); err != nil {
|
if err := json.Unmarshal([]byte(*r.Result), &v); err != nil {
|
||||||
return nil, &btcjson.Error{
|
return nil, btcjson.Error{
|
||||||
Code: btcjson.ErrParse.Code,
|
Code: btcjson.ErrParse.Code,
|
||||||
Message: err.Error(),
|
Message: err.Error(),
|
||||||
}
|
}
|
||||||
|
|
94
rpcclient.go
94
rpcclient.go
|
@ -269,20 +269,19 @@ func unmarshalNotification(s string) (btcjson.Cmd, error) {
|
||||||
|
|
||||||
// GetBestBlock gets both the block height and hash of the best block
|
// GetBestBlock gets both the block height and hash of the best block
|
||||||
// in the main chain.
|
// in the main chain.
|
||||||
func GetBestBlock(rpc ServerConn) (*btcws.GetBestBlockResult, *btcjson.Error) {
|
func GetBestBlock(rpc ServerConn) (*btcws.GetBestBlockResult, error) {
|
||||||
cmd := btcws.NewGetBestBlockCmd(<-NewJSONID)
|
cmd := btcws.NewGetBestBlockCmd(<-NewJSONID)
|
||||||
response := <-rpc.SendRequest(NewServerRequest(cmd))
|
response := <-rpc.SendRequest(NewServerRequest(cmd))
|
||||||
|
|
||||||
var resultData btcws.GetBestBlockResult
|
var resultData btcws.GetBestBlockResult
|
||||||
_, jsonErr := response.FinishUnmarshal(&resultData)
|
if _, err := response.FinishUnmarshal(&resultData); err != nil {
|
||||||
if jsonErr != nil {
|
return nil, err
|
||||||
return nil, jsonErr
|
|
||||||
}
|
}
|
||||||
return &resultData, nil
|
return &resultData, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetBlock requests details about a block with the given hash.
|
// GetBlock requests details about a block with the given hash.
|
||||||
func GetBlock(rpc ServerConn, blockHash string) (*btcjson.BlockResult, *btcjson.Error) {
|
func GetBlock(rpc ServerConn, blockHash string) (*btcjson.BlockResult, error) {
|
||||||
// NewGetBlockCmd should never fail with no optargs. If this does fail,
|
// NewGetBlockCmd should never fail with no optargs. If this does fail,
|
||||||
// panic now rather than later.
|
// panic now rather than later.
|
||||||
cmd, err := btcjson.NewGetBlockCmd(<-NewJSONID, blockHash)
|
cmd, err := btcjson.NewGetBlockCmd(<-NewJSONID, blockHash)
|
||||||
|
@ -292,64 +291,62 @@ func GetBlock(rpc ServerConn, blockHash string) (*btcjson.BlockResult, *btcjson.
|
||||||
response := <-rpc.SendRequest(NewServerRequest(cmd))
|
response := <-rpc.SendRequest(NewServerRequest(cmd))
|
||||||
|
|
||||||
var resultData btcjson.BlockResult
|
var resultData btcjson.BlockResult
|
||||||
_, jsonErr := response.FinishUnmarshal(&resultData)
|
if _, err := response.FinishUnmarshal(&resultData); err != nil {
|
||||||
if jsonErr != nil {
|
return nil, err
|
||||||
return nil, jsonErr
|
|
||||||
}
|
}
|
||||||
return &resultData, nil
|
return &resultData, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetCurrentNet requests the network a bitcoin RPC server is running on.
|
// GetCurrentNet requests the network a bitcoin RPC server is running on.
|
||||||
func GetCurrentNet(rpc ServerConn) (btcwire.BitcoinNet, *btcjson.Error) {
|
func GetCurrentNet(rpc ServerConn) (btcwire.BitcoinNet, error) {
|
||||||
cmd := btcws.NewGetCurrentNetCmd(<-NewJSONID)
|
cmd := btcws.NewGetCurrentNetCmd(<-NewJSONID)
|
||||||
response := <-rpc.SendRequest(NewServerRequest(cmd))
|
response := <-rpc.SendRequest(NewServerRequest(cmd))
|
||||||
|
|
||||||
var resultData uint32
|
var resultData uint32
|
||||||
_, jsonErr := response.FinishUnmarshal(&resultData)
|
if _, err := response.FinishUnmarshal(&resultData); err != nil {
|
||||||
if jsonErr != nil {
|
return 0, err
|
||||||
return 0, jsonErr
|
|
||||||
}
|
}
|
||||||
return btcwire.BitcoinNet(resultData), nil
|
return btcwire.BitcoinNet(resultData), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// NotifyBlocks requests blockconnected and blockdisconnected notifications.
|
// NotifyBlocks requests blockconnected and blockdisconnected notifications.
|
||||||
func NotifyBlocks(rpc ServerConn) *btcjson.Error {
|
func NotifyBlocks(rpc ServerConn) error {
|
||||||
cmd := btcws.NewNotifyBlocksCmd(<-NewJSONID)
|
cmd := btcws.NewNotifyBlocksCmd(<-NewJSONID)
|
||||||
response := <-rpc.SendRequest(NewServerRequest(cmd))
|
response := <-rpc.SendRequest(NewServerRequest(cmd))
|
||||||
_, jsonErr := response.FinishUnmarshal(nil)
|
_, err := response.FinishUnmarshal(nil)
|
||||||
return jsonErr
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// NotifyReceived requests notifications for new transactions that spend
|
// NotifyReceived requests notifications for new transactions that spend
|
||||||
// to any of the addresses in addrs.
|
// to any of the addresses in addrs.
|
||||||
func NotifyReceived(rpc ServerConn, addrs []string) *btcjson.Error {
|
func NotifyReceived(rpc ServerConn, addrs []string) error {
|
||||||
cmd := btcws.NewNotifyReceivedCmd(<-NewJSONID, addrs)
|
cmd := btcws.NewNotifyReceivedCmd(<-NewJSONID, addrs)
|
||||||
response := <-rpc.SendRequest(NewServerRequest(cmd))
|
response := <-rpc.SendRequest(NewServerRequest(cmd))
|
||||||
_, jsonErr := response.FinishUnmarshal(nil)
|
_, err := response.FinishUnmarshal(nil)
|
||||||
return jsonErr
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// NotifySpent requests notifications for when a transaction is processed which
|
// NotifySpent requests notifications for when a transaction is processed which
|
||||||
// spends op.
|
// spends op.
|
||||||
func NotifySpent(rpc ServerConn, outpoints []*btcwire.OutPoint) *btcjson.Error {
|
func NotifySpent(rpc ServerConn, outpoints []*btcwire.OutPoint) error {
|
||||||
ops := make([]btcws.OutPoint, 0, len(outpoints))
|
ops := make([]btcws.OutPoint, 0, len(outpoints))
|
||||||
for _, op := range outpoints {
|
for _, op := range outpoints {
|
||||||
ops = append(ops, *btcws.NewOutPointFromWire(op))
|
ops = append(ops, *btcws.NewOutPointFromWire(op))
|
||||||
}
|
}
|
||||||
cmd := btcws.NewNotifySpentCmd(<-NewJSONID, ops)
|
cmd := btcws.NewNotifySpentCmd(<-NewJSONID, ops)
|
||||||
response := <-rpc.SendRequest(NewServerRequest(cmd))
|
response := <-rpc.SendRequest(NewServerRequest(cmd))
|
||||||
_, jsonErr := response.FinishUnmarshal(nil)
|
_, err := response.FinishUnmarshal(nil)
|
||||||
return jsonErr
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rescan requests a blockchain rescan for transactions to any number of
|
// Rescan requests a blockchain rescan for transactions to any number of
|
||||||
// addresses and notifications to inform wallet about such transactions.
|
// addresses and notifications to inform wallet about such transactions.
|
||||||
func Rescan(rpc ServerConn, beginBlock int32, addrs []string,
|
func Rescan(rpc ServerConn, beginBlock int32, addrs []string,
|
||||||
outpoints []*btcwire.OutPoint) *btcjson.Error {
|
outpoints []*btcwire.OutPoint) error {
|
||||||
|
|
||||||
ops := make([]btcws.OutPoint, len(outpoints))
|
ops := make([]btcws.OutPoint, 0, len(outpoints))
|
||||||
for i := range outpoints {
|
for _, op := range outpoints {
|
||||||
ops[i] = *btcws.NewOutPointFromWire(outpoints[i])
|
ops = append(ops, *btcws.NewOutPointFromWire(op))
|
||||||
}
|
}
|
||||||
// NewRescanCmd should never fail with no optargs. If this does fail,
|
// NewRescanCmd should never fail with no optargs. If this does fail,
|
||||||
// panic now rather than later.
|
// panic now rather than later.
|
||||||
|
@ -358,12 +355,12 @@ func Rescan(rpc ServerConn, beginBlock int32, addrs []string,
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
response := <-rpc.SendRequest(NewServerRequest(cmd))
|
response := <-rpc.SendRequest(NewServerRequest(cmd))
|
||||||
_, jsonErr := response.FinishUnmarshal(nil)
|
_, err = response.FinishUnmarshal(nil)
|
||||||
return jsonErr
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// SendRawTransaction sends a hex-encoded transaction for relay.
|
// SendRawTransaction sends a hex-encoded transaction for relay.
|
||||||
func SendRawTransaction(rpc ServerConn, hextx string) (txid string, error *btcjson.Error) {
|
func SendRawTransaction(rpc ServerConn, hextx string) (txid string, err error) {
|
||||||
// NewSendRawTransactionCmd should never fail. In the exceptional case
|
// NewSendRawTransactionCmd should never fail. In the exceptional case
|
||||||
// where it does, panic here rather than later.
|
// where it does, panic here rather than later.
|
||||||
cmd, err := btcjson.NewSendRawTransactionCmd(<-NewJSONID, hextx)
|
cmd, err := btcjson.NewSendRawTransactionCmd(<-NewJSONID, hextx)
|
||||||
|
@ -373,11 +370,8 @@ func SendRawTransaction(rpc ServerConn, hextx string) (txid string, error *btcjs
|
||||||
response := <-rpc.SendRequest(NewServerRequest(cmd))
|
response := <-rpc.SendRequest(NewServerRequest(cmd))
|
||||||
|
|
||||||
var resultData string
|
var resultData string
|
||||||
_, jsonErr := response.FinishUnmarshal(&resultData)
|
_, err = response.FinishUnmarshal(&resultData)
|
||||||
if jsonErr != nil {
|
return resultData, err
|
||||||
return "", jsonErr
|
|
||||||
}
|
|
||||||
return resultData, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetRawTransaction returns a future representing a pending GetRawTransaction
|
// GetRawTransaction returns a future representing a pending GetRawTransaction
|
||||||
|
@ -396,22 +390,21 @@ func GetRawTransactionAsync(rpc ServerConn, txsha *btcwire.ShaHash) chan RawRPCR
|
||||||
// GetRawTransactionAsyncResult waits for the pending command in request -
|
// GetRawTransactionAsyncResult waits for the pending command in request -
|
||||||
// the reqsult of a previous GetRawTransactionAsync() call - and returns either
|
// the reqsult of a previous GetRawTransactionAsync() call - and returns either
|
||||||
// the requested transaction, or an error.
|
// the requested transaction, or an error.
|
||||||
func GetRawTransactionAsyncResult(request chan RawRPCResponse) (*btcutil.Tx,
|
func GetRawTransactionAsyncResult(request chan RawRPCResponse) (*btcutil.Tx, error) {
|
||||||
*btcjson.Error) {
|
|
||||||
response := <-request
|
response := <-request
|
||||||
|
|
||||||
var resultData string
|
var resultData string
|
||||||
_, jsonErr := response.FinishUnmarshal(&resultData)
|
_, err := response.FinishUnmarshal(&resultData)
|
||||||
if jsonErr != nil {
|
if err != nil {
|
||||||
return nil, jsonErr
|
return nil, err
|
||||||
}
|
}
|
||||||
serializedTx, err := hex.DecodeString(resultData)
|
serializedTx, err := hex.DecodeString(resultData)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, &btcjson.ErrDecodeHexString
|
return nil, btcjson.ErrDecodeHexString
|
||||||
}
|
}
|
||||||
utx, err := btcutil.NewTxFromBytes(serializedTx)
|
utx, err := btcutil.NewTxFromBytes(serializedTx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, &btcjson.ErrDeserialization
|
return nil, btcjson.ErrDeserialization
|
||||||
}
|
}
|
||||||
return utx, nil
|
return utx, nil
|
||||||
}
|
}
|
||||||
|
@ -419,26 +412,7 @@ func GetRawTransactionAsyncResult(request chan RawRPCResponse) (*btcutil.Tx,
|
||||||
// GetRawTransaction sends the non-verbose version of a getrawtransaction
|
// GetRawTransaction sends the non-verbose version of a getrawtransaction
|
||||||
// request to receive the serialized transaction referenced by txsha. If
|
// request to receive the serialized transaction referenced by txsha. If
|
||||||
// successful, the transaction is decoded and returned as a btcutil.Tx.
|
// successful, the transaction is decoded and returned as a btcutil.Tx.
|
||||||
func GetRawTransaction(rpc ServerConn, txsha *btcwire.ShaHash) (*btcutil.Tx, *btcjson.Error) {
|
func GetRawTransaction(rpc ServerConn, txsha *btcwire.ShaHash) (*btcutil.Tx, error) {
|
||||||
resp := GetRawTransactionAsync(rpc, txsha)
|
resp := GetRawTransactionAsync(rpc, txsha)
|
||||||
return GetRawTransactionAsyncResult(resp)
|
return GetRawTransactionAsyncResult(resp)
|
||||||
}
|
}
|
||||||
|
|
||||||
// VerboseGetRawTransaction sends the verbose version of a getrawtransaction
|
|
||||||
// request to receive details about a transaction.
|
|
||||||
func VerboseGetRawTransaction(rpc ServerConn, txsha *btcwire.ShaHash) (*btcjson.TxRawResult, *btcjson.Error) {
|
|
||||||
// NewGetRawTransactionCmd should never fail with a single optarg. If
|
|
||||||
// it does, panic now rather than later.
|
|
||||||
cmd, err := btcjson.NewGetRawTransactionCmd(<-NewJSONID, txsha.String(), 1)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
response := <-rpc.SendRequest(NewServerRequest(cmd))
|
|
||||||
|
|
||||||
var resultData btcjson.TxRawResult
|
|
||||||
_, jsonErr := response.FinishUnmarshal(&resultData)
|
|
||||||
if jsonErr != nil {
|
|
||||||
return nil, jsonErr
|
|
||||||
}
|
|
||||||
return &resultData, nil
|
|
||||||
}
|
|
||||||
|
|
1090
rpcserver.go
1090
rpcserver.go
File diff suppressed because it is too large
Load diff
29
sockets.go
29
sockets.go
|
@ -212,23 +212,13 @@ func genCertPair(certFile, keyFile string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ParseRequest parses a command or notification out of a JSON-RPC request,
|
|
||||||
// returning any errors as a JSON-RPC error.
|
|
||||||
func ParseRequest(msg []byte) (btcjson.Cmd, *btcjson.Error) {
|
|
||||||
cmd, err := btcjson.ParseMarshaledCmd(msg)
|
|
||||||
if err != nil || cmd.Id() == nil {
|
|
||||||
return cmd, &btcjson.ErrInvalidRequest
|
|
||||||
}
|
|
||||||
return cmd, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReplyToFrontend responds to a marshaled JSON-RPC request with a
|
// ReplyToFrontend responds to a marshaled JSON-RPC request with a
|
||||||
// marshaled JSON-RPC response for both standard and extension
|
// marshaled JSON-RPC response for both standard and extension
|
||||||
// (websocket) clients. The returned error is ErrBadAuth if a
|
// (websocket) clients. The returned error is ErrBadAuth if a
|
||||||
// missing, incorrect, or duplicate authentication request is
|
// missing, incorrect, or duplicate authentication request is
|
||||||
// received.
|
// received.
|
||||||
func (s *server) ReplyToFrontend(msg []byte, ws, authenticated bool) ([]byte, error) {
|
func (s *server) ReplyToFrontend(msg []byte, ws, authenticated bool) ([]byte, error) {
|
||||||
cmd, jsonErr := ParseRequest(msg)
|
cmd, parseErr := btcjson.ParseMarshaledCmd(msg)
|
||||||
var id interface{}
|
var id interface{}
|
||||||
if cmd != nil {
|
if cmd != nil {
|
||||||
id = cmd.Id()
|
id = cmd.Id()
|
||||||
|
@ -259,10 +249,10 @@ func (s *server) ReplyToFrontend(msg []byte, ws, authenticated bool) ([]byte, er
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if jsonErr != nil {
|
if parseErr != nil {
|
||||||
response := btcjson.Reply{
|
response := btcjson.Reply{
|
||||||
Id: &id,
|
Id: &id,
|
||||||
Error: jsonErr,
|
Error: &btcjson.ErrInvalidRequest,
|
||||||
}
|
}
|
||||||
mresponse, err := json.Marshal(response)
|
mresponse, err := json.Marshal(response)
|
||||||
// We expect the marshal to succeed. If it doesn't, it
|
// We expect the marshal to succeed. If it doesn't, it
|
||||||
|
@ -725,16 +715,18 @@ func BtcdConnect(certificates []byte) (*BtcdRPCConn, error) {
|
||||||
// single TrackSince function (or similar) which requests address
|
// single TrackSince function (or similar) which requests address
|
||||||
// notifications and performs the rescan since some block height.
|
// notifications and performs the rescan since some block height.
|
||||||
func Handshake(rpc ServerConn) error {
|
func Handshake(rpc ServerConn) error {
|
||||||
net, jsonErr := GetCurrentNet(rpc)
|
net, err := GetCurrentNet(rpc)
|
||||||
if jsonErr != nil {
|
if err != nil {
|
||||||
return jsonErr
|
return err
|
||||||
}
|
}
|
||||||
if net != activeNet.Net {
|
if net != activeNet.Net {
|
||||||
return errors.New("btcd and btcwallet running on different Bitcoin networks")
|
return errors.New("btcd and btcwallet running on different Bitcoin networks")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Request notifications for connected and disconnected blocks.
|
// Request notifications for connected and disconnected blocks.
|
||||||
NotifyBlocks(rpc)
|
if err := NotifyBlocks(rpc); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// Get current best block. If this is before than the oldest
|
// Get current best block. If this is before than the oldest
|
||||||
// saved block hash, assume that this btcd instance is not yet
|
// saved block hash, assume that this btcd instance is not yet
|
||||||
|
@ -767,8 +759,7 @@ func Handshake(rpc ServerConn) error {
|
||||||
log.Debugf("Checking for previous saved block with height %v hash %v",
|
log.Debugf("Checking for previous saved block with height %v hash %v",
|
||||||
bs.Height, bs.Hash)
|
bs.Height, bs.Hash)
|
||||||
|
|
||||||
_, jsonErr := GetBlock(rpc, bs.Hash.String())
|
if _, err := GetBlock(rpc, bs.Hash.String()); err != nil {
|
||||||
if jsonErr != nil {
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue