Browse Source

Add NewFloor40Floor helper method

Also added tracerr.Wrap(...) to missing places.
tmp/txsel-fix
arnaucube 3 years ago
parent
commit
dfd49164f4
9 changed files with 85 additions and 22 deletions
  1. +32
    -7
      common/float40.go
  2. +39
    -1
      common/float40_test.go
  3. +1
    -1
      common/l1tx.go
  4. +3
    -3
      common/tx.go
  5. +5
    -5
      coordinator/pipeline.go
  6. +1
    -1
      coordinator/txmanager.go
  7. +2
    -2
      db/historydb/historydb.go
  8. +1
    -1
      db/kvdb/kvdb.go
  9. +1
    -1
      node/node.go

+ 32
- 7
common/float40.go

@ -32,6 +32,8 @@ var (
// ErrFloat40NotEnoughPrecission is used when the given *big.Int can // ErrFloat40NotEnoughPrecission is used when the given *big.Int can
// not be represented as Float40 due not enough precission // not be represented as Float40 due not enough precission
ErrFloat40NotEnoughPrecission = errors.New("Float40 error, not enough precission") ErrFloat40NotEnoughPrecission = errors.New("Float40 error, not enough precission")
thres = big.NewInt(0x08_00_00_00_00)
) )
// Float40 represents a float in a 64 bit format // Float40 represents a float in a 64 bit format
@ -68,7 +70,7 @@ func (f40 Float40) BigInt() (*big.Int, error) {
var f40Uint64 uint64 = uint64(f40) & 0x00_00_00_FF_FF_FF_FF_FF var f40Uint64 uint64 = uint64(f40) & 0x00_00_00_FF_FF_FF_FF_FF
f40Bytes, err := f40.Bytes() f40Bytes, err := f40.Bytes()
if err != nil { if err != nil {
return nil, err
return nil, tracerr.Wrap(err)
} }
e := f40Bytes[0] & 0xF8 >> 3 // take first 5 bits e := f40Bytes[0] & 0xF8 >> 3 // take first 5 bits
@ -79,25 +81,48 @@ func (f40 Float40) BigInt() (*big.Int, error) {
return r, nil return r, nil
} }
// NewFloat40 encodes a *big.Int integer as a Float40, returning error in case
// of loss during the encoding.
func NewFloat40(f *big.Int) (Float40, error) {
// newFloat40ME takes a *big.Int integer and returns the m (mantissa) & e
// (exponent) from the Float40 representation
func newFloat40ME(f *big.Int) (*big.Int, *big.Int) {
m := f m := f
e := big.NewInt(0) e := big.NewInt(0)
zero := big.NewInt(0) zero := big.NewInt(0)
ten := big.NewInt(10) ten := big.NewInt(10)
thres := big.NewInt(0x08_00_00_00_00)
for new(big.Int).Mod(m, ten).Cmp(zero) == 0 && m.Cmp(thres) >= 0 { for new(big.Int).Mod(m, ten).Cmp(zero) == 0 && m.Cmp(thres) >= 0 {
m = new(big.Int).Div(m, ten) m = new(big.Int).Div(m, ten)
e = new(big.Int).Add(e, big.NewInt(1)) e = new(big.Int).Add(e, big.NewInt(1))
} }
return m, e
}
// NewFloat40 encodes a *big.Int integer as a Float40, returning error in case
// of loss during the encoding.
func NewFloat40(f *big.Int) (Float40, error) {
m, e := newFloat40ME(f)
if e.Int64() > 31 { if e.Int64() > 31 {
return 0, ErrFloat40E31
return 0, tracerr.Wrap(ErrFloat40E31)
} }
if m.Cmp(thres) >= 0 { if m.Cmp(thres) >= 0 {
return 0, ErrFloat40NotEnoughPrecission
return 0, tracerr.Wrap(ErrFloat40NotEnoughPrecission)
} }
r := new(big.Int).Add(m, r := new(big.Int).Add(m,
new(big.Int).Mul(e, thres)) new(big.Int).Mul(e, thres))
return Float40(r.Uint64()), nil return Float40(r.Uint64()), nil
} }
// NewFloat40Floor encodes a *big.Int integer as a Float40, rounding down in
// case of loss during the encoding. It returns an error in case that the number
// is too big (e>31). Warning: this method should not be used inside the
// hermez-node, it's a helper for external usage to generate valid Float40
// values.
func NewFloat40Floor(f *big.Int) (Float40, error) {
m, e := newFloat40ME(f)
if e.Int64() > 31 {
return 0, tracerr.Wrap(ErrFloat40E31)
}
r := new(big.Int).Add(m,
new(big.Int).Mul(e, thres))
return Float40(r.Uint64()), nil
}

+ 39
- 1
common/float40_test.go

