diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index fe4d4ea..5a7dc35 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -7,6 +7,15 @@ on: branches: [ master ] jobs: + golangci: + name: lint + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: golangci-lint + uses: golangci/golangci-lint-action@v2 + with: + version: v1.29 build: name: Build diff --git a/Makefile b/Makefile index 1bc40a4..9282f13 100644 --- a/Makefile +++ b/Makefile @@ -19,6 +19,9 @@ build: clean buidl: build +lint: + golangci-lint run ./... + init: ./build/hubble init diff --git a/aggregator/aggregator.go b/aggregator/aggregator.go index 047e825..a58476c 100644 --- a/aggregator/aggregator.go +++ b/aggregator/aggregator.go @@ -59,7 +59,10 @@ func NewAggregator() *Aggregator { // OnStart starts new block subscription func (a *Aggregator) OnStart() error { - a.BaseService.OnStart() // Always call the overridden method. + err := a.BaseService.OnStart() // Always call the overridden method. + if err != nil { + return err + } ctx, cancelAggregating := context.WithCancel(context.Background()) a.cancelAggregating = cancelAggregating diff --git a/cmd/flags.go b/cmd/flags.go index 3a2a45c..86d503c 100644 --- a/cmd/flags.go +++ b/cmd/flags.go @@ -1,15 +1,11 @@ package main const ( - FlagFromID = "from" - FlagToID = "to" - FlagPrivKey = "privkey" - FlagPubKey = "pubkey" - FlagAmount = "amount" - FlagFee = "fee" - FlagSignature = "sig" - FlagNonce = "nonce" - FlagTokenID = "token" - FlagDatabaseName = "dbname" - FlagNumberOfUsers = "count" + FlagFromID = "from" + FlagToID = "to" + FlagPrivKey = "privkey" + FlagPubKey = "pubkey" + FlagAmount = "amount" + FlagFee = "fee" + FlagDatabaseName = "dbname" ) diff --git a/cmd/main.go b/cmd/main.go index 547f7cd..ad0e2a0 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -41,10 +41,15 @@ func main() { ) // bind with-heimdall-config config with root cmd - viper.BindPFlag( + err := viper.BindPFlag( WithConfigPathFlag, rootCmd.Flags().Lookup(WithConfigPathFlag), ) + if err != nil { + fmt.Println("BindPFlag Error", err) + return + } + rootCmd.AddCommand(initCmd()) rootCmd.AddCommand(startCmd()) rootCmd.AddCommand(resetCmd()) @@ -56,7 +61,7 @@ func main() { rootCmd.AddCommand(migrationCmd) executor := Executor{rootCmd, os.Exit} - if err := executor.Command.Execute(); err != nil { + if err = executor.Command.Execute(); err != nil { fmt.Println("Error while executing command", err) return } diff --git a/cmd/start.go b/cmd/start.go index 68c7c0d..038b67c 100644 --- a/cmd/start.go +++ b/cmd/start.go @@ -59,8 +59,13 @@ func startCmd() *cobra.Command { go func() { // sig is a ^C, handle it for range catchSignal { - aggregator.Stop() - syncer.Stop() + if err := aggregator.Stop(); err != nil { + log.Fatalln("Unable to stop aggregator", "error", err) + } + if err := syncer.Stop(); err != nil { + log.Fatalln("Unable to stop syncer", "error", err) + } + core.DBInstance.Close() // exit os.Exit(1) @@ -68,7 +73,7 @@ func startCmd() *cobra.Command { }() if err := syncer.Start(); err != nil { - log.Fatalln("Unable to start syncer", "error") + log.Fatalln("Unable to start syncer", "error", err) } if err := aggregator.Start(); err != nil { @@ -143,10 +148,14 @@ func loadGenesisData(genesis config.Genesis) { // load params newParams := core.Params{StakeAmount: genesis.StakeAmount, MaxDepth: genesis.MaxTreeDepth, MaxDepositSubTreeHeight: genesis.MaxDepositSubTreeHeight} - core.DBInstance.UpdateStakeAmount(newParams.StakeAmount) - core.DBInstance.UpdateMaxDepth(newParams.MaxDepth) - core.DBInstance.UpdateDepositSubTreeHeight(newParams.MaxDepositSubTreeHeight) - core.DBInstance.UpdateFinalisationTimePerBatch(40320) + err = core.DBInstance.UpdateStakeAmount(newParams.StakeAmount) + common.PanicIfError(err) + err = core.DBInstance.UpdateMaxDepth(newParams.MaxDepth) + common.PanicIfError(err) + err = core.DBInstance.UpdateDepositSubTreeHeight(newParams.MaxDepositSubTreeHeight) + common.PanicIfError(err) + err = core.DBInstance.UpdateFinalisationTimePerBatch(40320) + common.PanicIfError(err) // load sync status err = core.DBInstance.InitSyncStatus(genesis.StartEthBlock) diff --git a/cmd/tx.go b/cmd/tx.go index 9c2825f..6dc2dd2 100644 --- a/cmd/tx.go +++ b/cmd/tx.go @@ -55,11 +55,16 @@ func sendTransferTx() *cobra.Command { cmd.Flags().StringP(FlagPubKey, "", "", "--pubkey=") cmd.Flags().StringP(FlagPrivKey, "", "", "--privkey=") cmd.Flags().StringP(FlagAmount, "", "", "--amount=") - cmd.MarkFlagRequired(FlagToID) - cmd.MarkFlagRequired(FlagFromID) - cmd.MarkFlagRequired(FlagPubKey) - cmd.MarkFlagRequired(FlagPrivKey) - cmd.MarkFlagRequired(FlagAmount) + err := cmd.MarkFlagRequired(FlagToID) + common.PanicIfError(err) + err = cmd.MarkFlagRequired(FlagFromID) + common.PanicIfError(err) + err = cmd.MarkFlagRequired(FlagPubKey) + common.PanicIfError(err) + err = cmd.MarkFlagRequired(FlagPrivKey) + common.PanicIfError(err) + err = cmd.MarkFlagRequired(FlagAmount) + common.PanicIfError(err) return cmd } @@ -172,9 +177,18 @@ func validateAndTransfer(db core.DB, bazooka core.Bazooka, fromIndex, toIndex, a return } - tx := core.NewPendingTx(fromIndex, toIndex, core.TX_TRANSFER_TYPE, []byte(""), txData) - tx.SignTx(priv, pub, common.Keccak256(tx.GetSignBytes())) - tx.AssignHash() + tx, err := core.NewPendingTx(fromIndex, toIndex, core.TX_TRANSFER_TYPE, []byte(""), txData) + if err != nil { + return + } + err = tx.SignTx(priv, pub, common.Keccak256(tx.GetSignBytes())) + if err != nil { + return + } + err = tx.AssignHash() + if err != nil { + return + } fmt.Println("Sending new tx", tx.String()) diff --git a/common/unpack.go b/common/unpack.go index 1484deb..1bda248 100644 --- a/common/unpack.go +++ b/common/unpack.go @@ -132,17 +132,6 @@ func capitalise(input string) string { return toCamelCase(strings.ToUpper(input[:1]) + input[1:]) } -// decapitalise makes a camel-case string which starts with a lower case character. -func decapitalise(input string) string { - for len(input) > 0 && input[0] == '_' { - input = input[1:] - } - if len(input) == 0 { - return "" - } - return toCamelCase(strings.ToLower(input[:1]) + input[1:]) -} - // toCamelCase converts an under-score string to a camel-case string func toCamelCase(input string) string { toupper := false diff --git a/common/util.go b/common/util.go index 7b696e3..7f8cfe1 100644 --- a/common/util.go +++ b/common/util.go @@ -65,9 +65,11 @@ func KeccakFromString(data string) (hash common.Hash, err error) { } -func RlpHash(x interface{}) (h common.Hash) { +func RlpHash(x interface{}) (h common.Hash, err error) { hw := sha3.NewLegacyKeccak256() - rlp.Encode(hw, x) + if err = rlp.Encode(hw, x); err != nil { + return + } hw.Sum(h[:0]) - return h + return h, nil } diff --git a/core/account.go b/core/account.go index 483a3f0..11ad9c5 100644 --- a/core/account.go +++ b/core/account.go @@ -151,7 +151,10 @@ func (db *DB) AddNewAccount(acc Account) error { // UpdateAccount updates the account func (db *DB) UpdateAccount(leaf Account) error { db.Logger.Info("Updated account pubkey", "ID", leaf.ID) - leaf.PopulateHash() + err := leaf.PopulateHash() + if err != nil { + return err + } siblings, err := db.GetAccountSiblings(leaf.Path) if err != nil { return err @@ -232,7 +235,10 @@ func (db *DB) storeAccountLeaf(pdaLeaf Account, path string, siblings []Account) // InsertCoordinatorPubkeyAccounts inserts the coordinator accounts func (db *DB) InsertCoordinatorPubkeyAccounts(coordinatorAccount *Account, depth uint64) error { coordinatorAccount.UpdatePath(GenCoordinatorPath(depth)) - coordinatorAccount.PopulateHash() + err := coordinatorAccount.PopulateHash() + if err != nil { + return err + } coordinatorAccount.Type = TYPE_TERMINAL return db.Instance.Create(&coordinatorAccount).Error } diff --git a/core/bazooka.go b/core/bazooka.go index c63a907..61eba6a 100644 --- a/core/bazooka.go +++ b/core/bazooka.go @@ -371,7 +371,12 @@ func (b *Bazooka) DecodeTransferTx(txBytes []byte) (from, to, nonce, txType, amo func (b *Bazooka) EncodeState(id, balance, nonce, token uint64) (accountBytes []byte, err error) { opts := bind.CallOpts{From: config.OperatorAddress} - accountBytes, err = b.Frontend.Encode(&opts, rollupclient.TypesUserState{big.NewInt(int64(id)), big.NewInt(int64(token)), big.NewInt(int64(balance)), big.NewInt(int64(nonce))}) + accountBytes, err = b.Frontend.Encode(&opts, rollupclient.TypesUserState{ + PubkeyIndex: big.NewInt(int64(id)), + TokenType: big.NewInt(int64(token)), + Balance: big.NewInt(int64(balance)), + Nonce: big.NewInt(int64(nonce)), + }) if err != nil { return } diff --git a/core/tx.go b/core/tx.go index ec53f8c..af44c78 100644 --- a/core/tx.go +++ b/core/tx.go @@ -44,8 +44,8 @@ func NewTx(from, to, txType uint64, sig, data []byte) Tx { } // NewPendingTx creates a new transaction -func NewPendingTx(from, to, txType uint64, sig, data []byte) Tx { - tx := Tx{ +func NewPendingTx(from, to, txType uint64, sig, data []byte) (tx Tx, err error) { + tx = Tx{ To: to, From: from, Data: data, @@ -53,8 +53,11 @@ func NewPendingTx(from, to, txType uint64, sig, data []byte) Tx { Status: TX_STATUS_PENDING, Type: txType, } - tx.AssignHash() - return tx + + if err = tx.AssignHash(); err != nil { + return + } + return } // GetSignBytes returns the transaction data that has to be signed @@ -87,12 +90,16 @@ func (tx *Tx) SignTx(key string, pubkey string, txBytes [32]byte) (err error) { } // AssignHash creates a tx hash and add it to the tx -func (t *Tx) AssignHash() { +func (t *Tx) AssignHash() (err error) { if t.TxHash != "" { + return nil + } + hash, err := common.RlpHash(t) + if err != nil { return } - hash := common.RlpHash(t) t.TxHash = hash.String() + return nil } func (t *Tx) String() string { @@ -186,8 +193,10 @@ func (tx *Tx) GetWitnessTranfer() (fromMerkleProof, toMerkleProof StateMerklePro dbCopy, _ := NewDB() // fetch from state MP - DBInstance.FetchMPWithID(tx.From, &fromMerkleProof) - + err = DBInstance.FetchMPWithID(tx.From, &fromMerkleProof) + if err != nil { + return + } toState, err := DBInstance.GetStateByIndex(tx.To) if err != nil { return @@ -326,7 +335,6 @@ func ProcessTxs(db DB, bz Bazooka, txs []Tx, isSyncing bool) (commitments []Comm commitment := Commitment{Txs: txInCommitment, UpdatedRoot: newRoot, BatchType: tx.Type, AggregatedSignature: aggregatedSig.ToBytes()} commitments = append(commitments, commitment) } - currentRoot = newRoot } return commitments, nil diff --git a/core/utils.go b/core/utils.go index 7a2a9af..e6395b6 100644 --- a/core/utils.go +++ b/core/utils.go @@ -1,7 +1,6 @@ package core import ( - "fmt" "math/big" "strconv" "strings" @@ -52,16 +51,6 @@ func UintToString(a uint64) string { return strconv.FormatUint(a, 2) } -func isRight(path string) bool { - dataRune := []rune(path) - // if the bit is 0 - if dataRune[len(path)-1] == 48 { - return false - } else { - return true - } -} - func GetNthBitFromRight(path string, index int) int { dataRune := []rune(path) // if the bit is 0 @@ -112,10 +101,6 @@ func GetAdjacentNodePath(path string) (string, error) { return pad.Left(UintToString(adjacentNodePath), len(path), "0"), nil } -func padNumberWithZero(value string, depth uint64) string { - return fmt.Sprintf("%03v", value) -} - // goes from 3 to 000000000011 func SolidityPathToNodePath(path uint64, depth uint64) (string, error) { pathWithoutPrefix := UintToString(path) diff --git a/core/utils_test.go b/core/utils_test.go index d26e669..35541b1 100644 --- a/core/utils_test.go +++ b/core/utils_test.go @@ -25,6 +25,9 @@ func TestBasicPathMutations(t *testing.T) { panic(err) } data, err := StringToUint(newPath) + if err != nil { + panic(err) + } fmt.Println("path generated", newPath, "data", data) } diff --git a/listener/processors.go b/listener/processors.go index 74dd214..d5bbdfd 100644 --- a/listener/processors.go +++ b/listener/processors.go @@ -239,6 +239,9 @@ func (s *Syncer) SendDepositFinalisationTx() { } err = s.loadedBazooka.FireDepositFinalisation(nodeToBeReplaced, siblings, params.MaxDepositSubTreeHeight) + if err != nil { + return + } } func (s *Syncer) applyTxsFromBatch(txsBytes []byte, txType uint64, isSyncing bool) (newRoot core.ByteArray, err error) { diff --git a/listener/syncer.go b/listener/syncer.go index ef9e819..df48150 100644 --- a/listener/syncer.go +++ b/listener/syncer.go @@ -66,7 +66,7 @@ func NewSyncer() Syncer { if err != nil { panic(err) } - + //nolint:govet // will fix later in #76 return *syncerService } @@ -161,7 +161,8 @@ func (s *Syncer) startSubscription(ctx context.Context, subscription ethereum.Su case err := <-subscription.Err(): // stop service s.Logger.Error("Error while subscribing new blocks", "error", err) - s.Stop() + err = s.Stop() + s.Logger.Error("Error while stopping", "error", err) // cancel subscription s.cancelSubscription() diff --git a/rest/api.go b/rest/api.go index 435c92a..94f490e 100644 --- a/rest/api.go +++ b/rest/api.go @@ -37,10 +37,13 @@ func TxReceiverHandler(w http.ResponseWriter, r *http.Request) { } // create a new pending transaction - userTx := core.NewPendingTx(tx.From, tx.To, core.TX_TRANSFER_TYPE, tx.Signature, tx.Message) + userTx, err := core.NewPendingTx(tx.From, tx.To, core.TX_TRANSFER_TYPE, tx.Signature, tx.Message) + if err != nil { + WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + } // add the transaction to pool - err := core.DBInstance.InsertTx(&userTx) + err = core.DBInstance.InsertTx(&userTx) if err != nil { WriteErrorResponse(w, http.StatusBadRequest, "Cannot read request") } @@ -53,7 +56,6 @@ func TxReceiverHandler(w http.ResponseWriter, r *http.Request) { // write headers and data w.Header().Set("Content-Type", "application/json") _, _ = w.Write(output) - return } // GetAccountHandler fetches the user account data like balance, token type and nonce @@ -76,7 +78,6 @@ func GetAccountHandler(w http.ResponseWriter, r *http.Request) { } w.Header().Set("Content-Type", "application/json") _, _ = w.Write(output) - return } // GetAccountHandler fetches the user account data like balance, token type and nonce @@ -98,5 +99,4 @@ func GetTxTemplateForTxType(w http.ResponseWriter, r *http.Request) { } w.Header().Set("Content-Type", "application/json") _, _ = w.Write(output) - return } diff --git a/tests/tx_test.go b/tests/tx_test.go index 6b7d5e6..6dc7b91 100644 --- a/tests/tx_test.go +++ b/tests/tx_test.go @@ -29,7 +29,10 @@ func setupDB() (db core.DB, cleanup func(), err error) { allMigrations := migrations.GetMigrations() m := migrations.NewGormigrate(db.Instance, migrations.DefaultOptions, allMigrations) - m.Migrate() + err = m.Migrate() + if err != nil { + return + } cleanup = func() { db.Close() os.Remove(tmpfile.Name()) @@ -50,8 +53,14 @@ func TestPopTx(t *testing.T) { config.GlobalCfg.TxsPerBatch = 2 tx1 := core.NewTx(1, 2, txType, []byte{00}, []byte{00}) - tx2 := core.NewPendingTx(1, 2, txType, []byte{00}, []byte{01}) - tx3 := core.NewPendingTx(1, 2, txType, []byte{00}, []byte{02}) + tx2, err := core.NewPendingTx(1, 2, txType, []byte{00}, []byte{01}) + if err != nil { + t.Errorf("PopTxs error %s", err) + } + tx3, err := core.NewPendingTx(1, 2, txType, []byte{00}, []byte{02}) + if err != nil { + t.Errorf("PopTxs error %s", err) + } if err = db.InsertTx(&tx1); err != nil { t.Errorf("PopTxs error %s", err) @@ -64,6 +73,9 @@ func TestPopTx(t *testing.T) { } fetchedTxType, err := db.FetchTxType() + if err != nil { + t.Error(err) + } assert.Equal(t, txType, fetchedTxType) txs, err := db.PopTxs() diff --git a/wallet/wallet.go b/wallet/wallet.go index a83012a..a7223ec 100644 --- a/wallet/wallet.go +++ b/wallet/wallet.go @@ -17,13 +17,6 @@ func BytesToSignature(b []byte) (blswallet.Signature, error) { return *sig, err } -func getBLSSignatures(sigs []blswallet.Signature) (blsSigs []*blswallet.Signature) { - for _, sig := range sigs { - blsSigs = append(blsSigs, &sig) - } - return -} - func NewWallet() (wallet Wallet, err error) { newAccount, err := blswallet.NewKeyPair(rand.Reader) if err != nil { diff --git a/wallet/wallet_test.go b/wallet/wallet_test.go index 794cbe0..3c8a42b 100644 --- a/wallet/wallet_test.go +++ b/wallet/wallet_test.go @@ -33,6 +33,9 @@ func TestVerifyAggregated(t *testing.T) { t.Fatal(err) } accountSignature, err := wallet.Sign(signBytes) + if err != nil { + t.Fatal(err) + } messages[i] = signBytes publicKeys[i] = wallet.signer.Account.Public signatures[i] = &accountSignature