diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 7b04a9d..174e4cf 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -12,5 +12,5 @@ jobs: uses: actions/checkout@v2 - name: Lint run: | - curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.24.0 - $(go env GOPATH)/bin/golangci-lint run --timeout=5m + curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.30.0 + $(go env GOPATH)/bin/golangci-lint run --timeout=5m -E whitespace -E gosec -E gci -E misspell -E gomnd --max-same-issues 0 diff --git a/README.md b/README.md index 65aa721..146f60d 100644 --- a/README.md +++ b/README.md @@ -12,3 +12,10 @@ POSTGRES_PASS=yourpasswordhere; sudo docker run --rm --name hermez-db-test -p 54 ``` POSTGRES_PASS=yourpasswordhere go test ./... ``` + +## Lint +- Install [golangci-lint](https://golangci-lint.run) +- Once installed, to check the lints +``` +golangci-lint run --timeout=5m -E whitespace -E gosec -E gci -E misspell -E gomnd --max-same-issues 0 +``` diff --git a/common/account.go b/common/account.go index 7d2493a..e7550bc 100644 --- a/common/account.go +++ b/common/account.go @@ -12,7 +12,13 @@ import ( cryptoUtils "github.com/iden3/go-iden3-crypto/utils" ) -const NLEAFELEMS = 4 +const ( + NLEAFELEMS = 4 + // maxNonceValue is the maximum value that the Account.Nonce can have (40 bits: maxNonceValue=2**40-1) + maxNonceValue = 0xffffffffff + // maxBalanceBytes is the maximum bytes that can use the Account.Balance *big.Int + maxBalanceBytes = 24 +) // Account is a struct that gives information of the holdings of an address and a specific token. Is the data structure that generates the Value stored in the leaf of the MerkleTree type Account struct { @@ -37,10 +43,10 @@ func (a *Account) String() string { func (a *Account) Bytes() ([32 * NLEAFELEMS]byte, error) { var b [32 * NLEAFELEMS]byte - if a.Nonce > 0xffffffffff { + if a.Nonce > maxNonceValue { return b, fmt.Errorf("%s Nonce", ErrNumOverflow) } - if len(a.Balance.Bytes()) > 24 { + if len(a.Balance.Bytes()) > maxBalanceBytes { return b, fmt.Errorf("%s Balance", ErrNumOverflow) } diff --git a/common/batch.go b/common/batch.go index 1eadb33..ef616ef 100644 --- a/common/batch.go +++ b/common/batch.go @@ -8,6 +8,8 @@ import ( ethCommon "github.com/ethereum/go-ethereum/common" ) +const batchNumBytesLen = 4 + // Batch is a struct that represents Hermez network batch type Batch struct { BatchNum BatchNum `meddler:"batch_num"` @@ -33,7 +35,7 @@ func (bn BatchNum) Bytes() []byte { // BatchNumFromBytes returns BatchNum from a []byte func BatchNumFromBytes(b []byte) (BatchNum, error) { - if len(b) != 4 { + if len(b) != batchNumBytesLen { return 0, fmt.Errorf("can not parse BatchNumFromBytes, bytes len %d, expected 4", len(b)) } batchNum := binary.LittleEndian.Uint32(b[:4]) diff --git a/common/fee.go b/common/fee.go index da3314f..1c9e185 100644 --- a/common/fee.go +++ b/common/fee.go @@ -1,6 +1,6 @@ package common -// Fee is a type that represents the percentage of tokens that will be payed in a transaction +// Fee is a type that represents the percentage of tokens that will be paid in a transaction // to incentivaise the materialization of it type Fee float64 @@ -15,5 +15,7 @@ type RecommendedFee struct { // FeeSelector is used to select a percentage from the FeePlan. type FeeSelector uint8 +const MAXFEEPLAN = 256 + // FeePlan represents the fee model, a position in the array indicates the percentage of tokens paid in concept of fee for a transaction -var FeePlan = [256]float64{} +var FeePlan = [MAXFEEPLAN]float64{} diff --git a/common/pooll2tx.go b/common/pooll2tx.go index 355ad6d..d2fa9c1 100644 --- a/common/pooll2tx.go +++ b/common/pooll2tx.go @@ -17,7 +17,7 @@ type Nonce uint64 // Bytes returns a byte array of length 5 representing the Nonce func (n Nonce) Bytes() ([5]byte, error) { - if n >= 1099511627776 { // 2**40bits + if n > maxNonceValue { return [5]byte{}, ErrNonceOverflow } var nonceBytes [8]byte diff --git a/common/pooll2tx_test.go b/common/pooll2tx_test.go index ef4e4e3..6c6b148 100644 --- a/common/pooll2tx_test.go +++ b/common/pooll2tx_test.go @@ -68,7 +68,6 @@ func TestTxCompressedData(t *testing.T) { // test vector value generated from javascript implementation assert.Equal(t, "6571340879233176732837827812956721483162819083004853354503", txCompressedData.String()) assert.Equal(t, "10c000000000b0000000a0009000000000008000000000007", hex.EncodeToString(txCompressedData.Bytes())[1:]) - } func TestHashToSign(t *testing.T) { diff --git a/common/smartcontractparams.go b/common/smartcontractparams.go index b91ad22..51ed380 100644 --- a/common/smartcontractparams.go +++ b/common/smartcontractparams.go @@ -16,6 +16,6 @@ type SmartContractParameters struct { ContractAddr ethCommon.Address // Ethereum address of the rollup smart contract NLevels uint16 // Heigth of the SMT. This will determine the maximum number of accounts that can coexist in the Hermez network by 2^nLevels MaxTxs uint16 // Max amount of txs that can be added in a batch, either L1 or L2 - FeeL1Tx *big.Int // amount of eth (in wei) that has to be payed to do a L1 tx - FeeDeposit *big.Int // amount of eth (in wei) that has to be payed to do a deposit + FeeL1Tx *big.Int // amount of eth (in wei) that has to be paid to do a L1 tx + FeeDeposit *big.Int // amount of eth (in wei) that has to be paid to do a deposit } diff --git a/common/syncstate.go b/common/syncstate.go index 5c5d5f4..7ac271d 100644 --- a/common/syncstate.go +++ b/common/syncstate.go @@ -4,7 +4,7 @@ import ( "time" ) -// SyncronizerState describes the syncronization progress of the smart contracts +// SyncronizerState describes the synchronization progress of the smart contracts type SyncronizerState struct { LastUpdate time.Time // last time this information was updated CurrentBatchNum BatchNum // Last batch that was forged on the blockchain diff --git a/common/tx.go b/common/tx.go index a24f408..e045e22 100644 --- a/common/tx.go +++ b/common/tx.go @@ -6,6 +6,12 @@ import ( "math/big" ) +const ( + idxBytesLen = 4 + // maxIdxValue is the maximum value that Idx can have (32 bits: maxIdxValue=2**32-1) + maxIdxValue = 0xffffffff +) + // Idx represents the account Index in the MerkleTree type Idx uint32 @@ -23,7 +29,7 @@ func (idx Idx) BigInt() *big.Int { // IdxFromBytes returns Idx from a byte array func IdxFromBytes(b []byte) (Idx, error) { - if len(b) != 4 { + if len(b) != idxBytesLen { return 0, fmt.Errorf("can not parse Idx, bytes len %d, expected 4", len(b)) } idx := binary.LittleEndian.Uint32(b[:4]) @@ -32,7 +38,7 @@ func IdxFromBytes(b []byte) (Idx, error) { // IdxFromBigInt converts a *big.Int to Idx type func IdxFromBigInt(b *big.Int) (Idx, error) { - if b.Int64() > 0xffffffff { // 2**32-1 + if b.Int64() > maxIdxValue { return 0, ErrNumOverflow } return Idx(uint32(b.Int64())), nil diff --git a/common/tx_test.go b/common/tx_test.go index 4851e5d..bce7ded 100644 --- a/common/tx_test.go +++ b/common/tx_test.go @@ -19,5 +19,4 @@ func TestIdx(t *testing.T) { assert.NotNil(t, err) assert.Equal(t, ErrNumOverflow, err) assert.Equal(t, Idx(0), i) - } diff --git a/coordinator/coordinator.go b/coordinator/coordinator.go index b8310f4..963f95c 100644 --- a/coordinator/coordinator.go +++ b/coordinator/coordinator.go @@ -294,17 +294,14 @@ func (c *Coordinator) isForgeSequence() bool { } func (c *Coordinator) purgeRemoveByTimeout() error { - return nil } func (c *Coordinator) purgeInvalidDueToL2TxsSelection(l2Txs []*common.PoolL2Tx) error { - return nil } func (c *Coordinator) shouldL1L2Batch() bool { - return false } diff --git a/coordinator/proofpool.go b/coordinator/proofpool.go index 7d7d564..5b70aec 100644 --- a/coordinator/proofpool.go +++ b/coordinator/proofpool.go @@ -20,6 +20,5 @@ type ServerProofPool struct { } func (p *ServerProofPool) GetNextAvailable() (*ServerProofInfo, error) { - return nil, nil } diff --git a/db/historydb/historydb.go b/db/historydb/historydb.go index 33f23cf..9a9b249 100644 --- a/db/historydb/historydb.go +++ b/db/historydb/historydb.go @@ -7,7 +7,9 @@ import ( "github.com/hermeznetwork/hermez-node/common" "github.com/hermeznetwork/hermez-node/db" "github.com/jmoiron/sqlx" - _ "github.com/lib/pq" // driver for postgres DB + + //nolint:errcheck // driver for postgres DB + _ "github.com/lib/pq" migrate "github.com/rubenv/sql-migrate" "github.com/russross/meddler" ) diff --git a/db/historydb/historydb_test.go b/db/historydb/historydb_test.go index c662c52..b634918 100644 --- a/db/historydb/historydb_test.go +++ b/db/historydb/historydb_test.go @@ -49,8 +49,8 @@ func TestBlocks(t *testing.T) { // Generate fake blocks blocks := genBlocks(fromBlock, toBlock) // Insert blocks into DB - for _, block := range blocks { - err := historyDB.AddBlock(&block) + for i := 0; i < len(blocks); i++ { + err := historyDB.AddBlock(&blocks[i]) assert.NoError(t, err) } // Get all blocks from DB diff --git a/db/l2db/l2db.go b/db/l2db/l2db.go index 9991437..a60af11 100644 --- a/db/l2db/l2db.go +++ b/db/l2db/l2db.go @@ -10,7 +10,9 @@ import ( "github.com/hermeznetwork/hermez-node/common" "github.com/hermeznetwork/hermez-node/db" "github.com/jmoiron/sqlx" - _ "github.com/lib/pq" // driver for postgres DB + + //nolint:errcheck // driver for postgres DB + _ "github.com/lib/pq" migrate "github.com/rubenv/sql-migrate" "github.com/russross/meddler" ) @@ -26,7 +28,7 @@ type L2DB struct { // NewL2DB creates a L2DB. // More info on how to set dbDialect and dbArgs here: http://gorm.io/docs/connecting_to_the_database.html -// safetyPeriod is the ammount of blockchain blocks that must be waited before deleting anything (to avoid reorg problems). +// safetyPeriod is the amount of blockchain blocks that must be waited before deleting anything (to avoid reorg problems). // maxTxs indicates the desired maximum amount of txs stored on the L2DB. // TTL indicates the maximum amount of time that a tx can be in the L2DB // (to prevent tx that won't ever be forged to stay there, will be used if maxTxs is exceeded). @@ -153,7 +155,7 @@ func (l2db *L2DB) UpdateTxs(txs []*common.PoolL2Tx) error { return nil } -// Reorg updates the state of txs that were updated in a batch that has been discarted due to a blockchian reorg. +// Reorg updates the state of txs that were updated in a batch that has been discarted due to a blockchain reorg. // The state of the affected txs can change form Forged -> Pending or from Invalid -> Pending func (l2db *L2DB) Reorg(lastValidBatch common.BatchNum) error { // TODO: impl diff --git a/db/l2db/l2db_test.go b/db/l2db/l2db_test.go index 3e3cda7..6ae58e9 100644 --- a/db/l2db/l2db_test.go +++ b/db/l2db/l2db_test.go @@ -122,7 +122,7 @@ func TestStartForging(t *testing.T) { func genTxs(n int) []*common.PoolL2Tx { // WARNING: This tx doesn't follow the protocol (signature, txID, ...) - // it's just to test geting/seting from/to the DB. + // it's just to test getting/setting from/to the DB. // Type and RqTxCompressedData: not initialized because it's not stored // on the DB and add noise when checking results. txs := make([]*common.PoolL2Tx, 0, n) diff --git a/db/statedb/statedb_test.go b/db/statedb/statedb_test.go index 39ec264..d850611 100644 --- a/db/statedb/statedb_test.go +++ b/db/statedb/statedb_test.go @@ -32,7 +32,6 @@ func newAccount(t *testing.T, i int) *common.Account { PublicKey: pk, EthAddr: address, } - } func TestStateDBWithoutMT(t *testing.T) { diff --git a/db/statedb/txprocessors.go b/db/statedb/txprocessors.go index 7db03af..0d8b75c 100644 --- a/db/statedb/txprocessors.go +++ b/db/statedb/txprocessors.go @@ -213,7 +213,7 @@ func (s *StateDB) applyDeposit(tx *common.L1Tx, transfer bool) error { if err != nil { return err } - // substract amount to the sender + // subtract amount to the sender accSender.Balance = new(big.Int).Sub(accSender.Balance, tx.Amount) // add amount to the receiver accReceiver.Balance = new(big.Int).Add(accReceiver.Balance, tx.Amount) @@ -247,7 +247,7 @@ func (s *StateDB) applyTransfer(tx *common.Tx) error { // increment nonce accSender.Nonce++ - // substract amount to the sender + // subtract amount to the sender accSender.Balance = new(big.Int).Sub(accSender.Balance, tx.Amount) // add amount to the receiver accReceiver.Balance = new(big.Int).Add(accReceiver.Balance, tx.Amount) @@ -267,7 +267,7 @@ func (s *StateDB) applyTransfer(tx *common.Tx) error { } func (s *StateDB) applyExit(exitTree *merkletree.MerkleTree, tx *common.Tx) (*common.Account, error) { - // 0. substract tx.Amount from current Account in StateMT + // 0. subtract tx.Amount from current Account in StateMT // add the tx.Amount into the Account (tx.FromIdx) in the ExitMT acc, err := s.GetAccount(tx.FromIdx) if err != nil { diff --git a/eth/client.go b/eth/client.go index 5b2e5da..8158a7d 100644 --- a/eth/client.go +++ b/eth/client.go @@ -27,20 +27,45 @@ var ( const ( errStrDeploy = "deployment of %s failed: %w" errStrWaitReceipt = "wait receipt of %s deploy failed: %w" + + // default values + defaultCallGasLimit = 300000 + defaultDeployGasLimit = 1000000 + defaultGasPriceDiv = 100 + defaultReceiptTimeout = 60 + defaultIntervalReceiptLoop = 200 ) +type Config struct { + CallGasLimit uint64 + DeployGasLimit uint64 + GasPriceDiv uint64 + ReceiptTimeout time.Duration // in seconds + IntervalReceiptLoop time.Duration // in milliseconds +} + // Client is an ethereum client to call Smart Contract methods. type Client struct { client *ethclient.Client account *accounts.Account ks *ethKeystore.KeyStore ReceiptTimeout time.Duration + config *Config } // NewClient creates a Client instance. The account is not mandatory (it can // be nil). If the account is nil, CallAuth will fail with ErrAccountNil. -func NewClient(client *ethclient.Client, account *accounts.Account, ks *ethKeystore.KeyStore) *Client { - return &Client{client: client, account: account, ks: ks, ReceiptTimeout: 60 * time.Second} +func NewClient(client *ethclient.Client, account *accounts.Account, ks *ethKeystore.KeyStore, config *Config) *Client { + if config == nil { + config = &Config{ + CallGasLimit: defaultCallGasLimit, + DeployGasLimit: defaultDeployGasLimit, + GasPriceDiv: defaultGasPriceDiv, + ReceiptTimeout: defaultReceiptTimeout, + IntervalReceiptLoop: defaultIntervalReceiptLoop, + } + } + return &Client{client: client, account: account, ks: ks, ReceiptTimeout: config.ReceiptTimeout * time.Second, config: config} } // BalanceAt retieves information about the default account @@ -67,7 +92,7 @@ func (c *Client) CallAuth(gasLimit uint64, return nil, err } inc := new(big.Int).Set(gasPrice) - inc.Div(inc, new(big.Int).SetUint64(100)) + inc.Div(inc, new(big.Int).SetUint64(c.config.GasPriceDiv)) gasPrice.Add(gasPrice, inc) log.Debug("Transaction metadata", "gasPrice", gasPrice) @@ -77,7 +102,7 @@ func (c *Client) CallAuth(gasLimit uint64, } auth.Value = big.NewInt(0) // in wei if gasLimit == 0 { - auth.GasLimit = uint64(300000) // in units + auth.GasLimit = c.config.CallGasLimit // in units } else { auth.GasLimit = gasLimit // in units } @@ -99,14 +124,13 @@ type ContractData struct { // Deploy a smart contract. `name` is used to log deployment information. fn // is a wrapper to the deploy function generated by abigen. In case of error, // the returned `ContractData` may have some parameters filled depending on the -// kind of error that ocurred. -// successfull. +// kind of error that occurred. func (c *Client) Deploy(name string, fn func(c *ethclient.Client, auth *bind.TransactOpts) (ethCommon.Address, *types.Transaction, interface{}, error)) (ContractData, error) { var contractData ContractData log.Info("Deploying", "contract", name) tx, err := c.CallAuth( - 1000000, + c.config.DeployGasLimit, func(client *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) { addr, tx, _, err := fn(client, auth) if err != nil { @@ -162,7 +186,7 @@ func (c *Client) waitReceipt(tx *types.Transaction, ctx context.Context, timeout if receipt != nil || time.Since(start) >= timeout { break } - time.Sleep(200 * time.Millisecond) + time.Sleep(c.config.IntervalReceiptLoop * time.Millisecond) } if receipt != nil && receipt.Status == types.ReceiptStatusFailed { @@ -174,7 +198,7 @@ func (c *Client) waitReceipt(tx *types.Transaction, ctx context.Context, timeout log.Debug("Pendingtransaction / Wait receipt timeout", "tx", txid.Hex(), "lasterr", err) return receipt, ErrReceiptNotReceived } - log.Debug("Successfull transaction", "tx", txid.Hex()) + log.Debug("Successful transaction", "tx", txid.Hex()) return receipt, err } diff --git a/priceupdater/priceupdater.go b/priceupdater/priceupdater.go index 0775a50..c4d5a1d 100644 --- a/priceupdater/priceupdater.go +++ b/priceupdater/priceupdater.go @@ -10,6 +10,11 @@ import ( "github.com/dghubble/sling" ) +const ( + defaultMaxIdleConns = 10 + defaultIdleConnTimeout = 10 +) + var ( // ErrSymbolDoesNotExistInDatabase is used when trying to get a token that is not in the DB ErrSymbolDoesNotExistInDatabase = errors.New("symbol does not exist in database") @@ -39,20 +44,17 @@ type PriceUpdater struct { // NewPriceUpdater is the constructor for the updater func NewPriceUpdater(config ConfigPriceUpdater) PriceUpdater { - return PriceUpdater{ db: make(map[string]TokenInfo), config: config, } - } // UpdatePrices is triggered by the Coordinator, and internally will update the token prices in the db func (p *PriceUpdater) UpdatePrices() error { - tr := &http.Transport{ - MaxIdleConns: 10, - IdleConnTimeout: 10 * time.Second, + MaxIdleConns: defaultMaxIdleConns, + IdleConnTimeout: defaultIdleConnTimeout * time.Second, DisableCompression: true, } httpClient := &http.Client{Transport: tr} @@ -61,12 +63,12 @@ func (p *PriceUpdater) UpdatePrices() error { state := [10]float64{} for _, tokenSymbol := range p.config.TokensList { - resp, err := client.New().Get("ticker/t" + tokenSymbol + "USD").ReceiveSuccess(&state) if err != nil { return err } - if resp.StatusCode != 200 { + // if resp.StatusCode != 200 { + if resp.StatusCode != http.StatusOK { return fmt.Errorf("Unexpected response status code: %v", resp.StatusCode) } @@ -77,7 +79,6 @@ func (p *PriceUpdater) UpdatePrices() error { } p.UpdateTokenInfo(tinfo) - } return nil @@ -85,17 +86,14 @@ func (p *PriceUpdater) UpdatePrices() error { // UpdateConfig allows to update the price-updater configuration func (p *PriceUpdater) UpdateConfig(config ConfigPriceUpdater) { - p.mu.Lock() defer p.mu.Unlock() p.config = config - } // Get one token information func (p *PriceUpdater) Get(tokenSymbol string) (TokenInfo, error) { - var info TokenInfo // Check if symbol exists in database @@ -107,12 +105,10 @@ func (p *PriceUpdater) Get(tokenSymbol string) (TokenInfo, error) { } return info, ErrSymbolDoesNotExistInDatabase - } // GetPrices gets all the prices contained in the db func (p *PriceUpdater) GetPrices() map[string]TokenInfo { - var info = make(map[string]TokenInfo) p.mu.RLock() @@ -127,10 +123,8 @@ func (p *PriceUpdater) GetPrices() map[string]TokenInfo { // UpdateTokenInfo updates one token info func (p *PriceUpdater) UpdateTokenInfo(tokenInfo TokenInfo) { - p.mu.Lock() defer p.mu.Unlock() p.db[tokenInfo.Symbol] = tokenInfo - } diff --git a/priceupdater/priceupdater_test.go b/priceupdater/priceupdater_test.go index 354d62e..5fa0cfb 100644 --- a/priceupdater/priceupdater_test.go +++ b/priceupdater/priceupdater_test.go @@ -7,7 +7,6 @@ import ( ) func TestCon(t *testing.T) { - config := ConfigPriceUpdater{ RecommendedFee: 1, @@ -36,5 +35,4 @@ func TestCon(t *testing.T) { prices := pud.GetPrices() assert.Equal(t, prices["ETH"], info) assert.Equal(t, prices["NEC"], info2) - } diff --git a/test/lang.go b/test/lang.go index a92bbee..d5dace5 100644 --- a/test/lang.go +++ b/test/lang.go @@ -313,7 +313,7 @@ func (p *Parser) parseLine() (*Instruction, error) { c.Literal += line return c, err } - if fee > 255 { + if fee > common.MAXFEEPLAN-1 { line, _ := p.s.r.ReadString('\n') c.Literal += line return c, fmt.Errorf("Fee %d can not be bigger than 255", fee) diff --git a/test/txs.go b/test/txs.go index 49be7ec..9b4d3bb 100644 --- a/test/txs.go +++ b/test/txs.go @@ -143,7 +143,6 @@ func GenerateTestTxs(t *testing.T, instructions Instructions) ([][]*common.L1Tx, default: continue } - } l1Txs = append(l1Txs, batchL1Txs) coordinatorL1Txs = append(coordinatorL1Txs, batchCoordinatorL1Txs) diff --git a/txselector/txselector_test.go b/txselector/txselector_test.go index dffdaf3..e13752d 100644 --- a/txselector/txselector_test.go +++ b/txselector/txselector_test.go @@ -7,7 +7,6 @@ import ( "github.com/hermeznetwork/hermez-node/db/l2db" "github.com/hermeznetwork/hermez-node/db/statedb" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) diff --git a/utils/utils.go b/utils/utils.go index 104a073..c7645a2 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -1,3 +1,4 @@ +//nolint:gomnd package utils import ( @@ -33,9 +34,7 @@ func (fl16 *Float16) BigInt() *big.Int { res := m.Mul(m, exp) if e5 != 0 && e.Cmp(big.NewInt(0)) != 0 { - res.Add(res, exp.Div(exp, big.NewInt(2))) - } return res } @@ -56,11 +55,9 @@ func floorFix2Float(_f *big.Int) Float16 { s := big.NewInt(0).Rsh(m, 10) for s.Cmp(zero) != 0 { - m.Div(m, ten) s.Rsh(m, 10) e++ - } return Float16(m.Int64() | e<<11) @@ -98,13 +95,11 @@ func NewFloat16(f *big.Int) (Float16, error) { d3 := big.NewInt(0).Abs(fi3.Sub(fi3, f)) if d.Cmp(d3) == 1 { - res = fl3 } // Do rounding check if res.BigInt().Cmp(f) == 0 { - return res, nil } return res, ErrRoundingLoss diff --git a/utils/utils_test.go b/utils/utils_test.go index ac05fba..9670e55 100644 --- a/utils/utils_test.go +++ b/utils/utils_test.go @@ -8,7 +8,6 @@ import ( ) func TestConversions(t *testing.T) { - testVector := map[Float16]string{ 0x307B: "123000000", 0x1DC6: "454500", @@ -24,7 +23,6 @@ func TestConversions(t *testing.T) { } for test := range testVector { - fix := test.BigInt() assert.Equal(t, fix.String(), testVector[test]) @@ -37,13 +35,10 @@ func TestConversions(t *testing.T) { fx2 := fl.BigInt() assert.Equal(t, fx2.String(), testVector[test]) - } - } func TestFloorFix2Float(t *testing.T) { - testVector := map[string]Float16{ "87999990000000000": 0x776f, "87950000000000001": 0x776f, @@ -52,16 +47,13 @@ func TestFloorFix2Float(t *testing.T) { } for test := range testVector { - bi := big.NewInt(0) bi.SetString(test, 10) testFloat := NewFloat16Floor(bi) assert.Equal(t, testFloat, testVector[test]) - } - } func TestConversionLosses(t *testing.T) { @@ -94,7 +86,6 @@ func TestConversionLosses(t *testing.T) { assert.Equal(t, ErrRoundingLoss, err) c = b.BigInt() assert.NotEqual(t, c, a) - } func BenchmarkFloat16(b *testing.B) {