mirror of
https://github.com/arnaucube/hermez-node.git
synced 2026-02-07 03:16:45 +01:00
Add abstraction method of processTxs to StateDB
- Update GHA lint.yml increasing timeout time to avoid GHA Lint errors
- Update common.BatchNum & common.Idx & common.Nonce usage in StateDB
- Add abstraction method of processTxs to StateDB
- Which will be used by Synchronizer & BatchBuilder
This commit is contained in:
@@ -17,7 +17,7 @@ const NLEAFELEMS = 4
|
||||
// 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 {
|
||||
TokenID TokenID
|
||||
Nonce uint64 // max of 40 bits used
|
||||
Nonce Nonce // max of 40 bits used
|
||||
Balance *big.Int // max of 192 bits used
|
||||
PublicKey *babyjub.PublicKey
|
||||
EthAddr ethCommon.Address
|
||||
@@ -44,8 +44,10 @@ func (a *Account) Bytes() ([32 * NLEAFELEMS]byte, error) {
|
||||
return b, fmt.Errorf("%s Balance", ErrNumOverflow)
|
||||
}
|
||||
|
||||
var nonceBytes [8]byte
|
||||
binary.LittleEndian.PutUint64(nonceBytes[:], a.Nonce)
|
||||
nonceBytes, err := a.Nonce.Bytes()
|
||||
if err != nil {
|
||||
return b, err
|
||||
}
|
||||
|
||||
copy(b[0:4], a.TokenID.Bytes())
|
||||
copy(b[4:9], nonceBytes[:])
|
||||
@@ -107,9 +109,9 @@ func AccountFromBigInts(e [NLEAFELEMS]*big.Int) (*Account, error) {
|
||||
// AccountFromBytes returns a Account from a byte array
|
||||
func AccountFromBytes(b [32 * NLEAFELEMS]byte) (*Account, error) {
|
||||
tokenID := binary.LittleEndian.Uint32(b[0:4])
|
||||
var nonceBytes [8]byte
|
||||
copy(nonceBytes[:], b[4:9])
|
||||
nonce := binary.LittleEndian.Uint64(nonceBytes[:])
|
||||
var nonceBytes5 [5]byte
|
||||
copy(nonceBytes5[:], b[4:9])
|
||||
nonce := NonceFromBytes(nonceBytes5)
|
||||
sign := b[10] == 1
|
||||
balance := new(big.Int).SetBytes(SwapEndianness(b[32:56])) // b[32:56], as Balance is 192 bits (24 bytes)
|
||||
if !bytes.Equal(b[56:64], []byte{0, 0, 0, 0, 0, 0, 0, 0}) {
|
||||
|
||||
@@ -23,7 +23,7 @@ func TestAccount(t *testing.T) {
|
||||
|
||||
account := &Account{
|
||||
TokenID: TokenID(1),
|
||||
Nonce: uint64(1234),
|
||||
Nonce: Nonce(1234),
|
||||
Balance: big.NewInt(1000),
|
||||
PublicKey: pk,
|
||||
EthAddr: ethCommon.HexToAddress("0xc58d29fA6e86E4FAe04DDcEd660d45BCf3Cb2370"),
|
||||
@@ -66,7 +66,7 @@ func TestAccountLoop(t *testing.T) {
|
||||
|
||||
account := &Account{
|
||||
TokenID: TokenID(i),
|
||||
Nonce: uint64(i),
|
||||
Nonce: Nonce(i),
|
||||
Balance: big.NewInt(1000),
|
||||
PublicKey: pk,
|
||||
EthAddr: address,
|
||||
@@ -98,7 +98,7 @@ func TestAccountHashValue(t *testing.T) {
|
||||
|
||||
account := &Account{
|
||||
TokenID: TokenID(1),
|
||||
Nonce: uint64(1234),
|
||||
Nonce: Nonce(1234),
|
||||
Balance: big.NewInt(1000),
|
||||
PublicKey: pk,
|
||||
EthAddr: ethCommon.HexToAddress("0xc58d29fA6e86E4FAe04DDcEd660d45BCf3Cb2370"),
|
||||
@@ -142,7 +142,7 @@ func TestAccountErrNumOverflowNonce(t *testing.T) {
|
||||
// check limit
|
||||
account := &Account{
|
||||
TokenID: TokenID(1),
|
||||
Nonce: uint64(math.Pow(2, 40) - 1),
|
||||
Nonce: Nonce(math.Pow(2, 40) - 1),
|
||||
Balance: big.NewInt(1000),
|
||||
PublicKey: pk,
|
||||
EthAddr: ethCommon.HexToAddress("0xc58d29fA6e86E4FAe04DDcEd660d45BCf3Cb2370"),
|
||||
@@ -151,7 +151,7 @@ func TestAccountErrNumOverflowNonce(t *testing.T) {
|
||||
assert.Nil(t, err)
|
||||
|
||||
// force value overflow
|
||||
account.Nonce = uint64(math.Pow(2, 40))
|
||||
account.Nonce = Nonce(math.Pow(2, 40))
|
||||
b, err := account.Bytes()
|
||||
assert.NotNil(t, err)
|
||||
assert.Equal(t, fmt.Errorf("%s Nonce", ErrNumOverflow), err)
|
||||
@@ -169,7 +169,7 @@ func TestAccountErrNumOverflowBalance(t *testing.T) {
|
||||
// check limit
|
||||
account := &Account{
|
||||
TokenID: TokenID(1),
|
||||
Nonce: uint64(math.Pow(2, 40) - 1),
|
||||
Nonce: Nonce(math.Pow(2, 40) - 1),
|
||||
Balance: new(big.Int).Sub(new(big.Int).Exp(big.NewInt(2), big.NewInt(192), nil), big.NewInt(1)),
|
||||
PublicKey: pk,
|
||||
EthAddr: ethCommon.HexToAddress("0xc58d29fA6e86E4FAe04DDcEd660d45BCf3Cb2370"),
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"math/big"
|
||||
|
||||
ethCommon "github.com/ethereum/go-ethereum/common"
|
||||
@@ -26,3 +28,19 @@ type Batch struct {
|
||||
|
||||
// BatchNum identifies a batch
|
||||
type BatchNum uint32
|
||||
|
||||
// Bytes returns a byte array of length 4 representing the BatchNum
|
||||
func (bn BatchNum) Bytes() []byte {
|
||||
var batchNumBytes [4]byte
|
||||
binary.LittleEndian.PutUint32(batchNumBytes[:], uint32(bn))
|
||||
return batchNumBytes[:]
|
||||
}
|
||||
|
||||
// BatchNumFromBytes returns BatchNum from a []byte
|
||||
func BatchNumFromBytes(b []byte) (BatchNum, error) {
|
||||
if len(b) != 4 {
|
||||
return 0, fmt.Errorf("can not parse BatchNumFromBytes, bytes len %d, expected 4", len(b))
|
||||
}
|
||||
batchNum := binary.LittleEndian.Uint32(b[:4])
|
||||
return BatchNum(batchNum), nil
|
||||
}
|
||||
|
||||
@@ -31,7 +31,6 @@ func (tx *L1Tx) Tx() *Tx {
|
||||
TxID: tx.TxID,
|
||||
FromIdx: tx.FromIdx,
|
||||
ToIdx: tx.ToIdx,
|
||||
TokenID: tx.TokenID,
|
||||
Amount: tx.Amount,
|
||||
Nonce: 0,
|
||||
Fee: 0,
|
||||
|
||||
@@ -18,3 +18,15 @@ type L2Tx struct {
|
||||
// Extra metadata, may be uninitialized
|
||||
Type TxType `meddler:"-"` // optional, descrives which kind of tx it's
|
||||
}
|
||||
|
||||
func (tx *L2Tx) Tx() *Tx {
|
||||
return &Tx{
|
||||
TxID: tx.TxID,
|
||||
FromIdx: tx.FromIdx,
|
||||
ToIdx: tx.ToIdx,
|
||||
Amount: tx.Amount,
|
||||
Nonce: tx.Nonce,
|
||||
Fee: tx.Fee,
|
||||
Type: tx.Type,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,11 +27,12 @@ func (n Nonce) Bytes() ([5]byte, error) {
|
||||
return b, nil
|
||||
}
|
||||
|
||||
func NonceFromBytes(b [5]byte) (Nonce, error) {
|
||||
// NonceFromBytes returns Nonce from a [5]byte
|
||||
func NonceFromBytes(b [5]byte) Nonce {
|
||||
var nonceBytes [8]byte
|
||||
copy(nonceBytes[:], b[:5])
|
||||
nonce := binary.LittleEndian.Uint64(nonceBytes[:])
|
||||
return Nonce(nonce), nil
|
||||
return Nonce(nonce)
|
||||
}
|
||||
|
||||
// PoolL2Tx is a struct that represents a L2Tx sent by an account to the coordinator hat is waiting to be forged
|
||||
@@ -171,12 +172,24 @@ func (tx *PoolL2Tx) VerifySignature(pk *babyjub.PublicKey) bool {
|
||||
return pk.VerifyPoseidon(h, tx.Signature)
|
||||
}
|
||||
|
||||
func (tx *PoolL2Tx) L2Tx() *L2Tx {
|
||||
return &L2Tx{
|
||||
TxID: tx.TxID,
|
||||
BatchNum: tx.BatchNum,
|
||||
FromIdx: tx.FromIdx,
|
||||
ToIdx: tx.ToIdx,
|
||||
Amount: tx.Amount,
|
||||
Fee: tx.Fee,
|
||||
Nonce: tx.Nonce,
|
||||
Type: tx.Type,
|
||||
}
|
||||
}
|
||||
|
||||
func (tx *PoolL2Tx) Tx() *Tx {
|
||||
return &Tx{
|
||||
TxID: tx.TxID,
|
||||
FromIdx: tx.FromIdx,
|
||||
ToIdx: tx.ToIdx,
|
||||
TokenID: tx.TokenID,
|
||||
Amount: tx.Amount,
|
||||
Nonce: tx.Nonce,
|
||||
Fee: tx.Fee,
|
||||
@@ -184,6 +197,14 @@ func (tx *PoolL2Tx) Tx() *Tx {
|
||||
}
|
||||
}
|
||||
|
||||
func PoolL2TxsToL2Txs(txs []*PoolL2Tx) []*L2Tx {
|
||||
var r []*L2Tx
|
||||
for _, tx := range txs {
|
||||
r = append(r, tx.L2Tx())
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
// PoolL2TxState is a struct that represents the status of a L2 transaction
|
||||
type PoolL2TxState string
|
||||
|
||||
|
||||
@@ -16,8 +16,7 @@ func TestNonceParser(t *testing.T) {
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 5, len(nBytes))
|
||||
assert.Equal(t, "0100000000", hex.EncodeToString(nBytes[:]))
|
||||
n2, err := NonceFromBytes(nBytes)
|
||||
assert.Nil(t, err)
|
||||
n2 := NonceFromBytes(nBytes)
|
||||
assert.Equal(t, n, n2)
|
||||
|
||||
// value before overflow
|
||||
@@ -26,8 +25,7 @@ func TestNonceParser(t *testing.T) {
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 5, len(nBytes))
|
||||
assert.Equal(t, "ffffffffff", hex.EncodeToString(nBytes[:]))
|
||||
n2, err = NonceFromBytes(nBytes)
|
||||
assert.Nil(t, err)
|
||||
n2 = NonceFromBytes(nBytes)
|
||||
assert.Equal(t, n, n2)
|
||||
|
||||
// expect value overflow
|
||||
@@ -35,8 +33,6 @@ func TestNonceParser(t *testing.T) {
|
||||
nBytes, err = n.Bytes()
|
||||
assert.NotNil(t, err)
|
||||
assert.Equal(t, ErrNonceOverflow, err)
|
||||
_, err = NonceFromBytes(nBytes)
|
||||
assert.Nil(t, err)
|
||||
}
|
||||
|
||||
func TestTxCompressedData(t *testing.T) {
|
||||
|
||||
11
common/tx.go
11
common/tx.go
@@ -2,6 +2,7 @@ package common
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"math/big"
|
||||
)
|
||||
|
||||
@@ -20,6 +21,15 @@ func (idx Idx) BigInt() *big.Int {
|
||||
return big.NewInt(int64(idx))
|
||||
}
|
||||
|
||||
// IdxFromBytes returns Idx from a byte array
|
||||
func IdxFromBytes(b []byte) (Idx, error) {
|
||||
if len(b) != 4 {
|
||||
return 0, fmt.Errorf("can not parse Idx, bytes len %d, expected 4", len(b))
|
||||
}
|
||||
idx := binary.LittleEndian.Uint32(b[:4])
|
||||
return Idx(idx), nil
|
||||
}
|
||||
|
||||
// IdxFromBigInt converts a *big.Int to Idx type
|
||||
func IdxFromBigInt(b *big.Int) (Idx, error) {
|
||||
if b.Int64() > 0xffffffff { // 2**32-1
|
||||
@@ -64,7 +74,6 @@ type Tx struct {
|
||||
TxID TxID
|
||||
FromIdx Idx // FromIdx is used by L1Tx/Deposit to indicate the Idx receiver of the L1Tx.LoadAmount (deposit)
|
||||
ToIdx Idx // ToIdx is ignored in L1Tx/Deposit, but used in the L1Tx/DepositTransfer
|
||||
TokenID TokenID
|
||||
Amount *big.Int
|
||||
Nonce Nonce // effective 40 bits used
|
||||
Fee FeeSelector
|
||||
|
||||
@@ -58,3 +58,7 @@ type ZKInputs struct {
|
||||
type CallDataForge struct {
|
||||
// TBD
|
||||
}
|
||||
|
||||
type ExitTreeLeaf struct {
|
||||
// TBD
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user