Merge pull request #1428 from wpaulino/sendrawtransaction-rpc-error

btcjson+rpc: match bitcoind's RPC error codes for rejected transactions
This commit is contained in:
Olaoluwa Osuntokun 2019-05-22 17:01:18 -07:00 committed by GitHub
commit 16327141da
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 38 additions and 10 deletions

View File

@ -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.

View File

@ -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