diff --git a/node/.env.local b/node/.env.local index a2c286cd8..5d924debd 100644 --- a/node/.env.local +++ b/node/.env.local @@ -12,7 +12,7 @@ SIGNER_PK= # this address is dummy contract in baobab -SUBMISSION_PROXY_CONTRACT=0xba5208a3b387796773Ecb38524C41eEa3b3541F9 +SUBMISSION_PROXY_CONTRACT=0x284E7E442d64108Bd593Ec4b41538dCE5aEdA858 PRIVATE_NETWORK_SECRET=anything diff --git a/node/pkg/admin/utils/utils.go b/node/pkg/admin/utils/utils.go index f24334b19..122863a3b 100644 --- a/node/pkg/admin/utils/utils.go +++ b/node/pkg/admin/utils/utils.go @@ -10,6 +10,7 @@ import ( "bisonai.com/orakl/node/pkg/bus" "bisonai.com/orakl/node/pkg/db" + errorSentinel "bisonai.com/orakl/node/pkg/error" "github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2/middleware/cors" @@ -30,12 +31,12 @@ func Setup(setupInfo SetupInfo) (*fiber.App, error) { ctx := context.Background() _, err := db.GetPool(ctx) if err != nil { - return nil, errors.New("error getting db pool") + return nil, errorSentinel.ErrAdminDbPoolNotFound } _, err = db.GetRedisConn(ctx) if err != nil { - return nil, errors.New("error getting redis conn") + return nil, errorSentinel.ErrAdminRedisConnNotFound } app := fiber.New(fiber.Config{ @@ -116,7 +117,7 @@ func SendMessage(c *fiber.Ctx, to string, command string, args map[string]interf messageBus, ok := c.Locals("bus").(*bus.MessageBus) if !ok { - return msg, errors.New("bus is not found, failed to message fetcher") + return msg, errorSentinel.ErrAdminMessageBusNotFound } msg = bus.Message{ diff --git a/node/pkg/aggregator/aggregator.go b/node/pkg/aggregator/aggregator.go index f36b3f6d3..1bed76284 100644 --- a/node/pkg/aggregator/aggregator.go +++ b/node/pkg/aggregator/aggregator.go @@ -3,12 +3,12 @@ package aggregator import ( "context" "encoding/json" - "fmt" "sync" "time" "bisonai.com/orakl/node/pkg/chain/helper" + errorSentinel "bisonai.com/orakl/node/pkg/error" "bisonai.com/orakl/node/pkg/raft" "bisonai.com/orakl/node/pkg/utils/calculator" pubsub "github.com/libp2p/go-libp2p-pubsub" @@ -18,7 +18,7 @@ import ( func NewAggregator(h host.Host, ps *pubsub.PubSub, topicString string, config Config) (*Aggregator, error) { if h == nil || ps == nil || topicString == "" { - return nil, fmt.Errorf("invalid parameters") + return nil, errorSentinel.ErrAggregatorInvalidInitValue } topic, err := ps.Join(topicString) @@ -84,7 +84,7 @@ func (n *Aggregator) HandleCustomMessage(ctx context.Context, message raft.Messa case ProofMsg: return n.HandleProofMessage(ctx, message) default: - return fmt.Errorf("unknown message type received in HandleCustomMessage: %v", message.Type) + return errorSentinel.ErrAggregatorUnhandledCustomMessage } } @@ -98,12 +98,12 @@ func (n *Aggregator) HandleRoundSyncMessage(ctx context.Context, msg raft.Messag if msg.SentFrom != n.Raft.GetLeader() { log.Warn().Str("Player", "Aggregator").Msg("round sync message sent from non-leader") - return fmt.Errorf("round sync message sent from non-leader") + return errorSentinel.ErrAggregatorNonLeaderRaftMessage } if roundSyncMessage.LeaderID == "" || roundSyncMessage.RoundID == 0 { log.Error().Str("Player", "Aggregator").Msg("invalid round sync message") - return fmt.Errorf("invalid round sync message: %v", roundSyncMessage) + return errorSentinel.ErrAggregatorInvalidRaftMessage } if n.Raft.GetRole() != raft.Leader { @@ -148,7 +148,7 @@ func (n *Aggregator) HandleSyncReplyMessage(ctx context.Context, msg raft.Messag if syncReplyMessage.RoundID == 0 { log.Error().Str("Player", "Aggregator").Msg("invalid sync reply message") - return fmt.Errorf("invalid sync reply message: %v", syncReplyMessage) + return errorSentinel.ErrAggregatorInvalidRaftMessage } n.AggregatorMutex.Lock() @@ -189,12 +189,12 @@ func (n *Aggregator) HandleTriggerMessage(ctx context.Context, msg raft.Message) if triggerMessage.RoundID == 0 { log.Error().Str("Player", "Aggregator").Msg("invalid trigger message") - return fmt.Errorf("invalid trigger message: %v", triggerMessage) + return errorSentinel.ErrAggregatorInvalidRaftMessage } if msg.SentFrom != n.Raft.GetLeader() { log.Warn().Str("Player", "Aggregator").Msg("trigger message sent from non-leader") - return fmt.Errorf("trigger message sent from non-leader") + return errorSentinel.ErrAggregatorNonLeaderRaftMessage } defer delete(n.PreparedLocalAggregates, triggerMessage.RoundID) return n.PublishPriceDataMessage(triggerMessage.RoundID, n.PreparedLocalAggregates[triggerMessage.RoundID]) @@ -210,7 +210,7 @@ func (n *Aggregator) HandlePriceDataMessage(ctx context.Context, msg raft.Messag if priceDataMessage.RoundID == 0 { log.Error().Str("Player", "Aggregator").Msg("invalid price data message") - return fmt.Errorf("invalid price data message: %v", priceDataMessage) + return errorSentinel.ErrAggregatorInvalidRaftMessage } n.AggregatorMutex.Lock() @@ -258,7 +258,7 @@ func (n *Aggregator) HandleProofMessage(ctx context.Context, msg raft.Message) e if proofMessage.RoundID == 0 { log.Error().Str("Player", "Aggregator").Msg("invalid proof message") - return fmt.Errorf("invalid proof message: %v", proofMessage) + return errorSentinel.ErrAggregatorInvalidRaftMessage } n.AggregatorMutex.Lock() diff --git a/node/pkg/aggregator/app.go b/node/pkg/aggregator/app.go index 2764a8e20..76d5d0542 100644 --- a/node/pkg/aggregator/app.go +++ b/node/pkg/aggregator/app.go @@ -2,7 +2,6 @@ package aggregator import ( "context" - "errors" "math/rand" "strconv" "time" @@ -10,6 +9,7 @@ import ( "bisonai.com/orakl/node/pkg/bus" "bisonai.com/orakl/node/pkg/db" + errorSentinel "bisonai.com/orakl/node/pkg/error" pubsub "github.com/libp2p/go-libp2p-pubsub" "github.com/libp2p/go-libp2p/core/host" "github.com/rs/zerolog/log" @@ -91,7 +91,7 @@ func (a *App) getConfigs(ctx context.Context) ([]Config, error) { func (a *App) startAggregator(ctx context.Context, aggregator *Aggregator) error { if aggregator == nil { - return errors.New("aggregator not found") + return errorSentinel.ErrAggregatorNotFound } log.Debug().Str("Player", "Aggregator").Str("name", aggregator.Name).Msg("starting aggregator") @@ -113,7 +113,7 @@ func (a *App) startAggregator(ctx context.Context, aggregator *Aggregator) error func (a *App) startAggregatorById(ctx context.Context, id int32) error { aggregator, ok := a.Aggregators[id] if !ok { - return errors.New("aggregator not found") + return errorSentinel.ErrAggregatorNotFound } return a.startAggregator(ctx, aggregator) } @@ -139,7 +139,7 @@ func (a *App) stopAggregator(aggregator *Aggregator) error { return nil } if aggregator.nodeCancel == nil { - return errors.New("aggregator cancel function not found") + return errorSentinel.ErrAggregatorCancelNotFound } aggregator.nodeCancel() aggregator.isRunning = false @@ -150,7 +150,7 @@ func (a *App) stopAggregator(aggregator *Aggregator) error { func (a *App) stopAggregatorById(id int32) error { aggregator, ok := a.Aggregators[id] if !ok { - return errors.New("aggregator not found") + return errorSentinel.ErrAggregatorNotFound } return a.stopAggregator(aggregator) } @@ -195,7 +195,7 @@ func (a *App) getAggregatorByName(name string) (*Aggregator, error) { return aggregator, nil } } - return nil, errors.New("aggregator not found") + return nil, errorSentinel.ErrAggregatorNotFound } func (a *App) handleMessage(ctx context.Context, msg bus.Message) { @@ -210,7 +210,7 @@ func (a *App) handleMessage(ctx context.Context, msg bus.Message) { } if msg.From != bus.ADMIN { - bus.HandleMessageError(errors.New("non-admin"), msg, "aggregator received message from non-admin") + bus.HandleMessageError(errorSentinel.ErrBusNonAdmin, msg, "aggregator received message from non-admin") return } @@ -281,7 +281,7 @@ func (a *App) handleMessage(ctx context.Context, msg bus.Message) { } msg.Response <- bus.MessageResponse{Success: true} default: - bus.HandleMessageError(errors.New("unknown-command"), msg, "aggregator received unknown command") + bus.HandleMessageError(errorSentinel.ErrBusUnknownCommand, msg, "aggregator received unknown command") return } } diff --git a/node/pkg/aggregator/utils.go b/node/pkg/aggregator/utils.go index b8cb88964..89b59e213 100644 --- a/node/pkg/aggregator/utils.go +++ b/node/pkg/aggregator/utils.go @@ -3,12 +3,11 @@ package aggregator import ( "bytes" "context" - "fmt" "strconv" - "strings" "time" "bisonai.com/orakl/node/pkg/db" + errorSentinel "bisonai.com/orakl/node/pkg/error" "github.com/rs/zerolog/log" ) @@ -48,7 +47,7 @@ func InsertGlobalAggregate(ctx context.Context, configId int32, value int64, rou } if len(errs) > 0 { - return fmt.Errorf(strings.Join(errs, "; ")) + return errorSentinel.ErrAggregatorGlobalAggregateInsertion } return nil @@ -80,7 +79,7 @@ func InsertProof(ctx context.Context, configId int32, round int32, proofs [][]by } if len(errs) > 0 { - return fmt.Errorf(strings.Join(errs, "; ")) + return errorSentinel.ErrAggregatorProofInsertion } return nil diff --git a/node/pkg/boot/boot.go b/node/pkg/boot/boot.go index dc3139c39..d2f82ed48 100644 --- a/node/pkg/boot/boot.go +++ b/node/pkg/boot/boot.go @@ -2,6 +2,7 @@ package boot import ( "context" + "errors" "fmt" "os" "time" @@ -9,6 +10,7 @@ import ( "bisonai.com/orakl/node/pkg/boot/peer" "bisonai.com/orakl/node/pkg/boot/utils" "bisonai.com/orakl/node/pkg/db" + errorSentinel "bisonai.com/orakl/node/pkg/error" libp2p_setup "bisonai.com/orakl/node/pkg/libp2p/setup" libp2p_utils "bisonai.com/orakl/node/pkg/libp2p/utils" "github.com/gofiber/fiber/v2" @@ -93,7 +95,7 @@ func RefreshJob(ctx context.Context) error { isAlive, liveCheckErr := libp2p_utils.IsHostAlive(ctx, h, connectionUrl) if liveCheckErr != nil { log.Error().Err(liveCheckErr).Msg("Failed to check peer") - if liveCheckErr.Error() != "failed to connect to peer" { + if !errors.Is(liveCheckErr, errorSentinel.ErrLibP2pFailToConnectPeer) { continue } } diff --git a/node/pkg/boot/utils/utils.go b/node/pkg/boot/utils/utils.go index 2dd46feb9..d4741a4cf 100644 --- a/node/pkg/boot/utils/utils.go +++ b/node/pkg/boot/utils/utils.go @@ -9,6 +9,7 @@ import ( "strings" "bisonai.com/orakl/node/pkg/db" + errorSentinel "bisonai.com/orakl/node/pkg/error" "github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2/middleware/cors" "github.com/gofiber/fiber/v2/middleware/recover" @@ -19,7 +20,7 @@ func Setup(ctx context.Context) (*fiber.App, error) { _, err := db.GetPool(ctx) if err != nil { log.Error().Err(err).Msg("error getting db pool") - return nil, errors.New("error getting db pool") + return nil, errorSentinel.ErrBootAPIDbPoolNotFound } app := fiber.New(fiber.Config{ diff --git a/node/pkg/bus/bus.go b/node/pkg/bus/bus.go index 31d120830..2ec2909e8 100644 --- a/node/pkg/bus/bus.go +++ b/node/pkg/bus/bus.go @@ -1,9 +1,9 @@ package bus import ( - "errors" "strconv" + errorSentinel "bisonai.com/orakl/node/pkg/error" "github.com/rs/zerolog/log" ) @@ -47,30 +47,30 @@ func (mb *MessageBus) Subscribe(id string) <-chan Message { func (mb *MessageBus) Publish(msg Message) error { ch, ok := mb.channels[msg.To] if !ok { - return errors.New("channel not found") + return errorSentinel.ErrBusChannelNotFound } select { case ch <- msg: return nil default: - return errors.New("failed to send message to channel") + return errorSentinel.ErrBusMsgPublishFail } } func ParseInt64MsgParam(msg Message, param string) (int64, error) { rawId, ok := msg.Content.Args[param] if !ok { - return 0, errors.New("param not found in message") + return 0, errorSentinel.ErrBusParamNotFound } idPayload, ok := rawId.(string) if !ok { - return 0, errors.New("failed to convert adapter id to string") + return 0, errorSentinel.ErrBusConvertParamFail } id, err := strconv.ParseInt(idPayload, 10, 64) if err != nil { - return 0, errors.New("failed to parse adapterId") + return 0, errorSentinel.ErrBusParseParamFail } return id, nil @@ -79,17 +79,17 @@ func ParseInt64MsgParam(msg Message, param string) (int64, error) { func ParseInt32MsgParam(msg Message, param string) (int32, error) { rawId, ok := msg.Content.Args[param] if !ok { - return 0, errors.New("param not found in message") + return 0, errorSentinel.ErrBusParamNotFound } idPayload, ok := rawId.(string) if !ok { - return 0, errors.New("failed to convert adapter id to string") + return 0, errorSentinel.ErrBusConvertParamFail } id, err := strconv.ParseInt(idPayload, 10, 32) if err != nil { - return 0, errors.New("failed to parse adapterId") + return 0, errorSentinel.ErrBusParseParamFail } return int32(id), nil @@ -98,12 +98,12 @@ func ParseInt32MsgParam(msg Message, param string) (int32, error) { func ParseStringMsgParam(msg Message, param string) (string, error) { raw, ok := msg.Content.Args[param] if !ok { - return "", errors.New("param not found in message") + return "", errorSentinel.ErrBusParamNotFound } payload, ok := raw.(string) if !ok { - return "", errors.New("failed to convert param to string") + return "", errorSentinel.ErrBusConvertParamFail } return payload, nil diff --git a/node/pkg/chain/helper/helper.go b/node/pkg/chain/helper/helper.go index 1405ae50a..0c7712e8c 100644 --- a/node/pkg/chain/helper/helper.go +++ b/node/pkg/chain/helper/helper.go @@ -3,13 +3,13 @@ package helper import ( "context" "crypto/ecdsa" - "errors" "math/big" "os" "strings" "time" "bisonai.com/orakl/node/pkg/chain/utils" + errorSentinel "bisonai.com/orakl/node/pkg/error" "bisonai.com/orakl/node/pkg/utils/request" "github.com/klaytn/klaytn/blockchain/types" "github.com/klaytn/klaytn/common" @@ -24,7 +24,7 @@ func setProviderAndReporter(config *ChainHelperConfig, blockchainType Blockchain config.ProviderUrl = os.Getenv(KlaytnProviderUrl) if config.ProviderUrl == "" { log.Error().Msg("provider url not set") - return errors.New("provider url not set") + return errorSentinel.ErrChainProviderUrlNotFound } } @@ -39,7 +39,7 @@ func setProviderAndReporter(config *ChainHelperConfig, blockchainType Blockchain config.ProviderUrl = os.Getenv(EthProviderUrl) if config.ProviderUrl == "" { log.Error().Msg("provider url not set") - return errors.New("provider url not set") + return errorSentinel.ErrChainProviderUrlNotFound } } @@ -50,7 +50,7 @@ func setProviderAndReporter(config *ChainHelperConfig, blockchainType Blockchain } } default: - return errors.New("unsupported blockchain type") + return errorSentinel.ErrChainReporterUnsupportedChain } return nil @@ -133,7 +133,7 @@ func (t *ChainHelper) Close() { func (t *ChainHelper) GetSignedFromDelegator(tx *types.Transaction) (*types.Transaction, error) { if t.delegatorUrl == "" { - return nil, errors.New("delegator url not set") + return nil, errorSentinel.ErrChainDelegatorUrlNotFound } payload, err := utils.MakePayload(tx) @@ -148,7 +148,7 @@ func (t *ChainHelper) GetSignedFromDelegator(tx *types.Transaction) (*types.Tran } if result.SignedRawTx == nil { - return nil, errors.New("no signed raw tx") + return nil, errorSentinel.ErrChainEmptySignedRawTx } return utils.HashToTx(*result.SignedRawTx) } @@ -249,7 +249,7 @@ func (t *ChainHelper) PublicAddress() (common.Address, error) { publicKey := privateKey.Public() publicKeyECDSA, ok := publicKey.(*ecdsa.PublicKey) if !ok { - return result, errors.New("error casting public key to ECDSA") + return result, errorSentinel.ErrChainPubKeyToECDSAFail } result = crypto.PubkeyToAddress(*publicKeyECDSA) return result, nil @@ -283,7 +283,7 @@ func NewSignHelper(pk string) (*SignHelper, error) { pk = os.Getenv(SignerPk) if pk == "" { log.Error().Msg("signer pk not set") - return nil, errors.New("signer pk not set") + return nil, errorSentinel.ErrChainSignerPKNotFound } } diff --git a/node/pkg/chain/tests/chain_test.go b/node/pkg/chain/tests/chain_test.go index 3aabe611e..818a37eb8 100644 --- a/node/pkg/chain/tests/chain_test.go +++ b/node/pkg/chain/tests/chain_test.go @@ -2,8 +2,6 @@ package tests import ( "context" - "errors" - "fmt" "math/big" "os" "strings" @@ -13,15 +11,14 @@ import ( "bisonai.com/orakl/node/pkg/chain/helper" "bisonai.com/orakl/node/pkg/chain/utils" "bisonai.com/orakl/node/pkg/db" + errorSentinel "bisonai.com/orakl/node/pkg/error" "github.com/klaytn/klaytn/blockchain/types" "github.com/klaytn/klaytn/crypto" "github.com/stretchr/testify/assert" ) var ( - ErrEmptyContractAddress = errors.New("contract address is empty") - ErrEmptyFunctionString = errors.New("function string is empty") - InsertProviderUrlQuery = "INSERT INTO provider_urls (chain_id, url, priority) VALUES (@chain_id, @url, @priority)" + InsertProviderUrlQuery = "INSERT INTO provider_urls (chain_id, url, priority) VALUES (@chain_id, @url, @priority)" ) func TestNewKlaytnHelper(t *testing.T) { @@ -135,13 +132,13 @@ func TestMakeDirectTx(t *testing.T) { name: "Test case 2", contractAddress: "", functionString: "increment()", - expectedError: ErrEmptyContractAddress, + expectedError: errorSentinel.ErrChainEmptyAddressParam, }, { name: "Test case 3", contractAddress: "0x93120927379723583c7a0dd2236fcb255e96949f", functionString: "", - expectedError: ErrEmptyFunctionString, + expectedError: errorSentinel.ErrChainEmptyFuncStringParam, }, } @@ -183,22 +180,20 @@ func TestMakeFeeDelegatedTx(t *testing.T) { name: "Test case 2", contractAddress: "", functionString: "increment()", - expectedError: ErrEmptyContractAddress, + expectedError: errorSentinel.ErrChainEmptyAddressParam, }, { name: "Test case 3", contractAddress: "0x93120927379723583c7a0dd2236fcb255e96949f", functionString: "", - expectedError: ErrEmptyFunctionString, + expectedError: errorSentinel.ErrChainEmptyFuncStringParam, }, } for _, test := range tests { feeDelegatedTx, err := klaytnHelper.MakeFeeDelegatedTx(ctx, test.contractAddress, test.functionString) if err != nil { - if err.Error() != test.expectedError.Error() { - t.Errorf("Test case %s: Expected error '%v', but got '%v'", test.name, test.expectedError, err) - } + assert.ErrorIs(t, err, test.expectedError) } if err == nil { assert.Equal(t, strings.ToLower(feeDelegatedTx.To().Hex()), test.contractAddress) @@ -409,14 +404,14 @@ func TestParseMethodSignature(t *testing.T) { expectedName: "", expectedInput: "", expectedOutput: "", - expectedError: fmt.Errorf("empty name"), + expectedError: errorSentinel.ErrChainEmptyNameParam, }, } for _, test := range tests { funcName, inputArgs, outputArgs, err := utils.ParseMethodSignature(test.input) - if err != nil && err.Error() != test.expectedError.Error() { - t.Errorf("Test case %s: Expected error '%v', but got '%v'", test.name, test.expectedError, err) + if err != nil { + assert.ErrorIs(t, err, test.expectedError) } if funcName != test.expectedName { t.Errorf("Test case %s: Expected function name '%s', but got '%s'", test.name, test.expectedName, funcName) diff --git a/node/pkg/chain/utils/utils.go b/node/pkg/chain/utils/utils.go index 48ca595eb..0a28235a1 100644 --- a/node/pkg/chain/utils/utils.go +++ b/node/pkg/chain/utils/utils.go @@ -5,7 +5,6 @@ import ( "context" "crypto/ecdsa" "encoding/hex" - "errors" "fmt" "math/big" "os" @@ -14,6 +13,7 @@ import ( "time" "bisonai.com/orakl/node/pkg/db" + errorSentinel "bisonai.com/orakl/node/pkg/error" "bisonai.com/orakl/node/pkg/utils/encryptor" "github.com/klaytn/klaytn" @@ -101,7 +101,7 @@ func GenerateViewABI(functionName string, inputs string, outputs string) (*abi.A func generateABI(functionName string, inputs string, outputs string, stateMutability string, payable bool) (*abi.ABI, error) { if functionName == "" { - return nil, errors.New("function name is empty") + return nil, errorSentinel.ErrChainEmptyFuncStringParam } inputArgs := MakeAbiFuncAttribute(inputs) @@ -155,23 +155,23 @@ func GetChainID(ctx context.Context, client ClientInterface) (*big.Int, error) { func MakeDirectTx(ctx context.Context, client ClientInterface, contractAddressHex string, reporter string, functionString string, chainID *big.Int, args ...interface{}) (*types.Transaction, error) { if client == nil { - return nil, errors.New("client is nil") + return nil, errorSentinel.ErrChainEmptyClientParam } if contractAddressHex == "" { - return nil, errors.New("contract address is empty") + return nil, errorSentinel.ErrChainEmptyAddressParam } if reporter == "" { - return nil, errors.New("reporter is empty") + return nil, errorSentinel.ErrChainEmptyReporterParam } if functionString == "" { - return nil, errors.New("function string is empty") + return nil, errorSentinel.ErrChainEmptyFuncStringParam } if chainID == nil { - return nil, errors.New("chain id is nil") + return nil, errorSentinel.ErrChainEmptyChainIdParam } functionName, inputs, outputs, err := ParseMethodSignature(functionString) @@ -199,7 +199,7 @@ func MakeDirectTx(ctx context.Context, client ClientInterface, contractAddressHe publicKey := privateKey.Public() publicKeyECDSA, ok := publicKey.(*ecdsa.PublicKey) if !ok { - return nil, errors.New("error casting public key to ECDSA") + return nil, errorSentinel.ErrChainPubKeyToECDSAFail } fromAddress := crypto.PubkeyToAddress(*publicKeyECDSA) @@ -234,23 +234,23 @@ func MakeDirectTx(ctx context.Context, client ClientInterface, contractAddressHe func MakeFeeDelegatedTx(ctx context.Context, client ClientInterface, contractAddressHex string, reporter string, functionString string, chainID *big.Int, args ...interface{}) (*types.Transaction, error) { if client == nil { - return nil, errors.New("client is nil") + return nil, errorSentinel.ErrChainEmptyClientParam } if contractAddressHex == "" { - return nil, errors.New("contract address is empty") + return nil, errorSentinel.ErrChainEmptyAddressParam } if reporter == "" { - return nil, errors.New("reporter is empty") + return nil, errorSentinel.ErrChainEmptyReporterParam } if functionString == "" { - return nil, errors.New("function string is empty") + return nil, errorSentinel.ErrChainEmptyFuncStringParam } if chainID == nil { - return nil, errors.New("chain id is nil") + return nil, errorSentinel.ErrChainEmptyChainIdParam } functionName, inputs, outputs, err := ParseMethodSignature(functionString) @@ -279,7 +279,7 @@ func MakeFeeDelegatedTx(ctx context.Context, client ClientInterface, contractAdd publicKey := privateKey.Public() publicKeyECDSA, ok := publicKey.(*ecdsa.PublicKey) if !ok { - return nil, errors.New("error casting public key to ECDSA") + return nil, errorSentinel.ErrChainPubKeyToECDSAFail } fromAddress := crypto.PubkeyToAddress(*publicKeyECDSA) @@ -336,7 +336,7 @@ func SignTxByFeePayer(ctx context.Context, client ClientInterface, tx *types.Tra feePayerPublicKey := feePayerPrivateKey.Public() publicKeyECDSA, ok := feePayerPublicKey.(*ecdsa.PublicKey) if !ok { - return nil, errors.New("error casting public key to ECDSA") + return nil, errorSentinel.ErrChainPubKeyToECDSAFail } updatedTx, err := UpdateFeePayer(tx, crypto.PubkeyToAddress(*publicKeyECDSA)) @@ -369,7 +369,7 @@ func SubmitRawTx(ctx context.Context, client ClientInterface, tx *types.Transact if receipt.Status != 1 { log.Error().Str("tx", receipt.TxHash.String()).Msg("tx failed") - return fmt.Errorf("transaction failed (hash: %s), status: %d", receipt.TxHash.String(), receipt.Status) + return errorSentinel.ErrChainTransactionFail } log.Debug().Str("Player", "ChainHelper").Any("hash", receipt.TxHash).Msg("tx success") @@ -400,7 +400,7 @@ func UpdateFeePayer(tx *types.Transaction, feePayer common.Address) (*types.Tran to := tx.To() if to == nil { - return nil, errors.New("to address is nil") + return nil, errorSentinel.ErrChainEmptyToAddress } remap := map[types.TxValueKeyType]interface{}{ @@ -422,15 +422,15 @@ func UpdateFeePayer(tx *types.Transaction, feePayer common.Address) (*types.Tran func ReadContract(ctx context.Context, client ClientInterface, functionString string, contractAddress string, args ...interface{}) (interface{}, error) { if client == nil { - return nil, errors.New("client is nil") + return nil, errorSentinel.ErrChainEmptyClientParam } if contractAddress == "" { - return nil, errors.New("contract address is empty") + return nil, errorSentinel.ErrChainEmptyAddressParam } if functionString == "" { - return nil, errors.New("function string is empty") + return nil, errorSentinel.ErrChainEmptyFuncStringParam } functionName, inputs, outputs, err := ParseMethodSignature(functionString) @@ -474,7 +474,7 @@ var ( func ParseMethodSignature(name string) (string, string, string, error) { if name == "" { - return "", "", "", fmt.Errorf("empty name") + return "", "", "", errorSentinel.ErrChainEmptyNameParam } name = strings.Replace(name, "\n", " ", -1) @@ -488,7 +488,7 @@ func ParseMethodSignature(name string) (string, string, string, error) { if strings.Contains(name, "returns") { matches := funcRegexpWithReturn.FindAllStringSubmatch(name, -1) if len(matches) == 0 { - return "", "", "", fmt.Errorf("no matches found") + return "", "", "", errorSentinel.ErrChainFailedToFindMethodSignatureMatch } funcName = strings.TrimSpace(matches[0][1]) inputArgs = strings.TrimSpace(matches[0][2]) @@ -496,7 +496,7 @@ func ParseMethodSignature(name string) (string, string, string, error) { } else { matches := funcRegexpWithoutReturn.FindAllStringSubmatch(name, -1) if len(matches) == 0 { - return "", "", "", fmt.Errorf("no matches found") + return "", "", "", errorSentinel.ErrChainFailedToFindMethodSignatureMatch } funcName = strings.TrimSpace(matches[0][1]) inputArgs = strings.TrimSpace(matches[0][2]) @@ -593,7 +593,7 @@ func StringToPk(pk string) (*ecdsa.PrivateKey, error) { func RecoverSigner(hash []byte, signature []byte) (address common.Address, err error) { if len(signature) != 65 { - return common.Address{}, fmt.Errorf("signature must be 65 bytes long") + return common.Address{}, errorSentinel.ErrChainInvalidSignatureLength } // use copy to avoid modifying the original signature diff --git a/node/pkg/db/pgsql.go b/node/pkg/db/pgsql.go index 09f253d09..de7a104d8 100644 --- a/node/pkg/db/pgsql.go +++ b/node/pkg/db/pgsql.go @@ -8,6 +8,7 @@ import ( "strings" "sync" + errorSentinel "bisonai.com/orakl/node/pkg/error" "github.com/jackc/pgx/v5" "github.com/jackc/pgx/v5/pgxpool" "github.com/rs/zerolog/log" @@ -31,7 +32,7 @@ func getPool(ctx context.Context, once *sync.Once) (*pgxpool.Pool, error) { connectionString := loadPgsqlConnectionString() if connectionString == "" { log.Error().Msg("DATABASE_URL is not set") - poolErr = errors.New("DATABASE_URL is not set") + poolErr = errorSentinel.ErrDbDatabaseUrlNotFound return } pool, poolErr = connectToPgsql(ctx, connectionString) @@ -137,19 +138,19 @@ func BulkSelect[T any](ctx context.Context, tableName string, columnNames []stri results := []T{} if tableName == "" { log.Error().Msg("tableName must not be empty") - return results, errors.New("tableName must not be empty") + return results, errorSentinel.ErrDbEmptyTableNameParam } if len(columnNames) == 0 { log.Error().Msg("columnNames must not be empty") - return results, errors.New("columnNames must not be empty") + return results, errorSentinel.ErrDbEmptyColumnNamesParam } if len(whereColumns) == 0 { log.Error().Msg("whereColumns must not be empty") - return results, errors.New("whereColumns must not be empty") + return results, errorSentinel.ErrDbEmptyWhereColumnsParam } if len(whereColumns) != len(whereValues) { log.Error().Strs("whereColumns", whereColumns).Any("whereValues", whereValues).Msg("whereColumns and whereValues must have the same length") - return results, errors.New("whereColumns and whereValues must have the same length") + return results, errorSentinel.ErrDbWhereColumnValueLengthMismatch } currentPool, err := GetPool(ctx) diff --git a/node/pkg/db/redis.go b/node/pkg/db/redis.go index 3c76298ee..ac68c2f40 100644 --- a/node/pkg/db/redis.go +++ b/node/pkg/db/redis.go @@ -3,11 +3,11 @@ package db import ( "context" "encoding/json" - "errors" "os" "sync" "time" + errorSentinel "bisonai.com/orakl/node/pkg/error" "github.com/redis/go-redis/v9" "github.com/rs/zerolog/log" ) @@ -170,13 +170,13 @@ func loadRedisConnectionString() (RedisConnectionInfo, error) { host := os.Getenv("REDIS_HOST") if host == "" { log.Error().Msg("REDIS_HOST not set") - return RedisConnectionInfo{}, errors.New("REDIS_HOST not set") + return RedisConnectionInfo{}, errorSentinel.ErrRdbHostNotFound } port := os.Getenv("REDIS_PORT") if port == "" { log.Error().Msg("REDIS_PORT not set") - return RedisConnectionInfo{}, errors.New("REDIS_PORT not set") + return RedisConnectionInfo{}, errorSentinel.ErrRdbPortNotFound } return RedisConnectionInfo{Host: host, Port: port}, nil diff --git a/node/pkg/error/sentinel.go b/node/pkg/error/sentinel.go new file mode 100644 index 000000000..d1e70bacc --- /dev/null +++ b/node/pkg/error/sentinel.go @@ -0,0 +1,194 @@ +package error + +import ( + "fmt" +) + +type Service int + +const ( + Fetcher Service = iota + Aggregator + Reporter + BootAPI + Admin + Por + Others +) + +type ErrorCode int + +const ( + NetworkError ErrorCode = iota + DatabaseError + InternalError + InvalidInputError + UnknownCaseError + InvalidRaftMessageError + InvalidBusMessageError + MultipleError +) + +var ServiceNames = map[Service]string{ + Fetcher: "Fetcher", + Aggregator: "Aggregator", + Reporter: "Reporter", + BootAPI: "BootAPI", + Admin: "Admin", + Por: "POR", + Others: "Others", +} + +var ErrorCodes = map[ErrorCode]string{ + NetworkError: "NetworkError", + DatabaseError: "DatabaseError", + InternalError: "InternalError", + InvalidInputError: "InvalidInputError", + UnknownCaseError: "UnknownCaseError", + InvalidRaftMessageError: "InvalidRaftMessageError", + InvalidBusMessageError: "InvalidBusMessageError", + MultipleError: "MultipleError", +} + +func (s Service) String() string { + name, ok := ServiceNames[s] + if !ok { + return "UnknownService" + } + return name +} + +func (e ErrorCode) String() string { + code, ok := ErrorCodes[e] + if !ok { + return "UnknownErrorCode" + } + return code +} + +type CustomError struct { + Service Service + Code ErrorCode + Message string +} + +func (e *CustomError) Error() string { + return fmt.Sprintf("Service: %s, Code: %s, Message: %s", e.Service, e.Code, e.Message) +} + +var ( + ErrAdminDbPoolNotFound = &CustomError{Service: Admin, Code: InternalError, Message: "db pool not found"} + ErrAdminRedisConnNotFound = &CustomError{Service: Admin, Code: InternalError, Message: "redisconn not found"} + ErrAdminMessageBusNotFound = &CustomError{Service: Admin, Code: InternalError, Message: "messagebus not found"} + + ErrAggregatorInvalidInitValue = &CustomError{Service: Aggregator, Code: InvalidInputError, Message: "Invalid init value parameters"} + ErrAggregatorUnhandledCustomMessage = &CustomError{Service: Aggregator, Code: UnknownCaseError, Message: "Unhandled custom message"} + ErrAggregatorInvalidRaftMessage = &CustomError{Service: Aggregator, Code: InvalidRaftMessageError, Message: "Invalid raft message"} + ErrAggregatorNonLeaderRaftMessage = &CustomError{Service: Aggregator, Code: InvalidRaftMessageError, Message: "Invalid raft message: message sent from non-leader"} + ErrAggregatorGlobalAggregateInsertion = &CustomError{Service: Aggregator, Code: DatabaseError, Message: "Failed to insert global aggregator"} + ErrAggregatorProofInsertion = &CustomError{Service: Aggregator, Code: DatabaseError, Message: "Failed to insert proof"} + ErrAggregatorNotFound = &CustomError{Service: Aggregator, Code: InternalError, Message: "Aggregator not found"} + ErrAggregatorCancelNotFound = &CustomError{Service: Aggregator, Code: InternalError, Message: "Aggregator cancel function not found"} + + ErrBootAPIDbPoolNotFound = &CustomError{Service: BootAPI, Code: InternalError, Message: "db pool not found"} + + ErrBusChannelNotFound = &CustomError{Service: Others, Code: InternalError, Message: "Channel not found"} + ErrBusMsgPublishFail = &CustomError{Service: Others, Code: InternalError, Message: "Failed to send message to channel"} + ErrBusParamNotFound = &CustomError{Service: Others, Code: InternalError, Message: "Param not found in message"} + ErrBusConvertParamFail = &CustomError{Service: Others, Code: InternalError, Message: "Failed to convert message param"} + ErrBusParseParamFail = &CustomError{Service: Others, Code: InternalError, Message: "Failed to parse message param"} + ErrBusNonAdmin = &CustomError{Service: Others, Code: InvalidBusMessageError, Message: "Non-admin bus message"} + ErrBusUnknownCommand = &CustomError{Service: Others, Code: InvalidBusMessageError, Message: "Unknown command"} + + ErrChainTransactionFail = &CustomError{Service: Others, Code: InternalError, Message: "transaction failed"} + ErrChainEmptyNameParam = &CustomError{Service: Others, Code: InvalidInputError, Message: "empty name param"} + ErrChainFailedToFindMethodSignatureMatch = &CustomError{Service: Others, Code: InternalError, Message: "failed to find method signature match"} + ErrChainInvalidSignatureLength = &CustomError{Service: Others, Code: InvalidInputError, Message: "invalid signature length"} + ErrChainProviderUrlNotFound = &CustomError{Service: Others, Code: InternalError, Message: "provider url not found"} + ErrChainReporterUnsupportedChain = &CustomError{Service: Others, Code: InvalidInputError, Message: "unsupported chain type"} + ErrChainDelegatorUrlNotFound = &CustomError{Service: Others, Code: InvalidInputError, Message: "delegator url not found"} + ErrChainEmptySignedRawTx = &CustomError{Service: Others, Code: InvalidInputError, Message: "empty signed raw tx"} + ErrChainPubKeyToECDSAFail = &CustomError{Service: Others, Code: InternalError, Message: "failed to convert public key to ECDSA"} + ErrChainSignerPKNotFound = &CustomError{Service: Others, Code: InvalidInputError, Message: "signer public key not found"} + ErrChainEmptyClientParam = &CustomError{Service: Others, Code: InvalidInputError, Message: "empty client param"} + ErrChainEmptyAddressParam = &CustomError{Service: Others, Code: InvalidInputError, Message: "empty address param"} + ErrChainEmptyReporterParam = &CustomError{Service: Others, Code: InvalidInputError, Message: "empty reporter param"} + ErrChainEmptyFuncStringParam = &CustomError{Service: Others, Code: InvalidInputError, Message: "empty function string param"} + ErrChainEmptyChainIdParam = &CustomError{Service: Others, Code: InvalidInputError, Message: "empty chain id param"} + ErrChainEmptyToAddress = &CustomError{Service: Others, Code: InvalidInputError, Message: "to address is empty"} + + ErrDbDatabaseUrlNotFound = &CustomError{Service: Others, Code: InternalError, Message: "DATABASE_URL not found"} + ErrDbEmptyTableNameParam = &CustomError{Service: Others, Code: InvalidInputError, Message: "empty table name"} + ErrDbEmptyColumnNamesParam = &CustomError{Service: Others, Code: InvalidInputError, Message: "empty column names"} + ErrDbEmptyWhereColumnsParam = &CustomError{Service: Others, Code: InvalidInputError, Message: "empty where columns"} + ErrDbWhereColumnValueLengthMismatch = &CustomError{Service: Others, Code: InvalidInputError, Message: "where column and value length mismatch"} + ErrRdbHostNotFound = &CustomError{Service: Others, Code: InternalError, Message: "REDIS_HOST not found"} + ErrRdbPortNotFound = &CustomError{Service: Others, Code: InternalError, Message: "REDIS_PORT not found"} + + ErrFetcherNotFound = &CustomError{Service: Fetcher, Code: InternalError, Message: "Fetcher not found"} + ErrFetcherCancelNotFound = &CustomError{Service: Fetcher, Code: InternalError, Message: "Fetcher cancel function not found"} + ErrFetcherInvalidType = &CustomError{Service: Fetcher, Code: InvalidInputError, Message: "Invalid fetcher type"} + ErrFetcherNoDataFetched = &CustomError{Service: Fetcher, Code: InternalError, Message: "No data fetched"} + ErrFetcherInvalidDexFetcherDefinition = &CustomError{Service: Fetcher, Code: InvalidInputError, Message: "Invalid dex fetcher definition"} + ErrFetcherChainHelperNotFound = &CustomError{Service: Fetcher, Code: InternalError, Message: "Chain helper not found"} + ErrFetcherInvalidRawResult = &CustomError{Service: Fetcher, Code: InternalError, Message: "Invalid raw result"} + ErrFetcherConvertToBigInt = &CustomError{Service: Fetcher, Code: InternalError, Message: "Failed to convert to big.Int"} + ErrFetcherInvalidInput = &CustomError{Service: Fetcher, Code: InvalidInputError, Message: "Invalid input"} + ErrFetcherDivisionByZero = &CustomError{Service: Fetcher, Code: InternalError, Message: "Division by zero"} + + ErrLibP2pEmptyNonLocalAddress = &CustomError{Service: Others, Code: InternalError, Message: "Host has no non-local addresses"} + ErrLibP2pAddressSplitFail = &CustomError{Service: Others, Code: InternalError, Message: "Failed to split address"} + ErrLibP2pFailToConnectPeer = &CustomError{Service: Others, Code: InternalError, Message: "Failed to connect to peer"} + + ErrPorProviderUrlNotFound = &CustomError{Service: Por, Code: InternalError, Message: "POR_PROVIDER_URL not found"} + ErrPorReporterPkNotFound = &CustomError{Service: Por, Code: InvalidInputError, Message: "POR_REPORTER_PK not found"} + ErrPorRawResultCastFail = &CustomError{Service: Por, Code: InternalError, Message: "Failed to cast raw result to slice"} + ErrPorRoundIdCastFail = &CustomError{Service: Por, Code: InternalError, Message: "Failed to cast round id to int32"} + ErrPorUpdatedAtCastFail = &CustomError{Service: Por, Code: InternalError, Message: "Failed to cast updated at to big.Int"} + ErrPorAnswerCastFail = &CustomError{Service: Por, Code: InternalError, Message: "Failed to cast answer to big.Int"} + ErrPorJobFail = &CustomError{Service: Por, Code: InternalError, Message: "job failed"} + + ErrRaftLeaderIdMismatch = &CustomError{Service: Others, Code: InternalError, Message: "Leader id mismatch"} + + ErrReporterSubmissionProxyContractNotFound = &CustomError{Service: Reporter, Code: InternalError, Message: "SUBMISSION_PROXY_CONTRACT not found"} + ErrReporterNoReportersSet = &CustomError{Service: Reporter, Code: InternalError, Message: "No reporters set"} + ErrReporterNotFound = &CustomError{Service: Reporter, Code: InternalError, Message: "Reporter not found"} + ErrReporterAlreadyRunning = &CustomError{Service: Reporter, Code: InternalError, Message: "Reporter already running"} + ErrReporterCancelNotFound = &CustomError{Service: Reporter, Code: InternalError, Message: "Reporter cancel function not found"} + ErrReporterEmptyConfigs = &CustomError{Service: Reporter, Code: InternalError, Message: "Empty configs"} + ErrReporterJobFailed = &CustomError{Service: Reporter, Code: InternalError, Message: "Job failed"} + ErrReporterReportFailed = &CustomError{Service: Reporter, Code: InternalError, Message: "Report failed"} + ErrReporterProofNotFound = &CustomError{Service: Reporter, Code: InternalError, Message: "Proof not found"} + ErrReporterUnknownMessageType = &CustomError{Service: Reporter, Code: InvalidRaftMessageError, Message: "Unknown message type"} + ErrReporterKlaytnHelperNotFound = &CustomError{Service: Reporter, Code: InternalError, Message: "Klaytn helper not found"} + ErrReporterDeviationReportFail = &CustomError{Service: Reporter, Code: InternalError, Message: "Deviation report failed"} + ErrReporterEmptyValidAggregates = &CustomError{Service: Reporter, Code: InternalError, Message: "Empty valid aggregates"} + ErrReporterEmptyAggregatesParam = &CustomError{Service: Reporter, Code: InvalidInputError, Message: "Empty aggregates param"} + ErrReporterEmptySubmissionPairsParam = &CustomError{Service: Reporter, Code: InvalidInputError, Message: "Empty submission pairs param"} + ErrReporterEmptyProofParam = &CustomError{Service: Reporter, Code: InvalidInputError, Message: "Empty proof param"} + ErrReporterInvalidAggregateFound = &CustomError{Service: Reporter, Code: InternalError, Message: "Invalid aggregate found"} + ErrReporterMissingProof = &CustomError{Service: Reporter, Code: InternalError, Message: "Missing proof"} + ErrReporterResultCastToInterfaceFail = &CustomError{Service: Reporter, Code: InternalError, Message: "Failed to cast result to interface"} + ErrReporterResultCastToAddressFail = &CustomError{Service: Reporter, Code: InternalError, Message: "Failed to cast result to address"} + ErrReporterSignerNotWhitelisted = &CustomError{Service: Reporter, Code: InternalError, Message: "Signer not whitelisted"} + ErrReporterEmptyValidProofs = &CustomError{Service: Reporter, Code: InternalError, Message: "Empty valid proofs"} + ErrReporterInvalidProofLength = &CustomError{Service: Reporter, Code: InvalidInputError, Message: "Invalid proof length"} + ErrReporterBusMessageByNonAdmin = &CustomError{Service: Reporter, Code: InvalidBusMessageError, Message: "Bus message sent by non-admin"} + ErrReporterClear = &CustomError{Service: Reporter, Code: InternalError, Message: "Failed to clear reporters"} + ErrReporterStart = &CustomError{Service: Reporter, Code: InternalError, Message: "Failed to start reporters"} + ErrReporterStop = &CustomError{Service: Reporter, Code: InternalError, Message: "Failed to stop reporters"} + + ErrReducerCastToFloatFail = &CustomError{Service: Others, Code: InternalError, Message: "Failed to cast to float"} + ErrReducerIndexCastToInterfaceFail = &CustomError{Service: Others, Code: InternalError, Message: "Failed to cast to interface from INDEX"} + ErrReducerParseCastToInterfaceFail = &CustomError{Service: Others, Code: InternalError, Message: "Failed to cast to interface from PARSE"} + ErrReducerParseCastToStringFail = &CustomError{Service: Others, Code: InternalError, Message: "Failed to cast to string from PARSE"} + ErrReducerParseCastToMapFail = &CustomError{Service: Others, Code: InternalError, Message: "Failed to cast to map from PARSE"} + ErrReducerMulCastToFloatFail = &CustomError{Service: Others, Code: InternalError, Message: "Failed to cast to float from MUL"} + ErrReducerDivCastToFloatFail = &CustomError{Service: Others, Code: InternalError, Message: "Failed to cast to float from DIV"} + ErrReducerDivDivsionByZero = &CustomError{Service: Others, Code: InternalError, Message: "Division by zero from DIV"} + ErrReducerDivFromCastToFloatFail = &CustomError{Service: Others, Code: InternalError, Message: "Failed to cast to float from DIVFROM"} + ErrReducerUnknownReducerFunc = &CustomError{Service: Others, Code: InternalError, Message: "Unknown reducer function"} + ErrRequestStatusNotOk = &CustomError{Service: Others, Code: InternalError, Message: "Request status not OK"} + ErrCalculatorEmptyArr = &CustomError{Service: Others, Code: InternalError, Message: "Empty array"} + ErrRetrierJobFail = &CustomError{Service: Others, Code: InternalError, Message: "Job failed"} +) diff --git a/node/pkg/fetcher/app.go b/node/pkg/fetcher/app.go index bc5b1ae23..243760b4e 100644 --- a/node/pkg/fetcher/app.go +++ b/node/pkg/fetcher/app.go @@ -2,17 +2,16 @@ package fetcher import ( "context" - "errors" "fmt" "math/rand" "os" - "strconv" "time" "bisonai.com/orakl/node/pkg/bus" chain_helper "bisonai.com/orakl/node/pkg/chain/helper" "bisonai.com/orakl/node/pkg/db" + errorSentinel "bisonai.com/orakl/node/pkg/error" "github.com/rs/zerolog/log" ) @@ -168,7 +167,7 @@ func (a *App) startFetcherById(ctx context.Context, configId int32) error { return a.startFetcher(ctx, fetcher) } log.Error().Str("Player", "Fetcher").Int32("adapterId", configId).Msg("fetcher not found") - return errors.New("fetcher not found by id:" + strconv.Itoa(int(configId))) + return errorSentinel.ErrFetcherNotFound } func (a *App) startAllFetchers(ctx context.Context) error { @@ -191,7 +190,7 @@ func (a *App) stopFetcher(ctx context.Context, fetcher *Fetcher) error { return nil } if fetcher.cancel == nil { - return errors.New("fetcher cancel function not found") + return errorSentinel.ErrFetcherCancelNotFound } fetcher.cancel() fetcher.isRunning = false @@ -202,7 +201,7 @@ func (a *App) stopFetcherById(ctx context.Context, configId int32) error { if fetcher, ok := a.Fetchers[configId]; ok { return a.stopFetcher(ctx, fetcher) } - return errors.New("fetcher not found by id:" + strconv.Itoa(int(configId))) + return errorSentinel.ErrFetcherNotFound } func (a *App) stopAllFetchers(ctx context.Context) error { diff --git a/node/pkg/fetcher/fetcher.go b/node/pkg/fetcher/fetcher.go index 11795ebf4..64882712a 100644 --- a/node/pkg/fetcher/fetcher.go +++ b/node/pkg/fetcher/fetcher.go @@ -3,12 +3,12 @@ package fetcher import ( "context" "encoding/json" - "errors" "fmt" "math/big" "math/rand" "time" + errorSentinel "bisonai.com/orakl/node/pkg/error" "bisonai.com/orakl/node/pkg/utils/calculator" "bisonai.com/orakl/node/pkg/utils/reducer" "bisonai.com/orakl/node/pkg/utils/request" @@ -128,7 +128,7 @@ func (f *Fetcher) fetch(chainHelpers map[string]ChainHelper, proxies []Proxy) ([ return } default: - errChan <- errors.New("unknown fetcher type") + errChan <- errorSentinel.ErrFetcherInvalidType } dataChan <- FeedData{FeedID: feed.ID, Value: resultValue} @@ -146,7 +146,7 @@ func (f *Fetcher) fetch(chainHelpers map[string]ChainHelper, proxies []Proxy) ([ } if len(data) < 1 { - return nil, errors.New("no data fetched") + return nil, errorSentinel.ErrFetcherNoDataFetched } errString := "" @@ -155,7 +155,7 @@ func (f *Fetcher) fetch(chainHelpers map[string]ChainHelper, proxies []Proxy) ([ errString += err.Error() + "\n" } - log.Warn().Str("Player", "Fetcher").Err(fmt.Errorf("errors in fetching: %s", errString)).Msg("errors in fetching") + log.Warn().Str("Player", "Fetcher").Str("errs", errString).Msg("errors in fetching") } return data, nil @@ -174,12 +174,12 @@ func (f *Fetcher) cex(definition *Definition, proxies []Proxy) (float64, error) func (f *Fetcher) uniswapV3(definition *Definition, chainHelpers map[string]ChainHelper) (float64, error) { if definition.Address == nil || definition.ChainID == nil || definition.Token0Decimals == nil || definition.Token1Decimals == nil { log.Error().Any("definition", definition).Msg("missing required fields for uniswapV3") - return 0, errors.New("missing required fields for uniswapV3") + return 0, errorSentinel.ErrFetcherInvalidDexFetcherDefinition } helper := chainHelpers[*definition.ChainID] if helper == nil { - return 0, errors.New("chain helper not found") + return 0, errorSentinel.ErrFetcherChainHelperNotFound } rawResult, err := helper.ReadContract(context.Background(), *definition.Address, "function slot0() external view returns (uint160 sqrtPriceX96, int24 tick, uint16 observationIndex, uint16 observationCardinality, uint16 observationCardinalityNext, uint8 feeProtocol, bool unlocked)") @@ -190,12 +190,12 @@ func (f *Fetcher) uniswapV3(definition *Definition, chainHelpers map[string]Chai rawResultSlice, ok := rawResult.([]interface{}) if !ok || len(rawResultSlice) < 1 { - return 0, errors.New("unexpected raw result type") + return 0, errorSentinel.ErrFetcherInvalidRawResult } sqrtPriceX96, ok := rawResultSlice[0].(*big.Int) if !ok { - return 0, errors.New("unexpected result on converting to bigint") + return 0, errorSentinel.ErrFetcherConvertToBigInt } return getTokenPrice(sqrtPriceX96, definition) diff --git a/node/pkg/fetcher/utils.go b/node/pkg/fetcher/utils.go index 0913e1261..30fe541c8 100644 --- a/node/pkg/fetcher/utils.go +++ b/node/pkg/fetcher/utils.go @@ -2,13 +2,13 @@ package fetcher import ( "context" - "errors" "math" "math/big" "strconv" "time" "bisonai.com/orakl/node/pkg/db" + errorSentinel "bisonai.com/orakl/node/pkg/error" "bisonai.com/orakl/node/pkg/utils/reducer" "bisonai.com/orakl/node/pkg/utils/request" "github.com/rs/zerolog/log" @@ -26,7 +26,7 @@ func getTokenPrice(sqrtPriceX96 *big.Int, definition *Definition) (float64, erro decimal0 := *definition.Token0Decimals decimal1 := *definition.Token1Decimals if sqrtPriceX96 == nil || decimal0 == 0 || decimal1 == 0 { - return 0, errors.New("invalid input") + return 0, errorSentinel.ErrFetcherInvalidInput } sqrtPriceX96Float := new(big.Float).SetInt(sqrtPriceX96) @@ -38,7 +38,7 @@ func getTokenPrice(sqrtPriceX96 *big.Int, definition *Definition) (float64, erro datum := sqrtPriceX96Float.Quo(sqrtPriceX96Float, decimalDiff) if definition.Reciprocal != nil && *definition.Reciprocal { if datum == nil || datum.Sign() == 0 { - return 0, errors.New("division by zero error from reciprocal division") + return 0, errorSentinel.ErrFetcherDivisionByZero } datum = datum.Quo(new(big.Float).SetFloat64(1), datum) } diff --git a/node/pkg/libp2p/utils/utils.go b/node/pkg/libp2p/utils/utils.go index 9abd46976..f65474f2f 100644 --- a/node/pkg/libp2p/utils/utils.go +++ b/node/pkg/libp2p/utils/utils.go @@ -2,13 +2,13 @@ package utils import ( "context" - "errors" "fmt" "strconv" "time" "strings" + errorSentinel "bisonai.com/orakl/node/pkg/error" "bisonai.com/orakl/node/pkg/utils/retrier" "github.com/libp2p/go-libp2p/core/host" @@ -36,7 +36,7 @@ func GetHostAddress(host host.Host) (string, error) { if addr == nil { log.Error().Msg("host has no non-local addresses") - return "", errors.New("host has no non-local addresses") + return "", errorSentinel.ErrLibP2pEmptyNonLocalAddress } return addr.Encapsulate(hostAddr).String(), nil @@ -63,7 +63,7 @@ func IsHostAlive(ctx context.Context, h host.Host, addr string) (bool, error) { ) if lastErr != nil { - return false, fmt.Errorf("failed to connect to peer") + return false, errorSentinel.ErrLibP2pFailToConnectPeer } err = h.Network().ClosePeer(info.ID) @@ -86,13 +86,13 @@ func ExtractPayloadFromHost(h host.Host) (ip string, port int, host_id string, e if addr == nil { log.Error().Msg("host has no non-local addresses") - return "", 0, "", errors.New("host has no non-local addresses") + return "", 0, "", errorSentinel.ErrLibP2pEmptyNonLocalAddress } splitted := strings.Split(addr.String(), "/") if len(splitted) < 5 { log.Error().Msg("error splitting address") - return "", 0, "", errors.New("error splitting address") + return "", 0, "", errorSentinel.ErrLibP2pAddressSplitFail } ip = splitted[2] rawPort := splitted[4] diff --git a/node/pkg/por/app.go b/node/pkg/por/app.go index ed478a79e..f5320fbab 100644 --- a/node/pkg/por/app.go +++ b/node/pkg/por/app.go @@ -3,7 +3,6 @@ package por import ( "context" "encoding/json" - "errors" "math" "math/big" "net/http" @@ -11,6 +10,7 @@ import ( "time" "bisonai.com/orakl/node/pkg/chain/helper" + errorSentinel "bisonai.com/orakl/node/pkg/error" "bisonai.com/orakl/node/pkg/fetcher" "bisonai.com/orakl/node/pkg/utils/request" "bisonai.com/orakl/node/pkg/utils/retrier" @@ -28,7 +28,7 @@ func New(ctx context.Context) (*App, error) { if providerUrl == "" { providerUrl = os.Getenv("KLAYTN_PROVIDER_URL") if providerUrl == "" { - return nil, errors.New("POR_PROVIDER_URL not set") + return nil, errorSentinel.ErrPorProviderUrlNotFound } } @@ -63,7 +63,7 @@ func New(ctx context.Context) (*App, error) { porReporterPk := os.Getenv("POR_REPORTER_PK") if porReporterPk == "" { - return nil, errors.New("POR_REPORTER_PK not set") + return nil, errorSentinel.ErrPorReporterPkNotFound } chainHelper, err := helper.NewChainHelper( @@ -242,12 +242,12 @@ func (a *App) GetRoundID(ctx context.Context) (uint32, error) { rawResultSlice, ok := rawResult.([]interface{}) if !ok { - return 0, errors.New("failed to cast raw result to slice") + return 0, errorSentinel.ErrPorRawResultCastFail } RoundID, ok := rawResultSlice[1].(uint32) if !ok { - return 0, errors.New("failed to cast roundId to uint32") + return 0, errorSentinel.ErrPorRoundIdCastFail } return RoundID, nil @@ -261,17 +261,17 @@ func (a *App) GetLastInfo(ctx context.Context) (LastInfo, error) { rawResultSlice, ok := rawResult.([]interface{}) if !ok { - return LastInfo{}, errors.New("failed to cast raw result to slice") + return LastInfo{}, errorSentinel.ErrPorRawResultCastFail } updatedAt, ok := rawResultSlice[3].(*big.Int) if !ok { - return LastInfo{}, errors.New("failed to cast updatedAt to big.Int") + return LastInfo{}, errorSentinel.ErrPorUpdatedAtCastFail } answer, ok := rawResultSlice[1].(*big.Int) if !ok { - return LastInfo{}, errors.New("failed to cast answer to big.Int") + return LastInfo{}, errorSentinel.ErrPorAnswerCastFail } return LastInfo{ diff --git a/node/pkg/raft/raft.go b/node/pkg/raft/raft.go index ce3c82eec..6bf7d8181 100644 --- a/node/pkg/raft/raft.go +++ b/node/pkg/raft/raft.go @@ -3,13 +3,13 @@ package raft import ( "context" "encoding/json" - "fmt" "math/rand" "sync" "time" "github.com/rs/zerolog/log" + errorSentinel "bisonai.com/orakl/node/pkg/error" pubsub "github.com/libp2p/go-libp2p-pubsub" "github.com/libp2p/go-libp2p/core/host" ) @@ -122,7 +122,7 @@ func (r *Raft) handleHeartbeat(msg Message) error { } if heartbeatMessage.LeaderID != msg.SentFrom { - return fmt.Errorf("leader id mismatch") + return errorSentinel.ErrRaftLeaderIdMismatch } currentRole := r.GetRole() diff --git a/node/pkg/reporter/app.go b/node/pkg/reporter/app.go index 4d65c83e4..aea9e2acb 100644 --- a/node/pkg/reporter/app.go +++ b/node/pkg/reporter/app.go @@ -2,15 +2,13 @@ package reporter import ( "context" - "errors" - "fmt" "os" - "strings" "time" "bisonai.com/orakl/node/pkg/bus" "bisonai.com/orakl/node/pkg/chain/helper" "bisonai.com/orakl/node/pkg/db" + errorSentinel "bisonai.com/orakl/node/pkg/error" "github.com/klaytn/klaytn/common" pubsub "github.com/libp2p/go-libp2p-pubsub" "github.com/libp2p/go-libp2p/core/host" @@ -46,7 +44,7 @@ func (a *App) setReporters(ctx context.Context, h host.Host, ps *pubsub.PubSub) contractAddress := os.Getenv("SUBMISSION_PROXY_CONTRACT") if contractAddress == "" { - return errors.New("SUBMISSION_PROXY_CONTRACT not set") + return errorSentinel.ErrReporterSubmissionProxyContractNotFound } tmpChainHelper, err := helper.NewChainHelper(ctx) @@ -87,7 +85,7 @@ func (a *App) setReporters(ctx context.Context, h host.Host, ps *pubsub.PubSub) } if len(a.Reporters) == 0 { log.Error().Str("Player", "Reporter").Msg("no reporters set") - return errors.New("no reporters set") + return errorSentinel.ErrReporterNotFound } groupedDeviationConfigs := groupConfigsByAggregateIntervals(configs) @@ -131,7 +129,7 @@ func (a *App) clearReporters() error { a.Reporters = make([]*Reporter, 0) if len(errs) > 0 { - return fmt.Errorf("errors occurred while stopping reporters: %v", errs) + return errorSentinel.ErrReporterClear } return nil @@ -149,7 +147,7 @@ func (a *App) startReporters(ctx context.Context) error { } if len(errs) > 0 { - return fmt.Errorf(strings.Join(errs, "; ")) + return errorSentinel.ErrReporterStart } return nil @@ -167,7 +165,7 @@ func (a *App) stopReporters() error { } if len(errs) > 0 { - return fmt.Errorf(strings.Join(errs, "; ")) + return errorSentinel.ErrReporterStop } return nil @@ -200,7 +198,7 @@ func (a *App) handleMessage(ctx context.Context, msg bus.Message) { switch msg.Content.Command { case bus.ACTIVATE_REPORTER: if msg.From != bus.ADMIN { - bus.HandleMessageError(errors.New("non-admin"), msg, "reporter received message from non-admin") + bus.HandleMessageError(errorSentinel.ErrBusNonAdmin, msg, "reporter received message from non-admin") return } err := a.startReporters(ctx) @@ -211,7 +209,7 @@ func (a *App) handleMessage(ctx context.Context, msg bus.Message) { msg.Response <- bus.MessageResponse{Success: true} case bus.DEACTIVATE_REPORTER: if msg.From != bus.ADMIN { - bus.HandleMessageError(errors.New("non-admin"), msg, "reporter received message from non-admin") + bus.HandleMessageError(errorSentinel.ErrBusNonAdmin, msg, "reporter received message from non-admin") return } err := a.stopReporters() @@ -222,7 +220,7 @@ func (a *App) handleMessage(ctx context.Context, msg bus.Message) { msg.Response <- bus.MessageResponse{Success: true} case bus.REFRESH_REPORTER: if msg.From != bus.ADMIN { - bus.HandleMessageError(errors.New("non-admin"), msg, "reporter received message from non-admin") + bus.HandleMessageError(errorSentinel.ErrBusNonAdmin, msg, "reporter received message from non-admin") return } err := a.stopReporters() @@ -252,13 +250,13 @@ func (a *App) GetReporterWithInterval(interval int) (*Reporter, error) { return reporter, nil } } - return nil, errors.New("reporter not found") + return nil, errorSentinel.ErrReporterNotFound } func startReporter(ctx context.Context, reporter *Reporter) error { if reporter.isRunning { log.Debug().Str("Player", "Reporter").Msg("reporter already running") - return errors.New("reporter already running") + return errorSentinel.ErrReporterAlreadyRunning } err := reporter.SetKlaytnHelper(ctx) @@ -284,7 +282,7 @@ func stopReporter(reporter *Reporter) error { if reporter.nodeCancel == nil { log.Error().Str("Player", "Reporter").Msg("reporter cancel function not found") - return errors.New("reporter cancel function not found") + return errorSentinel.ErrReporterCancelNotFound } reporter.nodeCancel() diff --git a/node/pkg/reporter/reporter.go b/node/pkg/reporter/reporter.go index 5ee47cca2..fb6fce5d0 100644 --- a/node/pkg/reporter/reporter.go +++ b/node/pkg/reporter/reporter.go @@ -3,12 +3,12 @@ package reporter import ( "context" "encoding/json" - "errors" "strconv" "time" "bisonai.com/orakl/node/pkg/chain/helper" chain_utils "bisonai.com/orakl/node/pkg/chain/utils" + errorSentinel "bisonai.com/orakl/node/pkg/error" "bisonai.com/orakl/node/pkg/raft" "bisonai.com/orakl/node/pkg/utils/retrier" @@ -26,8 +26,8 @@ func NewReporter(ctx context.Context, opts ...ReporterOption) (*Reporter, error) } if len(config.Configs) == 0 { - log.Error().Str("Player", "Reporter").Err(errors.New("no submission pairs")).Msg("no submission pairs to make new reporter") - return nil, errors.New("no submission pairs") + log.Error().Str("Player", "Reporter").Msg("no submission pairs to make new reporter") + return nil, errorSentinel.ErrReporterEmptyConfigs } topicString := TOPIC_STRING + "-" @@ -106,7 +106,7 @@ func (r *Reporter) leaderJob() error { if err != nil { log.Error().Str("Player", "Reporter").Err(err).Msg("failed to report, resigning from leader") r.resignLeader() - return errors.New("failed to report") + return errorSentinel.ErrReporterReportFailed } err = r.PublishSubmissionMessage(validAggregates) @@ -192,7 +192,7 @@ func (r *Reporter) orderProofs(ctx context.Context, proofMap map[int32][]byte, a proof, ok := proofMap[agg.ConfigID] if !ok { log.Error().Str("Player", "Reporter").Msg("proof not found") - return nil, errors.New("proof not found") + return nil, errorSentinel.ErrReporterProofNotFound } orderedProof, err := r.orderProof(ctx, proof, agg) @@ -216,14 +216,14 @@ func (r *Reporter) handleCustomMessage(ctx context.Context, msg raft.Message) er case SubmissionMsg: return r.HandleSubmissionMessage(ctx, msg) default: - return errors.New("unknown message type") + return errorSentinel.ErrReporterUnknownMessageType } } func (r *Reporter) reportWithProofs(ctx context.Context, aggregates []GlobalAggregate, proofMap map[int32][]byte) error { log.Debug().Str("Player", "Reporter").Int("aggregates", len(aggregates)).Msg("reporting with proofs") if r.KlaytnHelper == nil { - return errors.New("klaytn helper not set") + return errorSentinel.ErrReporterKlaytnHelperNotFound } addresses, values, timestamps, proofs, err := MakeContractArgsWithProofs(aggregates, r.SubmissionPairs, proofMap) @@ -331,7 +331,7 @@ func (r *Reporter) deviationJob() error { if err != nil { log.Error().Str("Player", "Reporter").Err(err).Msg("failed to report deviation, resigning from leader") r.resignLeader() - return errors.New("failed to report deviation") + return errorSentinel.ErrReporterDeviationReportFail } err = r.PublishSubmissionMessage(deviatingAggregates) diff --git a/node/pkg/reporter/reporter_test.go b/node/pkg/reporter/reporter_test.go index f5401885e..59793e9b2 100644 --- a/node/pkg/reporter/reporter_test.go +++ b/node/pkg/reporter/reporter_test.go @@ -8,6 +8,7 @@ import ( "testing" "bisonai.com/orakl/node/pkg/chain/helper" + errorSentinel "bisonai.com/orakl/node/pkg/error" "bisonai.com/orakl/node/pkg/raft" "github.com/klaytn/klaytn/common" "github.com/stretchr/testify/assert" @@ -135,7 +136,8 @@ func TestHandleCustomMessage(t *testing.T) { } err = reporter.handleCustomMessage(ctx, raft.Message{}) - assert.Equal(t, err.Error(), "unknown message type") + assert.ErrorIs(t, err, errorSentinel.ErrReporterUnknownMessageType) + } func TestGetLatestGlobalAggregates(t *testing.T) { diff --git a/node/pkg/reporter/utils.go b/node/pkg/reporter/utils.go index f29b8a71f..2d4e296dd 100644 --- a/node/pkg/reporter/utils.go +++ b/node/pkg/reporter/utils.go @@ -3,7 +3,6 @@ package reporter import ( "bytes" "context" - "errors" "math" "math/big" "strconv" @@ -12,6 +11,7 @@ import ( "bisonai.com/orakl/node/pkg/chain/helper" chain_utils "bisonai.com/orakl/node/pkg/chain/utils" "bisonai.com/orakl/node/pkg/db" + errorSentinel "bisonai.com/orakl/node/pkg/error" "github.com/klaytn/klaytn/common" "github.com/rs/zerolog/log" @@ -73,7 +73,7 @@ func StoreLastSubmission(ctx context.Context, aggregates []GlobalAggregate) erro } if len(vals) == 0 { - return errors.New("no valid aggregates") + return errorSentinel.ErrReporterEmptyValidAggregates } return db.MSetObject(ctx, vals) } @@ -100,15 +100,15 @@ func ConvertPgsqlProofsToProofs(pgsqlProofs []PgsqlProof) []Proof { func MakeContractArgsWithProofs(aggregates []GlobalAggregate, submissionPairs map[int32]SubmissionPair, proofMap map[int32][]byte) ([]common.Address, []*big.Int, []*big.Int, [][]byte, error) { if len(aggregates) == 0 { - return nil, nil, nil, nil, errors.New("no aggregates") + return nil, nil, nil, nil, errorSentinel.ErrReporterEmptyAggregatesParam } if len(submissionPairs) == 0 { - return nil, nil, nil, nil, errors.New("no submission pairs") + return nil, nil, nil, nil, errorSentinel.ErrReporterEmptySubmissionPairsParam } if len(proofMap) == 0 { - return nil, nil, nil, nil, errors.New("no proofs") + return nil, nil, nil, nil, errorSentinel.ErrReporterEmptyProofParam } addresses := make([]common.Address, len(aggregates)) @@ -119,7 +119,7 @@ func MakeContractArgsWithProofs(aggregates []GlobalAggregate, submissionPairs ma for i, agg := range aggregates { if agg.ConfigID == 0 || agg.Value < 0 { log.Error().Str("Player", "Reporter").Int32("configId", agg.ConfigID).Int64("value", agg.Value).Msg("skipping invalid aggregate") - return nil, nil, nil, nil, errors.New("invalid aggregate exists") + return nil, nil, nil, nil, errorSentinel.ErrReporterInvalidAggregateFound } addresses[i] = submissionPairs[agg.ConfigID].Address values[i] = big.NewInt(agg.Value) @@ -128,7 +128,7 @@ func MakeContractArgsWithProofs(aggregates []GlobalAggregate, submissionPairs ma } if len(addresses) == 0 || len(values) == 0 || len(proofs) == 0 || len(timestamps) == 0 { - return nil, nil, nil, nil, errors.New("no valid aggregates") + return nil, nil, nil, nil, errorSentinel.ErrReporterEmptyValidAggregates } return addresses, values, timestamps, proofs, nil } @@ -184,7 +184,7 @@ func GetProofsAsMap(ctx context.Context, aggregates []GlobalAggregate) (map[int3 if len(proofs) < len(aggregates) { log.Error().Str("Player", "Reporter").Msg("proofs not found for all aggregates") - return nil, errors.New("proofs not found for all aggregates") + return nil, errorSentinel.ErrReporterMissingProof } return ProofsToMap(proofs), nil } @@ -237,13 +237,13 @@ func ReadOnchainWhitelist(ctx context.Context, chainHelper *helper.ChainHelper, rawResultSlice, ok := result.([]interface{}) if !ok { log.Error().Str("Player", "Reporter").Msg("unexpected raw result type") - return nil, errors.New("unexpected result type") + return nil, errorSentinel.ErrReporterResultCastToInterfaceFail } arr, ok := rawResultSlice[0].([]common.Address) if !ok { log.Error().Str("Player", "Reporter").Msg("unexpected raw result type") - return nil, errors.New("unexpected rawResult type") + return nil, errorSentinel.ErrReporterResultCastToAddressFail } return arr, nil } @@ -252,7 +252,7 @@ func CheckForNonWhitelistedSigners(signers []common.Address, whitelist []common. for _, signer := range signers { if !isWhitelisted(signer, whitelist) { log.Error().Str("Player", "Reporter").Str("signer", signer.Hex()).Msg("non-whitelisted signer") - return errors.New("non-whitelisted signer") + return errorSentinel.ErrReporterSignerNotWhitelisted } } return nil @@ -278,7 +278,7 @@ func OrderProof(signerMap map[common.Address][]byte, whitelist []common.Address) if len(tmpProofs) == 0 { log.Error().Str("Player", "Reporter").Msg("no valid proofs") - return nil, errors.New("no valid proofs") + return nil, errorSentinel.ErrReporterEmptyValidProofs } return bytes.Join(tmpProofs, nil), nil @@ -307,11 +307,11 @@ func GetSignerListFromProofs(hash []byte, proofChunks [][]byte) ([]common.Addres func SplitProofToChunk(proof []byte) ([][]byte, error) { if len(proof) == 0 { - return nil, errors.New("empty proof") + return nil, errorSentinel.ErrReporterEmptyProofParam } if len(proof)%65 != 0 { - return nil, errors.New("invalid proof length") + return nil, errorSentinel.ErrReporterInvalidProofLength } proofs := make([][]byte, 0, len(proof)/65) diff --git a/node/pkg/reporter/utils_test.go b/node/pkg/reporter/utils_test.go index f3fcdad54..5934fccbf 100644 --- a/node/pkg/reporter/utils_test.go +++ b/node/pkg/reporter/utils_test.go @@ -8,6 +8,7 @@ import ( chain_utils "bisonai.com/orakl/node/pkg/chain/utils" "bisonai.com/orakl/node/pkg/db" + errorSentinel "bisonai.com/orakl/node/pkg/error" "github.com/klaytn/klaytn/common" "github.com/stretchr/testify/assert" ) @@ -38,7 +39,7 @@ func TestCheckForNonWhitelistedSigners(t *testing.T) { err := CheckForNonWhitelistedSigners(signers, whitelist) - assert.EqualError(t, err, "non-whitelisted signer") + assert.ErrorIs(t, err, errorSentinel.ErrReporterSignerNotWhitelisted) }) t.Run("Empty signers", func(t *testing.T) { @@ -101,7 +102,7 @@ func TestOrderProof(t *testing.T) { proof, err := OrderProof(signerMap, whitelist) - assert.EqualError(t, err, "no valid proofs") + assert.ErrorIs(t, err, errorSentinel.ErrReporterEmptyValidProofs) assert.Nil(t, proof) }) } @@ -176,7 +177,7 @@ func TestSplitProofToChunk(t *testing.T) { chunks, err := SplitProofToChunk(proof) assert.Nil(t, chunks) - assert.EqualError(t, err, "empty proof") + assert.ErrorIs(t, err, errorSentinel.ErrReporterEmptyProofParam) }) t.Run("Invalid proof length", func(t *testing.T) { @@ -184,7 +185,7 @@ func TestSplitProofToChunk(t *testing.T) { chunks, err := SplitProofToChunk(proof) assert.Nil(t, chunks) - assert.EqualError(t, err, "invalid proof length") + assert.ErrorIs(t, err, errorSentinel.ErrReporterInvalidProofLength) }) t.Run("Valid proof", func(t *testing.T) { diff --git a/node/pkg/utils/calculator/calculator.go b/node/pkg/utils/calculator/calculator.go index 57bf8bcf0..b7dc4f167 100644 --- a/node/pkg/utils/calculator/calculator.go +++ b/node/pkg/utils/calculator/calculator.go @@ -1,9 +1,10 @@ package calculator import ( - "errors" "math/rand" "sort" + + errorSentinel "bisonai.com/orakl/node/pkg/error" ) func RandomNumberGenerator() int { @@ -12,7 +13,7 @@ func RandomNumberGenerator() int { func GetIntAvg(nums []int) (int, error) { if len(nums) == 0 { - return 0, errors.New("empty array") + return 0, errorSentinel.ErrCalculatorEmptyArr } var sum int for _, v := range nums { @@ -23,7 +24,7 @@ func GetIntAvg(nums []int) (int, error) { func GetIntMed(nums []int) (int, error) { if len(nums) == 0 { - return 0, errors.New("empty array") + return 0, errorSentinel.ErrCalculatorEmptyArr } sort.Ints(nums) n := len(nums) @@ -37,7 +38,7 @@ func GetIntMed(nums []int) (int, error) { func GetInt64Avg(nums []int64) (int64, error) { if len(nums) == 0 { - return 0, errors.New("empty array") + return 0, errorSentinel.ErrCalculatorEmptyArr } var sum int64 for _, v := range nums { @@ -48,7 +49,7 @@ func GetInt64Avg(nums []int64) (int64, error) { func GetInt64Med(nums []int64) (int64, error) { if len(nums) == 0 { - return 0, errors.New("empty array") + return 0, errorSentinel.ErrCalculatorEmptyArr } sort.Slice(nums, func(i, j int) bool { return nums[i] < nums[j] }) n := len(nums) @@ -62,7 +63,7 @@ func GetInt64Med(nums []int64) (int64, error) { func GetFloatAvg(data []float64) (float64, error) { if len(data) == 0 { - return 0, errors.New("empty array") + return 0, errorSentinel.ErrCalculatorEmptyArr } var sum float64 for _, v := range data { @@ -73,7 +74,7 @@ func GetFloatAvg(data []float64) (float64, error) { func GetFloatMed(data []float64) (float64, error) { if len(data) == 0 { - return 0, errors.New("empty array") + return 0, errorSentinel.ErrCalculatorEmptyArr } sort.Float64s(data) if len(data)%2 == 0 { diff --git a/node/pkg/utils/reducer/reducer.go b/node/pkg/utils/reducer/reducer.go index aedfb713a..604f8a887 100644 --- a/node/pkg/utils/reducer/reducer.go +++ b/node/pkg/utils/reducer/reducer.go @@ -1,9 +1,10 @@ package reducer import ( - "fmt" "math" "strconv" + + errorSentinel "bisonai.com/orakl/node/pkg/error" ) type Reducer struct { @@ -22,7 +23,7 @@ func Reduce(raw interface{}, reducers []Reducer) (float64, error) { } result, ok := raw.(float64) if !ok { - return 0, fmt.Errorf("cannot cast raw data to float") + return 0, errorSentinel.ErrReducerCastToFloatFail } return result, nil } @@ -32,7 +33,7 @@ func reduce(raw interface{}, reducer Reducer) (interface{}, error) { case "INDEX": castedRaw, ok := raw.([]interface{}) if !ok { - return nil, fmt.Errorf("cannot cast raw data to []interface{}") + return nil, errorSentinel.ErrReducerIndexCastToInterfaceFail } index, err := tryParseFloat(reducer.Args) if err != nil { @@ -43,20 +44,20 @@ func reduce(raw interface{}, reducer Reducer) (interface{}, error) { case "PARSE": args, ok := reducer.Args.([]interface{}) if !ok { - return nil, fmt.Errorf("cannot cast reducer.Args to []interface{}") + return nil, errorSentinel.ErrReducerParseCastToInterfaceFail } argStrs := make([]string, len(args)) for i, arg := range args { argStr, ok := arg.(string) if !ok { - return nil, fmt.Errorf("cannot cast arg to string") + return nil, errorSentinel.ErrReducerParseCastToStringFail } argStrs[i] = argStr } for _, arg := range argStrs { castedRaw, ok := raw.(map[string]interface{}) if !ok { - return nil, fmt.Errorf("cannot cast raw data to map[string]interface{}") + return nil, errorSentinel.ErrReducerParseCastToMapFail } raw = castedRaw[arg] } @@ -68,7 +69,7 @@ func reduce(raw interface{}, reducer Reducer) (interface{}, error) { } arg, ok := reducer.Args.(float64) if !ok { - return nil, fmt.Errorf("cannot cast reducer.Args to float64") + return nil, errorSentinel.ErrReducerMulCastToFloatFail } return castedRaw * arg, nil @@ -96,10 +97,10 @@ func reduce(raw interface{}, reducer Reducer) (interface{}, error) { } arg, ok := reducer.Args.(float64) if !ok { - return nil, fmt.Errorf("cannot cast reducer.Args to float64") + return nil, errorSentinel.ErrReducerDivCastToFloatFail } if arg == 0 { - return nil, fmt.Errorf("cannot divide by zero") + return nil, errorSentinel.ErrReducerDivDivsionByZero } return castedRaw / arg, nil case "DIVFROM": @@ -109,11 +110,11 @@ func reduce(raw interface{}, reducer Reducer) (interface{}, error) { } arg, ok := reducer.Args.(float64) if !ok { - return nil, fmt.Errorf("cannot cast reducer.Args to float64") + return nil, errorSentinel.ErrReducerDivFromCastToFloatFail } return arg / castedRaw, nil default: - return nil, fmt.Errorf("unknown reducer function: %s", reducer.Function) + return nil, errorSentinel.ErrReducerUnknownReducerFunc } } @@ -131,5 +132,5 @@ func tryParseFloat(raw interface{}) (float64, error) { return f, nil } } - return 0, fmt.Errorf("cannot parse raw data to float") + return 0, errorSentinel.ErrReducerCastToFloatFail } diff --git a/node/pkg/utils/request/request.go b/node/pkg/utils/request/request.go index a658174c8..e1f0f56e8 100644 --- a/node/pkg/utils/request/request.go +++ b/node/pkg/utils/request/request.go @@ -3,12 +3,12 @@ package request import ( "bytes" "encoding/json" - "fmt" "io" "net/http" "net/url" "time" + errorSentinel "bisonai.com/orakl/node/pkg/error" "github.com/rs/zerolog/log" ) @@ -33,7 +33,7 @@ func UrlRequest[T any](urlEndpoint string, method string, requestBody interface{ Int("status", response.StatusCode). Str("url", urlEndpoint). Msg("failed to make request") - return result, fmt.Errorf("failed to get status ok: %s\nstatus: %d", urlEndpoint, response.StatusCode) + return result, errorSentinel.ErrRequestStatusNotOk } resultBody, err := io.ReadAll(response.Body) diff --git a/node/pkg/utils/retrier/retrier.go b/node/pkg/utils/retrier/retrier.go index c38f0017a..8267c6d5b 100644 --- a/node/pkg/utils/retrier/retrier.go +++ b/node/pkg/utils/retrier/retrier.go @@ -2,10 +2,10 @@ package retrier import ( "crypto/rand" - "errors" "math/big" "time" + errorSentinel "bisonai.com/orakl/node/pkg/error" "github.com/rs/zerolog/log" ) @@ -26,7 +26,7 @@ func Retry(job func() error, maxAttempts int, initialTimeout time.Duration, maxT return nil } log.Error().Msg("job failed") - return errors.New("job failed") + return errorSentinel.ErrRetrierJobFail } func calculateJitter(baseTimeout time.Duration) time.Duration {