btcjson+rpc: match bitcoind's RPC error codes for rejected transactions
This commit is contained in:
parent
96897255fd
commit
d055892599
2 changed files with 38 additions and 10 deletions
|
@ -76,6 +76,9 @@ const (
|
|||
ErrRPCInvalidTxVout RPCErrorCode = -5
|
||||
ErrRPCRawTxString RPCErrorCode = -32602
|
||||
ErrRPCDecodeHexString RPCErrorCode = -22
|
||||
ErrRPCTxError RPCErrorCode = -25
|
||||
ErrRPCTxRejected RPCErrorCode = -26
|
||||
ErrRPCTxAlreadyInChain RPCErrorCode = -27
|
||||
)
|
||||
|
||||
// Errors that are specific to btcd.
|
||||
|
|
45
rpcserver.go
45
rpcserver.go
|
@ -3323,19 +3323,44 @@ func handleSendRawTransaction(s *rpcServer, cmd interface{}, closeChan <-chan st
|
|||
if err != nil {
|
||||
// When the error is a rule error, it means the transaction was
|
||||
// simply rejected as opposed to something actually going wrong,
|
||||
// so log it as such. Otherwise, something really did go wrong,
|
||||
// so log it as an actual error. In both cases, a JSON-RPC
|
||||
// error is returned to the client with the deserialization
|
||||
// error code (to match bitcoind behavior).
|
||||
if _, ok := err.(mempool.RuleError); ok {
|
||||
rpcsLog.Debugf("Rejected transaction %v: %v", tx.Hash(),
|
||||
err)
|
||||
} else {
|
||||
// so log it as such. Otherwise, something really did go wrong,
|
||||
// so log it as an actual error and return.
|
||||
ruleErr, ok := err.(mempool.RuleError)
|
||||
if !ok {
|
||||
rpcsLog.Errorf("Failed to process transaction %v: %v",
|
||||
tx.Hash(), err)
|
||||
|
||||
return nil, &btcjson.RPCError{
|
||||
Code: btcjson.ErrRPCTxError,
|
||||
Message: "TX rejected: " + err.Error(),
|
||||
}
|
||||
}
|
||||
|
||||
rpcsLog.Debugf("Rejected transaction %v: %v", tx.Hash(), err)
|
||||
|
||||
// We'll then map the rule error to the appropriate RPC error,
|
||||
// matching bitcoind's behavior.
|
||||
code := btcjson.ErrRPCTxError
|
||||
if txRuleErr, ok := ruleErr.Err.(mempool.TxRuleError); ok {
|
||||
errDesc := txRuleErr.Description
|
||||
switch {
|
||||
case strings.Contains(
|
||||
strings.ToLower(errDesc), "orphan transaction",
|
||||
):
|
||||
code = btcjson.ErrRPCTxError
|
||||
|
||||
case strings.Contains(
|
||||
strings.ToLower(errDesc), "transaction already exists",
|
||||
):
|
||||
code = btcjson.ErrRPCTxAlreadyInChain
|
||||
|
||||
default:
|
||||
code = btcjson.ErrRPCTxRejected
|
||||
}
|
||||
}
|
||||
|
||||
return nil, &btcjson.RPCError{
|
||||
Code: btcjson.ErrRPCDeserialization,
|
||||
Code: code,
|
||||
Message: "TX rejected: " + err.Error(),
|
||||
}
|
||||
}
|
||||
|
@ -4281,7 +4306,7 @@ func newRPCServer(config *rpcserverConfig) (*rpcServer, error) {
|
|||
gbtWorkState: newGbtWorkState(config.TimeSource),
|
||||
helpCacher: newHelpCacher(),
|
||||
requestProcessShutdown: make(chan struct{}),
|
||||
quit: make(chan int),
|
||||
quit: make(chan int),
|
||||
}
|
||||
if cfg.RPCUser != "" && cfg.RPCPass != "" {
|
||||
login := cfg.RPCUser + ":" + cfg.RPCPass
|
||||
|
|
Loading…
Reference in a new issue