code: func extractRejectCode(err error) (wire.RejectCode, bool) {
  	// Pull the underlying error out of a RuleError.
  	if rerr, ok := err.(RuleError); ok {
  		err = rerr.Err
  	}
  
  	switch err := err.(type) {
  	case blockchain.RuleError:
  		// Convert the chain error to a reject code.
  		var code wire.RejectCode
  		switch err.ErrorCode {
  		// Rejected due to duplicate.
  		case blockchain.ErrDuplicateBlock:
  			code = wire.RejectDuplicate
  
  		// Rejected due to obsolete version.
  		case blockchain.ErrBlockVersionTooOld:
  			code = wire.RejectObsolete
  
  		// Rejected due to checkpoint.
  		case blockchain.ErrCheckpointTimeTooOld:
  			fallthrough
  		case blockchain.ErrDifficultyTooLow:
  			fallthrough
  		case blockchain.ErrBadCheckpoint:
  			fallthrough
  		case blockchain.ErrForkTooOld:
  			code = wire.RejectCheckpoint
  
  		// Everything else is due to the block or transaction being invalid.
  		default:
  			code = wire.RejectInvalid
  		}
  
  		return code, true
  
  	case TxRuleError:
  		return err.RejectCode, true
  
  	case nil:
  		return wire.RejectInvalid, false
  	}
  
  	return wire.RejectInvalid, false
  }
docs: // extractRejectCode attempts to return a relevant reject code for a given error
  // by examining the error for known types.  It will return true if a code
  // was successfully extracted.