@ -4,6 +4,7 @@ import (
"math/big" "math/big"
"testing" "testing"
"github.com/hermeznetwork/tracerr"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
@ -55,7 +56,44 @@ func TestExpectError(t *testing.T) {
bi, ok := new(big.Int).SetString(test, 10) bi, ok := new(big.Int).SetString(test, 10)
require.True(t, ok) require.True(t, ok)
_, err := NewFloat40(bi) _, err := NewFloat40(bi)
assert.Equal(t, testVector[test], err)
assert.Equal(t, testVector[test], tracerr.Unwrap(err))
}
}
func TestNewFloat40Floor(t *testing.T) {
testVector := map[string][]uint64{
// []int contains [Float40 value, Flot40 Floor value], when
// Float40 value is expected to be 0, is because is expected to
// be an error
"9922334455000000000000000000000000000000": {1040714485495, 1040714485495},
"9922334455000000000000000000000000000001": {0, 6846188881046405121},
"9922334454999999999999999999999999999999": {0, 6846188881046405119},
"42949672950000000000000000000000000000000": {1069446856703, 1069446856703},
"99223344556573838487575": {0, 16754928163869896727},
"992233445500000000000000000000000000000000": {0, 0},
"343597383670000000000000000000000000000000": {1099511627775, 1099511627775},
"343597383680000000000000000000000000000000": {0, 1099511627776},
"343597383690000000000000000000000000000000": {0, 1099511627777},
"343597383700000000000000000000000000000000": {0, 0},
}
for test := range testVector {
bi, ok := new(big.Int).SetString(test, 10)
require.True(t, ok)
f40, err := NewFloat40(bi)
if f40 == 0 {
assert.Error(t, err)
} else {
assert.NoError(t, err)
}
assert.Equal(t, testVector[test][0], uint64(f40))
f40, err = NewFloat40Floor(bi)
if f40 == 0 {
assert.Equal(t, ErrFloat40E31, tracerr.Unwrap(err))
} else {
assert.NoError(t, err)
}
assert.Equal(t, testVector[test][1], uint64(f40))
} }
} }

+ 1
- 1
common/l1tx.go

@ -259,7 +259,7 @@ func L1TxFromDataAvailability(b []byte, nLevels uint32) (*L1Tx, error) {
} }
l1tx.ToIdx = toIdx l1tx.ToIdx = toIdx
l1tx.EffectiveAmount, err = Float40FromBytes(amountBytes).BigInt() l1tx.EffectiveAmount, err = Float40FromBytes(amountBytes).BigInt()
return &l1tx, err
return &l1tx, tracerr.Wrap(err)
} }
// BytesGeneric returns the generic representation of a L1Tx. This method is // BytesGeneric returns the generic representation of a L1Tx. This method is

+ 3
- 3
common/tx.go

@ -15,12 +15,12 @@ import (
) )
const ( const (
// TXIDPrefixL1UserTx is the prefix that determines that the TxID is
// for a L1UserTx
// TxIDPrefixL1UserTx is the prefix that determines that the TxID is for
// a L1UserTx
//nolinter:gomnd //nolinter:gomnd
TxIDPrefixL1UserTx = byte(0) TxIDPrefixL1UserTx = byte(0)
// TXIDPrefixL1CoordTx is the prefix that determines that the TxID is
// TxIDPrefixL1CoordTx is the prefix that determines that the TxID is
// for a L1CoordinatorTx // for a L1CoordinatorTx
//nolinter:gomnd //nolinter:gomnd
TxIDPrefixL1CoordTx = byte(1) TxIDPrefixL1CoordTx = byte(1)

+ 5
- 5
coordinator/pipeline.go

@ -210,7 +210,7 @@ func (p *Pipeline) handleForgeBatch(ctx context.Context,
return nil, ctx.Err() return nil, ctx.Err()
} else if err != nil { } else if err != nil {
log.Errorw("proversPool.Get", "err", err) log.Errorw("proversPool.Get", "err", err)
return nil, err
return nil, tracerr.Wrap(err)
} }
defer func() { defer func() {
// If we encounter any error (notice that this function returns // If we encounter any error (notice that this function returns
@ -240,7 +240,7 @@ func (p *Pipeline) handleForgeBatch(ctx context.Context,
} else { } else {
log.Errorw("forgeBatch", "err", err) log.Errorw("forgeBatch", "err", err)
} }
return nil, err
return nil, tracerr.Wrap(err)
} }
// 3. Send the ZKInputs to the proof server // 3. Send the ZKInputs to the proof server
@ -249,7 +249,7 @@ func (p *Pipeline) handleForgeBatch(ctx context.Context,
return nil, ctx.Err() return nil, ctx.Err()
} else if err != nil { } else if err != nil {
log.Errorw("sendServerProof", "err", err) log.Errorw("sendServerProof", "err", err)
return nil, err
return nil, tracerr.Wrap(err)
} }
return batchInfo, nil return batchInfo, nil
} }
@ -427,7 +427,7 @@ func (p *Pipeline) forgeBatch(batchNum common.BatchNum) (batchInfo *BatchInfo, e
// If we haven't reached the ForgeDelay, skip forging the batch // If we haven't reached the ForgeDelay, skip forging the batch
if slotCommitted && now.Sub(p.lastForgeTime) < p.cfg.ForgeDelay { if slotCommitted && now.Sub(p.lastForgeTime) < p.cfg.ForgeDelay {
return nil, errForgeBeforeDelay
return nil, tracerr.Wrap(errForgeBeforeDelay)
} }
// 1. Decide if we forge L2Tx or L1+L2Tx // 1. Decide if we forge L2Tx or L1+L2Tx
@ -485,7 +485,7 @@ func (p *Pipeline) forgeBatch(batchNum common.BatchNum) (batchInfo *BatchInfo, e
if err := p.txSelector.Reset(batchInfo.BatchNum-1, false); err != nil { if err := p.txSelector.Reset(batchInfo.BatchNum-1, false); err != nil {
return nil, tracerr.Wrap(err) return nil, tracerr.Wrap(err)
} }
return nil, errForgeNoTxsBeforeDelay
return nil, tracerr.Wrap(errForgeNoTxsBeforeDelay)
} }
} }

