mirror of
https://github.com/arnaucube/hermez-node.git
synced 2026-02-07 03:16:45 +01:00
Add linter checks to GHA & Fix code to pass lints
Add linter checks to GHA & Fix code to pass lints. The linters added are: - whitespace: Tool for detection of leading and trailing whitespace - gosec: Inspects source code for security problems - gci: Gci control golang package import order and make it always deterministic - misspell: Finds commonly misspelled English words in comments - gomnd: An analyzer to detect magic numbers The file utils/utils.go is excluded from the checks of gomnd, as uses magic numbers through the code
This commit is contained in:
4
.github/workflows/lint.yml
vendored
4
.github/workflows/lint.yml
vendored
@@ -12,5 +12,5 @@ jobs:
|
|||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
- name: Lint
|
- name: Lint
|
||||||
run: |
|
run: |
|
||||||
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.24.0
|
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
|
$(go env GOPATH)/bin/golangci-lint run --timeout=5m -E whitespace -E gosec -E gci -E misspell -E gomnd --max-same-issues 0
|
||||||
|
|||||||
@@ -12,3 +12,10 @@ POSTGRES_PASS=yourpasswordhere; sudo docker run --rm --name hermez-db-test -p 54
|
|||||||
```
|
```
|
||||||
POSTGRES_PASS=yourpasswordhere go test ./...
|
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
|
||||||
|
```
|
||||||
|
|||||||
@@ -12,7 +12,13 @@ import (
|
|||||||
cryptoUtils "github.com/iden3/go-iden3-crypto/utils"
|
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
|
// 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 {
|
type Account struct {
|
||||||
@@ -37,10 +43,10 @@ func (a *Account) String() string {
|
|||||||
func (a *Account) Bytes() ([32 * NLEAFELEMS]byte, error) {
|
func (a *Account) Bytes() ([32 * NLEAFELEMS]byte, error) {
|
||||||
var b [32 * NLEAFELEMS]byte
|
var b [32 * NLEAFELEMS]byte
|
||||||
|
|
||||||
if a.Nonce > 0xffffffffff {
|
if a.Nonce > maxNonceValue {
|
||||||
return b, fmt.Errorf("%s Nonce", ErrNumOverflow)
|
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)
|
return b, fmt.Errorf("%s Balance", ErrNumOverflow)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ import (
|
|||||||
ethCommon "github.com/ethereum/go-ethereum/common"
|
ethCommon "github.com/ethereum/go-ethereum/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const batchNumBytesLen = 4
|
||||||
|
|
||||||
// Batch is a struct that represents Hermez network batch
|
// Batch is a struct that represents Hermez network batch
|
||||||
type Batch struct {
|
type Batch struct {
|
||||||
BatchNum BatchNum `meddler:"batch_num"`
|
BatchNum BatchNum `meddler:"batch_num"`
|
||||||
@@ -33,7 +35,7 @@ func (bn BatchNum) Bytes() []byte {
|
|||||||
|
|
||||||
// BatchNumFromBytes returns BatchNum from a []byte
|
// BatchNumFromBytes returns BatchNum from a []byte
|
||||||
func BatchNumFromBytes(b []byte) (BatchNum, error) {
|
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))
|
return 0, fmt.Errorf("can not parse BatchNumFromBytes, bytes len %d, expected 4", len(b))
|
||||||
}
|
}
|
||||||
batchNum := binary.LittleEndian.Uint32(b[:4])
|
batchNum := binary.LittleEndian.Uint32(b[:4])
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package common
|
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
|
// to incentivaise the materialization of it
|
||||||
type Fee float64
|
type Fee float64
|
||||||
|
|
||||||
@@ -15,5 +15,7 @@ type RecommendedFee struct {
|
|||||||
// FeeSelector is used to select a percentage from the FeePlan.
|
// FeeSelector is used to select a percentage from the FeePlan.
|
||||||
type FeeSelector uint8
|
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
|
// 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{}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ type Nonce uint64
|
|||||||
|
|
||||||
// Bytes returns a byte array of length 5 representing the Nonce
|
// Bytes returns a byte array of length 5 representing the Nonce
|
||||||
func (n Nonce) Bytes() ([5]byte, error) {
|
func (n Nonce) Bytes() ([5]byte, error) {
|
||||||
if n >= 1099511627776 { // 2**40bits
|
if n > maxNonceValue {
|
||||||
return [5]byte{}, ErrNonceOverflow
|
return [5]byte{}, ErrNonceOverflow
|
||||||
}
|
}
|
||||||
var nonceBytes [8]byte
|
var nonceBytes [8]byte
|
||||||
|
|||||||
@@ -68,7 +68,6 @@ func TestTxCompressedData(t *testing.T) {
|
|||||||
// test vector value generated from javascript implementation
|
// test vector value generated from javascript implementation
|
||||||
assert.Equal(t, "6571340879233176732837827812956721483162819083004853354503", txCompressedData.String())
|
assert.Equal(t, "6571340879233176732837827812956721483162819083004853354503", txCompressedData.String())
|
||||||
assert.Equal(t, "10c000000000b0000000a0009000000000008000000000007", hex.EncodeToString(txCompressedData.Bytes())[1:])
|
assert.Equal(t, "10c000000000b0000000a0009000000000008000000000007", hex.EncodeToString(txCompressedData.Bytes())[1:])
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestHashToSign(t *testing.T) {
|
func TestHashToSign(t *testing.T) {
|
||||||
|
|||||||
@@ -16,6 +16,6 @@ type SmartContractParameters struct {
|
|||||||
ContractAddr ethCommon.Address // Ethereum address of the rollup smart contract
|
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
|
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
|
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
|
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 payed to do a deposit
|
FeeDeposit *big.Int // amount of eth (in wei) that has to be paid to do a deposit
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// SyncronizerState describes the syncronization progress of the smart contracts
|
// SyncronizerState describes the synchronization progress of the smart contracts
|
||||||
type SyncronizerState struct {
|
type SyncronizerState struct {
|
||||||
LastUpdate time.Time // last time this information was updated
|
LastUpdate time.Time // last time this information was updated
|
||||||
CurrentBatchNum BatchNum // Last batch that was forged on the blockchain
|
CurrentBatchNum BatchNum // Last batch that was forged on the blockchain
|
||||||
|
|||||||
10
common/tx.go
10
common/tx.go
@@ -6,6 +6,12 @@ import (
|
|||||||
"math/big"
|
"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
|
// Idx represents the account Index in the MerkleTree
|
||||||
type Idx uint32
|
type Idx uint32
|
||||||
|
|
||||||
@@ -23,7 +29,7 @@ func (idx Idx) BigInt() *big.Int {
|
|||||||
|
|
||||||
// IdxFromBytes returns Idx from a byte array
|
// IdxFromBytes returns Idx from a byte array
|
||||||
func IdxFromBytes(b []byte) (Idx, error) {
|
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))
|
return 0, fmt.Errorf("can not parse Idx, bytes len %d, expected 4", len(b))
|
||||||
}
|
}
|
||||||
idx := binary.LittleEndian.Uint32(b[:4])
|
idx := binary.LittleEndian.Uint32(b[:4])
|
||||||
@@ -32,7 +38,7 @@ func IdxFromBytes(b []byte) (Idx, error) {
|
|||||||
|
|
||||||
// IdxFromBigInt converts a *big.Int to Idx type
|
// IdxFromBigInt converts a *big.Int to Idx type
|
||||||
func IdxFromBigInt(b *big.Int) (Idx, error) {
|
func IdxFromBigInt(b *big.Int) (Idx, error) {
|
||||||
if b.Int64() > 0xffffffff { // 2**32-1
|
if b.Int64() > maxIdxValue {
|
||||||
return 0, ErrNumOverflow
|
return 0, ErrNumOverflow
|
||||||
}
|
}
|
||||||
return Idx(uint32(b.Int64())), nil
|
return Idx(uint32(b.Int64())), nil
|
||||||
|
|||||||
@@ -19,5 +19,4 @@ func TestIdx(t *testing.T) {
|
|||||||
assert.NotNil(t, err)
|
assert.NotNil(t, err)
|
||||||
assert.Equal(t, ErrNumOverflow, err)
|
assert.Equal(t, ErrNumOverflow, err)
|
||||||
assert.Equal(t, Idx(0), i)
|
assert.Equal(t, Idx(0), i)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -294,17 +294,14 @@ func (c *Coordinator) isForgeSequence() bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Coordinator) purgeRemoveByTimeout() error {
|
func (c *Coordinator) purgeRemoveByTimeout() error {
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Coordinator) purgeInvalidDueToL2TxsSelection(l2Txs []*common.PoolL2Tx) error {
|
func (c *Coordinator) purgeInvalidDueToL2TxsSelection(l2Txs []*common.PoolL2Tx) error {
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Coordinator) shouldL1L2Batch() bool {
|
func (c *Coordinator) shouldL1L2Batch() bool {
|
||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,5 @@ type ServerProofPool struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *ServerProofPool) GetNextAvailable() (*ServerProofInfo, error) {
|
func (p *ServerProofPool) GetNextAvailable() (*ServerProofInfo, error) {
|
||||||
|
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,9 @@ import (
|
|||||||
"github.com/hermeznetwork/hermez-node/common"
|
"github.com/hermeznetwork/hermez-node/common"
|
||||||
"github.com/hermeznetwork/hermez-node/db"
|
"github.com/hermeznetwork/hermez-node/db"
|
||||||
"github.com/jmoiron/sqlx"
|
"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"
|
migrate "github.com/rubenv/sql-migrate"
|
||||||
"github.com/russross/meddler"
|
"github.com/russross/meddler"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -49,8 +49,8 @@ func TestBlocks(t *testing.T) {
|
|||||||
// Generate fake blocks
|
// Generate fake blocks
|
||||||
blocks := genBlocks(fromBlock, toBlock)
|
blocks := genBlocks(fromBlock, toBlock)
|
||||||
// Insert blocks into DB
|
// Insert blocks into DB
|
||||||
for _, block := range blocks {
|
for i := 0; i < len(blocks); i++ {
|
||||||
err := historyDB.AddBlock(&block)
|
err := historyDB.AddBlock(&blocks[i])
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
}
|
}
|
||||||
// Get all blocks from DB
|
// Get all blocks from DB
|
||||||
|
|||||||
@@ -10,7 +10,9 @@ import (
|
|||||||
"github.com/hermeznetwork/hermez-node/common"
|
"github.com/hermeznetwork/hermez-node/common"
|
||||||
"github.com/hermeznetwork/hermez-node/db"
|
"github.com/hermeznetwork/hermez-node/db"
|
||||||
"github.com/jmoiron/sqlx"
|
"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"
|
migrate "github.com/rubenv/sql-migrate"
|
||||||
"github.com/russross/meddler"
|
"github.com/russross/meddler"
|
||||||
)
|
)
|
||||||
@@ -26,7 +28,7 @@ type L2DB struct {
|
|||||||
|
|
||||||
// NewL2DB creates a L2DB.
|
// NewL2DB creates a L2DB.
|
||||||
// More info on how to set dbDialect and dbArgs here: http://gorm.io/docs/connecting_to_the_database.html
|
// 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.
|
// 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
|
// 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).
|
// (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
|
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
|
// The state of the affected txs can change form Forged -> Pending or from Invalid -> Pending
|
||||||
func (l2db *L2DB) Reorg(lastValidBatch common.BatchNum) error {
|
func (l2db *L2DB) Reorg(lastValidBatch common.BatchNum) error {
|
||||||
// TODO: impl
|
// TODO: impl
|
||||||
|
|||||||
@@ -122,7 +122,7 @@ func TestStartForging(t *testing.T) {
|
|||||||
|
|
||||||
func genTxs(n int) []*common.PoolL2Tx {
|
func genTxs(n int) []*common.PoolL2Tx {
|
||||||
// WARNING: This tx doesn't follow the protocol (signature, txID, ...)
|
// 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
|
// Type and RqTxCompressedData: not initialized because it's not stored
|
||||||
// on the DB and add noise when checking results.
|
// on the DB and add noise when checking results.
|
||||||
txs := make([]*common.PoolL2Tx, 0, n)
|
txs := make([]*common.PoolL2Tx, 0, n)
|
||||||
|
|||||||
@@ -32,7 +32,6 @@ func newAccount(t *testing.T, i int) *common.Account {
|
|||||||
PublicKey: pk,
|
PublicKey: pk,
|
||||||
EthAddr: address,
|
EthAddr: address,
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestStateDBWithoutMT(t *testing.T) {
|
func TestStateDBWithoutMT(t *testing.T) {
|
||||||
|
|||||||
@@ -213,7 +213,7 @@ func (s *StateDB) applyDeposit(tx *common.L1Tx, transfer bool) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// substract amount to the sender
|
// subtract amount to the sender
|
||||||
accSender.Balance = new(big.Int).Sub(accSender.Balance, tx.Amount)
|
accSender.Balance = new(big.Int).Sub(accSender.Balance, tx.Amount)
|
||||||
// add amount to the receiver
|
// add amount to the receiver
|
||||||
accReceiver.Balance = new(big.Int).Add(accReceiver.Balance, tx.Amount)
|
accReceiver.Balance = new(big.Int).Add(accReceiver.Balance, tx.Amount)
|
||||||
@@ -247,7 +247,7 @@ func (s *StateDB) applyTransfer(tx *common.Tx) error {
|
|||||||
// increment nonce
|
// increment nonce
|
||||||
accSender.Nonce++
|
accSender.Nonce++
|
||||||
|
|
||||||
// substract amount to the sender
|
// subtract amount to the sender
|
||||||
accSender.Balance = new(big.Int).Sub(accSender.Balance, tx.Amount)
|
accSender.Balance = new(big.Int).Sub(accSender.Balance, tx.Amount)
|
||||||
// add amount to the receiver
|
// add amount to the receiver
|
||||||
accReceiver.Balance = new(big.Int).Add(accReceiver.Balance, tx.Amount)
|
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) {
|
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
|
// add the tx.Amount into the Account (tx.FromIdx) in the ExitMT
|
||||||
acc, err := s.GetAccount(tx.FromIdx)
|
acc, err := s.GetAccount(tx.FromIdx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -27,20 +27,45 @@ var (
|
|||||||
const (
|
const (
|
||||||
errStrDeploy = "deployment of %s failed: %w"
|
errStrDeploy = "deployment of %s failed: %w"
|
||||||
errStrWaitReceipt = "wait receipt of %s deploy 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.
|
// Client is an ethereum client to call Smart Contract methods.
|
||||||
type Client struct {
|
type Client struct {
|
||||||
client *ethclient.Client
|
client *ethclient.Client
|
||||||
account *accounts.Account
|
account *accounts.Account
|
||||||
ks *ethKeystore.KeyStore
|
ks *ethKeystore.KeyStore
|
||||||
ReceiptTimeout time.Duration
|
ReceiptTimeout time.Duration
|
||||||
|
config *Config
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewClient creates a Client instance. The account is not mandatory (it can
|
// NewClient creates a Client instance. The account is not mandatory (it can
|
||||||
// be nil). If the account is nil, CallAuth will fail with ErrAccountNil.
|
// be nil). If the account is nil, CallAuth will fail with ErrAccountNil.
|
||||||
func NewClient(client *ethclient.Client, account *accounts.Account, ks *ethKeystore.KeyStore) *Client {
|
func NewClient(client *ethclient.Client, account *accounts.Account, ks *ethKeystore.KeyStore, config *Config) *Client {
|
||||||
return &Client{client: client, account: account, ks: ks, ReceiptTimeout: 60 * time.Second}
|
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
|
// BalanceAt retieves information about the default account
|
||||||
@@ -67,7 +92,7 @@ func (c *Client) CallAuth(gasLimit uint64,
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
inc := new(big.Int).Set(gasPrice)
|
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)
|
gasPrice.Add(gasPrice, inc)
|
||||||
log.Debug("Transaction metadata", "gasPrice", gasPrice)
|
log.Debug("Transaction metadata", "gasPrice", gasPrice)
|
||||||
|
|
||||||
@@ -77,7 +102,7 @@ func (c *Client) CallAuth(gasLimit uint64,
|
|||||||
}
|
}
|
||||||
auth.Value = big.NewInt(0) // in wei
|
auth.Value = big.NewInt(0) // in wei
|
||||||
if gasLimit == 0 {
|
if gasLimit == 0 {
|
||||||
auth.GasLimit = uint64(300000) // in units
|
auth.GasLimit = c.config.CallGasLimit // in units
|
||||||
} else {
|
} else {
|
||||||
auth.GasLimit = gasLimit // in units
|
auth.GasLimit = gasLimit // in units
|
||||||
}
|
}
|
||||||
@@ -99,14 +124,13 @@ type ContractData struct {
|
|||||||
// Deploy a smart contract. `name` is used to log deployment information. fn
|
// 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,
|
// 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
|
// the returned `ContractData` may have some parameters filled depending on the
|
||||||
// kind of error that ocurred.
|
// kind of error that occurred.
|
||||||
// successfull.
|
|
||||||
func (c *Client) Deploy(name string,
|
func (c *Client) Deploy(name string,
|
||||||
fn func(c *ethclient.Client, auth *bind.TransactOpts) (ethCommon.Address, *types.Transaction, interface{}, error)) (ContractData, error) {
|
fn func(c *ethclient.Client, auth *bind.TransactOpts) (ethCommon.Address, *types.Transaction, interface{}, error)) (ContractData, error) {
|
||||||
var contractData ContractData
|
var contractData ContractData
|
||||||
log.Info("Deploying", "contract", name)
|
log.Info("Deploying", "contract", name)
|
||||||
tx, err := c.CallAuth(
|
tx, err := c.CallAuth(
|
||||||
1000000,
|
c.config.DeployGasLimit,
|
||||||
func(client *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) {
|
func(client *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) {
|
||||||
addr, tx, _, err := fn(client, auth)
|
addr, tx, _, err := fn(client, auth)
|
||||||
if err != nil {
|
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 {
|
if receipt != nil || time.Since(start) >= timeout {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
time.Sleep(200 * time.Millisecond)
|
time.Sleep(c.config.IntervalReceiptLoop * time.Millisecond)
|
||||||
}
|
}
|
||||||
|
|
||||||
if receipt != nil && receipt.Status == types.ReceiptStatusFailed {
|
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)
|
log.Debug("Pendingtransaction / Wait receipt timeout", "tx", txid.Hex(), "lasterr", err)
|
||||||
return receipt, ErrReceiptNotReceived
|
return receipt, ErrReceiptNotReceived
|
||||||
}
|
}
|
||||||
log.Debug("Successfull transaction", "tx", txid.Hex())
|
log.Debug("Successful transaction", "tx", txid.Hex())
|
||||||
|
|
||||||
return receipt, err
|
return receipt, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,11 @@ import (
|
|||||||
"github.com/dghubble/sling"
|
"github.com/dghubble/sling"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
defaultMaxIdleConns = 10
|
||||||
|
defaultIdleConnTimeout = 10
|
||||||
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// ErrSymbolDoesNotExistInDatabase is used when trying to get a token that is not in the DB
|
// ErrSymbolDoesNotExistInDatabase is used when trying to get a token that is not in the DB
|
||||||
ErrSymbolDoesNotExistInDatabase = errors.New("symbol does not exist in database")
|
ErrSymbolDoesNotExistInDatabase = errors.New("symbol does not exist in database")
|
||||||
@@ -39,20 +44,17 @@ type PriceUpdater struct {
|
|||||||
|
|
||||||
// NewPriceUpdater is the constructor for the updater
|
// NewPriceUpdater is the constructor for the updater
|
||||||
func NewPriceUpdater(config ConfigPriceUpdater) PriceUpdater {
|
func NewPriceUpdater(config ConfigPriceUpdater) PriceUpdater {
|
||||||
|
|
||||||
return PriceUpdater{
|
return PriceUpdater{
|
||||||
db: make(map[string]TokenInfo),
|
db: make(map[string]TokenInfo),
|
||||||
config: config,
|
config: config,
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdatePrices is triggered by the Coordinator, and internally will update the token prices in the db
|
// UpdatePrices is triggered by the Coordinator, and internally will update the token prices in the db
|
||||||
func (p *PriceUpdater) UpdatePrices() error {
|
func (p *PriceUpdater) UpdatePrices() error {
|
||||||
|
|
||||||
tr := &http.Transport{
|
tr := &http.Transport{
|
||||||
MaxIdleConns: 10,
|
MaxIdleConns: defaultMaxIdleConns,
|
||||||
IdleConnTimeout: 10 * time.Second,
|
IdleConnTimeout: defaultIdleConnTimeout * time.Second,
|
||||||
DisableCompression: true,
|
DisableCompression: true,
|
||||||
}
|
}
|
||||||
httpClient := &http.Client{Transport: tr}
|
httpClient := &http.Client{Transport: tr}
|
||||||
@@ -61,12 +63,12 @@ func (p *PriceUpdater) UpdatePrices() error {
|
|||||||
state := [10]float64{}
|
state := [10]float64{}
|
||||||
|
|
||||||
for _, tokenSymbol := range p.config.TokensList {
|
for _, tokenSymbol := range p.config.TokensList {
|
||||||
|
|
||||||
resp, err := client.New().Get("ticker/t" + tokenSymbol + "USD").ReceiveSuccess(&state)
|
resp, err := client.New().Get("ticker/t" + tokenSymbol + "USD").ReceiveSuccess(&state)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
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)
|
return fmt.Errorf("Unexpected response status code: %v", resp.StatusCode)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,7 +79,6 @@ func (p *PriceUpdater) UpdatePrices() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
p.UpdateTokenInfo(tinfo)
|
p.UpdateTokenInfo(tinfo)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@@ -85,17 +86,14 @@ func (p *PriceUpdater) UpdatePrices() error {
|
|||||||
|
|
||||||
// UpdateConfig allows to update the price-updater configuration
|
// UpdateConfig allows to update the price-updater configuration
|
||||||
func (p *PriceUpdater) UpdateConfig(config ConfigPriceUpdater) {
|
func (p *PriceUpdater) UpdateConfig(config ConfigPriceUpdater) {
|
||||||
|
|
||||||
p.mu.Lock()
|
p.mu.Lock()
|
||||||
defer p.mu.Unlock()
|
defer p.mu.Unlock()
|
||||||
|
|
||||||
p.config = config
|
p.config = config
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get one token information
|
// Get one token information
|
||||||
func (p *PriceUpdater) Get(tokenSymbol string) (TokenInfo, error) {
|
func (p *PriceUpdater) Get(tokenSymbol string) (TokenInfo, error) {
|
||||||
|
|
||||||
var info TokenInfo
|
var info TokenInfo
|
||||||
|
|
||||||
// Check if symbol exists in database
|
// Check if symbol exists in database
|
||||||
@@ -107,12 +105,10 @@ func (p *PriceUpdater) Get(tokenSymbol string) (TokenInfo, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return info, ErrSymbolDoesNotExistInDatabase
|
return info, ErrSymbolDoesNotExistInDatabase
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetPrices gets all the prices contained in the db
|
// GetPrices gets all the prices contained in the db
|
||||||
func (p *PriceUpdater) GetPrices() map[string]TokenInfo {
|
func (p *PriceUpdater) GetPrices() map[string]TokenInfo {
|
||||||
|
|
||||||
var info = make(map[string]TokenInfo)
|
var info = make(map[string]TokenInfo)
|
||||||
|
|
||||||
p.mu.RLock()
|
p.mu.RLock()
|
||||||
@@ -127,10 +123,8 @@ func (p *PriceUpdater) GetPrices() map[string]TokenInfo {
|
|||||||
|
|
||||||
// UpdateTokenInfo updates one token info
|
// UpdateTokenInfo updates one token info
|
||||||
func (p *PriceUpdater) UpdateTokenInfo(tokenInfo TokenInfo) {
|
func (p *PriceUpdater) UpdateTokenInfo(tokenInfo TokenInfo) {
|
||||||
|
|
||||||
p.mu.Lock()
|
p.mu.Lock()
|
||||||
defer p.mu.Unlock()
|
defer p.mu.Unlock()
|
||||||
|
|
||||||
p.db[tokenInfo.Symbol] = tokenInfo
|
p.db[tokenInfo.Symbol] = tokenInfo
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestCon(t *testing.T) {
|
func TestCon(t *testing.T) {
|
||||||
|
|
||||||
config := ConfigPriceUpdater{
|
config := ConfigPriceUpdater{
|
||||||
|
|
||||||
RecommendedFee: 1,
|
RecommendedFee: 1,
|
||||||
@@ -36,5 +35,4 @@ func TestCon(t *testing.T) {
|
|||||||
prices := pud.GetPrices()
|
prices := pud.GetPrices()
|
||||||
assert.Equal(t, prices["ETH"], info)
|
assert.Equal(t, prices["ETH"], info)
|
||||||
assert.Equal(t, prices["NEC"], info2)
|
assert.Equal(t, prices["NEC"], info2)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -313,7 +313,7 @@ func (p *Parser) parseLine() (*Instruction, error) {
|
|||||||
c.Literal += line
|
c.Literal += line
|
||||||
return c, err
|
return c, err
|
||||||
}
|
}
|
||||||
if fee > 255 {
|
if fee > common.MAXFEEPLAN-1 {
|
||||||
line, _ := p.s.r.ReadString('\n')
|
line, _ := p.s.r.ReadString('\n')
|
||||||
c.Literal += line
|
c.Literal += line
|
||||||
return c, fmt.Errorf("Fee %d can not be bigger than 255", fee)
|
return c, fmt.Errorf("Fee %d can not be bigger than 255", fee)
|
||||||
|
|||||||
@@ -143,7 +143,6 @@ func GenerateTestTxs(t *testing.T, instructions Instructions) ([][]*common.L1Tx,
|
|||||||
default:
|
default:
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
l1Txs = append(l1Txs, batchL1Txs)
|
l1Txs = append(l1Txs, batchL1Txs)
|
||||||
coordinatorL1Txs = append(coordinatorL1Txs, batchCoordinatorL1Txs)
|
coordinatorL1Txs = append(coordinatorL1Txs, batchCoordinatorL1Txs)
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import (
|
|||||||
|
|
||||||
"github.com/hermeznetwork/hermez-node/db/l2db"
|
"github.com/hermeznetwork/hermez-node/db/l2db"
|
||||||
"github.com/hermeznetwork/hermez-node/db/statedb"
|
"github.com/hermeznetwork/hermez-node/db/statedb"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
//nolint:gomnd
|
||||||
package utils
|
package utils
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -33,9 +34,7 @@ func (fl16 *Float16) BigInt() *big.Int {
|
|||||||
res := m.Mul(m, exp)
|
res := m.Mul(m, exp)
|
||||||
|
|
||||||
if e5 != 0 && e.Cmp(big.NewInt(0)) != 0 {
|
if e5 != 0 && e.Cmp(big.NewInt(0)) != 0 {
|
||||||
|
|
||||||
res.Add(res, exp.Div(exp, big.NewInt(2)))
|
res.Add(res, exp.Div(exp, big.NewInt(2)))
|
||||||
|
|
||||||
}
|
}
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
@@ -56,11 +55,9 @@ func floorFix2Float(_f *big.Int) Float16 {
|
|||||||
s := big.NewInt(0).Rsh(m, 10)
|
s := big.NewInt(0).Rsh(m, 10)
|
||||||
|
|
||||||
for s.Cmp(zero) != 0 {
|
for s.Cmp(zero) != 0 {
|
||||||
|
|
||||||
m.Div(m, ten)
|
m.Div(m, ten)
|
||||||
s.Rsh(m, 10)
|
s.Rsh(m, 10)
|
||||||
e++
|
e++
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Float16(m.Int64() | e<<11)
|
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))
|
d3 := big.NewInt(0).Abs(fi3.Sub(fi3, f))
|
||||||
|
|
||||||
if d.Cmp(d3) == 1 {
|
if d.Cmp(d3) == 1 {
|
||||||
|
|
||||||
res = fl3
|
res = fl3
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do rounding check
|
// Do rounding check
|
||||||
if res.BigInt().Cmp(f) == 0 {
|
if res.BigInt().Cmp(f) == 0 {
|
||||||
|
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
return res, ErrRoundingLoss
|
return res, ErrRoundingLoss
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestConversions(t *testing.T) {
|
func TestConversions(t *testing.T) {
|
||||||
|
|
||||||
testVector := map[Float16]string{
|
testVector := map[Float16]string{
|
||||||
0x307B: "123000000",
|
0x307B: "123000000",
|
||||||
0x1DC6: "454500",
|
0x1DC6: "454500",
|
||||||
@@ -24,7 +23,6 @@ func TestConversions(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for test := range testVector {
|
for test := range testVector {
|
||||||
|
|
||||||
fix := test.BigInt()
|
fix := test.BigInt()
|
||||||
|
|
||||||
assert.Equal(t, fix.String(), testVector[test])
|
assert.Equal(t, fix.String(), testVector[test])
|
||||||
@@ -37,13 +35,10 @@ func TestConversions(t *testing.T) {
|
|||||||
|
|
||||||
fx2 := fl.BigInt()
|
fx2 := fl.BigInt()
|
||||||
assert.Equal(t, fx2.String(), testVector[test])
|
assert.Equal(t, fx2.String(), testVector[test])
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFloorFix2Float(t *testing.T) {
|
func TestFloorFix2Float(t *testing.T) {
|
||||||
|
|
||||||
testVector := map[string]Float16{
|
testVector := map[string]Float16{
|
||||||
"87999990000000000": 0x776f,
|
"87999990000000000": 0x776f,
|
||||||
"87950000000000001": 0x776f,
|
"87950000000000001": 0x776f,
|
||||||
@@ -52,16 +47,13 @@ func TestFloorFix2Float(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for test := range testVector {
|
for test := range testVector {
|
||||||
|
|
||||||
bi := big.NewInt(0)
|
bi := big.NewInt(0)
|
||||||
bi.SetString(test, 10)
|
bi.SetString(test, 10)
|
||||||
|
|
||||||
testFloat := NewFloat16Floor(bi)
|
testFloat := NewFloat16Floor(bi)
|
||||||
|
|
||||||
assert.Equal(t, testFloat, testVector[test])
|
assert.Equal(t, testFloat, testVector[test])
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestConversionLosses(t *testing.T) {
|
func TestConversionLosses(t *testing.T) {
|
||||||
@@ -94,7 +86,6 @@ func TestConversionLosses(t *testing.T) {
|
|||||||
assert.Equal(t, ErrRoundingLoss, err)
|
assert.Equal(t, ErrRoundingLoss, err)
|
||||||
c = b.BigInt()
|
c = b.BigInt()
|
||||||
assert.NotEqual(t, c, a)
|
assert.NotEqual(t, c, a)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkFloat16(b *testing.B) {
|
func BenchmarkFloat16(b *testing.B) {
|
||||||
|
|||||||
Reference in New Issue
Block a user