+ 1
- 1
coordinator/txmanager.go

@ -67,7 +67,7 @@ func NewTxManager(ctx context.Context, cfg *Config, ethClient eth.ClientInterfac
} }
accNonce, err := ethClient.EthNonceAt(ctx, *address, nil) accNonce, err := ethClient.EthNonceAt(ctx, *address, nil)
if err != nil { if err != nil {
return nil, err
return nil, tracerr.Wrap(err)
} }
log.Infow("TxManager started", "nonce", accNonce) log.Infow("TxManager started", "nonce", accNonce)
return &TxManager{ return &TxManager{

+ 2
- 2
db/historydb/historydb.go

@ -179,7 +179,7 @@ func (hdb *HistoryDB) GetBatch(batchNum common.BatchNum) (*common.Batch, error)
batch.slot_num, batch.total_fees_usd FROM batch WHERE batch_num = $1;`, batch.slot_num, batch.total_fees_usd FROM batch WHERE batch_num = $1;`,
batchNum, batchNum,
) )
return &batch, err
return &batch, tracerr.Wrap(err)
} }
// GetAllBatches retrieve all batches from the DB // GetAllBatches retrieve all batches from the DB
@ -235,7 +235,7 @@ func (hdb *HistoryDB) GetLastBatch() (*common.Batch, error) {
batch.num_accounts, batch.last_idx, batch.exit_root, batch.forge_l1_txs_num, batch.num_accounts, batch.last_idx, batch.exit_root, batch.forge_l1_txs_num,
batch.slot_num, batch.total_fees_usd FROM batch ORDER BY batch_num DESC LIMIT 1;`, batch.slot_num, batch.total_fees_usd FROM batch ORDER BY batch_num DESC LIMIT 1;`,
) )
return &batch, err
return &batch, tracerr.Wrap(err)
} }
// GetLastL1BatchBlockNum returns the blockNum of the latest forged l1Batch // GetLastL1BatchBlockNum returns the blockNum of the latest forged l1Batch

+ 1
- 1
db/kvdb/kvdb.go

@ -458,7 +458,7 @@ func (k *KVDB) CheckpointExists(batchNum common.BatchNum) (bool, error) {
if _, err := os.Stat(source); os.IsNotExist(err) { if _, err := os.Stat(source); os.IsNotExist(err) {
return false, nil return false, nil
} else if err != nil { } else if err != nil {
return false, err
return false, tracerr.Wrap(err)
} }
return true, nil return true, nil
} }

+ 1
- 1
node/node.go

@ -268,7 +268,7 @@ func NewNode(mode Mode, cfg *config.Node) (*Node, error) {
if err := auth.Sign(func(msg []byte) ([]byte, error) { if err := auth.Sign(func(msg []byte) ([]byte, error) {
return keyStore.SignHash(feeAccount, msg) return keyStore.SignHash(feeAccount, msg)
}, chainIDU16, cfg.SmartContracts.Rollup); err != nil { }, chainIDU16, cfg.SmartContracts.Rollup); err != nil {
return nil, err
return nil, tracerr.Wrap(err)
} }
coordAccount := &txselector.CoordAccount{ coordAccount := &txselector.CoordAccount{
Addr: cfg.Coordinator.FeeAccount.Address, Addr: cfg.Coordinator.FeeAccount.Address,

Loading…
Cancel
Save