Browse Source

Merge pull request #603 from hermeznetwork/feature/update-linter-lll

Add lll to linter checks
tmp/txsel-fix
Eduard S 3 years ago
committed by GitHub
parent
commit
4390fd8346
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
63 changed files with 1571 additions and 758 deletions
  1. +2
    -1
      batchbuilder/batchbuilder.go
  2. +2
    -1
      batchbuilder/batchbuilder_test.go
  3. +4
    -2
      common/account.go
  4. +37
    -15
      common/account_test.go
  5. +5
    -1
      common/accountcreationauths_test.go
  6. +11
    -6
      common/batch.go
  7. +10
    -5
      common/coordinator.go
  8. +4
    -2
      common/ethauction.go
  9. +38
    -22
      common/ethrollup.go
  10. +1
    -0
      common/ethwdelayer.go
  11. +28
    -15
      common/l1tx.go
  12. +15
    -7
      common/l1tx_test.go
  13. +4
    -3
      common/l2tx.go
  14. +14
    -7
      common/l2tx_test.go
  15. +4
    -2
      common/pooll2tx.go
  16. +20
    -9
      common/pooll2tx_test.go
  17. +5
    -3
      common/token.go
  18. +28
    -18
      common/tx.go
  19. +4
    -2
      common/tx_test.go
  20. +12
    -5
      common/utils_test.go
  21. +10
    -6
      common/zk.go
  22. +5
    -3
      coordinator/coordinator.go
  23. +2
    -1
      coordinator/coordinator_test.go
  24. +6
    -3
      coordinator/pipeline.go
  25. +11
    -5
      coordinator/txmanager.go
  26. +14
    -7
      db/statedb/statedb.go
  27. +11
    -5
      db/statedb/statedb_test.go
  28. +18
    -8
      db/statedb/utils.go
  29. +123
    -63
      eth/auction.go
  30. +10
    -5
      eth/auction_test.go
  31. +6
    -3
      eth/client.go
  32. +12
    -6
      eth/ethereum.go
  33. +13
    -6
      eth/helpers.go
  34. +7
    -3
      eth/main_test.go
  35. +113
    -55
      eth/rollup.go
  36. +145
    -69
      eth/rollup_test.go
  37. +57
    -29
      eth/wdelayer.go
  38. +12
    -5
      eth/wdelayer_test.go
  39. +8
    -5
      node/node.go
  40. +4
    -2
      priceupdater/priceupdater.go
  41. +2
    -1
      prover/prover.go
  42. +2
    -1
      synchronizer/synchronizer.go
  43. +8
    -4
      synchronizer/synchronizer_test.go
  44. +2
    -1
      test/debugapi/debugapi_test.go
  45. +89
    -48
      test/ethclient.go
  46. +3
    -1
      test/ethclient_test.go
  47. +27
    -13
      test/historydb.go
  48. +2
    -1
      test/l2db.go
  49. +1
    -0
      test/proofserver/proofserver.go
  50. +14
    -5
      test/til/lang.go
  51. +29
    -10
      test/til/lang_test.go
  52. +42
    -17
      test/til/txs.go
  53. +58
    -33
      test/til/txs_test.go
  54. +2
    -1
      test/txsets/tilsets.go
  55. +35
    -14
      test/txsets/txhelpers.go
  56. +55
    -22
      test/zkproof/flows_test.go
  57. +8
    -4
      test/zkproof/zkproof_test.go
  58. +52
    -22
      txprocessor/txprocessor.go
  59. +52
    -21
      txprocessor/txprocessor_test.go
  60. +3
    -3
      txprocessor/utils.go
  61. +164
    -78
      txprocessor/zkinputsgen_test.go
  62. +16
    -7
      txselector/txselector.go
  63. +70
    -36
      txselector/txselector_test.go

+ 2
- 1
batchbuilder/batchbuilder.go

@ -28,7 +28,8 @@ type ConfigBatch struct {
// NewBatchBuilder constructs a new BatchBuilder, and executes the bb.Reset
// method
func NewBatchBuilder(dbpath string, synchronizerStateDB *statedb.StateDB, batchNum common.BatchNum, nLevels uint64) (*BatchBuilder, error) {
func NewBatchBuilder(dbpath string, synchronizerStateDB *statedb.StateDB, batchNum common.BatchNum,
nLevels uint64) (*BatchBuilder, error) {
localStateDB, err := statedb.NewLocalStateDB(
statedb.Config{
Path: dbpath,

+ 2
- 1
batchbuilder/batchbuilder_test.go

@ -15,7 +15,8 @@ func TestBatchBuilder(t *testing.T) {
require.Nil(t, err)
defer assert.Nil(t, os.RemoveAll(dir))
synchDB, err := statedb.NewStateDB(statedb.Config{Path: dir, Keep: 128, Type: statedb.TypeBatchBuilder, NLevels: 0})
synchDB, err := statedb.NewStateDB(statedb.Config{Path: dir, Keep: 128,
Type: statedb.TypeBatchBuilder, NLevels: 0})
assert.Nil(t, err)
bbDir, err := ioutil.TempDir("", "tmpBatchBuilderDB")

+ 4
- 2
common/account.go

@ -72,7 +72,8 @@ func (idx Idx) BigInt() *big.Int {
// IdxFromBytes returns Idx from a byte array
func IdxFromBytes(b []byte) (Idx, error) {
if len(b) != IdxBytesLen {
return 0, tracerr.Wrap(fmt.Errorf("can not parse Idx, bytes len %d, expected %d", len(b), IdxBytesLen))
return 0, tracerr.Wrap(fmt.Errorf("can not parse Idx, bytes len %d, expected %d",
len(b), IdxBytesLen))
}
var idxBytes [8]byte
copy(idxBytes[2:], b[:])
@ -194,7 +195,8 @@ func (a *Account) BigInts() ([NLeafElems]*big.Int, error) {
return e, nil
}
// HashValue returns the value of the Account, which is the Poseidon hash of its *big.Int representation
// HashValue returns the value of the Account, which is the Poseidon hash of its
// *big.Int representation
func (a *Account) HashValue() (*big.Int, error) {
bi, err := a.BigInts()
if err != nil {

+ 37
- 15
common/account_test.go

@ -76,7 +76,8 @@ func TestNonceParser(t *testing.T) {
func TestAccount(t *testing.T) {
var sk babyjub.PrivateKey
_, err := hex.Decode(sk[:], []byte("0001020304050607080900010203040506070809000102030405060708090001"))
_, err := hex.Decode(sk[:],
[]byte("0001020304050607080900010203040506070809000102030405060708090001"))
assert.NoError(t, err)
pk := sk.Public()
@ -115,7 +116,8 @@ func TestAccountLoop(t *testing.T) {
// check that for different deterministic BabyJubJub keys & random Address there is no problem
for i := 0; i < 256; i++ {
var sk babyjub.PrivateKey
_, err := hex.Decode(sk[:], []byte("0001020304050607080900010203040506070809000102030405060708090001"))
_, err := hex.Decode(sk[:],
[]byte("0001020304050607080900010203040506070809000102030405060708090001"))
assert.NoError(t, err)
pk := sk.Public()
@ -199,7 +201,8 @@ func bigFromStr(h string, u int) *big.Int {
func TestAccountHashValue(t *testing.T) {
var sk babyjub.PrivateKey
_, err := hex.Decode(sk[:], []byte("0001020304050607080900010203040506070809000102030405060708090001"))
_, err := hex.Decode(sk[:],
[]byte("0001020304050607080900010203040506070809000102030405060708090001"))
assert.NoError(t, err)
pk := sk.Public()
@ -212,13 +215,16 @@ func TestAccountHashValue(t *testing.T) {
}
v, err := account.HashValue()
assert.NoError(t, err)
assert.Equal(t, "16297758255249203915951182296472515138555043617458222397753168518282206850764", v.String())
assert.Equal(t,
"16297758255249203915951182296472515138555043617458222397753168518282206850764",
v.String())
}
func TestAccountHashValueTestVectors(t *testing.T) {
// values from js test vectors
ay := new(big.Int).Sub(new(big.Int).Exp(big.NewInt(2), big.NewInt(253), nil), big.NewInt(1))
assert.Equal(t, "1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", (hex.EncodeToString(ay.Bytes())))
assert.Equal(t, "1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
(hex.EncodeToString(ay.Bytes())))
bjjPoint, err := babyjub.PointFromSignAndY(true, ay)
require.NoError(t, err)
bjj := babyjub.PublicKey(*bjjPoint)
@ -236,16 +242,22 @@ func TestAccountHashValueTestVectors(t *testing.T) {
assert.NoError(t, err)
assert.Equal(t, "9444732965739290427391", e[0].String())
assert.Equal(t, "6277101735386680763835789423207666416102355444464034512895", e[1].String())
assert.Equal(t, "14474011154664524427946373126085988481658748083205070504932198000989141204991", e[2].String())
assert.Equal(t,
"14474011154664524427946373126085988481658748083205070504932198000989141204991",
e[2].String())
assert.Equal(t, "1461501637330902918203684832716283019655932542975", e[3].String())
h, err := poseidon.Hash(e[:])
assert.NoError(t, err)
assert.Equal(t, "4550823210217540218403400309533329186487982452461145263910122718498735057257", h.String())
assert.Equal(t,
"4550823210217540218403400309533329186487982452461145263910122718498735057257",
h.String())
v, err := account.HashValue()
assert.NoError(t, err)
assert.Equal(t, "4550823210217540218403400309533329186487982452461145263910122718498735057257", v.String())
assert.Equal(t,
"4550823210217540218403400309533329186487982452461145263910122718498735057257",
v.String())
// second account
ay = big.NewInt(0)
@ -261,7 +273,9 @@ func TestAccountHashValueTestVectors(t *testing.T) {
}
v, err = account.HashValue()
assert.NoError(t, err)
assert.Equal(t, "7750253361301235345986002241352365187241910378619330147114280396816709365657", v.String())
assert.Equal(t,
"7750253361301235345986002241352365187241910378619330147114280396816709365657",
v.String())
// third account
ay = bigFromStr("21b0a1688b37f77b1d1d5539ec3b826db5ac78b2513f574a04c50a7d4f8246d7", 16)
@ -279,11 +293,15 @@ func TestAccountHashValueTestVectors(t *testing.T) {
assert.NoError(t, err)
assert.Equal(t, "554050781187", e[0].String())
assert.Equal(t, "42000000000000000000", e[1].String())
assert.Equal(t, "15238403086306505038849621710779816852318505119327426213168494964113886299863", e[2].String())
assert.Equal(t,
"15238403086306505038849621710779816852318505119327426213168494964113886299863",
e[2].String())
assert.Equal(t, "935037732739828347587684875151694054123613453305", e[3].String())
v, err = account.HashValue()
assert.NoError(t, err)
assert.Equal(t, "10565754214047872850889045989683221123564392137456000481397520902594455245517", v.String())
assert.Equal(t,
"10565754214047872850889045989683221123564392137456000481397520902594455245517",
v.String())
}
func TestAccountErrNotInFF(t *testing.T) {
@ -312,7 +330,8 @@ func TestAccountErrNotInFF(t *testing.T) {
func TestAccountErrNumOverflowNonce(t *testing.T) {
var sk babyjub.PrivateKey
_, err := hex.Decode(sk[:], []byte("0001020304050607080900010203040506070809000102030405060708090001"))
_, err := hex.Decode(sk[:],
[]byte("0001020304050607080900010203040506070809000102030405060708090001"))
assert.NoError(t, err)
pk := sk.Public()
@ -339,7 +358,8 @@ func TestAccountErrNumOverflowNonce(t *testing.T) {
func TestAccountErrNumOverflowBalance(t *testing.T) {
var sk babyjub.PrivateKey
_, err := hex.Decode(sk[:], []byte("0001020304050607080900010203040506070809000102030405060708090001"))
_, err := hex.Decode(sk[:],
[]byte("0001020304050607080900010203040506070809000102030405060708090001"))
assert.NoError(t, err)
pk := sk.Public()
@ -351,14 +371,16 @@ func TestAccountErrNumOverflowBalance(t *testing.T) {
BJJ: pk.Compress(),
EthAddr: ethCommon.HexToAddress("0xc58d29fA6e86E4FAe04DDcEd660d45BCf3Cb2370"),
}
assert.Equal(t, "6277101735386680763835789423207666416102355444464034512895", account.Balance.String())
assert.Equal(t, "6277101735386680763835789423207666416102355444464034512895",
account.Balance.String())
_, err = account.Bytes()
assert.NoError(t, err)
// force value overflow
account.Balance = new(big.Int).Exp(big.NewInt(2), big.NewInt(192), nil)
assert.Equal(t, "6277101735386680763835789423207666416102355444464034512896", account.Balance.String())
assert.Equal(t, "6277101735386680763835789423207666416102355444464034512896",
account.Balance.String())
b, err := account.Bytes()
assert.NotNil(t, err)
assert.Equal(t, fmt.Errorf("%s Balance", ErrNumOverflow), tracerr.Unwrap(err))

+ 5
- 1
common/accountcreationauths_test.go

@ -13,7 +13,8 @@ import (
func TestAccountCreationAuthSignVerify(t *testing.T) {
// Ethereum key
ethSk, err := ethCrypto.HexToECDSA("fad9c8855b740a0b7ed4c221dbad0f33a83a49cad6b3fe8d5817ac83d38b6a19")
ethSk, err :=
ethCrypto.HexToECDSA("fad9c8855b740a0b7ed4c221dbad0f33a83a49cad6b3fe8d5817ac83d38b6a19")
require.NoError(t, err)
ethAddr := ethCrypto.PubkeyToAddress(ethSk.PublicKey)
@ -69,6 +70,7 @@ func TestAccountCreationAuthJSComp(t *testing.T) {
sigExpected string
}
var tvs []testVector
//nolint:lll
tv0 := testVector{
ethSk: "0000000000000000000000000000000000000000000000000000000000000001",
expectedAddress: "0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf",
@ -79,6 +81,7 @@ func TestAccountCreationAuthJSComp(t *testing.T) {
hashExpected: "c56eba41e511df100c804c5c09288f35887efea4f033be956481af335df3bea2",
sigExpected: "dbedcc5ce02db8f48afbdb2feba9a3a31848eaa8fca5f312ce37b01db45d2199208335330d4445bd2f51d1db68dbc0d0bf3585c4a07504b4efbe46a69eaae5a21b",
}
//nolint:lll
tv1 := testVector{
ethSk: "0000000000000000000000000000000000000000000000000000000000000002",
expectedAddress: "0x2B5AD5c4795c026514f8317c7a215E218DcCD6cF",
@ -89,6 +92,7 @@ func TestAccountCreationAuthJSComp(t *testing.T) {
hashExpected: "deb9afa479282cf27b442ce8ba86b19448aa87eacef691521a33db5d0feb9959",
sigExpected: "6a0da90ba2d2b1be679a28ebe54ee03082d44b836087391cd7d2607c1e4dafe04476e6e88dccb8707c68312512f16c947524b35c80f26c642d23953e9bb84c701c",
}
//nolint:lll
tv2 := testVector{
ethSk: "c5e8f61d1ab959b397eecc0a37a6517b8e67a0e7cf1f4bce5591f3ed80199122",
expectedAddress: "0xc783df8a850f42e7F7e57013759C285caa701eB6",

+ 11
- 6
common/batch.go

@ -13,8 +13,9 @@ const batchNumBytesLen = 8
// Batch is a struct that represents Hermez network batch
type Batch struct {
BatchNum BatchNum `meddler:"batch_num"`
EthBlockNum int64 `meddler:"eth_block_num"` // Ethereum block in which the batch is forged
BatchNum BatchNum `meddler:"batch_num"`
// Ethereum block in which the batch is forged
EthBlockNum int64 `meddler:"eth_block_num"`
ForgerAddr ethCommon.Address `meddler:"forger_addr"`
CollectedFees map[TokenID]*big.Int `meddler:"fees_collected,json"`
FeeIdxsCoordinator []Idx `meddler:"fee_idxs_coordinator,json"`
@ -22,9 +23,11 @@ type Batch struct {
NumAccounts int `meddler:"num_accounts"`
LastIdx int64 `meddler:"last_idx"`
ExitRoot *big.Int `meddler:"exit_root,bigint"`
ForgeL1TxsNum *int64 `meddler:"forge_l1_txs_num"` // optional, Only when the batch forges L1 txs. Identifier that corresponds to the group of L1 txs forged in the current batch.
SlotNum int64 `meddler:"slot_num"` // Slot in which the batch is forged
TotalFeesUSD *float64 `meddler:"total_fees_usd"`
// ForgeL1TxsNum is optional, Only when the batch forges L1 txs. Identifier that corresponds
// to the group of L1 txs forged in the current batch.
ForgeL1TxsNum *int64 `meddler:"forge_l1_txs_num"`
SlotNum int64 `meddler:"slot_num"` // Slot in which the batch is forged
TotalFeesUSD *float64 `meddler:"total_fees_usd"`
}
// NewEmptyBatch creates a new empty batch
@ -63,7 +66,9 @@ func (bn BatchNum) BigInt() *big.Int {
// BatchNumFromBytes returns BatchNum from a []byte
func BatchNumFromBytes(b []byte) (BatchNum, error) {
if len(b) != batchNumBytesLen {
return 0, tracerr.Wrap(fmt.Errorf("can not parse BatchNumFromBytes, bytes len %d, expected %d", len(b), batchNumBytesLen))
return 0,
tracerr.Wrap(fmt.Errorf("can not parse BatchNumFromBytes, bytes len %d, expected %d",
len(b), batchNumBytesLen))
}
batchNum := binary.BigEndian.Uint64(b[:batchNumBytesLen])
return BatchNum(batchNum), nil

+ 10
- 5
common/coordinator.go

@ -5,10 +5,15 @@ import (
)
// Coordinator represents a Hermez network coordinator who wins an auction for an specific slot
// WARNING: this is strongly based on the previous implementation, once the new spec is done, this may change a lot.
// WARNING: this is strongly based on the previous implementation, once the new spec is done, this
// may change a lot.
type Coordinator struct {
Bidder ethCommon.Address `meddler:"bidder_addr"` // address of the bidder
Forger ethCommon.Address `meddler:"forger_addr"` // address of the forger
EthBlockNum int64 `meddler:"eth_block_num"` // block in which the coordinator was registered
URL string `meddler:"url"` // URL of the coordinators API
// Bidder is the address of the bidder
Bidder ethCommon.Address `meddler:"bidder_addr"`
// Forger is the address of the forger
Forger ethCommon.Address `meddler:"forger_addr"`
// EthBlockNum is the block in which the coordinator was registered
EthBlockNum int64 `meddler:"eth_block_num"`
// URL of the coordinators API
URL string `meddler:"url"`
}

+ 4
- 2
common/ethauction.go

@ -68,11 +68,13 @@ type AuctionVariables struct {
ClosedAuctionSlots uint16 `meddler:"closed_auction_slots" validate:"required"`
// Distance (#slots) to the farthest slot to which you can bid (30 days = 4320 slots )
OpenAuctionSlots uint16 `meddler:"open_auction_slots" validate:"required"`
// How the HEZ tokens deposited by the slot winner are distributed (Burn: 40% - Donation: 40% - HGT: 20%)
// How the HEZ tokens deposited by the slot winner are distributed (Burn: 40% - Donation:
// 40% - HGT: 20%)
AllocationRatio [3]uint16 `meddler:"allocation_ratio,json" validate:"required"`
// Minimum outbid (percentage) over the previous one to consider it valid
Outbidding uint16 `meddler:"outbidding" validate:"required"`
// Number of blocks at the end of a slot in which any coordinator can forge if the winner has not forged one before
// Number of blocks at the end of a slot in which any coordinator can forge if the winner
// has not forged one before
SlotDeadline uint8 `meddler:"slot_deadline" validate:"required"`
}

+ 38
- 22
common/ethrollup.go

@ -20,19 +20,22 @@ const (
// RollupConstExitIDx IDX 1 is reserved for exits
RollupConstExitIDx = 1
// RollupConstLimitTokens Max number of tokens allowed to be registered inside the rollup
RollupConstLimitTokens = (1 << 32)
// RollupConstL1CoordinatorTotalBytes [4 bytes] token + [32 bytes] babyjub + [65 bytes] compressedSignature
RollupConstLimitTokens = (1 << 32) //nolint:gomnd
// RollupConstL1CoordinatorTotalBytes [4 bytes] token + [32 bytes] babyjub + [65 bytes]
// compressedSignature
RollupConstL1CoordinatorTotalBytes = 101
// RollupConstL1UserTotalBytes [20 bytes] fromEthAddr + [32 bytes] fromBjj-compressed + [6 bytes] fromIdx +
// [5 bytes] depositAmountFloat40 + [5 bytes] amountFloat40 + [4 bytes] tokenId + [6 bytes] toIdx
// RollupConstL1UserTotalBytes [20 bytes] fromEthAddr + [32 bytes] fromBjj-compressed + [6
// bytes] fromIdx + [5 bytes] depositAmountFloat40 + [5 bytes] amountFloat40 + [4 bytes]
// tokenId + [6 bytes] toIdx
RollupConstL1UserTotalBytes = 78
// RollupConstMaxL1UserTx Maximum L1-user transactions allowed to be queued in a batch
RollupConstMaxL1UserTx = 128
// RollupConstMaxL1Tx Maximum L1 transactions allowed to be queued in a batch
RollupConstMaxL1Tx = 256
// RollupConstInputSHAConstantBytes [6 bytes] lastIdx + [6 bytes] newLastIdx + [32 bytes] stateRoot + [32 bytes] newStRoot + [32 bytes] newExitRoot +
// [_MAX_L1_TX * _L1_USER_TOTALBYTES bytes] l1TxsData + totalL2TxsDataLength + feeIdxCoordinatorLength + [2 bytes] chainID =
// 18542 bytes + totalL2TxsDataLength + feeIdxCoordinatorLength
// RollupConstInputSHAConstantBytes [6 bytes] lastIdx + [6 bytes] newLastIdx + [32 bytes]
// stateRoot + [32 bytes] newStRoot + [32 bytes] newExitRoot + [_MAX_L1_TX *
// _L1_USER_TOTALBYTES bytes] l1TxsData + totalL2TxsDataLength + feeIdxCoordinatorLength +
// [2 bytes] chainID = 18542 bytes + totalL2TxsDataLength + feeIdxCoordinatorLength
RollupConstInputSHAConstantBytes = 18546
// RollupConstNumBuckets Number of buckets
RollupConstNumBuckets = 5
@ -44,14 +47,18 @@ const (
var (
// RollupConstLimitDepositAmount Max deposit amount allowed (depositAmount: L1 --> L2)
RollupConstLimitDepositAmount, _ = new(big.Int).SetString("340282366920938463463374607431768211456", 10)
RollupConstLimitDepositAmount, _ = new(big.Int).SetString(
"340282366920938463463374607431768211456", 10)
// RollupConstLimitL2TransferAmount Max amount allowed (amount L2 --> L2)
RollupConstLimitL2TransferAmount, _ = new(big.Int).SetString("6277101735386680763835789423207666416102355444464034512896", 10)
// RollupConstEthAddressInternalOnly This ethereum address is used internally for rollup accounts that don't have ethereum address, only Babyjubjub
// This non-ethereum accounts can be created by the coordinator and allow users to have a rollup
// account without needing an ethereum address
RollupConstEthAddressInternalOnly = ethCommon.HexToAddress("0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF")
RollupConstLimitL2TransferAmount, _ = new(big.Int).SetString(
"6277101735386680763835789423207666416102355444464034512896", 10)
// RollupConstEthAddressInternalOnly This ethereum address is used internally for rollup
// accounts that don't have ethereum address, only Babyjubjub.
// This non-ethereum accounts can be created by the coordinator and allow users to have a
// rollup account without needing an ethereum address
RollupConstEthAddressInternalOnly = ethCommon.HexToAddress(
"0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF")
// RollupConstRfield Modulus zkSNARK
RollupConstRfield, _ = new(big.Int).SetString(
"21888242871839275222246405745257275088548364400416034343698204186575808495617", 10)
@ -63,24 +70,32 @@ var (
// RollupConstRecipientInterfaceHash ERC777 recipient interface hash
RollupConstRecipientInterfaceHash = crypto.Keccak256([]byte("ERC777TokensRecipient"))
// RollupConstPerformL1UserTxSignature the signature of the function that can be called thru an ERC777 `send`
RollupConstPerformL1UserTxSignature = crypto.Keccak256([]byte("addL1Transaction(uint256,uint48,uint16,uint16,uint32,uint48)"))
// RollupConstAddTokenSignature the signature of the function that can be called thru an ERC777 `send`
// RollupConstPerformL1UserTxSignature the signature of the function that can be called thru
// an ERC777 `send`
RollupConstPerformL1UserTxSignature = crypto.Keccak256([]byte(
"addL1Transaction(uint256,uint48,uint16,uint16,uint32,uint48)"))
// RollupConstAddTokenSignature the signature of the function that can be called thru an
// ERC777 `send`
RollupConstAddTokenSignature = crypto.Keccak256([]byte("addToken(address)"))
// RollupConstSendSignature ERC777 Signature
RollupConstSendSignature = crypto.Keccak256([]byte("send(address,uint256,bytes)"))
// RollupConstERC777Granularity ERC777 Signature
RollupConstERC777Granularity = crypto.Keccak256([]byte("granularity()"))
// RollupConstWithdrawalDelayerDeposit This constant are used to deposit tokens from ERC77 tokens into withdrawal delayer
// RollupConstWithdrawalDelayerDeposit This constant are used to deposit tokens from ERC77
// tokens into withdrawal delayer
RollupConstWithdrawalDelayerDeposit = crypto.Keccak256([]byte("deposit(address,address,uint192)"))
// ERC20 signature
// RollupConstTransferSignature This constant is used in the _safeTransfer internal method in order to safe GAS.
// RollupConstTransferSignature This constant is used in the _safeTransfer internal method
// in order to safe GAS.
RollupConstTransferSignature = crypto.Keccak256([]byte("transfer(address,uint256)"))
// RollupConstTransferFromSignature This constant is used in the _safeTransfer internal method in order to safe GAS.
RollupConstTransferFromSignature = crypto.Keccak256([]byte("transferFrom(address,address,uint256)"))
// RollupConstApproveSignature This constant is used in the _safeTransfer internal method in order to safe GAS.
// RollupConstTransferFromSignature This constant is used in the _safeTransfer internal
// method in order to safe GAS.
RollupConstTransferFromSignature = crypto.Keccak256([]byte(
"transferFrom(address,address,uint256)"))
// RollupConstApproveSignature This constant is used in the _safeTransfer internal method in
// order to safe GAS.
RollupConstApproveSignature = crypto.Keccak256([]byte("approve(address,uint256)"))
// RollupConstERC20Signature ERC20 decimals signature
RollupConstERC20Signature = crypto.Keccak256([]byte("decimals()"))
@ -141,6 +156,7 @@ type TokenExchange struct {
}
// RollupVariables are the variables of the Rollup Smart Contract
//nolint:lll
type RollupVariables struct {
EthBlockNum int64 `meddler:"eth_block_num"`
FeeAddToken *big.Int `meddler:"fee_add_token,bigint" validate:"required"`

+ 1
- 0
common/ethwdelayer.go

@ -27,6 +27,7 @@ type WDelayerEscapeHatchWithdrawal struct {
}
// WDelayerVariables are the variables of the Withdrawal Delayer Smart Contract
//nolint:lll
type WDelayerVariables struct {
EthBlockNum int64 `json:"ethereumBlockNum" meddler:"eth_block_num"`
// HermezRollupAddress ethCommon.Address `json:"hermezRollupAddress" meddler:"rollup_address"`

+ 28
- 15
common/l1tx.go

@ -21,25 +21,33 @@ type L1Tx struct {
// where type:
// - L1UserTx: 0
// - L1CoordinatorTx: 1
TxID TxID `meddler:"id"`
ToForgeL1TxsNum *int64 `meddler:"to_forge_l1_txs_num"` // toForgeL1TxsNum in which the tx was forged / will be forged
Position int `meddler:"position"`
UserOrigin bool `meddler:"user_origin"` // true if the tx was originated by a user, false if it was aoriginated by a coordinator. Note that this differ from the spec for implementation simplification purpposes
FromIdx Idx `meddler:"from_idx,zeroisnull"` // FromIdx is used by L1Tx/Deposit to indicate the Idx receiver of the L1Tx.DepositAmount (deposit)
TxID TxID `meddler:"id"`
// ToForgeL1TxsNum indicates in which the tx was forged / will be forged
ToForgeL1TxsNum *int64 `meddler:"to_forge_l1_txs_num"`
Position int `meddler:"position"`
// UserOrigin is set to true if the tx was originated by a user, false if it was
// aoriginated by a coordinator. Note that this differ from the spec for implementation
// simplification purpposes
UserOrigin bool `meddler:"user_origin"`
// FromIdx is used by L1Tx/Deposit to indicate the Idx receiver of the L1Tx.DepositAmount
// (deposit)
FromIdx Idx `meddler:"from_idx,zeroisnull"`
EffectiveFromIdx Idx `meddler:"effective_from_idx,zeroisnull"`
FromEthAddr ethCommon.Address `meddler:"from_eth_addr,zeroisnull"`
FromBJJ babyjub.PublicKeyComp `meddler:"from_bjj,zeroisnull"`
ToIdx Idx `meddler:"to_idx"` // ToIdx is ignored in L1Tx/Deposit, but used in the L1Tx/DepositAndTransfer
TokenID TokenID `meddler:"token_id"`
Amount *big.Int `meddler:"amount,bigint"`
// ToIdx is ignored in L1Tx/Deposit, but used in the L1Tx/DepositAndTransfer
ToIdx Idx `meddler:"to_idx"`
TokenID TokenID `meddler:"token_id"`
Amount *big.Int `meddler:"amount,bigint"`
// EffectiveAmount only applies to L1UserTx.
EffectiveAmount *big.Int `meddler:"effective_amount,bigintnull"`
DepositAmount *big.Int `meddler:"deposit_amount,bigint"`
// EffectiveDepositAmount only applies to L1UserTx.
EffectiveDepositAmount *big.Int `meddler:"effective_deposit_amount,bigintnull"`
EthBlockNum int64 `meddler:"eth_block_num"` // Ethereum Block Number in which this L1Tx was added to the queue
Type TxType `meddler:"type"`
BatchNum *BatchNum `meddler:"batch_num"`
EffectiveDepositAmount *big.Int `meddler:"effective_deposit_amount,bigintnull"`
// Ethereum Block Number in which this L1Tx was added to the queue
EthBlockNum int64 `meddler:"eth_block_num"`
Type TxType `meddler:"type"`
BatchNum *BatchNum `meddler:"batch_num"`
}
// NewL1Tx returns the given L1Tx with the TxId & Type parameters calculated
@ -331,7 +339,9 @@ func (tx *L1Tx) BytesCoordinatorTx(compressedSignatureBytes []byte) ([]byte, err
// L1UserTxFromBytes decodes a L1Tx from []byte
func L1UserTxFromBytes(b []byte) (*L1Tx, error) {
if len(b) != RollupConstL1UserTotalBytes {
return nil, tracerr.Wrap(fmt.Errorf("Can not parse L1Tx bytes, expected length %d, current: %d", 68, len(b)))
return nil,
tracerr.Wrap(fmt.Errorf("Can not parse L1Tx bytes, expected length %d, current: %d",
68, len(b)))
}
tx := &L1Tx{
@ -369,9 +379,12 @@ func L1UserTxFromBytes(b []byte) (*L1Tx, error) {
}
// L1CoordinatorTxFromBytes decodes a L1Tx from []byte
func L1CoordinatorTxFromBytes(b []byte, chainID *big.Int, hermezAddress ethCommon.Address) (*L1Tx, error) {
func L1CoordinatorTxFromBytes(b []byte, chainID *big.Int, hermezAddress ethCommon.Address) (*L1Tx,
error) {
if len(b) != RollupConstL1CoordinatorTotalBytes {
return nil, tracerr.Wrap(fmt.Errorf("Can not parse L1CoordinatorTx bytes, expected length %d, current: %d", 101, len(b)))
return nil, tracerr.Wrap(
fmt.Errorf("Can not parse L1CoordinatorTx bytes, expected length %d, current: %d",
101, len(b)))
}
tx := &L1Tx{

+ 15
- 7
common/l1tx_test.go

@ -29,7 +29,8 @@ func TestNewL1UserTx(t *testing.T) {
}
l1Tx, err := NewL1Tx(l1Tx)
assert.NoError(t, err)
assert.Equal(t, "0x00a6cbae3b8661fb75b0919ca6605a02cfb04d9c6dd16870fa0fcdf01befa32768", l1Tx.TxID.String())
assert.Equal(t, "0x00a6cbae3b8661fb75b0919ca6605a02cfb04d9c6dd16870fa0fcdf01befa32768",
l1Tx.TxID.String())
}
func TestNewL1CoordinatorTx(t *testing.T) {
@ -46,7 +47,8 @@ func TestNewL1CoordinatorTx(t *testing.T) {
}
l1Tx, err := NewL1Tx(l1Tx)
assert.NoError(t, err)
assert.Equal(t, "0x01274482d73df4dab34a1b6740adfca347a462513aa14e82f27b12f818d1b68c84", l1Tx.TxID.String())
assert.Equal(t, "0x01274482d73df4dab34a1b6740adfca347a462513aa14e82f27b12f818d1b68c84",
l1Tx.TxID.String())
}
func TestL1TxCompressedData(t *testing.T) {
@ -199,7 +201,8 @@ func TestL1userTxByteParsers(t *testing.T) {
func TestL1TxByteParsersCompatibility(t *testing.T) {
// Data from compatibility test
var pkComp babyjub.PublicKeyComp
pkCompB, err := hex.DecodeString("0dd02deb2c81068e7a0f7e327df80b4ab79ee1f41a7def613e73a20c32eece5a")
pkCompB, err :=
hex.DecodeString("0dd02deb2c81068e7a0f7e327df80b4ab79ee1f41a7def613e73a20c32eece5a")
require.NoError(t, err)
pkCompL := SwapEndianness(pkCompB)
err = pkComp.UnmarshalText([]byte(hex.EncodeToString(pkCompL)))
@ -220,7 +223,8 @@ func TestL1TxByteParsersCompatibility(t *testing.T) {
encodedData, err := l1Tx.BytesUser()
require.NoError(t, err)
expected := "85dab5b9e2e361d0c208d77be90efcc0439b0a530dd02deb2c81068e7a0f7e327df80b4ab79ee1f41a7def613e73a20c32eece5a000001c638db52540be400459682f0000020039c0000053cb88d"
expected := "85dab5b9e2e361d0c208d77be90efcc0439b0a530dd02deb2c81068e7a0f7e327df80b4ab79e" +
"e1f41a7def613e73a20c32eece5a000001c638db52540be400459682f0000020039c0000053cb88d"
assert.Equal(t, expected, hex.EncodeToString(encodedData))
}
@ -228,7 +232,8 @@ func TestL1CoordinatorTxByteParsers(t *testing.T) {
hermezAddress := ethCommon.HexToAddress("0xD6C850aeBFDC46D7F4c207e445cC0d6B0919BDBe")
chainID := big.NewInt(1337)
privateKey, err := crypto.HexToECDSA("fad9c8855b740a0b7ed4c221dbad0f33a83a49cad6b3fe8d5817ac83d38b6a19")
privateKey, err :=
crypto.HexToECDSA("fad9c8855b740a0b7ed4c221dbad0f33a83a49cad6b3fe8d5817ac83d38b6a19")
require.NoError(t, err)
publicKey := privateKey.Public()
@ -300,7 +305,8 @@ func TestL1CoordinatorTxByteParsersCompatibility(t *testing.T) {
signature = append(signature, v[:]...)
var pkComp babyjub.PublicKeyComp
pkCompB, err := hex.DecodeString("a2c2807ee39c3b3378738cff85a46a9465bb8fcf44ea597c33da9719be7c259c")
pkCompB, err :=
hex.DecodeString("a2c2807ee39c3b3378738cff85a46a9465bb8fcf44ea597c33da9719be7c259c")
require.NoError(t, err)
pkCompL := SwapEndianness(pkCompB)
err = pkComp.UnmarshalText([]byte(hex.EncodeToString(pkCompL)))
@ -315,7 +321,9 @@ func TestL1CoordinatorTxByteParsersCompatibility(t *testing.T) {
encodeData, err := l1Tx.BytesCoordinatorTx(signature)
require.NoError(t, err)
expected, err := utils.HexDecode("1b186d7122ff7f654cfed3156719774898d573900c86599a885a706dbdffe5ea8cda71e5eb097e115405d84d1e7b464009b434b32c014a2df502d1f065ced8bc3ba2c2807ee39c3b3378738cff85a46a9465bb8fcf44ea597c33da9719be7c259c000000e7")
expected, err := utils.HexDecode("1b186d7122ff7f654cfed3156719774898d573900c86599a885a706" +
"dbdffe5ea8cda71e5eb097e115405d84d1e7b464009b434b32c014a2df502d1f065ced8bc3ba2c28" +
"07ee39c3b3378738cff85a46a9465bb8fcf44ea597c33da9719be7c259c000000e7")
require.NoError(t, err)
assert.Equal(t, expected, encodeData)

+ 4
- 3
common/l2tx.go

@ -21,9 +21,10 @@ type L2Tx struct {
Amount *big.Int `meddler:"amount,bigint"`
Fee FeeSelector `meddler:"fee"`
// Nonce is filled by the TxProcessor
Nonce Nonce `meddler:"nonce"`
Type TxType `meddler:"type"`
EthBlockNum int64 `meddler:"eth_block_num"` // EthereumBlockNumber in which this L2Tx was added to the queue
Nonce Nonce `meddler:"nonce"`
Type TxType `meddler:"type"`
// EthBlockNum in which this L2Tx was added to the queue
EthBlockNum int64 `meddler:"eth_block_num"`
}
// NewL2Tx returns the given L2Tx with the TxId & Type parameters calculated

+ 14
- 7
common/l2tx_test.go

@ -19,7 +19,8 @@ func TestNewL2Tx(t *testing.T) {
}
l2Tx, err := NewL2Tx(l2Tx)
assert.NoError(t, err)
assert.Equal(t, "0x022669acda59b827d20ef5354a3eebd1dffb3972b0a6bf89d18bfd2efa0ab9f41e", l2Tx.TxID.String())
assert.Equal(t, "0x022669acda59b827d20ef5354a3eebd1dffb3972b0a6bf89d18bfd2efa0ab9f41e",
l2Tx.TxID.String())
l2Tx = &L2Tx{
FromIdx: 87654,
@ -30,7 +31,8 @@ func TestNewL2Tx(t *testing.T) {
}
l2Tx, err = NewL2Tx(l2Tx)
assert.NoError(t, err)
assert.Equal(t, "0x029e7499a830f8f5eb17c07da48cf91415710f1bcbe0169d363ff91e81faf92fc2", l2Tx.TxID.String())
assert.Equal(t, "0x029e7499a830f8f5eb17c07da48cf91415710f1bcbe0169d363ff91e81faf92fc2",
l2Tx.TxID.String())
l2Tx = &L2Tx{
FromIdx: 87654,
@ -42,7 +44,8 @@ func TestNewL2Tx(t *testing.T) {
}
l2Tx, err = NewL2Tx(l2Tx)
assert.NoError(t, err)
assert.Equal(t, "0x0255c70ed20e1b8935232e1b9c5884dbcc88a6e1a3454d24f2d77252eb2bb0b64e", l2Tx.TxID.String())
assert.Equal(t, "0x0255c70ed20e1b8935232e1b9c5884dbcc88a6e1a3454d24f2d77252eb2bb0b64e",
l2Tx.TxID.String())
l2Tx = &L2Tx{
FromIdx: 87654,
@ -54,7 +57,8 @@ func TestNewL2Tx(t *testing.T) {
}
l2Tx, err = NewL2Tx(l2Tx)
assert.NoError(t, err)
assert.Equal(t, "0x0206b372f967061d1148bbcff679de38120e075141a80a07326d0f514c2efc6ca9", l2Tx.TxID.String())
assert.Equal(t, "0x0206b372f967061d1148bbcff679de38120e075141a80a07326d0f514c2efc6ca9",
l2Tx.TxID.String())
l2Tx = &L2Tx{
FromIdx: 1,
@ -66,7 +70,8 @@ func TestNewL2Tx(t *testing.T) {
}
l2Tx, err = NewL2Tx(l2Tx)
assert.NoError(t, err)
assert.Equal(t, "0x0236f7ea5bccf78ba60baf56c058d235a844f9b09259fd0efa4f5f72a7d4a26618", l2Tx.TxID.String())
assert.Equal(t, "0x0236f7ea5bccf78ba60baf56c058d235a844f9b09259fd0efa4f5f72a7d4a26618",
l2Tx.TxID.String())
l2Tx = &L2Tx{
FromIdx: 999,
@ -78,7 +83,8 @@ func TestNewL2Tx(t *testing.T) {
}
l2Tx, err = NewL2Tx(l2Tx)
assert.NoError(t, err)
assert.Equal(t, "0x02ac122f5b709ce190129fecbbe35bfd30c70e6433dbd85a8eb743d110906a1dc1", l2Tx.TxID.String())
assert.Equal(t, "0x02ac122f5b709ce190129fecbbe35bfd30c70e6433dbd85a8eb743d110906a1dc1",
l2Tx.TxID.String())
l2Tx = &L2Tx{
FromIdx: 4444,
@ -90,7 +96,8 @@ func TestNewL2Tx(t *testing.T) {
}
l2Tx, err = NewL2Tx(l2Tx)
assert.NoError(t, err)
assert.Equal(t, "0x02c674951a81881b7bc50db3b9e5efd97ac88550c7426ac548720e5057cfba515a", l2Tx.TxID.String())
assert.Equal(t, "0x02c674951a81881b7bc50db3b9e5efd97ac88550c7426ac548720e5057cfba515a",
l2Tx.TxID.String())
}
func TestL2TxByteParsers(t *testing.T) {

+ 4
- 2
common/pooll2tx.go

@ -16,7 +16,8 @@ import (
// EmptyBJJComp contains the 32 byte array of a empty BabyJubJub PublicKey
// Compressed. It is a valid point in the BabyJubJub curve, so does not give
// errors when being decompressed.
var EmptyBJJComp = babyjub.PublicKeyComp([32]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0})
var EmptyBJJComp = babyjub.PublicKeyComp([32]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0})
// PoolL2Tx is a struct that represents a L2Tx sent by an account to the
// coordinator that is waiting to be forged
@ -318,7 +319,8 @@ func (tx *PoolL2Tx) HashToSign(chainID uint16) (*big.Int, error) {
_, rqToBJJY := babyjub.UnpackSignY(tx.RqToBJJ)
return poseidon.Hash([]*big.Int{toCompressedData, e1, toBJJY, rqTxCompressedDataV2, rqToEthAddr, rqToBJJY})
return poseidon.Hash([]*big.Int{toCompressedData, e1, toBJJY, rqTxCompressedDataV2,
rqToEthAddr, rqToBJJY})
}
// VerifySignature returns true if the signature verification is correct for the given PublicKeyComp

+ 20
- 9
common/pooll2tx_test.go

@ -21,17 +21,20 @@ func TestNewPoolL2Tx(t *testing.T) {
}
poolL2Tx, err := NewPoolL2Tx(poolL2Tx)
assert.NoError(t, err)
assert.Equal(t, "0x022669acda59b827d20ef5354a3eebd1dffb3972b0a6bf89d18bfd2efa0ab9f41e", poolL2Tx.TxID.String())
assert.Equal(t, "0x022669acda59b827d20ef5354a3eebd1dffb3972b0a6bf89d18bfd2efa0ab9f41e",
poolL2Tx.TxID.String())
}
func TestTxCompressedDataAndTxCompressedDataV2JSVectors(t *testing.T) {
// test vectors values generated from javascript implementation
var skPositive babyjub.PrivateKey // 'Positive' refers to the sign
_, err := hex.Decode(skPositive[:], []byte("0001020304050607080900010203040506070809000102030405060708090001"))
_, err := hex.Decode(skPositive[:],
[]byte("0001020304050607080900010203040506070809000102030405060708090001"))
assert.NoError(t, err)
var skNegative babyjub.PrivateKey // 'Negative' refers to the sign
_, err = hex.Decode(skNegative[:], []byte("0001020304050607080900010203040506070809000102030405060708090002"))
_, err = hex.Decode(skNegative[:],
[]byte("0001020304050607080900010203040506070809000102030405060708090002"))
assert.NoError(t, err)
amount, ok := new(big.Int).SetString("343597383670000000000000000000000000000000", 10)
@ -123,7 +126,8 @@ func TestTxCompressedDataAndTxCompressedDataV2JSVectors(t *testing.T) {
func TestRqTxCompressedDataV2(t *testing.T) {
var sk babyjub.PrivateKey
_, err := hex.Decode(sk[:], []byte("0001020304050607080900010203040506070809000102030405060708090001"))
_, err := hex.Decode(sk[:],
[]byte("0001020304050607080900010203040506070809000102030405060708090001"))
assert.NoError(t, err)
tx := PoolL2Tx{
RqFromIdx: 7,
@ -142,7 +146,8 @@ func TestRqTxCompressedDataV2(t *testing.T) {
expected, ok := new(big.Int).SetString(expectedStr, 10)
assert.True(t, ok)
assert.Equal(t, expected.Bytes(), txCompressedData.Bytes())
assert.Equal(t, "010c000000000b0000000a0000000009000000000008000000000007", hex.EncodeToString(txCompressedData.Bytes()))
assert.Equal(t, "010c000000000b0000000a0000000009000000000008000000000007",
hex.EncodeToString(txCompressedData.Bytes()))
}
func TestHashToSign(t *testing.T) {
@ -157,13 +162,15 @@ func TestHashToSign(t *testing.T) {
}
toSign, err := tx.HashToSign(chainID)
assert.NoError(t, err)
assert.Equal(t, "2d49ce1d4136e06f64e3eb1f79a346e6ee3e93ceeac909a57806a8d87005c263", hex.EncodeToString(toSign.Bytes()))
assert.Equal(t, "2d49ce1d4136e06f64e3eb1f79a346e6ee3e93ceeac909a57806a8d87005c263",
hex.EncodeToString(toSign.Bytes()))
}
func TestVerifyTxSignature(t *testing.T) {
chainID := uint16(0)
var sk babyjub.PrivateKey
_, err := hex.Decode(sk[:], []byte("0001020304050607080900010203040506070809000102030405060708090001"))
_, err := hex.Decode(sk[:],
[]byte("0001020304050607080900010203040506070809000102030405060708090001"))
assert.NoError(t, err)
tx := PoolL2Tx{
FromIdx: 2,
@ -177,7 +184,9 @@ func TestVerifyTxSignature(t *testing.T) {
}
toSign, err := tx.HashToSign(chainID)
assert.NoError(t, err)
assert.Equal(t, "1571327027383224465388301747239444557034990637650927918405777653988509342917", toSign.String())
assert.Equal(t,
"1571327027383224465388301747239444557034990637650927918405777653988509342917",
toSign.String())
sig := sk.SignPoseidon(toSign)
tx.Signature = sig.Compress()
@ -188,7 +197,9 @@ func TestDecompressEmptyBJJComp(t *testing.T) {
pkComp := EmptyBJJComp
pk, err := pkComp.Decompress()
require.NoError(t, err)
assert.Equal(t, "2957874849018779266517920829765869116077630550401372566248359756137677864698", pk.X.String())
assert.Equal(t,
"2957874849018779266517920829765869116077630550401372566248359756137677864698",
pk.X.String())
assert.Equal(t, "0", pk.Y.String())
}

+ 5
- 3
common/token.go

@ -15,8 +15,9 @@ const tokenIDBytesLen = 4
// Token is a struct that represents an Ethereum token that is supported in Hermez network
type Token struct {
TokenID TokenID `json:"id" meddler:"token_id"`
EthBlockNum int64 `json:"ethereumBlockNum" meddler:"eth_block_num"` // Ethereum block number in which this token was registered
TokenID TokenID `json:"id" meddler:"token_id"`
// EthBlockNum indicates the Ethereum block number in which this token was registered
EthBlockNum int64 `json:"ethereumBlockNum" meddler:"eth_block_num"`
EthAddr ethCommon.Address `json:"ethereumAddress" meddler:"eth_addr"`
Name string `json:"name" meddler:"name"`
Symbol string `json:"symbol" meddler:"symbol"`
@ -48,7 +49,8 @@ func (t TokenID) BigInt() *big.Int {
// TokenIDFromBytes returns TokenID from a byte array
func TokenIDFromBytes(b []byte) (TokenID, error) {
if len(b) != tokenIDBytesLen {
return 0, tracerr.Wrap(fmt.Errorf("can not parse TokenID, bytes len %d, expected 4", len(b)))
return 0, tracerr.Wrap(fmt.Errorf("can not parse TokenID, bytes len %d, expected 4",
len(b)))
}
tid := binary.BigEndian.Uint32(b[:4])
return TokenID(tid), nil

+ 28
- 18
common/tx.go

@ -51,7 +51,8 @@ func (txid *TxID) Scan(src interface{}) error {
return tracerr.Wrap(fmt.Errorf("can't scan %T into TxID", src))
}
if len(srcB) != TxIDLen {
return tracerr.Wrap(fmt.Errorf("can't scan []byte of len %d into TxID, need %d", len(srcB), TxIDLen))
return tracerr.Wrap(fmt.Errorf("can't scan []byte of len %d into TxID, need %d",
len(srcB), TxIDLen))
}
copy(txid[:], srcB)
return nil
@ -102,13 +103,15 @@ func (txid *TxID) UnmarshalText(data []byte) error {
type TxType string
const (
// TxTypeExit represents L2->L1 token transfer. A leaf for this account appears in the exit tree of the block
// TxTypeExit represents L2->L1 token transfer. A leaf for this account appears in the exit
// tree of the block
TxTypeExit TxType = "Exit"
// TxTypeTransfer represents L2->L2 token transfer
TxTypeTransfer TxType = "Transfer"
// TxTypeDeposit represents L1->L2 transfer
TxTypeDeposit TxType = "Deposit"
// TxTypeCreateAccountDeposit represents creation of a new leaf in the state tree (newAcconut) + L1->L2 transfer
// TxTypeCreateAccountDeposit represents creation of a new leaf in the state tree
// (newAcconut) + L1->L2 transfer
TxTypeCreateAccountDeposit TxType = "CreateAccountDeposit"
// TxTypeCreateAccountDepositTransfer represents L1->L2 transfer + L2->L2 transfer
TxTypeCreateAccountDepositTransfer TxType = "CreateAccountDepositTransfer"
@ -124,24 +127,31 @@ const (
TxTypeTransferToBJJ TxType = "TransferToBJJ"
)
// Tx is a struct used by the TxSelector & BatchBuilder as a generic type generated from L1Tx & PoolL2Tx
// Tx is a struct used by the TxSelector & BatchBuilder as a generic type generated from L1Tx &
// PoolL2Tx
type Tx struct {
// Generic
IsL1 bool `meddler:"is_l1"`
TxID TxID `meddler:"id"`
Type TxType `meddler:"type"`
Position int `meddler:"position"`
FromIdx Idx `meddler:"from_idx"`
ToIdx Idx `meddler:"to_idx"`
Amount *big.Int `meddler:"amount,bigint"`
AmountFloat float64 `meddler:"amount_f"`
TokenID TokenID `meddler:"token_id"`
USD *float64 `meddler:"amount_usd"`
BatchNum *BatchNum `meddler:"batch_num"` // batchNum in which this tx was forged. If the tx is L2, this must be != 0
EthBlockNum int64 `meddler:"eth_block_num"` // Ethereum Block Number in which this L1Tx was added to the queue
IsL1 bool `meddler:"is_l1"`
TxID TxID `meddler:"id"`
Type TxType `meddler:"type"`
Position int `meddler:"position"`
FromIdx Idx `meddler:"from_idx"`
ToIdx Idx `meddler:"to_idx"`
Amount *big.Int `meddler:"amount,bigint"`
AmountFloat float64 `meddler:"amount_f"`
TokenID TokenID `meddler:"token_id"`
USD *float64 `meddler:"amount_usd"`
// BatchNum in which this tx was forged. If the tx is L2, this must be != 0
BatchNum *BatchNum `meddler:"batch_num"`
// Ethereum Block Number in which this L1Tx was added to the queue
EthBlockNum int64 `meddler:"eth_block_num"`
// L1
ToForgeL1TxsNum *int64 `meddler:"to_forge_l1_txs_num"` // toForgeL1TxsNum in which the tx was forged / will be forged
UserOrigin *bool `meddler:"user_origin"` // true if the tx was originated by a user, false if it was aoriginated by a coordinator. Note that this differ from the spec for implementation simplification purpposes
// ToForgeL1TxsNum in which the tx was forged / will be forged
ToForgeL1TxsNum *int64 `meddler:"to_forge_l1_txs_num"`
// UserOrigin is set to true if the tx was originated by a user, false if it was aoriginated
// by a coordinator. Note that this differ from the spec for implementation simplification
// purpposes
UserOrigin *bool `meddler:"user_origin"`
FromEthAddr ethCommon.Address `meddler:"from_eth_addr"`
FromBJJ babyjub.PublicKeyComp `meddler:"from_bjj"`
DepositAmount *big.Int `meddler:"deposit_amount,bigintnull"`

+ 4
- 2
common/tx_test.go

@ -21,8 +21,10 @@ func TestSignatureConstant(t *testing.T) {
func TestTxIDScannerValue(t *testing.T) {
txid0 := &TxID{}
txid1 := &TxID{}
txid0B := [TxIDLen]byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2}
txid1B := [TxIDLen]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
txid0B := [TxIDLen]byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2,
3, 4, 5, 6, 7, 8, 9, 0, 1, 2}
txid1B := [TxIDLen]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
copy(txid0[:], txid0B[:])
copy(txid1[:], txid1B[:])

+ 12
- 5
common/utils_test.go

@ -21,16 +21,23 @@ func TestBJJFromStringWithChecksum(t *testing.T) {
assert.NoError(t, err)
// expected values computed with js implementation
assert.Equal(t, "2492816973395423007340226948038371729989170225696553239457870892535792679622", pk.X.String())
assert.Equal(t, "15238403086306505038849621710779816852318505119327426213168494964113886299863", pk.Y.String())
assert.Equal(t,
"2492816973395423007340226948038371729989170225696553239457870892535792679622",
pk.X.String())
assert.Equal(t,
"15238403086306505038849621710779816852318505119327426213168494964113886299863",
pk.Y.String())
}
func TestRmEndingZeroes(t *testing.T) {
s0, err := merkletree.NewHashFromHex("0x0000000000000000000000000000000000000000000000000000000000000000")
s0, err :=
merkletree.NewHashFromHex("0x0000000000000000000000000000000000000000000000000000000000000000")
require.NoError(t, err)
s1, err := merkletree.NewHashFromHex("0x0000000000000000000000000000000000000000000000000000000000000001")
s1, err :=
merkletree.NewHashFromHex("0x0000000000000000000000000000000000000000000000000000000000000001")
require.NoError(t, err)
s2, err := merkletree.NewHashFromHex("0x0000000000000000000000000000000000000000000000000000000000000002")
s2, err :=
merkletree.NewHashFromHex("0x0000000000000000000000000000000000000000000000000000000000000002")
require.NoError(t, err)
// expect cropped last zeroes

+ 10
- 6
common/zk.go

@ -130,8 +130,8 @@ type ZKInputs struct {
RqOffset []*big.Int `json:"rqOffset"` // uint8 (max 3 bits), len: [maxTx]
// transaction L2 request data
// RqTxCompressedDataV2
RqTxCompressedDataV2 []*big.Int `json:"rqTxCompressedDataV2"` // big.Int (max 251 bits), len: [maxTx]
// RqTxCompressedDataV2 big.Int (max 251 bits), len: [maxTx]
RqTxCompressedDataV2 []*big.Int `json:"rqTxCompressedDataV2"`
// RqToEthAddr
RqToEthAddr []*big.Int `json:"rqToEthAddr"` // ethCommon.Address, len: [maxTx]
// RqToBJJAy
@ -301,7 +301,8 @@ func (z ZKInputs) MarshalJSON() ([]byte, error) {
}
// NewZKInputs returns a pointer to an initialized struct of ZKInputs
func NewZKInputs(chainID uint16, maxTx, maxL1Tx, maxFeeIdxs, nLevels uint32, currentNumBatch *big.Int) *ZKInputs {
func NewZKInputs(chainID uint16, maxTx, maxL1Tx, maxFeeIdxs, nLevels uint32,
currentNumBatch *big.Int) *ZKInputs {
zki := &ZKInputs{}
zki.Metadata.MaxFeeIdxs = maxFeeIdxs
zki.Metadata.MaxLevels = uint32(48) //nolint:gomnd
@ -480,7 +481,7 @@ func (z ZKInputs) ToHashGlobalData() ([]byte, error) {
b = append(b, newExitRoot...)
// [MAX_L1_TX * (2 * MAX_NLEVELS + 528) bits] L1TxsData
l1TxDataLen := (2*z.Metadata.MaxLevels + 528)
l1TxDataLen := (2*z.Metadata.MaxLevels + 528) //nolint:gomnd
l1TxsDataLen := (z.Metadata.MaxL1Tx * l1TxDataLen)
l1TxsData := make([]byte, l1TxsDataLen/8) //nolint:gomnd
for i := 0; i < len(z.Metadata.L1TxsData); i++ {
@ -506,11 +507,14 @@ func (z ZKInputs) ToHashGlobalData() ([]byte, error) {
l2TxsData = append(l2TxsData, z.Metadata.L2TxsData[i]...)
}
if len(l2TxsData) > int(expectedL2TxsDataLen) {
return nil, tracerr.Wrap(fmt.Errorf("len(l2TxsData): %d, expected: %d", len(l2TxsData), expectedL2TxsDataLen))
return nil, tracerr.Wrap(fmt.Errorf("len(l2TxsData): %d, expected: %d",
len(l2TxsData), expectedL2TxsDataLen))
}
b = append(b, l2TxsData...)
l2TxsPadding := make([]byte, (int(z.Metadata.MaxTx)-len(z.Metadata.L1TxsDataAvailability)-len(z.Metadata.L2TxsData))*int(l2TxDataLen)/8) //nolint:gomnd
l2TxsPadding := make([]byte,
(int(z.Metadata.MaxTx)-len(z.Metadata.L1TxsDataAvailability)-
len(z.Metadata.L2TxsData))*int(l2TxDataLen)/8) //nolint:gomnd
b = append(b, l2TxsPadding...)
// [NLevels * MAX_TOKENS_FEE bits] feeTxsData

+ 5
- 3
coordinator/coordinator.go

@ -25,8 +25,9 @@ import (
var (
errLastL1BatchNotSynced = fmt.Errorf("last L1Batch not synced yet")
errForgeNoTxsBeforeDelay = fmt.Errorf("no txs to forge and we haven't reached the forge no txs delay")
errForgeBeforeDelay = fmt.Errorf("we haven't reached the forge delay")
errForgeNoTxsBeforeDelay = fmt.Errorf(
"no txs to forge and we haven't reached the forge no txs delay")
errForgeBeforeDelay = fmt.Errorf("we haven't reached the forge delay")
)
const (
@ -473,7 +474,8 @@ func (c *Coordinator) handleReorg(ctx context.Context, msg *MsgSyncReorg) error
// handleStopPipeline handles stopping the pipeline. If failedBatchNum is 0,
// the next pipeline will start from the last state of the synchronizer,
// otherwise, it will state from failedBatchNum-1.
func (c *Coordinator) handleStopPipeline(ctx context.Context, reason string, failedBatchNum common.BatchNum) error {
func (c *Coordinator) handleStopPipeline(ctx context.Context, reason string,
failedBatchNum common.BatchNum) error {
batchNum := c.stats.Sync.LastBatch.BatchNum
if failedBatchNum != 0 {
batchNum = failedBatchNum - 1

+ 2
- 1
coordinator/coordinator_test.go

@ -126,7 +126,8 @@ func newTestModules(t *testing.T) modules {
batchBuilderDBPath, err = ioutil.TempDir("", "tmpBatchBuilderDB")
require.NoError(t, err)
deleteme = append(deleteme, batchBuilderDBPath)
batchBuilder, err := batchbuilder.NewBatchBuilder(batchBuilderDBPath, syncStateDB, 0, uint64(nLevels))
batchBuilder, err := batchbuilder.NewBatchBuilder(batchBuilderDBPath, syncStateDB, 0,
uint64(nLevels))
assert.NoError(t, err)
return modules{

+ 6
- 3
coordinator/pipeline.go

@ -124,7 +124,8 @@ func NewPipeline(ctx context.Context,
}
// SetSyncStatsVars is a thread safe method to sets the synchronizer Stats
func (p *Pipeline) SetSyncStatsVars(ctx context.Context, stats *synchronizer.Stats, vars *synchronizer.SCVariablesPtr) {
func (p *Pipeline) SetSyncStatsVars(ctx context.Context, stats *synchronizer.Stats,
vars *synchronizer.SCVariablesPtr) {
select {
case p.statsVarsCh <- statsVars{Stats: *stats, Vars: *vars}:
case <-ctx.Done():
@ -500,7 +501,8 @@ func (p *Pipeline) forgeBatch(batchNum common.BatchNum) (batchInfo *BatchInfo, e
batchInfo.CoordIdxs = coordIdxs
batchInfo.VerifierIdx = p.cfg.VerifierIdx
if err := p.l2DB.StartForging(common.TxIDsFromPoolL2Txs(poolL2Txs), batchInfo.BatchNum); err != nil {
if err := p.l2DB.StartForging(common.TxIDsFromPoolL2Txs(poolL2Txs),
batchInfo.BatchNum); err != nil {
return nil, tracerr.Wrap(err)
}
if err := p.l2DB.UpdateTxsInfo(discardedL2Txs); err != nil {
@ -544,7 +546,8 @@ func (p *Pipeline) forgeBatch(batchNum common.BatchNum) (batchInfo *BatchInfo, e
// waitServerProof gets the generated zkProof & sends it to the SmartContract
func (p *Pipeline) waitServerProof(ctx context.Context, batchInfo *BatchInfo) error {
proof, pubInputs, err := batchInfo.ServerProof.GetProof(ctx) // blocking call, until not resolved don't continue. Returns when the proof server has calculated the proof
proof, pubInputs, err := batchInfo.ServerProof.GetProof(ctx) // blocking call,
// until not resolved don't continue. Returns when the proof server has calculated the proof
if err != nil {
return tracerr.Wrap(err)
}

+ 11
- 5
coordinator/txmanager.go

@ -55,7 +55,8 @@ type TxManager struct {
// NewTxManager creates a new TxManager
func NewTxManager(ctx context.Context, cfg *Config, ethClient eth.ClientInterface, l2DB *l2db.L2DB,
coord *Coordinator, scConsts *synchronizer.SCConsts, initSCVars *synchronizer.SCVariables) (*TxManager, error) {
coord *Coordinator, scConsts *synchronizer.SCConsts, initSCVars *synchronizer.SCVariables) (
*TxManager, error) {
chainID, err := ethClient.EthChainID()
if err != nil {
return nil, tracerr.Wrap(err)
@ -102,7 +103,8 @@ func (t *TxManager) AddBatch(ctx context.Context, batchInfo *BatchInfo) {
}
// SetSyncStatsVars is a thread safe method to sets the synchronizer Stats
func (t *TxManager) SetSyncStatsVars(ctx context.Context, stats *synchronizer.Stats, vars *synchronizer.SCVariablesPtr) {
func (t *TxManager) SetSyncStatsVars(ctx context.Context, stats *synchronizer.Stats,
vars *synchronizer.SCVariablesPtr) {
select {
case t.statsVarsCh <- statsVars{Stats: *stats, Vars: *vars}:
case <-ctx.Done():
@ -191,7 +193,8 @@ func addPerc(v *big.Int, p int64) *big.Int {
return r.Add(v, r)
}
func (t *TxManager) sendRollupForgeBatch(ctx context.Context, batchInfo *BatchInfo, resend bool) error {
func (t *TxManager) sendRollupForgeBatch(ctx context.Context, batchInfo *BatchInfo,
resend bool) error {
var ethTx *types.Transaction
var err error
var auth *bind.TransactOpts
@ -275,7 +278,8 @@ func (t *TxManager) sendRollupForgeBatch(ctx context.Context, batchInfo *BatchIn
t.lastSentL1BatchBlockNum = t.stats.Eth.LastBlock.Num + 1
}
}
if err := t.l2DB.DoneForging(common.TxIDsFromL2Txs(batchInfo.L2Txs), batchInfo.BatchNum); err != nil {
if err := t.l2DB.DoneForging(common.TxIDsFromL2Txs(batchInfo.L2Txs),
batchInfo.BatchNum); err != nil {
return tracerr.Wrap(err)
}
return nil
@ -307,7 +311,9 @@ func (t *TxManager) checkEthTransactionReceipt(ctx context.Context, batchInfo *B
}
}
if err != nil {
return tracerr.Wrap(fmt.Errorf("reached max attempts for ethClient.EthTransactionReceipt: %w", err))
return tracerr.Wrap(
fmt.Errorf("reached max attempts for ethClient.EthTransactionReceipt: %w",
err))
}
batchInfo.Receipt = receipt
t.cfg.debugBatchStore(batchInfo)

+ 14
- 7
db/statedb/statedb.go

@ -17,7 +17,8 @@ import (
var (
// ErrStateDBWithoutMT is used when a method that requires a MerkleTree
// is called in a StateDB that does not have a MerkleTree defined
ErrStateDBWithoutMT = errors.New("Can not call method to use MerkleTree in a StateDB without MerkleTree")
ErrStateDBWithoutMT = errors.New(
"Can not call method to use MerkleTree in a StateDB without MerkleTree")
// ErrAccountAlreadyExists is used when CreateAccount is called and the
// Account already exists
@ -28,7 +29,8 @@ var (
ErrIdxNotFound = errors.New("Idx can not be found")
// ErrGetIdxNoCase is used when trying to get the Idx from EthAddr &
// BJJ with not compatible combination
ErrGetIdxNoCase = errors.New("Can not get Idx due unexpected combination of ethereum Address & BabyJubJub PublicKey")
ErrGetIdxNoCase = errors.New(
"Can not get Idx due unexpected combination of ethereum Address & BabyJubJub PublicKey")
// PrefixKeyIdx is the key prefix for idx in the db
PrefixKeyIdx = []byte("i:")
@ -144,7 +146,8 @@ func NewStateDB(cfg Config) (*StateDB, error) {
}
}
if cfg.Type == TypeTxSelector && cfg.NLevels != 0 {
return nil, tracerr.Wrap(fmt.Errorf("invalid StateDB parameters: StateDB type==TypeStateDB can not have nLevels!=0"))
return nil, tracerr.Wrap(
fmt.Errorf("invalid StateDB parameters: StateDB type==TypeStateDB can not have nLevels!=0"))
}
return &StateDB{
@ -347,7 +350,8 @@ func GetAccountInTreeDB(sto db.Storage, idx common.Idx) (*common.Account, error)
// CreateAccount creates a new Account in the StateDB for the given Idx. If
// StateDB.MT==nil, MerkleTree is not affected, otherwise updates the
// MerkleTree, returning a CircomProcessorProof.
func (s *StateDB) CreateAccount(idx common.Idx, account *common.Account) (*merkletree.CircomProcessorProof, error) {
func (s *StateDB) CreateAccount(idx common.Idx, account *common.Account) (
*merkletree.CircomProcessorProof, error) {
cpp, err := CreateAccountInTreeDB(s.db.DB(), s.MT, idx, account)
if err != nil {
return cpp, tracerr.Wrap(err)
@ -361,7 +365,8 @@ func (s *StateDB) CreateAccount(idx common.Idx, account *common.Account) (*merkl
// from ExitTree. Creates a new Account in the StateDB for the given Idx. If
// StateDB.MT==nil, MerkleTree is not affected, otherwise updates the
// MerkleTree, returning a CircomProcessorProof.
func CreateAccountInTreeDB(sto db.Storage, mt *merkletree.MerkleTree, idx common.Idx, account *common.Account) (*merkletree.CircomProcessorProof, error) {
func CreateAccountInTreeDB(sto db.Storage, mt *merkletree.MerkleTree, idx common.Idx,
account *common.Account) (*merkletree.CircomProcessorProof, error) {
// store at the DB the key: v, and value: leaf.Bytes()
v, err := account.HashValue()
if err != nil {
@ -410,7 +415,8 @@ func CreateAccountInTreeDB(sto db.Storage, mt *merkletree.MerkleTree, idx common
// UpdateAccount updates the Account in the StateDB for the given Idx. If
// StateDB.mt==nil, MerkleTree is not affected, otherwise updates the
// MerkleTree, returning a CircomProcessorProof.
func (s *StateDB) UpdateAccount(idx common.Idx, account *common.Account) (*merkletree.CircomProcessorProof, error) {
func (s *StateDB) UpdateAccount(idx common.Idx, account *common.Account) (
*merkletree.CircomProcessorProof, error) {
return UpdateAccountInTreeDB(s.db.DB(), s.MT, idx, account)
}
@ -418,7 +424,8 @@ func (s *StateDB) UpdateAccount(idx common.Idx, account *common.Account) (*merkl
// from ExitTree. Updates the Account in the StateDB for the given Idx. If
// StateDB.mt==nil, MerkleTree is not affected, otherwise updates the
// MerkleTree, returning a CircomProcessorProof.
func UpdateAccountInTreeDB(sto db.Storage, mt *merkletree.MerkleTree, idx common.Idx, account *common.Account) (*merkletree.CircomProcessorProof, error) {
func UpdateAccountInTreeDB(sto db.Storage, mt *merkletree.MerkleTree, idx common.Idx,
account *common.Account) (*merkletree.CircomProcessorProof, error) {
// store at the DB the key: v, and value: account.Bytes()
v, err := account.HashValue()
if err != nil {

+ 11
- 5
db/statedb/statedb_test.go

@ -22,7 +22,8 @@ import (
func newAccount(t *testing.T, i int) *common.Account {
var sk babyjub.PrivateKey
_, err := hex.Decode(sk[:], []byte("0001020304050607080900010203040506070809000102030405060708090001"))
_, err := hex.Decode(sk[:],
[]byte("0001020304050607080900010203040506070809000102030405060708090001"))
require.NoError(t, err)
pk := sk.Public()
@ -371,7 +372,8 @@ func TestCheckpoints(t *testing.T) {
dirLocal, err := ioutil.TempDir("", "ldb")
require.NoError(t, err)
defer require.NoError(t, os.RemoveAll(dirLocal))
ldb, err := NewLocalStateDB(Config{Path: dirLocal, Keep: 128, Type: TypeBatchBuilder, NLevels: 32}, sdb)
ldb, err := NewLocalStateDB(Config{Path: dirLocal, Keep: 128, Type: TypeBatchBuilder,
NLevels: 32}, sdb)
require.NoError(t, err)
// get checkpoint 4 from sdb (StateDB) to ldb (LocalStateDB)
@ -392,7 +394,8 @@ func TestCheckpoints(t *testing.T) {
dirLocal2, err := ioutil.TempDir("", "ldb2")
require.NoError(t, err)
defer require.NoError(t, os.RemoveAll(dirLocal2))
ldb2, err := NewLocalStateDB(Config{Path: dirLocal2, Keep: 128, Type: TypeBatchBuilder, NLevels: 32}, sdb)
ldb2, err := NewLocalStateDB(Config{Path: dirLocal2, Keep: 128, Type: TypeBatchBuilder,
NLevels: 32}, sdb)
require.NoError(t, err)
// get checkpoint 4 from sdb (StateDB) to ldb (LocalStateDB)
@ -471,7 +474,8 @@ func TestCheckAccountsTreeTestVectors(t *testing.T) {
ay0 := new(big.Int).Sub(new(big.Int).Exp(big.NewInt(2), big.NewInt(253), nil), big.NewInt(1))
// test value from js version (compatibility-canary)
assert.Equal(t, "1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", (hex.EncodeToString(ay0.Bytes())))
assert.Equal(t, "1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
(hex.EncodeToString(ay0.Bytes())))
bjjPoint0Comp := babyjub.PackSignY(true, ay0)
bjj0 := babyjub.PublicKeyComp(bjjPoint0Comp)
@ -530,7 +534,9 @@ func TestCheckAccountsTreeTestVectors(t *testing.T) {
require.NoError(t, err)
}
// root value generated by js version:
assert.Equal(t, "17298264051379321456969039521810887093935433569451713402227686942080129181291", sdb.MT.Root().BigInt().String())
assert.Equal(t,
"17298264051379321456969039521810887093935433569451713402227686942080129181291",
sdb.MT.Root().BigInt().String())
}
// TestListCheckpoints performs almost the same test than kvdb/kvdb_test.go

+ 18
- 8
db/statedb/utils.go

@ -18,7 +18,8 @@ func concatEthAddrTokenID(addr ethCommon.Address, tokenID common.TokenID) []byte
b = append(b[:], tokenID.Bytes()[:]...)
return b
}
func concatEthAddrBJJTokenID(addr ethCommon.Address, pk babyjub.PublicKeyComp, tokenID common.TokenID) []byte {
func concatEthAddrBJJTokenID(addr ethCommon.Address, pk babyjub.PublicKeyComp,
tokenID common.TokenID) []byte {
pkComp := pk
var b []byte
b = append(b, addr.Bytes()...)
@ -32,7 +33,8 @@ func concatEthAddrBJJTokenID(addr ethCommon.Address, pk babyjub.PublicKeyComp, t
// - key: EthAddr & BabyJubJub PublicKey Compressed, value: idx
// If Idx already exist for the given EthAddr & BJJ, the remaining Idx will be
// always the smallest one.
func (s *StateDB) setIdxByEthAddrBJJ(idx common.Idx, addr ethCommon.Address, pk babyjub.PublicKeyComp, tokenID common.TokenID) error {
func (s *StateDB) setIdxByEthAddrBJJ(idx common.Idx, addr ethCommon.Address,
pk babyjub.PublicKeyComp, tokenID common.TokenID) error {
oldIdx, err := s.GetIdxByEthAddrBJJ(addr, pk, tokenID)
if err == nil {
// EthAddr & BJJ already have an Idx
@ -40,7 +42,8 @@ func (s *StateDB) setIdxByEthAddrBJJ(idx common.Idx, addr ethCommon.Address, pk
// if new idx is smaller, store the new one
// if new idx is bigger, don't store and return, as the used one will be the old
if idx >= oldIdx {
log.Debug("StateDB.setIdxByEthAddrBJJ: Idx not stored because there already exist a smaller Idx for the given EthAddr & BJJ")
log.Debug("StateDB.setIdxByEthAddrBJJ: Idx not stored because there " +
"already exist a smaller Idx for the given EthAddr & BJJ")
return nil
}
}
@ -80,7 +83,8 @@ func (s *StateDB) setIdxByEthAddrBJJ(idx common.Idx, addr ethCommon.Address, pk
// GetIdxByEthAddr returns the smallest Idx in the StateDB for the given
// Ethereum Address. Will return common.Idx(0) and error in case that Idx is
// not found in the StateDB.
func (s *StateDB) GetIdxByEthAddr(addr ethCommon.Address, tokenID common.TokenID) (common.Idx, error) {
func (s *StateDB) GetIdxByEthAddr(addr ethCommon.Address, tokenID common.TokenID) (common.Idx,
error) {
k := concatEthAddrTokenID(addr, tokenID)
b, err := s.db.DB().Get(append(PrefixKeyAddr, k...))
if err != nil {
@ -116,18 +120,22 @@ func (s *StateDB) GetIdxByEthAddrBJJ(addr ethCommon.Address, pk babyjub.PublicKe
return common.Idx(0), tracerr.Wrap(ErrIdxNotFound)
} else if err != nil {
return common.Idx(0),
tracerr.Wrap(fmt.Errorf("GetIdxByEthAddrBJJ: %s: ToEthAddr: %s, ToBJJ: %s, TokenID: %d", ErrIdxNotFound, addr.Hex(), pk, tokenID))
tracerr.Wrap(fmt.Errorf("GetIdxByEthAddrBJJ: %s: ToEthAddr: %s, ToBJJ: %s, TokenID: %d",
ErrIdxNotFound, addr.Hex(), pk, tokenID))
}
idx, err := common.IdxFromBytes(b)
if err != nil {
return common.Idx(0),
tracerr.Wrap(fmt.Errorf("GetIdxByEthAddrBJJ: %s: ToEthAddr: %s, ToBJJ: %s, TokenID: %d", err, addr.Hex(), pk, tokenID))
tracerr.Wrap(fmt.Errorf("GetIdxByEthAddrBJJ: %s: ToEthAddr: %s, ToBJJ: %s, TokenID: %d",
err, addr.Hex(), pk, tokenID))
}
return idx, nil
}
// rest of cases (included case ToEthAddr==0) are not possible
return common.Idx(0),
tracerr.Wrap(fmt.Errorf("GetIdxByEthAddrBJJ: Not found, %s: ToEthAddr: %s, ToBJJ: %s, TokenID: %d", ErrGetIdxNoCase, addr.Hex(), pk, tokenID))
tracerr.Wrap(
fmt.Errorf("GetIdxByEthAddrBJJ: Not found, %s: ToEthAddr: %s, ToBJJ: %s, TokenID: %d",
ErrGetIdxNoCase, addr.Hex(), pk, tokenID))
}
// GetTokenIDsFromIdxs returns a map containing the common.TokenID with its
@ -137,7 +145,9 @@ func (s *StateDB) GetTokenIDsFromIdxs(idxs []common.Idx) (map[common.TokenID]com
for i := 0; i < len(idxs); i++ {
a, err := s.GetAccount(idxs[i])
if err != nil {
return nil, tracerr.Wrap(fmt.Errorf("GetTokenIDsFromIdxs error on GetAccount with Idx==%d: %s", idxs[i], err.Error()))
return nil,
tracerr.Wrap(fmt.Errorf("GetTokenIDsFromIdxs error on GetAccount with Idx==%d: %s",
idxs[i], err.Error()))
}
m[a.TokenID] = idxs[i]
}

+ 123
- 63
eth/auction.go

@ -70,7 +70,8 @@ type AuctionEventInitialize struct {
}
// AuctionVariables returns the AuctionVariables from the initialize event
func (ei *AuctionEventInitialize) AuctionVariables(InitialMinimalBidding *big.Int) *common.AuctionVariables {
func (ei *AuctionEventInitialize) AuctionVariables(
InitialMinimalBidding *big.Int) *common.AuctionVariables {
return &common.AuctionVariables{
EthBlockNum: 0,
DonationAddress: ei.DonationAddress,
@ -222,12 +223,15 @@ type AuctionInterface interface {
AuctionGetAllocationRatio() ([3]uint16, error)
AuctionSetDonationAddress(newDonationAddress ethCommon.Address) (*types.Transaction, error)
AuctionGetDonationAddress() (*ethCommon.Address, error)
AuctionSetBootCoordinator(newBootCoordinator ethCommon.Address, newBootCoordinatorURL string) (*types.Transaction, error)
AuctionSetBootCoordinator(newBootCoordinator ethCommon.Address,
newBootCoordinatorURL string) (*types.Transaction, error)
AuctionGetBootCoordinator() (*ethCommon.Address, error)
AuctionChangeDefaultSlotSetBid(slotSet int64, newInitialMinBid *big.Int) (*types.Transaction, error)
AuctionChangeDefaultSlotSetBid(slotSet int64,
newInitialMinBid *big.Int) (*types.Transaction, error)
// Coordinator Management
AuctionSetCoordinator(forger ethCommon.Address, coordinatorURL string) (*types.Transaction, error)
AuctionSetCoordinator(forger ethCommon.Address, coordinatorURL string) (*types.Transaction,
error)
// Slot Info
AuctionGetSlotNumber(blockNum int64) (int64, error)
@ -237,7 +241,8 @@ type AuctionInterface interface {
AuctionGetSlotSet(slot int64) (*big.Int, error)
// Bidding
AuctionBid(amount *big.Int, slot int64, bidAmount *big.Int, deadline *big.Int) (tx *types.Transaction, err error)
AuctionBid(amount *big.Int, slot int64, bidAmount *big.Int, deadline *big.Int) (
tx *types.Transaction, err error)
AuctionMultiBid(amount *big.Int, startingSlot, endingSlot int64, slotSets [6]bool,
maxBid, minBid, deadline *big.Int) (tx *types.Transaction, err error)
@ -275,8 +280,10 @@ type AuctionClient struct {
}
// NewAuctionClient creates a new AuctionClient. `tokenAddress` is the address of the HEZ tokens.
func NewAuctionClient(client *EthereumClient, address ethCommon.Address, tokenHEZCfg TokenConfig) (*AuctionClient, error) {
contractAbi, err := abi.JSON(strings.NewReader(string(HermezAuctionProtocol.HermezAuctionProtocolABI)))
func NewAuctionClient(client *EthereumClient, address ethCommon.Address,
tokenHEZCfg TokenConfig) (*AuctionClient, error) {
contractAbi, err :=
abi.JSON(strings.NewReader(string(HermezAuctionProtocol.HermezAuctionProtocolABI)))
if err != nil {
return nil, tracerr.Wrap(err)
}
@ -331,7 +338,8 @@ func (c *AuctionClient) AuctionGetSlotDeadline() (slotDeadline uint8, err error)
}
// AuctionSetOpenAuctionSlots is the interface to call the smart contract function
func (c *AuctionClient) AuctionSetOpenAuctionSlots(newOpenAuctionSlots uint16) (tx *types.Transaction, err error) {
func (c *AuctionClient) AuctionSetOpenAuctionSlots(
newOpenAuctionSlots uint16) (tx *types.Transaction, err error) {
if tx, err = c.client.CallAuth(
0,
func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) {
@ -355,7 +363,8 @@ func (c *AuctionClient) AuctionGetOpenAuctionSlots() (openAuctionSlots uint16, e
}
// AuctionSetClosedAuctionSlots is the interface to call the smart contract function
func (c *AuctionClient) AuctionSetClosedAuctionSlots(newClosedAuctionSlots uint16) (tx *types.Transaction, err error) {
func (c *AuctionClient) AuctionSetClosedAuctionSlots(
newClosedAuctionSlots uint16) (tx *types.Transaction, err error) {
if tx, err = c.client.CallAuth(
0,
func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) {
@ -379,7 +388,8 @@ func (c *AuctionClient) AuctionGetClosedAuctionSlots() (closedAuctionSlots uint1
}
// AuctionSetOutbidding is the interface to call the smart contract function
func (c *AuctionClient) AuctionSetOutbidding(newOutbidding uint16) (tx *types.Transaction, err error) {
func (c *AuctionClient) AuctionSetOutbidding(newOutbidding uint16) (tx *types.Transaction,
err error) {
if tx, err = c.client.CallAuth(
12500000, //nolint:gomnd
func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) {
@ -403,7 +413,8 @@ func (c *AuctionClient) AuctionGetOutbidding() (outbidding uint16, err error) {
}
// AuctionSetAllocationRatio is the interface to call the smart contract function
func (c *AuctionClient) AuctionSetAllocationRatio(newAllocationRatio [3]uint16) (tx *types.Transaction, err error) {
func (c *AuctionClient) AuctionSetAllocationRatio(
newAllocationRatio [3]uint16) (tx *types.Transaction, err error) {
if tx, err = c.client.CallAuth(
0,
func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) {
@ -427,7 +438,8 @@ func (c *AuctionClient) AuctionGetAllocationRatio() (allocationRation [3]uint16,
}
// AuctionSetDonationAddress is the interface to call the smart contract function
func (c *AuctionClient) AuctionSetDonationAddress(newDonationAddress ethCommon.Address) (tx *types.Transaction, err error) {
func (c *AuctionClient) AuctionSetDonationAddress(
newDonationAddress ethCommon.Address) (tx *types.Transaction, err error) {
if tx, err = c.client.CallAuth(
0,
func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) {
@ -440,7 +452,8 @@ func (c *AuctionClient) AuctionSetDonationAddress(newDonationAddress ethCommon.A
}
// AuctionGetDonationAddress is the interface to call the smart contract function
func (c *AuctionClient) AuctionGetDonationAddress() (donationAddress *ethCommon.Address, err error) {
func (c *AuctionClient) AuctionGetDonationAddress() (donationAddress *ethCommon.Address,
err error) {
var _donationAddress ethCommon.Address
if err := c.client.Call(func(ec *ethclient.Client) error {
_donationAddress, err = c.auction.GetDonationAddress(c.opts)
@ -452,11 +465,13 @@ func (c *AuctionClient) AuctionGetDonationAddress() (donationAddress *ethCommon.
}
// AuctionSetBootCoordinator is the interface to call the smart contract function
func (c *AuctionClient) AuctionSetBootCoordinator(newBootCoordinator ethCommon.Address, newBootCoordinatorURL string) (tx *types.Transaction, err error) {
func (c *AuctionClient) AuctionSetBootCoordinator(newBootCoordinator ethCommon.Address,
newBootCoordinatorURL string) (tx *types.Transaction, err error) {
if tx, err = c.client.CallAuth(
0,
func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) {
return c.auction.SetBootCoordinator(auth, newBootCoordinator, newBootCoordinatorURL)
return c.auction.SetBootCoordinator(auth, newBootCoordinator,
newBootCoordinatorURL)
},
); err != nil {
return nil, tracerr.Wrap(fmt.Errorf("Failed setting bootCoordinator: %w", err))
@ -465,7 +480,8 @@ func (c *AuctionClient) AuctionSetBootCoordinator(newBootCoordinator ethCommon.A
}
// AuctionGetBootCoordinator is the interface to call the smart contract function
func (c *AuctionClient) AuctionGetBootCoordinator() (bootCoordinator *ethCommon.Address, err error) {
func (c *AuctionClient) AuctionGetBootCoordinator() (bootCoordinator *ethCommon.Address,
err error) {
var _bootCoordinator ethCommon.Address
if err := c.client.Call(func(ec *ethclient.Client) error {
_bootCoordinator, err = c.auction.GetBootCoordinator(c.opts)
@ -477,7 +493,8 @@ func (c *AuctionClient) AuctionGetBootCoordinator() (bootCoordinator *ethCommon.
}
// AuctionChangeDefaultSlotSetBid is the interface to call the smart contract function
func (c *AuctionClient) AuctionChangeDefaultSlotSetBid(slotSet int64, newInitialMinBid *big.Int) (tx *types.Transaction, err error) {
func (c *AuctionClient) AuctionChangeDefaultSlotSetBid(slotSet int64,
newInitialMinBid *big.Int) (tx *types.Transaction, err error) {
if tx, err = c.client.CallAuth(
0,
func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) {
@ -491,7 +508,8 @@ func (c *AuctionClient) AuctionChangeDefaultSlotSetBid(slotSet int64, newInitial
}
// AuctionGetClaimableHEZ is the interface to call the smart contract function
func (c *AuctionClient) AuctionGetClaimableHEZ(claimAddress ethCommon.Address) (claimableHEZ *big.Int, err error) {
func (c *AuctionClient) AuctionGetClaimableHEZ(
claimAddress ethCommon.Address) (claimableHEZ *big.Int, err error) {
if err := c.client.Call(func(ec *ethclient.Client) error {
claimableHEZ, err = c.auction.GetClaimableHEZ(c.opts, claimAddress)
return tracerr.Wrap(err)
@ -502,7 +520,8 @@ func (c *AuctionClient) AuctionGetClaimableHEZ(claimAddress ethCommon.Address) (
}
// AuctionSetCoordinator is the interface to call the smart contract function
func (c *AuctionClient) AuctionSetCoordinator(forger ethCommon.Address, coordinatorURL string) (tx *types.Transaction, err error) {
func (c *AuctionClient) AuctionSetCoordinator(forger ethCommon.Address,
coordinatorURL string) (tx *types.Transaction, err error) {
if tx, err = c.client.CallAuth(
0,
func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) {
@ -551,7 +570,8 @@ func (c *AuctionClient) AuctionGetSlotSet(slot int64) (slotSet *big.Int, err err
}
// AuctionGetDefaultSlotSetBid is the interface to call the smart contract function
func (c *AuctionClient) AuctionGetDefaultSlotSetBid(slotSet uint8) (minBidSlotSet *big.Int, err error) {
func (c *AuctionClient) AuctionGetDefaultSlotSetBid(slotSet uint8) (minBidSlotSet *big.Int,
err error) {
if err := c.client.Call(func(ec *ethclient.Client) error {
minBidSlotSet, err = c.auction.GetDefaultSlotSetBid(c.opts, slotSet)
return tracerr.Wrap(err)
@ -574,7 +594,8 @@ func (c *AuctionClient) AuctionGetSlotNumber(blockNum int64) (slot int64, err er
}
// AuctionBid is the interface to call the smart contract function
func (c *AuctionClient) AuctionBid(amount *big.Int, slot int64, bidAmount *big.Int, deadline *big.Int) (tx *types.Transaction, err error) {
func (c *AuctionClient) AuctionBid(amount *big.Int, slot int64, bidAmount *big.Int,
deadline *big.Int) (tx *types.Transaction, err error) {
if tx, err = c.client.CallAuth(
0,
func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) {
@ -586,7 +607,8 @@ func (c *AuctionClient) AuctionBid(amount *big.Int, slot int64, bidAmount *big.I
}
tokenName := c.tokenHEZCfg.Name
tokenAddr := c.tokenHEZCfg.Address
digest, _ := createPermitDigest(tokenAddr, owner, spender, c.chainID, amount, nonce, deadline, tokenName)
digest, _ := createPermitDigest(tokenAddr, owner, spender, c.chainID,
amount, nonce, deadline, tokenName)
signature, _ := c.client.ks.SignHash(*c.client.account, digest)
permit := createPermit(owner, spender, amount, deadline, digest, signature)
_slot := big.NewInt(slot)
@ -599,8 +621,8 @@ func (c *AuctionClient) AuctionBid(amount *big.Int, slot int64, bidAmount *big.I
}
// AuctionMultiBid is the interface to call the smart contract function
func (c *AuctionClient) AuctionMultiBid(amount *big.Int, startingSlot, endingSlot int64, slotSets [6]bool,
maxBid, minBid, deadline *big.Int) (tx *types.Transaction, err error) {
func (c *AuctionClient) AuctionMultiBid(amount *big.Int, startingSlot, endingSlot int64,
slotSets [6]bool, maxBid, minBid, deadline *big.Int) (tx *types.Transaction, err error) {
if tx, err = c.client.CallAuth(
1000000, //nolint:gomnd
func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) {
@ -613,12 +635,14 @@ func (c *AuctionClient) AuctionMultiBid(amount *big.Int, startingSlot, endingSlo
tokenName := c.tokenHEZCfg.Name
tokenAddr := c.tokenHEZCfg.Address
digest, _ := createPermitDigest(tokenAddr, owner, spender, c.chainID, amount, nonce, deadline, tokenName)
digest, _ := createPermitDigest(tokenAddr, owner, spender, c.chainID,
amount, nonce, deadline, tokenName)
signature, _ := c.client.ks.SignHash(*c.client.account, digest)
permit := createPermit(owner, spender, amount, deadline, digest, signature)
_startingSlot := big.NewInt(startingSlot)
_endingSlot := big.NewInt(endingSlot)
return c.auction.ProcessMultiBid(auth, amount, _startingSlot, _endingSlot, slotSets, maxBid, minBid, permit)
return c.auction.ProcessMultiBid(auth, amount, _startingSlot, _endingSlot,
slotSets, maxBid, minBid, permit)
},
); err != nil {
return nil, tracerr.Wrap(fmt.Errorf("Failed multibid: %w", err))
@ -627,7 +651,8 @@ func (c *AuctionClient) AuctionMultiBid(amount *big.Int, startingSlot, endingSlo
}
// AuctionCanForge is the interface to call the smart contract function
func (c *AuctionClient) AuctionCanForge(forger ethCommon.Address, blockNum int64) (canForge bool, err error) {
func (c *AuctionClient) AuctionCanForge(forger ethCommon.Address, blockNum int64) (canForge bool,
err error) {
if err := c.client.Call(func(ec *ethclient.Client) error {
canForge, err = c.auction.CanForge(c.opts, forger, big.NewInt(blockNum))
return tracerr.Wrap(err)
@ -680,7 +705,8 @@ func (c *AuctionClient) AuctionConstants() (auctionConstants *common.AuctionCons
if err != nil {
return tracerr.Wrap(err)
}
auctionConstants.InitialMinimalBidding, err = c.auction.INITIALMINIMALBIDDING(c.opts)
auctionConstants.InitialMinimalBidding, err =
c.auction.INITIALMINIMALBIDDING(c.opts)
if err != nil {
return tracerr.Wrap(err)
}
@ -751,21 +777,35 @@ func (c *AuctionClient) AuctionVariables() (auctionVariables *common.AuctionVari
}
var (
logAuctionNewBid = crypto.Keccak256Hash([]byte("NewBid(uint128,uint128,address)"))
logAuctionNewSlotDeadline = crypto.Keccak256Hash([]byte("NewSlotDeadline(uint8)"))
logAuctionNewClosedAuctionSlots = crypto.Keccak256Hash([]byte("NewClosedAuctionSlots(uint16)"))
logAuctionNewOutbidding = crypto.Keccak256Hash([]byte("NewOutbidding(uint16)"))
logAuctionNewDonationAddress = crypto.Keccak256Hash([]byte("NewDonationAddress(address)"))
logAuctionNewBootCoordinator = crypto.Keccak256Hash([]byte("NewBootCoordinator(address,string)"))
logAuctionNewOpenAuctionSlots = crypto.Keccak256Hash([]byte("NewOpenAuctionSlots(uint16)"))
logAuctionNewAllocationRatio = crypto.Keccak256Hash([]byte("NewAllocationRatio(uint16[3])"))
logAuctionSetCoordinator = crypto.Keccak256Hash([]byte("SetCoordinator(address,address,string)"))
logAuctionNewForgeAllocated = crypto.Keccak256Hash([]byte("NewForgeAllocated(address,address,uint128,uint128,uint128,uint128)"))
logAuctionNewDefaultSlotSetBid = crypto.Keccak256Hash([]byte("NewDefaultSlotSetBid(uint128,uint128)"))
logAuctionNewForge = crypto.Keccak256Hash([]byte("NewForge(address,uint128)"))
logAuctionHEZClaimed = crypto.Keccak256Hash([]byte("HEZClaimed(address,uint128)"))
logAuctionInitialize = crypto.Keccak256Hash([]byte(
"InitializeHermezAuctionProtocolEvent(address,address,string,uint16,uint8,uint16,uint16,uint16[3])"))
logAuctionNewBid = crypto.Keccak256Hash([]byte(
"NewBid(uint128,uint128,address)"))
logAuctionNewSlotDeadline = crypto.Keccak256Hash([]byte(
"NewSlotDeadline(uint8)"))
logAuctionNewClosedAuctionSlots = crypto.Keccak256Hash([]byte(
"NewClosedAuctionSlots(uint16)"))
logAuctionNewOutbidding = crypto.Keccak256Hash([]byte(
"NewOutbidding(uint16)"))
logAuctionNewDonationAddress = crypto.Keccak256Hash([]byte(
"NewDonationAddress(address)"))
logAuctionNewBootCoordinator = crypto.Keccak256Hash([]byte(
"NewBootCoordinator(address,string)"))
logAuctionNewOpenAuctionSlots = crypto.Keccak256Hash([]byte(
"NewOpenAuctionSlots(uint16)"))
logAuctionNewAllocationRatio = crypto.Keccak256Hash([]byte(
"NewAllocationRatio(uint16[3])"))
logAuctionSetCoordinator = crypto.Keccak256Hash([]byte(
"SetCoordinator(address,address,string)"))
logAuctionNewForgeAllocated = crypto.Keccak256Hash([]byte(
"NewForgeAllocated(address,address,uint128,uint128,uint128,uint128)"))
logAuctionNewDefaultSlotSetBid = crypto.Keccak256Hash([]byte(
"NewDefaultSlotSetBid(uint128,uint128)"))
logAuctionNewForge = crypto.Keccak256Hash([]byte(
"NewForge(address,uint128)"))
logAuctionHEZClaimed = crypto.Keccak256Hash([]byte(
"HEZClaimed(address,uint128)"))
logAuctionInitialize = crypto.Keccak256Hash([]byte(
"InitializeHermezAuctionProtocolEvent(address,address,string," +
"uint16,uint8,uint16,uint16,uint16[3])"))
)
// AuctionEventInit returns the initialize event with its corresponding block number
@ -781,7 +821,8 @@ func (c *AuctionClient) AuctionEventInit() (*AuctionEventInitialize, int64, erro
return nil, 0, tracerr.Wrap(err)
}
if len(logs) != 1 {
return nil, 0, tracerr.Wrap(fmt.Errorf("no event of type InitializeHermezAuctionProtocolEvent found"))
return nil, 0,
tracerr.Wrap(fmt.Errorf("no event of type InitializeHermezAuctionProtocolEvent found"))
}
vLog := logs[0]
if vLog.Topics[0] != logAuctionInitialize {
@ -829,7 +870,8 @@ func (c *AuctionClient) AuctionEventsByBlock(blockNum int64,
for _, vLog := range logs {
if blockHash != nil && vLog.BlockHash != *blockHash {
log.Errorw("Block hash mismatch", "expected", blockHash.String(), "got", vLog.BlockHash.String())
log.Errorw("Block hash mismatch", "expected", blockHash.String(), "got",
vLog.BlockHash.String())
return nil, tracerr.Wrap(ErrBlockHashMismatchEvent)
}
switch vLog.Topics[0] {
@ -840,7 +882,8 @@ func (c *AuctionClient) AuctionEventsByBlock(blockNum int64,
Address ethCommon.Address
}
var newBid AuctionEventNewBid
if err := c.contractAbi.UnpackIntoInterface(&auxNewBid, "NewBid", vLog.Data); err != nil {
if err := c.contractAbi.UnpackIntoInterface(&auxNewBid, "NewBid",
vLog.Data); err != nil {
return nil, tracerr.Wrap(err)
}
newBid.BidAmount = auxNewBid.BidAmount
@ -849,48 +892,60 @@ func (c *AuctionClient) AuctionEventsByBlock(blockNum int64,
auctionEvents.NewBid = append(auctionEvents.NewBid, newBid)
case logAuctionNewSlotDeadline:
var newSlotDeadline AuctionEventNewSlotDeadline
if err := c.contractAbi.UnpackIntoInterface(&newSlotDeadline, "NewSlotDeadline", vLog.Data); err != nil {
if err := c.contractAbi.UnpackIntoInterface(&newSlotDeadline,
"NewSlotDeadline", vLog.Data); err != nil {
return nil, tracerr.Wrap(err)
}
auctionEvents.NewSlotDeadline = append(auctionEvents.NewSlotDeadline, newSlotDeadline)
case logAuctionNewClosedAuctionSlots:
var newClosedAuctionSlots AuctionEventNewClosedAuctionSlots
if err := c.contractAbi.UnpackIntoInterface(&newClosedAuctionSlots, "NewClosedAuctionSlots", vLog.Data); err != nil {
if err := c.contractAbi.UnpackIntoInterface(&newClosedAuctionSlots,
"NewClosedAuctionSlots", vLog.Data); err != nil {
return nil, tracerr.Wrap(err)
}
auctionEvents.NewClosedAuctionSlots = append(auctionEvents.NewClosedAuctionSlots, newClosedAuctionSlots)
auctionEvents.NewClosedAuctionSlots =
append(auctionEvents.NewClosedAuctionSlots, newClosedAuctionSlots)
case logAuctionNewOutbidding:
var newOutbidding AuctionEventNewOutbidding
if err := c.contractAbi.UnpackIntoInterface(&newOutbidding, "NewOutbidding", vLog.Data); err != nil {
if err := c.contractAbi.UnpackIntoInterface(&newOutbidding, "NewOutbidding",
vLog.Data); err != nil {
return nil, tracerr.Wrap(err)
}
auctionEvents.NewOutbidding = append(auctionEvents.NewOutbidding, newOutbidding)
case logAuctionNewDonationAddress:
var newDonationAddress AuctionEventNewDonationAddress
newDonationAddress.NewDonationAddress = ethCommon.BytesToAddress(vLog.Topics[1].Bytes())
auctionEvents.NewDonationAddress = append(auctionEvents.NewDonationAddress, newDonationAddress)
auctionEvents.NewDonationAddress = append(auctionEvents.NewDonationAddress,
newDonationAddress)
case logAuctionNewBootCoordinator:
var newBootCoordinator AuctionEventNewBootCoordinator
if err := c.contractAbi.UnpackIntoInterface(&newBootCoordinator, "NewBootCoordinator", vLog.Data); err != nil {
if err := c.contractAbi.UnpackIntoInterface(&newBootCoordinator,
"NewBootCoordinator", vLog.Data); err != nil {
return nil, tracerr.Wrap(err)
}
newBootCoordinator.NewBootCoordinator = ethCommon.BytesToAddress(vLog.Topics[1].Bytes())
auctionEvents.NewBootCoordinator = append(auctionEvents.NewBootCoordinator, newBootCoordinator)
auctionEvents.NewBootCoordinator = append(auctionEvents.NewBootCoordinator,
newBootCoordinator)
case logAuctionNewOpenAuctionSlots:
var newOpenAuctionSlots AuctionEventNewOpenAuctionSlots
if err := c.contractAbi.UnpackIntoInterface(&newOpenAuctionSlots, "NewOpenAuctionSlots", vLog.Data); err != nil {
if err := c.contractAbi.UnpackIntoInterface(&newOpenAuctionSlots,
"NewOpenAuctionSlots", vLog.Data); err != nil {
return nil, tracerr.Wrap(err)
}
auctionEvents.NewOpenAuctionSlots = append(auctionEvents.NewOpenAuctionSlots, newOpenAuctionSlots)
auctionEvents.NewOpenAuctionSlots =
append(auctionEvents.NewOpenAuctionSlots, newOpenAuctionSlots)
case logAuctionNewAllocationRatio:
var newAllocationRatio AuctionEventNewAllocationRatio
if err := c.contractAbi.UnpackIntoInterface(&newAllocationRatio, "NewAllocationRatio", vLog.Data); err != nil {
if err := c.contractAbi.UnpackIntoInterface(&newAllocationRatio,
"NewAllocationRatio", vLog.Data); err != nil {
return nil, tracerr.Wrap(err)
}
auctionEvents.NewAllocationRatio = append(auctionEvents.NewAllocationRatio, newAllocationRatio)
auctionEvents.NewAllocationRatio = append(auctionEvents.NewAllocationRatio,
newAllocationRatio)
case logAuctionSetCoordinator:
var setCoordinator AuctionEventSetCoordinator
if err := c.contractAbi.UnpackIntoInterface(&setCoordinator, "SetCoordinator", vLog.Data); err != nil {
if err := c.contractAbi.UnpackIntoInterface(&setCoordinator,
"SetCoordinator", vLog.Data); err != nil {
return nil, tracerr.Wrap(err)
}
setCoordinator.BidderAddress = ethCommon.BytesToAddress(vLog.Topics[1].Bytes())
@ -898,25 +953,29 @@ func (c *AuctionClient) AuctionEventsByBlock(blockNum int64,
auctionEvents.SetCoordinator = append(auctionEvents.SetCoordinator, setCoordinator)
case logAuctionNewForgeAllocated:
var newForgeAllocated AuctionEventNewForgeAllocated
if err := c.contractAbi.UnpackIntoInterface(&newForgeAllocated, "NewForgeAllocated", vLog.Data); err != nil {
if err := c.contractAbi.UnpackIntoInterface(&newForgeAllocated,
"NewForgeAllocated", vLog.Data); err != nil {
return nil, tracerr.Wrap(err)
}
newForgeAllocated.Bidder = ethCommon.BytesToAddress(vLog.Topics[1].Bytes())
newForgeAllocated.Forger = ethCommon.BytesToAddress(vLog.Topics[2].Bytes())
newForgeAllocated.SlotToForge = new(big.Int).SetBytes(vLog.Topics[3][:]).Int64()
auctionEvents.NewForgeAllocated = append(auctionEvents.NewForgeAllocated, newForgeAllocated)
auctionEvents.NewForgeAllocated = append(auctionEvents.NewForgeAllocated,
newForgeAllocated)
case logAuctionNewDefaultSlotSetBid:
var auxNewDefaultSlotSetBid struct {
SlotSet *big.Int
NewInitialMinBid *big.Int
}
var newDefaultSlotSetBid AuctionEventNewDefaultSlotSetBid
if err := c.contractAbi.UnpackIntoInterface(&auxNewDefaultSlotSetBid, "NewDefaultSlotSetBid", vLog.Data); err != nil {
if err := c.contractAbi.UnpackIntoInterface(&auxNewDefaultSlotSetBid,
"NewDefaultSlotSetBid", vLog.Data); err != nil {
return nil, tracerr.Wrap(err)
}
newDefaultSlotSetBid.NewInitialMinBid = auxNewDefaultSlotSetBid.NewInitialMinBid
newDefaultSlotSetBid.SlotSet = auxNewDefaultSlotSetBid.SlotSet.Int64()
auctionEvents.NewDefaultSlotSetBid = append(auctionEvents.NewDefaultSlotSetBid, newDefaultSlotSetBid)
auctionEvents.NewDefaultSlotSetBid =
append(auctionEvents.NewDefaultSlotSetBid, newDefaultSlotSetBid)
case logAuctionNewForge:
var newForge AuctionEventNewForge
newForge.Forger = ethCommon.BytesToAddress(vLog.Topics[1].Bytes())
@ -924,7 +983,8 @@ func (c *AuctionClient) AuctionEventsByBlock(blockNum int64,
auctionEvents.NewForge = append(auctionEvents.NewForge, newForge)
case logAuctionHEZClaimed:
var HEZClaimed AuctionEventHEZClaimed
if err := c.contractAbi.UnpackIntoInterface(&HEZClaimed, "HEZClaimed", vLog.Data); err != nil {
if err := c.contractAbi.UnpackIntoInterface(&HEZClaimed, "HEZClaimed",
vLog.Data); err != nil {
return nil, tracerr.Wrap(err)
}
HEZClaimed.Owner = ethCommon.BytesToAddress(vLog.Topics[1].Bytes())

+ 10
- 5
eth/auction_test.go

@ -58,7 +58,8 @@ func TestAuctionConstants(t *testing.T) {
func TestAuctionVariables(t *testing.T) {
INITMINBID := new(big.Int)
INITMINBID.SetString(minBidStr, 10)
defaultSlotSetBid := [6]*big.Int{INITMINBID, INITMINBID, INITMINBID, INITMINBID, INITMINBID, INITMINBID}
defaultSlotSetBid := [6]*big.Int{INITMINBID, INITMINBID, INITMINBID, INITMINBID, INITMINBID,
INITMINBID}
auctionVariables, err := auctionClientTest.AuctionVariables()
require.Nil(t, err)
@ -132,7 +133,8 @@ func TestAuctionSetClosedAuctionSlots(t *testing.T) {
require.Nil(t, err)
auctionEvents, err := auctionClientTest.AuctionEventsByBlock(currentBlockNum, nil)
require.Nil(t, err)
assert.Equal(t, newClosedAuctionSlots, auctionEvents.NewClosedAuctionSlots[0].NewClosedAuctionSlots)
assert.Equal(t, newClosedAuctionSlots,
auctionEvents.NewClosedAuctionSlots[0].NewClosedAuctionSlots)
_, err = auctionClientTest.AuctionSetClosedAuctionSlots(closedAuctionSlots)
require.Nil(t, err)
}
@ -228,7 +230,8 @@ func TestAuctionSetBootCoordinator(t *testing.T) {
require.Nil(t, err)
assert.Equal(t, newBootCoordinator, auctionEvents.NewBootCoordinator[0].NewBootCoordinator)
assert.Equal(t, newBootCoordinatorURL, auctionEvents.NewBootCoordinator[0].NewBootCoordinatorURL)
_, err = auctionClientTest.AuctionSetBootCoordinator(bootCoordinatorAddressConst, bootCoordinatorURL)
_, err = auctionClientTest.AuctionSetBootCoordinator(bootCoordinatorAddressConst,
bootCoordinatorURL)
require.Nil(t, err)
}
@ -342,7 +345,8 @@ func TestAuctionMultiBid(t *testing.T) {
budget := new(big.Int)
budget.SetString("45200000000000000000", 10)
bidderAddress := governanceAddressConst
_, err = auctionClientTest.AuctionMultiBid(budget, currentSlot+4, currentSlot+10, slotSet, maxBid, minBid, deadline)
_, err = auctionClientTest.AuctionMultiBid(budget, currentSlot+4, currentSlot+10, slotSet,
maxBid, minBid, deadline)
require.Nil(t, err)
currentBlockNum, err := auctionClientTest.client.EthLastBlock()
require.Nil(t, err)
@ -383,7 +387,8 @@ func TestAuctionClaimHEZ(t *testing.T) {
}
func TestAuctionForge(t *testing.T) {
auctionClientTestHermez, err := NewAuctionClient(ethereumClientHermez, auctionTestAddressConst, tokenHEZ)
auctionClientTestHermez, err := NewAuctionClient(ethereumClientHermez,
auctionTestAddressConst, tokenHEZ)
require.Nil(t, err)
slotConst := 4
blockNum := int64(int(blocksPerSlot)*slotConst + int(genesisBlock))

+ 6
- 3
eth/client.go

@ -64,16 +64,19 @@ type ClientConfig struct {
}
// NewClient creates a new Client to interact with Ethereum and the Hermez smart contracts.
func NewClient(client *ethclient.Client, account *accounts.Account, ks *ethKeystore.KeyStore, cfg *ClientConfig) (*Client, error) {
func NewClient(client *ethclient.Client, account *accounts.Account, ks *ethKeystore.KeyStore,
cfg *ClientConfig) (*Client, error) {
ethereumClient, err := NewEthereumClient(client, account, ks, &cfg.Ethereum)
if err != nil {
return nil, tracerr.Wrap(err)
}
auctionClient, err := NewAuctionClient(ethereumClient, cfg.Auction.Address, cfg.Auction.TokenHEZ)
auctionClient, err := NewAuctionClient(ethereumClient, cfg.Auction.Address,
cfg.Auction.TokenHEZ)
if err != nil {
return nil, tracerr.Wrap(err)
}
rollupClient, err := NewRollupClient(ethereumClient, cfg.Rollup.Address, cfg.Auction.TokenHEZ)
rollupClient, err := NewRollupClient(ethereumClient, cfg.Rollup.Address,
cfg.Auction.TokenHEZ)
if err != nil {
return nil, tracerr.Wrap(err)
}

+ 12
- 6
eth/ethereum.go

@ -64,7 +64,8 @@ type EthereumConfig struct {
GasPriceDiv uint64
}
// EthereumClient is an ethereum client to call Smart Contract methods and check blockchain information.
// EthereumClient is an ethereum client to call Smart Contract methods and check blockchain
// information.
type EthereumClient struct {
client *ethclient.Client
chainID *big.Int
@ -76,7 +77,8 @@ type EthereumClient struct {
// NewEthereumClient creates a EthereumClient instance. The account is not mandatory (it can
// be nil). If the account is nil, CallAuth will fail with ErrAccountNil.
func NewEthereumClient(client *ethclient.Client, account *accounts.Account, ks *ethKeystore.KeyStore, config *EthereumConfig) (*EthereumClient, error) {
func NewEthereumClient(client *ethclient.Client, account *accounts.Account,
ks *ethKeystore.KeyStore, config *EthereumConfig) (*EthereumClient, error) {
if config == nil {
config = &EthereumConfig{
CallGasLimit: defaultCallGasLimit,
@ -166,7 +168,8 @@ func (c *EthereumClient) NewAuth() (*bind.TransactOpts, error) {
// This call requires a valid account with Ether that can be spend during the
// call.
func (c *EthereumClient) CallAuth(gasLimit uint64,
fn func(*ethclient.Client, *bind.TransactOpts) (*types.Transaction, error)) (*types.Transaction, error) {
fn func(*ethclient.Client, *bind.TransactOpts) (*types.Transaction, error)) (*types.Transaction,
error) {
if c.account == nil {
return nil, tracerr.Wrap(ErrAccountNil)
}
@ -212,7 +215,8 @@ func (c *EthereumClient) Call(fn func(*ethclient.Client) error) error {
}
// EthTransactionReceipt returns the transaction receipt of the given txHash
func (c *EthereumClient) EthTransactionReceipt(ctx context.Context, txHash ethCommon.Hash) (*types.Receipt, error) {
func (c *EthereumClient) EthTransactionReceipt(ctx context.Context,
txHash ethCommon.Hash) (*types.Receipt, error) {
return c.client.TransactionReceipt(ctx, txHash)
}
@ -228,13 +232,15 @@ func (c *EthereumClient) EthLastBlock() (int64, error) {
}
// EthHeaderByNumber internally calls ethclient.Client HeaderByNumber
// func (c *EthereumClient) EthHeaderByNumber(ctx context.Context, number *big.Int) (*types.Header, error) {
// func (c *EthereumClient) EthHeaderByNumber(ctx context.Context, number *big.Int) (*types.Header,
// error) {
// return c.client.HeaderByNumber(ctx, number)
// }
// EthBlockByNumber internally calls ethclient.Client BlockByNumber and returns
// *common.Block. If number == -1, the latests known block is returned.
func (c *EthereumClient) EthBlockByNumber(ctx context.Context, number int64) (*common.Block, error) {
func (c *EthereumClient) EthBlockByNumber(ctx context.Context, number int64) (*common.Block,
error) {
blockNum := big.NewInt(number)
if number == -1 {
blockNum = nil

+ 13
- 6
eth/helpers.go

@ -14,7 +14,8 @@ import (
func addBlock(url string) {
method := "POST"
payload := strings.NewReader("{\n \"jsonrpc\":\"2.0\",\n \"method\":\"evm_mine\",\n \"params\":[],\n \"id\":1\n}")
payload := strings.NewReader(
"{\n \"jsonrpc\":\"2.0\",\n \"method\":\"evm_mine\",\n \"params\":[],\n \"id\":1\n}")
client := &http.Client{}
req, err := http.NewRequest(method, url, payload)
@ -45,7 +46,9 @@ func addTime(seconds float64, url string) {
secondsStr := strconv.FormatFloat(seconds, 'E', -1, 32)
method := "POST"
payload := strings.NewReader("{\n \"jsonrpc\":\"2.0\",\n \"method\":\"evm_increaseTime\",\n \"params\":[" + secondsStr + "],\n \"id\":1\n}")
payload := strings.NewReader(
"{\n \"jsonrpc\":\"2.0\",\n \"method\":\"evm_increaseTime\",\n \"params\":[" +
secondsStr + "],\n \"id\":1\n}")
client := &http.Client{}
req, err := http.NewRequest(method, url, payload)
@ -66,13 +69,16 @@ func addTime(seconds float64, url string) {
}()
}
func createPermitDigest(tokenAddr, owner, spender ethCommon.Address, chainID, value, nonce, deadline *big.Int, tokenName string) ([]byte, error) {
func createPermitDigest(tokenAddr, owner, spender ethCommon.Address, chainID, value, nonce,
deadline *big.Int, tokenName string) ([]byte, error) {
// NOTE: We ignore hash.Write errors because we are writing to a memory
// buffer and don't expect any errors to occur.
abiPermit := []byte("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)")
abiPermit :=
[]byte("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)")
hashPermit := sha3.NewLegacyKeccak256()
hashPermit.Write(abiPermit) //nolint:errcheck,gosec
abiEIP712Domain := []byte("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)")
abiEIP712Domain :=
[]byte("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)")
hashEIP712Domain := sha3.NewLegacyKeccak256()
hashEIP712Domain.Write(abiEIP712Domain) //nolint:errcheck,gosec
var encodeBytes []byte
@ -124,7 +130,8 @@ func createPermitDigest(tokenAddr, owner, spender ethCommon.Address, chainID, va
return hashBytes2.Sum(nil), nil
}
func createPermit(owner, spender ethCommon.Address, amount, deadline *big.Int, digest, signature []byte) []byte {
func createPermit(owner, spender ethCommon.Address, amount, deadline *big.Int, digest,
signature []byte) []byte {
r := signature[0:32]
s := signature[32:64]
v := signature[64] + byte(27) //nolint:gomnd

+ 7
- 3
eth/main_test.go

@ -26,7 +26,8 @@ var (
mnemonic = "explain tackle mirror kit van hammer degree position ginger unfair soup bonus"
)
func genAcc(w *hdwallet.Wallet, ks *keystore.KeyStore, i int) (*accounts.Account, ethCommon.Address) {
func genAcc(w *hdwallet.Wallet, ks *keystore.KeyStore, i int) (*accounts.Account,
ethCommon.Address) {
path := hdwallet.MustParseDerivationPath(fmt.Sprintf("m/44'/60'/0'/0/%d", i))
account, err := w.Derive(path, false)
if err != nil {
@ -111,7 +112,9 @@ func getEnvVariables() {
if err != nil {
log.Fatal(errEnvVar)
}
if auctionAddressStr == "" || auctionTestAddressStr == "" || tokenHEZAddressStr == "" || hermezRollupAddressStr == "" || wdelayerAddressStr == "" || wdelayerTestAddressStr == "" || genesisBlockEnv == "" {
if auctionAddressStr == "" || auctionTestAddressStr == "" || tokenHEZAddressStr == "" ||
hermezRollupAddressStr == "" || wdelayerAddressStr == "" || wdelayerTestAddressStr == "" ||
genesisBlockEnv == "" {
log.Fatal(errEnvVar)
}
@ -189,7 +192,8 @@ func TestMain(m *testing.M) {
log.Fatal(err)
}
ethereumClientEmergencyCouncil, err = NewEthereumClient(ethClient, emergencyCouncilAccount, ks, nil)
ethereumClientEmergencyCouncil, err = NewEthereumClient(ethClient,
emergencyCouncilAccount, ks, nil)
if err != nil {
log.Fatal(err)
}

+ 113
- 55
eth/rollup.go

@ -243,13 +243,20 @@ type RollupInterface interface {
// Public Functions
RollupForgeBatch(*RollupForgeBatchArgs, *bind.TransactOpts) (*types.Transaction, error)
RollupAddToken(tokenAddress ethCommon.Address, feeAddToken, deadline *big.Int) (*types.Transaction, error)
RollupAddToken(tokenAddress ethCommon.Address, feeAddToken,
deadline *big.Int) (*types.Transaction, error)
RollupWithdrawMerkleProof(babyPubKey babyjub.PublicKeyComp, tokenID uint32, numExitRoot, idx int64, amount *big.Int, siblings []*big.Int, instantWithdraw bool) (*types.Transaction, error)
RollupWithdrawCircuit(proofA, proofC [2]*big.Int, proofB [2][2]*big.Int, tokenID uint32, numExitRoot, idx int64, amount *big.Int, instantWithdraw bool) (*types.Transaction, error)
RollupWithdrawMerkleProof(babyPubKey babyjub.PublicKeyComp, tokenID uint32, numExitRoot,
idx int64, amount *big.Int, siblings []*big.Int, instantWithdraw bool) (*types.Transaction,
error)
RollupWithdrawCircuit(proofA, proofC [2]*big.Int, proofB [2][2]*big.Int, tokenID uint32,
numExitRoot, idx int64, amount *big.Int, instantWithdraw bool) (*types.Transaction, error)
RollupL1UserTxERC20ETH(fromBJJ babyjub.PublicKeyComp, fromIdx int64, depositAmount *big.Int, amount *big.Int, tokenID uint32, toIdx int64) (*types.Transaction, error)
RollupL1UserTxERC20Permit(fromBJJ babyjub.PublicKeyComp, fromIdx int64, depositAmount *big.Int, amount *big.Int, tokenID uint32, toIdx int64, deadline *big.Int) (tx *types.Transaction, err error)
RollupL1UserTxERC20ETH(fromBJJ babyjub.PublicKeyComp, fromIdx int64, depositAmount *big.Int,
amount *big.Int, tokenID uint32, toIdx int64) (*types.Transaction, error)
RollupL1UserTxERC20Permit(fromBJJ babyjub.PublicKeyComp, fromIdx int64,
depositAmount *big.Int, amount *big.Int, tokenID uint32, toIdx int64,
deadline *big.Int) (tx *types.Transaction, err error)
// Governance Public Functions
RollupUpdateForgeL1L2BatchTimeout(newForgeL1L2BatchTimeout int64) (*types.Transaction, error)
@ -287,7 +294,8 @@ type RollupClient struct {
}
// NewRollupClient creates a new RollupClient
func NewRollupClient(client *EthereumClient, address ethCommon.Address, tokenHEZCfg TokenConfig) (*RollupClient, error) {
func NewRollupClient(client *EthereumClient, address ethCommon.Address,
tokenHEZCfg TokenConfig) (*RollupClient, error) {
contractAbi, err := abi.JSON(strings.NewReader(string(Hermez.HermezABI)))
if err != nil {
return nil, tracerr.Wrap(err)
@ -323,7 +331,8 @@ func NewRollupClient(client *EthereumClient, address ethCommon.Address, tokenHEZ
}
// RollupForgeBatch is the interface to call the smart contract function
func (c *RollupClient) RollupForgeBatch(args *RollupForgeBatchArgs, auth *bind.TransactOpts) (tx *types.Transaction, err error) {
func (c *RollupClient) RollupForgeBatch(args *RollupForgeBatchArgs,
auth *bind.TransactOpts) (tx *types.Transaction, err error) {
if auth == nil {
auth, err = c.client.NewAuth()
if err != nil {
@ -401,7 +410,8 @@ func (c *RollupClient) RollupForgeBatch(args *RollupForgeBatchArgs, auth *bind.T
// RollupAddToken is the interface to call the smart contract function.
// `feeAddToken` is the amount of HEZ tokens that will be paid to add the
// token. `feeAddToken` must match the public value of the smart contract.
func (c *RollupClient) RollupAddToken(tokenAddress ethCommon.Address, feeAddToken, deadline *big.Int) (tx *types.Transaction, err error) {
func (c *RollupClient) RollupAddToken(tokenAddress ethCommon.Address, feeAddToken,
deadline *big.Int) (tx *types.Transaction, err error) {
if tx, err = c.client.CallAuth(
0,
func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) {
@ -413,9 +423,11 @@ func (c *RollupClient) RollupAddToken(tokenAddress ethCommon.Address, feeAddToke
}
tokenName := c.tokenHEZCfg.Name
tokenAddr := c.tokenHEZCfg.Address
digest, _ := createPermitDigest(tokenAddr, owner, spender, c.chainID, feeAddToken, nonce, deadline, tokenName)
digest, _ := createPermitDigest(tokenAddr, owner, spender, c.chainID,
feeAddToken, nonce, deadline, tokenName)
signature, _ := c.client.ks.SignHash(*c.client.account, digest)
permit := createPermit(owner, spender, feeAddToken, deadline, digest, signature)
permit := createPermit(owner, spender, feeAddToken, deadline, digest,
signature)
return c.hermez.AddToken(auth, tokenAddress, permit)
},
@ -426,7 +438,9 @@ func (c *RollupClient) RollupAddToken(tokenAddress ethCommon.Address, feeAddToke
}
// RollupWithdrawMerkleProof is the interface to call the smart contract function
func (c *RollupClient) RollupWithdrawMerkleProof(fromBJJ babyjub.PublicKeyComp, tokenID uint32, numExitRoot, idx int64, amount *big.Int, siblings []*big.Int, instantWithdraw bool) (tx *types.Transaction, err error) {
func (c *RollupClient) RollupWithdrawMerkleProof(fromBJJ babyjub.PublicKeyComp, tokenID uint32,
numExitRoot, idx int64, amount *big.Int, siblings []*big.Int,
instantWithdraw bool) (tx *types.Transaction, err error) {
if tx, err = c.client.CallAuth(
0,
func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) {
@ -434,7 +448,8 @@ func (c *RollupClient) RollupWithdrawMerkleProof(fromBJJ babyjub.PublicKeyComp,
babyPubKey := new(big.Int).SetBytes(pkCompB)
numExitRootB := uint32(numExitRoot)
idxBig := big.NewInt(idx)
return c.hermez.WithdrawMerkleProof(auth, tokenID, amount, babyPubKey, numExitRootB, siblings, idxBig, instantWithdraw)
return c.hermez.WithdrawMerkleProof(auth, tokenID, amount, babyPubKey,
numExitRootB, siblings, idxBig, instantWithdraw)
},
); err != nil {
return nil, tracerr.Wrap(fmt.Errorf("Failed update WithdrawMerkleProof: %w", err))
@ -443,13 +458,17 @@ func (c *RollupClient) RollupWithdrawMerkleProof(fromBJJ babyjub.PublicKeyComp,
}
// RollupWithdrawCircuit is the interface to call the smart contract function
func (c *RollupClient) RollupWithdrawCircuit(proofA, proofC [2]*big.Int, proofB [2][2]*big.Int, tokenID uint32, numExitRoot, idx int64, amount *big.Int, instantWithdraw bool) (*types.Transaction, error) {
func (c *RollupClient) RollupWithdrawCircuit(proofA, proofC [2]*big.Int, proofB [2][2]*big.Int,
tokenID uint32, numExitRoot, idx int64, amount *big.Int, instantWithdraw bool) (*types.Transaction,
error) {
log.Error("TODO")
return nil, tracerr.Wrap(errTODO)
}
// RollupL1UserTxERC20ETH is the interface to call the smart contract function
func (c *RollupClient) RollupL1UserTxERC20ETH(fromBJJ babyjub.PublicKeyComp, fromIdx int64, depositAmount *big.Int, amount *big.Int, tokenID uint32, toIdx int64) (tx *types.Transaction, err error) {
func (c *RollupClient) RollupL1UserTxERC20ETH(fromBJJ babyjub.PublicKeyComp, fromIdx int64,
depositAmount *big.Int, amount *big.Int, tokenID uint32, toIdx int64) (tx *types.Transaction,
err error) {
if tx, err = c.client.CallAuth(
0,
func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) {
@ -484,7 +503,9 @@ func (c *RollupClient) RollupL1UserTxERC20ETH(fromBJJ babyjub.PublicKeyComp, fro
}
// RollupL1UserTxERC20Permit is the interface to call the smart contract function
func (c *RollupClient) RollupL1UserTxERC20Permit(fromBJJ babyjub.PublicKeyComp, fromIdx int64, depositAmount *big.Int, amount *big.Int, tokenID uint32, toIdx int64, deadline *big.Int) (tx *types.Transaction, err error) {
func (c *RollupClient) RollupL1UserTxERC20Permit(fromBJJ babyjub.PublicKeyComp, fromIdx int64,
depositAmount *big.Int, amount *big.Int, tokenID uint32, toIdx int64,
deadline *big.Int) (tx *types.Transaction, err error) {
if tx, err = c.client.CallAuth(
0,
func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) {
@ -516,11 +537,12 @@ func (c *RollupClient) RollupL1UserTxERC20Permit(fromBJJ babyjub.PublicKeyComp,
}
tokenName := c.tokenHEZCfg.Name
tokenAddr := c.tokenHEZCfg.Address
digest, _ := createPermitDigest(tokenAddr, owner, spender, c.chainID, amount, nonce, deadline, tokenName)
digest, _ := createPermitDigest(tokenAddr, owner, spender, c.chainID,
amount, nonce, deadline, tokenName)
signature, _ := c.client.ks.SignHash(*c.client.account, digest)
permit := createPermit(owner, spender, amount, deadline, digest, signature)
return c.hermez.AddL1Transaction(auth, babyPubKey, fromIdxBig, uint16(depositAmountF),
uint16(amountF), tokenID, toIdxBig, permit)
return c.hermez.AddL1Transaction(auth, babyPubKey, fromIdxBig,
uint16(depositAmountF), uint16(amountF), tokenID, toIdxBig, permit)
},
); err != nil {
return nil, tracerr.Wrap(fmt.Errorf("Failed add L1 Tx ERC20Permit: %w", err))
@ -552,11 +574,13 @@ func (c *RollupClient) RollupLastForgedBatch() (lastForgedBatch int64, err error
}
// RollupUpdateForgeL1L2BatchTimeout is the interface to call the smart contract function
func (c *RollupClient) RollupUpdateForgeL1L2BatchTimeout(newForgeL1L2BatchTimeout int64) (tx *types.Transaction, err error) {
func (c *RollupClient) RollupUpdateForgeL1L2BatchTimeout(
newForgeL1L2BatchTimeout int64) (tx *types.Transaction, err error) {
if tx, err = c.client.CallAuth(
0,
func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) {
return c.hermez.UpdateForgeL1L2BatchTimeout(auth, uint8(newForgeL1L2BatchTimeout))
return c.hermez.UpdateForgeL1L2BatchTimeout(auth,
uint8(newForgeL1L2BatchTimeout))
},
); err != nil {
return nil, tracerr.Wrap(fmt.Errorf("Failed update ForgeL1L2BatchTimeout: %w", err))
@ -565,7 +589,8 @@ func (c *RollupClient) RollupUpdateForgeL1L2BatchTimeout(newForgeL1L2BatchTimeou
}
// RollupUpdateFeeAddToken is the interface to call the smart contract function
func (c *RollupClient) RollupUpdateFeeAddToken(newFeeAddToken *big.Int) (tx *types.Transaction, err error) {
func (c *RollupClient) RollupUpdateFeeAddToken(newFeeAddToken *big.Int) (tx *types.Transaction,
err error) {
if tx, err = c.client.CallAuth(
0,
func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) {
@ -600,7 +625,8 @@ func (c *RollupClient) RollupUpdateBucketsParameters(
}
// RollupUpdateTokenExchange is the interface to call the smart contract function
func (c *RollupClient) RollupUpdateTokenExchange(addressArray []ethCommon.Address, valueArray []uint64) (tx *types.Transaction, err error) {
func (c *RollupClient) RollupUpdateTokenExchange(addressArray []ethCommon.Address,
valueArray []uint64) (tx *types.Transaction, err error) {
if tx, err = c.client.CallAuth(
0,
func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) {
@ -613,7 +639,8 @@ func (c *RollupClient) RollupUpdateTokenExchange(addressArray []ethCommon.Addres
}
// RollupUpdateWithdrawalDelay is the interface to call the smart contract function
func (c *RollupClient) RollupUpdateWithdrawalDelay(newWithdrawalDelay int64) (tx *types.Transaction, err error) {
func (c *RollupClient) RollupUpdateWithdrawalDelay(newWithdrawalDelay int64) (tx *types.Transaction,
err error) {
if tx, err = c.client.CallAuth(
0,
func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) {
@ -639,7 +666,8 @@ func (c *RollupClient) RollupSafeMode() (tx *types.Transaction, err error) {
}
// RollupInstantWithdrawalViewer is the interface to call the smart contract function
func (c *RollupClient) RollupInstantWithdrawalViewer(tokenAddress ethCommon.Address, amount *big.Int) (instantAllowed bool, err error) {
func (c *RollupClient) RollupInstantWithdrawalViewer(tokenAddress ethCommon.Address,
amount *big.Int) (instantAllowed bool, err error) {
if err := c.client.Call(func(ec *ethclient.Client) error {
instantAllowed, err = c.hermez.InstantWithdrawalViewer(c.opts, tokenAddress, amount)
return tracerr.Wrap(err)
@ -674,7 +702,8 @@ func (c *RollupClient) RollupConstants() (rollupConstants *common.RollupConstant
}
newRollupVerifier.MaxTx = rollupVerifier.MaxTx.Int64()
newRollupVerifier.NLevels = rollupVerifier.NLevels.Int64()
rollupConstants.Verifiers = append(rollupConstants.Verifiers, newRollupVerifier)
rollupConstants.Verifiers = append(rollupConstants.Verifiers,
newRollupVerifier)
}
rollupConstants.HermezAuctionContract, err = c.hermez.HermezAuctionContract(c.opts)
if err != nil {
@ -693,19 +722,30 @@ func (c *RollupClient) RollupConstants() (rollupConstants *common.RollupConstant
}
var (
logHermezL1UserTxEvent = crypto.Keccak256Hash([]byte("L1UserTxEvent(uint32,uint8,bytes)"))
logHermezAddToken = crypto.Keccak256Hash([]byte("AddToken(address,uint32)"))
logHermezForgeBatch = crypto.Keccak256Hash([]byte("ForgeBatch(uint32,uint16)"))
logHermezUpdateForgeL1L2BatchTimeout = crypto.Keccak256Hash([]byte("UpdateForgeL1L2BatchTimeout(uint8)"))
logHermezUpdateFeeAddToken = crypto.Keccak256Hash([]byte("UpdateFeeAddToken(uint256)"))
logHermezWithdrawEvent = crypto.Keccak256Hash([]byte("WithdrawEvent(uint48,uint32,bool)"))
logHermezUpdateBucketWithdraw = crypto.Keccak256Hash([]byte("UpdateBucketWithdraw(uint8,uint256,uint256)"))
logHermezUpdateWithdrawalDelay = crypto.Keccak256Hash([]byte("UpdateWithdrawalDelay(uint64)"))
logHermezUpdateBucketsParameters = crypto.Keccak256Hash([]byte("UpdateBucketsParameters(uint256[4][" +
strconv.Itoa(common.RollupConstNumBuckets) + "])"))
logHermezUpdateTokenExchange = crypto.Keccak256Hash([]byte("UpdateTokenExchange(address[],uint64[])"))
logHermezSafeMode = crypto.Keccak256Hash([]byte("SafeMode()"))
logHermezInitialize = crypto.Keccak256Hash([]byte("InitializeHermezEvent(uint8,uint256,uint64)"))
logHermezL1UserTxEvent = crypto.Keccak256Hash([]byte(
"L1UserTxEvent(uint32,uint8,bytes)"))
logHermezAddToken = crypto.Keccak256Hash([]byte(
"AddToken(address,uint32)"))
logHermezForgeBatch = crypto.Keccak256Hash([]byte(
"ForgeBatch(uint32,uint16)"))
logHermezUpdateForgeL1L2BatchTimeout = crypto.Keccak256Hash([]byte(
"UpdateForgeL1L2BatchTimeout(uint8)"))
logHermezUpdateFeeAddToken = crypto.Keccak256Hash([]byte(
"UpdateFeeAddToken(uint256)"))
logHermezWithdrawEvent = crypto.Keccak256Hash([]byte(
"WithdrawEvent(uint48,uint32,bool)"))
logHermezUpdateBucketWithdraw = crypto.Keccak256Hash([]byte(
"UpdateBucketWithdraw(uint8,uint256,uint256)"))
logHermezUpdateWithdrawalDelay = crypto.Keccak256Hash([]byte(
"UpdateWithdrawalDelay(uint64)"))
logHermezUpdateBucketsParameters = crypto.Keccak256Hash([]byte(
"UpdateBucketsParameters(uint256[4][" + strconv.Itoa(common.RollupConstNumBuckets) + "])"))
logHermezUpdateTokenExchange = crypto.Keccak256Hash([]byte(
"UpdateTokenExchange(address[],uint64[])"))
logHermezSafeMode = crypto.Keccak256Hash([]byte(
"SafeMode()"))
logHermezInitialize = crypto.Keccak256Hash([]byte(
"InitializeHermezEvent(uint8,uint256,uint64)"))
)
// RollupEventInit returns the initialize event with its corresponding block number
@ -729,7 +769,8 @@ func (c *RollupClient) RollupEventInit() (*RollupEventInitialize, int64, error)
}
var rollupInit RollupEventInitialize
if err := c.contractAbi.UnpackIntoInterface(&rollupInit, "InitializeHermezEvent", vLog.Data); err != nil {
if err := c.contractAbi.UnpackIntoInterface(&rollupInit, "InitializeHermezEvent",
vLog.Data); err != nil {
return nil, 0, tracerr.Wrap(err)
}
return &rollupInit, int64(vLog.BlockNumber), tracerr.Wrap(err)
@ -810,7 +851,8 @@ func (c *RollupClient) RollupEventsByBlock(blockNum int64,
var updateForgeL1L2BatchTimeout struct {
NewForgeL1L2BatchTimeout uint8
}
err := c.contractAbi.UnpackIntoInterface(&updateForgeL1L2BatchTimeout, "UpdateForgeL1L2BatchTimeout", vLog.Data)
err := c.contractAbi.UnpackIntoInterface(&updateForgeL1L2BatchTimeout,
"UpdateForgeL1L2BatchTimeout", vLog.Data)
if err != nil {
return nil, tracerr.Wrap(err)
}
@ -838,14 +880,16 @@ func (c *RollupClient) RollupEventsByBlock(blockNum int64,
case logHermezUpdateBucketWithdraw:
var updateBucketWithdrawAux rollupEventUpdateBucketWithdrawAux
var updateBucketWithdraw RollupEventUpdateBucketWithdraw
err := c.contractAbi.UnpackIntoInterface(&updateBucketWithdrawAux, "UpdateBucketWithdraw", vLog.Data)
err := c.contractAbi.UnpackIntoInterface(&updateBucketWithdrawAux,
"UpdateBucketWithdraw", vLog.Data)
if err != nil {
return nil, tracerr.Wrap(err)
}
updateBucketWithdraw.Withdrawals = updateBucketWithdrawAux.Withdrawals
updateBucketWithdraw.NumBucket = int(new(big.Int).SetBytes(vLog.Topics[1][:]).Int64())
updateBucketWithdraw.BlockStamp = new(big.Int).SetBytes(vLog.Topics[2][:]).Int64()
rollupEvents.UpdateBucketWithdraw = append(rollupEvents.UpdateBucketWithdraw, updateBucketWithdraw)
rollupEvents.UpdateBucketWithdraw =
append(rollupEvents.UpdateBucketWithdraw, updateBucketWithdraw)
case logHermezUpdateWithdrawalDelay:
var withdrawalDelay RollupEventUpdateWithdrawalDelay
@ -857,7 +901,8 @@ func (c *RollupClient) RollupEventsByBlock(blockNum int64,
case logHermezUpdateBucketsParameters:
var bucketsParametersAux rollupEventUpdateBucketsParametersAux
var bucketsParameters RollupEventUpdateBucketsParameters
err := c.contractAbi.UnpackIntoInterface(&bucketsParametersAux, "UpdateBucketsParameters", vLog.Data)
err := c.contractAbi.UnpackIntoInterface(&bucketsParametersAux,
"UpdateBucketsParameters", vLog.Data)
if err != nil {
return nil, tracerr.Wrap(err)
}
@ -867,7 +912,8 @@ func (c *RollupClient) RollupEventsByBlock(blockNum int64,
bucketsParameters.ArrayBuckets[i].BlockWithdrawalRate = bucket[2]
bucketsParameters.ArrayBuckets[i].MaxWithdrawals = bucket[3]
}
rollupEvents.UpdateBucketsParameters = append(rollupEvents.UpdateBucketsParameters, bucketsParameters)
rollupEvents.UpdateBucketsParameters =
append(rollupEvents.UpdateBucketsParameters, bucketsParameters)
case logHermezUpdateTokenExchange:
var tokensExchange RollupEventUpdateTokenExchange
err := c.contractAbi.UnpackIntoInterface(&tokensExchange, "UpdateTokenExchange", vLog.Data)
@ -899,7 +945,8 @@ func (c *RollupClient) RollupEventsByBlock(blockNum int64,
// RollupForgeBatchArgs returns the arguments used in a ForgeBatch call in the
// Rollup Smart Contract in the given transaction, and the sender address.
func (c *RollupClient) RollupForgeBatchArgs(ethTxHash ethCommon.Hash, l1UserTxsLen uint16) (*RollupForgeBatchArgs, *ethCommon.Address, error) {
func (c *RollupClient) RollupForgeBatchArgs(ethTxHash ethCommon.Hash,
l1UserTxsLen uint16) (*RollupForgeBatchArgs, *ethCommon.Address, error) {
tx, _, err := c.client.client.TransactionByHash(context.Background(), ethTxHash)
if err != nil {
return nil, nil, tracerr.Wrap(fmt.Errorf("TransactionByHash: %w", err))
@ -914,7 +961,8 @@ func (c *RollupClient) RollupForgeBatchArgs(ethTxHash ethCommon.Hash, l1UserTxsL
if err != nil {
return nil, nil, tracerr.Wrap(err)
}
sender, err := c.client.client.TransactionSender(context.Background(), tx, receipt.Logs[0].BlockHash, receipt.Logs[0].Index)
sender, err := c.client.client.TransactionSender(context.Background(), tx,
receipt.Logs[0].BlockHash, receipt.Logs[0].Index)
if err != nil {
return nil, nil, tracerr.Wrap(err)
}
@ -939,7 +987,7 @@ func (c *RollupClient) RollupForgeBatchArgs(ethTxHash ethCommon.Hash, l1UserTxsL
FeeIdxCoordinator: []common.Idx{},
}
nLevels := c.consts.Verifiers[rollupForgeBatchArgs.VerifierIdx].NLevels
lenL1L2TxsBytes := int((nLevels/8)*2 + common.Float40BytesLength + 1)
lenL1L2TxsBytes := int((nLevels/8)*2 + common.Float40BytesLength + 1) //nolint:gomnd
numBytesL1TxUser := int(l1UserTxsLen) * lenL1L2TxsBytes
numTxsL1Coord := len(aux.EncodedL1CoordinatorTx) / common.RollupConstL1CoordinatorTotalBytes
numBytesL1TxCoord := numTxsL1Coord * lenL1L2TxsBytes
@ -949,7 +997,9 @@ func (c *RollupClient) RollupForgeBatchArgs(ethTxHash ethCommon.Hash, l1UserTxsL
l1UserTxsData = aux.L1L2TxsData[:numBytesL1TxUser]
}
for i := 0; i < int(l1UserTxsLen); i++ {
l1Tx, err := common.L1TxFromDataAvailability(l1UserTxsData[i*lenL1L2TxsBytes:(i+1)*lenL1L2TxsBytes], uint32(nLevels))
l1Tx, err :=
common.L1TxFromDataAvailability(l1UserTxsData[i*lenL1L2TxsBytes:(i+1)*lenL1L2TxsBytes],
uint32(nLevels))
if err != nil {
return nil, nil, tracerr.Wrap(err)
}
@ -961,14 +1011,17 @@ func (c *RollupClient) RollupForgeBatchArgs(ethTxHash ethCommon.Hash, l1UserTxsL
}
numTxsL2 := len(l2TxsData) / lenL1L2TxsBytes
for i := 0; i < numTxsL2; i++ {
l2Tx, err := common.L2TxFromBytesDataAvailability(l2TxsData[i*lenL1L2TxsBytes:(i+1)*lenL1L2TxsBytes], int(nLevels))
l2Tx, err :=
common.L2TxFromBytesDataAvailability(l2TxsData[i*lenL1L2TxsBytes:(i+1)*lenL1L2TxsBytes],
int(nLevels))
if err != nil {
return nil, nil, tracerr.Wrap(err)
}
rollupForgeBatchArgs.L2TxsData = append(rollupForgeBatchArgs.L2TxsData, *l2Tx)
}
for i := 0; i < numTxsL1Coord; i++ {
bytesL1Coordinator := aux.EncodedL1CoordinatorTx[i*common.RollupConstL1CoordinatorTotalBytes : (i+1)*common.RollupConstL1CoordinatorTotalBytes]
bytesL1Coordinator :=
aux.EncodedL1CoordinatorTx[i*common.RollupConstL1CoordinatorTotalBytes : (i+1)*common.RollupConstL1CoordinatorTotalBytes] //nolint:lll
var signature []byte
v := bytesL1Coordinator[0]
s := bytesL1Coordinator[1:33]
@ -981,24 +1034,29 @@ func (c *RollupClient) RollupForgeBatchArgs(ethTxHash ethCommon.Hash, l1UserTxsL
return nil, nil, tracerr.Wrap(err)
}
rollupForgeBatchArgs.L1CoordinatorTxs = append(rollupForgeBatchArgs.L1CoordinatorTxs, *l1Tx)
rollupForgeBatchArgs.L1CoordinatorTxsAuths = append(rollupForgeBatchArgs.L1CoordinatorTxsAuths, signature)
rollupForgeBatchArgs.L1CoordinatorTxsAuths =
append(rollupForgeBatchArgs.L1CoordinatorTxsAuths, signature)
}
lenFeeIdxCoordinatorBytes := int(nLevels / 8) //nolint:gomnd
numFeeIdxCoordinator := len(aux.FeeIdxCoordinator) / lenFeeIdxCoordinatorBytes
for i := 0; i < numFeeIdxCoordinator; i++ {
var paddedFeeIdx [6]byte
// TODO: This check is not necessary: the first case will always work. Test it before removing the if.
// TODO: This check is not necessary: the first case will always work. Test it
// before removing the if.
if lenFeeIdxCoordinatorBytes < common.IdxBytesLen {
copy(paddedFeeIdx[6-lenFeeIdxCoordinatorBytes:], aux.FeeIdxCoordinator[i*lenFeeIdxCoordinatorBytes:(i+1)*lenFeeIdxCoordinatorBytes])
copy(paddedFeeIdx[6-lenFeeIdxCoordinatorBytes:],
aux.FeeIdxCoordinator[i*lenFeeIdxCoordinatorBytes:(i+1)*lenFeeIdxCoordinatorBytes])
} else {
copy(paddedFeeIdx[:], aux.FeeIdxCoordinator[i*lenFeeIdxCoordinatorBytes:(i+1)*lenFeeIdxCoordinatorBytes])
copy(paddedFeeIdx[:],
aux.FeeIdxCoordinator[i*lenFeeIdxCoordinatorBytes:(i+1)*lenFeeIdxCoordinatorBytes])
}
feeIdxCoordinator, err := common.IdxFromBytes(paddedFeeIdx[:])
if err != nil {
return nil, nil, tracerr.Wrap(err)
}
if feeIdxCoordinator != common.Idx(0) {
rollupForgeBatchArgs.FeeIdxCoordinator = append(rollupForgeBatchArgs.FeeIdxCoordinator, feeIdxCoordinator)
rollupForgeBatchArgs.FeeIdxCoordinator =
append(rollupForgeBatchArgs.FeeIdxCoordinator, feeIdxCoordinator)
}
}
return &rollupForgeBatchArgs, &sender, nil

+ 145
- 69
eth/rollup_test.go

@ -116,7 +116,8 @@ func TestRollupForgeBatch(t *testing.T) {
minBid.SetString("11000000000000000000", 10)
budget := new(big.Int)
budget.SetString("45200000000000000000", 10)
_, err = auctionClient.AuctionMultiBid(budget, currentSlot+4, currentSlot+10, slotSet, maxBid, minBid, deadline)
_, err = auctionClient.AuctionMultiBid(budget, currentSlot+4, currentSlot+10, slotSet,
maxBid, minBid, deadline)
require.NoError(t, err)
// Add Blocks
@ -128,12 +129,18 @@ func TestRollupForgeBatch(t *testing.T) {
// Forge Batch 1
args := new(RollupForgeBatchArgs)
args.FeeIdxCoordinator = []common.Idx{} // When encoded, 64 times the 0 idx means that no idx to collect fees is specified.
l1CoordinatorBytes, err := hex.DecodeString("1c660323607bb113e586183609964a333d07ebe4bef3be82ec13af453bae9590bd7711cdb6abf42f176eadfbe5506fbef5e092e5543733f91b0061d9a7747fa10694a915a6470fa230de387b51e6f4db0b09787867778687b55197ad6d6a86eac000000001")
// When encoded, 64 times the 0 idx means that no idx to collect fees is specified.
args.FeeIdxCoordinator = []common.Idx{}
l1CoordinatorBytes, err := hex.DecodeString(
"1c660323607bb113e586183609964a333d07ebe4bef3be82ec13af453bae9590bd7711cdb6abf" +
"42f176eadfbe5506fbef5e092e5543733f91b0061d9a7747fa10694a915a6470fa230" +
"de387b51e6f4db0b09787867778687b55197ad6d6a86eac000000001")
require.NoError(t, err)
numTxsL1 := len(l1CoordinatorBytes) / common.RollupConstL1CoordinatorTotalBytes
for i := 0; i < numTxsL1; i++ {
bytesL1Coordinator := l1CoordinatorBytes[i*common.RollupConstL1CoordinatorTotalBytes : (i+1)*common.RollupConstL1CoordinatorTotalBytes]
bytesL1Coordinator :=
l1CoordinatorBytes[i*common.RollupConstL1CoordinatorTotalBytes : (i+1)*
common.RollupConstL1CoordinatorTotalBytes]
var signature []byte
v := bytesL1Coordinator[0]
s := bytesL1Coordinator[1:33]
@ -149,9 +156,12 @@ func TestRollupForgeBatch(t *testing.T) {
args.L1UserTxs = []common.L1Tx{}
args.L2TxsData = []common.L2Tx{}
newStateRoot := new(big.Int)
newStateRoot.SetString("18317824016047294649053625209337295956588174734569560016974612130063629505228", 10)
newStateRoot.SetString(
"18317824016047294649053625209337295956588174734569560016974612130063629505228",
10)
newExitRoot := new(big.Int)
bytesNumExitRoot, err := hex.DecodeString("10a89d5fe8d488eda1ba371d633515739933c706c210c604f5bd209180daa43b")
bytesNumExitRoot, err := hex.DecodeString(
"10a89d5fe8d488eda1ba371d633515739933c706c210c604f5bd209180daa43b")
require.NoError(t, err)
newExitRoot.SetBytes(bytesNumExitRoot)
args.NewLastIdx = int64(300)
@ -206,7 +216,8 @@ func TestRollupUpdateForgeL1L2BatchTimeout(t *testing.T) {
rollupEvents, err := rollupClient.RollupEventsByBlock(currentBlockNum, nil)
require.NoError(t, err)
assert.Equal(t, newForgeL1L2BatchTimeout, rollupEvents.UpdateForgeL1L2BatchTimeout[0].NewForgeL1L2BatchTimeout)
assert.Equal(t, newForgeL1L2BatchTimeout,
rollupEvents.UpdateForgeL1L2BatchTimeout[0].NewForgeL1L2BatchTimeout)
}
func TestRollupUpdateFeeAddToken(t *testing.T) {
@ -248,7 +259,8 @@ func TestRollupUpdateWithdrawalDelay(t *testing.T) {
require.NoError(t, err)
rollupEvents, err := rollupClient.RollupEventsByBlock(currentBlockNum, nil)
require.NoError(t, err)
assert.Equal(t, newWithdrawalDelay, int64(rollupEvents.UpdateWithdrawalDelay[0].NewWithdrawalDelay))
assert.Equal(t, newWithdrawalDelay,
int64(rollupEvents.UpdateWithdrawalDelay[0].NewWithdrawalDelay))
}
func TestRollupUpdateTokenExchange(t *testing.T) {
@ -287,7 +299,8 @@ func TestRollupL1UserTxETHCreateAccountDeposit(t *testing.T) {
}
L1UserTxs = append(L1UserTxs, l1Tx)
_, err = rollupClientAux.RollupL1UserTxERC20ETH(l1Tx.FromBJJ, fromIdxInt64, l1Tx.DepositAmount, l1Tx.Amount, tokenIDUint32, toIdxInt64)
_, err = rollupClientAux.RollupL1UserTxERC20ETH(l1Tx.FromBJJ, fromIdxInt64,
l1Tx.DepositAmount, l1Tx.Amount, tokenIDUint32, toIdxInt64)
require.NoError(t, err)
currentBlockNum, err := rollupClient.client.EthLastBlock()
@ -299,11 +312,13 @@ func TestRollupL1UserTxETHCreateAccountDeposit(t *testing.T) {
assert.Equal(t, l1Tx.DepositAmount, rollupEvents.L1UserTx[0].L1UserTx.DepositAmount)
assert.Equal(t, l1Tx.TokenID, rollupEvents.L1UserTx[0].L1UserTx.TokenID)
assert.Equal(t, l1Tx.Amount, rollupEvents.L1UserTx[0].L1UserTx.Amount)
assert.Equal(t, rollupClientAux.client.account.Address, rollupEvents.L1UserTx[0].L1UserTx.FromEthAddr)
assert.Equal(t, rollupClientAux.client.account.Address,
rollupEvents.L1UserTx[0].L1UserTx.FromEthAddr)
}
func TestRollupL1UserTxERC20CreateAccountDeposit(t *testing.T) {
rollupClientAux2, err := NewRollupClient(ethereumClientAux2, hermezRollupAddressConst, tokenHEZ)
rollupClientAux2, err := NewRollupClient(ethereumClientAux2, hermezRollupAddressConst,
tokenHEZ)
require.NoError(t, err)
key := genKeysBjj(1)
fromIdxInt64 := int64(0)
@ -319,7 +334,8 @@ func TestRollupL1UserTxERC20CreateAccountDeposit(t *testing.T) {
}
L1UserTxs = append(L1UserTxs, l1Tx)
_, err = rollupClientAux2.RollupL1UserTxERC20ETH(l1Tx.FromBJJ, fromIdxInt64, l1Tx.DepositAmount, l1Tx.Amount, tokenHEZID, toIdxInt64)
_, err = rollupClientAux2.RollupL1UserTxERC20ETH(l1Tx.FromBJJ, fromIdxInt64,
l1Tx.DepositAmount, l1Tx.Amount, tokenHEZID, toIdxInt64)
require.NoError(t, err)
currentBlockNum, err := rollupClient.client.EthLastBlock()
@ -331,11 +347,13 @@ func TestRollupL1UserTxERC20CreateAccountDeposit(t *testing.T) {
assert.Equal(t, l1Tx.DepositAmount, rollupEvents.L1UserTx[0].L1UserTx.DepositAmount)
assert.Equal(t, l1Tx.TokenID, rollupEvents.L1UserTx[0].L1UserTx.TokenID)
assert.Equal(t, l1Tx.Amount, rollupEvents.L1UserTx[0].L1UserTx.Amount)
assert.Equal(t, rollupClientAux2.client.account.Address, rollupEvents.L1UserTx[0].L1UserTx.FromEthAddr)
assert.Equal(t, rollupClientAux2.client.account.Address,
rollupEvents.L1UserTx[0].L1UserTx.FromEthAddr)
}
func TestRollupL1UserTxERC20PermitCreateAccountDeposit(t *testing.T) {
rollupClientAux, err := NewRollupClient(ethereumClientAux, hermezRollupAddressConst, tokenHEZ)
rollupClientAux, err := NewRollupClient(ethereumClientAux, hermezRollupAddressConst,
tokenHEZ)
require.NoError(t, err)
key := genKeysBjj(3)
fromIdxInt64 := int64(0)
@ -351,7 +369,8 @@ func TestRollupL1UserTxERC20PermitCreateAccountDeposit(t *testing.T) {
}
L1UserTxs = append(L1UserTxs, l1Tx)
_, err = rollupClientAux.RollupL1UserTxERC20Permit(l1Tx.FromBJJ, fromIdxInt64, l1Tx.DepositAmount, l1Tx.Amount, tokenIDERC777, toIdxInt64, deadline)
_, err = rollupClientAux.RollupL1UserTxERC20Permit(l1Tx.FromBJJ, fromIdxInt64,
l1Tx.DepositAmount, l1Tx.Amount, tokenIDERC777, toIdxInt64, deadline)
require.NoError(t, err)
currentBlockNum, err := rollupClient.client.EthLastBlock()
@ -363,11 +382,13 @@ func TestRollupL1UserTxERC20PermitCreateAccountDeposit(t *testing.T) {
assert.Equal(t, l1Tx.DepositAmount, rollupEvents.L1UserTx[0].L1UserTx.DepositAmount)
assert.Equal(t, l1Tx.TokenID, rollupEvents.L1UserTx[0].L1UserTx.TokenID)
assert.Equal(t, l1Tx.Amount, rollupEvents.L1UserTx[0].L1UserTx.Amount)
assert.Equal(t, rollupClientAux.client.account.Address, rollupEvents.L1UserTx[0].L1UserTx.FromEthAddr)
assert.Equal(t, rollupClientAux.client.account.Address,
rollupEvents.L1UserTx[0].L1UserTx.FromEthAddr)
}
func TestRollupL1UserTxETHDeposit(t *testing.T) {
rollupClientAux, err := NewRollupClient(ethereumClientAux, hermezRollupAddressConst, tokenHEZ)
rollupClientAux, err := NewRollupClient(ethereumClientAux, hermezRollupAddressConst,
tokenHEZ)
require.NoError(t, err)
fromIdxInt64 := int64(256)
toIdxInt64 := int64(0)
@ -383,7 +404,8 @@ func TestRollupL1UserTxETHDeposit(t *testing.T) {
}
L1UserTxs = append(L1UserTxs, l1Tx)
_, err = rollupClientAux.RollupL1UserTxERC20ETH(l1Tx.FromBJJ, fromIdxInt64, l1Tx.DepositAmount, l1Tx.Amount, tokenIDUint32, toIdxInt64)
_, err = rollupClientAux.RollupL1UserTxERC20ETH(l1Tx.FromBJJ, fromIdxInt64,
l1Tx.DepositAmount, l1Tx.Amount, tokenIDUint32, toIdxInt64)
require.NoError(t, err)
currentBlockNum, err := rollupClient.client.EthLastBlock()
@ -394,11 +416,13 @@ func TestRollupL1UserTxETHDeposit(t *testing.T) {
assert.Equal(t, l1Tx.DepositAmount, rollupEvents.L1UserTx[0].L1UserTx.DepositAmount)
assert.Equal(t, l1Tx.TokenID, rollupEvents.L1UserTx[0].L1UserTx.TokenID)
assert.Equal(t, l1Tx.Amount, rollupEvents.L1UserTx[0].L1UserTx.Amount)
assert.Equal(t, rollupClientAux.client.account.Address, rollupEvents.L1UserTx[0].L1UserTx.FromEthAddr)
assert.Equal(t, rollupClientAux.client.account.Address,
rollupEvents.L1UserTx[0].L1UserTx.FromEthAddr)
}
func TestRollupL1UserTxERC20Deposit(t *testing.T) {
rollupClientAux2, err := NewRollupClient(ethereumClientAux2, hermezRollupAddressConst, tokenHEZ)
rollupClientAux2, err := NewRollupClient(ethereumClientAux2, hermezRollupAddressConst,
tokenHEZ)
require.NoError(t, err)
fromIdxInt64 := int64(257)
toIdxInt64 := int64(0)
@ -413,7 +437,8 @@ func TestRollupL1UserTxERC20Deposit(t *testing.T) {
}
L1UserTxs = append(L1UserTxs, l1Tx)
_, err = rollupClientAux2.RollupL1UserTxERC20ETH(l1Tx.FromBJJ, fromIdxInt64, l1Tx.DepositAmount, l1Tx.Amount, tokenHEZID, toIdxInt64)
_, err = rollupClientAux2.RollupL1UserTxERC20ETH(l1Tx.FromBJJ, fromIdxInt64,
l1Tx.DepositAmount, l1Tx.Amount, tokenHEZID, toIdxInt64)
require.NoError(t, err)
currentBlockNum, err := rollupClient.client.EthLastBlock()
@ -424,11 +449,13 @@ func TestRollupL1UserTxERC20Deposit(t *testing.T) {
assert.Equal(t, l1Tx.DepositAmount, rollupEvents.L1UserTx[0].L1UserTx.DepositAmount)
assert.Equal(t, l1Tx.TokenID, rollupEvents.L1UserTx[0].L1UserTx.TokenID)
assert.Equal(t, l1Tx.Amount, rollupEvents.L1UserTx[0].L1UserTx.Amount)
assert.Equal(t, rollupClientAux2.client.account.Address, rollupEvents.L1UserTx[0].L1UserTx.FromEthAddr)
assert.Equal(t, rollupClientAux2.client.account.Address,
rollupEvents.L1UserTx[0].L1UserTx.FromEthAddr)
}
func TestRollupL1UserTxERC20PermitDeposit(t *testing.T) {
rollupClientAux, err := NewRollupClient(ethereumClientAux, hermezRollupAddressConst, tokenHEZ)
rollupClientAux, err := NewRollupClient(ethereumClientAux, hermezRollupAddressConst,
tokenHEZ)
require.NoError(t, err)
fromIdxInt64 := int64(258)
toIdxInt64 := int64(0)
@ -442,7 +469,8 @@ func TestRollupL1UserTxERC20PermitDeposit(t *testing.T) {
}
L1UserTxs = append(L1UserTxs, l1Tx)
_, err = rollupClientAux.RollupL1UserTxERC20Permit(l1Tx.FromBJJ, fromIdxInt64, l1Tx.DepositAmount, l1Tx.Amount, tokenIDERC777, toIdxInt64, deadline)
_, err = rollupClientAux.RollupL1UserTxERC20Permit(l1Tx.FromBJJ, fromIdxInt64,
l1Tx.DepositAmount, l1Tx.Amount, tokenIDERC777, toIdxInt64, deadline)
require.NoError(t, err)
currentBlockNum, err := rollupClient.client.EthLastBlock()
@ -453,11 +481,13 @@ func TestRollupL1UserTxERC20PermitDeposit(t *testing.T) {
assert.Equal(t, l1Tx.DepositAmount, rollupEvents.L1UserTx[0].L1UserTx.DepositAmount)
assert.Equal(t, l1Tx.TokenID, rollupEvents.L1UserTx[0].L1UserTx.TokenID)
assert.Equal(t, l1Tx.Amount, rollupEvents.L1UserTx[0].L1UserTx.Amount)
assert.Equal(t, rollupClientAux.client.account.Address, rollupEvents.L1UserTx[0].L1UserTx.FromEthAddr)
assert.Equal(t, rollupClientAux.client.account.Address,
rollupEvents.L1UserTx[0].L1UserTx.FromEthAddr)
}
func TestRollupL1UserTxETHDepositTransfer(t *testing.T) {
rollupClientAux, err := NewRollupClient(ethereumClientAux, hermezRollupAddressConst, tokenHEZ)
rollupClientAux, err := NewRollupClient(ethereumClientAux, hermezRollupAddressConst,
tokenHEZ)
require.NoError(t, err)
fromIdxInt64 := int64(256)
toIdxInt64 := int64(257)
@ -473,7 +503,8 @@ func TestRollupL1UserTxETHDepositTransfer(t *testing.T) {
}
L1UserTxs = append(L1UserTxs, l1Tx)
_, err = rollupClientAux.RollupL1UserTxERC20ETH(l1Tx.FromBJJ, fromIdxInt64, l1Tx.DepositAmount, l1Tx.Amount, tokenIDUint32, toIdxInt64)
_, err = rollupClientAux.RollupL1UserTxERC20ETH(l1Tx.FromBJJ, fromIdxInt64,
l1Tx.DepositAmount, l1Tx.Amount, tokenIDUint32, toIdxInt64)
require.NoError(t, err)
currentBlockNum, err := rollupClient.client.EthLastBlock()
@ -484,11 +515,13 @@ func TestRollupL1UserTxETHDepositTransfer(t *testing.T) {
assert.Equal(t, l1Tx.DepositAmount, rollupEvents.L1UserTx[0].L1UserTx.DepositAmount)
assert.Equal(t, l1Tx.TokenID, rollupEvents.L1UserTx[0].L1UserTx.TokenID)
assert.Equal(t, l1Tx.Amount, rollupEvents.L1UserTx[0].L1UserTx.Amount)
assert.Equal(t, rollupClientAux.client.account.Address, rollupEvents.L1UserTx[0].L1UserTx.FromEthAddr)
assert.Equal(t, rollupClientAux.client.account.Address,
rollupEvents.L1UserTx[0].L1UserTx.FromEthAddr)
}
func TestRollupL1UserTxERC20DepositTransfer(t *testing.T) {
rollupClientAux2, err := NewRollupClient(ethereumClientAux2, hermezRollupAddressConst, tokenHEZ)
rollupClientAux2, err := NewRollupClient(ethereumClientAux2, hermezRollupAddressConst,
tokenHEZ)
require.NoError(t, err)
fromIdxInt64 := int64(257)
toIdxInt64 := int64(258)
@ -503,7 +536,8 @@ func TestRollupL1UserTxERC20DepositTransfer(t *testing.T) {
}
L1UserTxs = append(L1UserTxs, l1Tx)
_, err = rollupClientAux2.RollupL1UserTxERC20ETH(l1Tx.FromBJJ, fromIdxInt64, l1Tx.DepositAmount, l1Tx.Amount, tokenHEZID, toIdxInt64)
_, err = rollupClientAux2.RollupL1UserTxERC20ETH(l1Tx.FromBJJ, fromIdxInt64,
l1Tx.DepositAmount, l1Tx.Amount, tokenHEZID, toIdxInt64)
require.NoError(t, err)
currentBlockNum, err := rollupClient.client.EthLastBlock()
@ -514,11 +548,13 @@ func TestRollupL1UserTxERC20DepositTransfer(t *testing.T) {
assert.Equal(t, l1Tx.DepositAmount, rollupEvents.L1UserTx[0].L1UserTx.DepositAmount)
assert.Equal(t, l1Tx.TokenID, rollupEvents.L1UserTx[0].L1UserTx.TokenID)
assert.Equal(t, l1Tx.Amount, rollupEvents.L1UserTx[0].L1UserTx.Amount)
assert.Equal(t, rollupClientAux2.client.account.Address, rollupEvents.L1UserTx[0].L1UserTx.FromEthAddr)
assert.Equal(t, rollupClientAux2.client.account.Address,
rollupEvents.L1UserTx[0].L1UserTx.FromEthAddr)
}
func TestRollupL1UserTxERC20PermitDepositTransfer(t *testing.T) {
rollupClientAux, err := NewRollupClient(ethereumClientAux, hermezRollupAddressConst, tokenHEZ)
rollupClientAux, err := NewRollupClient(ethereumClientAux, hermezRollupAddressConst,
tokenHEZ)
require.NoError(t, err)
fromIdxInt64 := int64(258)
toIdxInt64 := int64(259)
@ -533,7 +569,8 @@ func TestRollupL1UserTxERC20PermitDepositTransfer(t *testing.T) {
}
L1UserTxs = append(L1UserTxs, l1Tx)
_, err = rollupClientAux.RollupL1UserTxERC20Permit(l1Tx.FromBJJ, fromIdxInt64, l1Tx.DepositAmount, l1Tx.Amount, tokenIDERC777, toIdxInt64, deadline)
_, err = rollupClientAux.RollupL1UserTxERC20Permit(l1Tx.FromBJJ, fromIdxInt64,
l1Tx.DepositAmount, l1Tx.Amount, tokenIDERC777, toIdxInt64, deadline)
require.NoError(t, err)
currentBlockNum, err := rollupClient.client.EthLastBlock()
@ -544,11 +581,13 @@ func TestRollupL1UserTxERC20PermitDepositTransfer(t *testing.T) {
assert.Equal(t, l1Tx.DepositAmount, rollupEvents.L1UserTx[0].L1UserTx.DepositAmount)
assert.Equal(t, l1Tx.TokenID, rollupEvents.L1UserTx[0].L1UserTx.TokenID)
assert.Equal(t, l1Tx.Amount, rollupEvents.L1UserTx[0].L1UserTx.Amount)
assert.Equal(t, rollupClientAux.client.account.Address, rollupEvents.L1UserTx[0].L1UserTx.FromEthAddr)
assert.Equal(t, rollupClientAux.client.account.Address,
rollupEvents.L1UserTx[0].L1UserTx.FromEthAddr)
}
func TestRollupL1UserTxETHCreateAccountDepositTransfer(t *testing.T) {
rollupClientAux, err := NewRollupClient(ethereumClientAux, hermezRollupAddressConst, tokenHEZ)
rollupClientAux, err := NewRollupClient(ethereumClientAux, hermezRollupAddressConst,
tokenHEZ)
require.NoError(t, err)
fromIdxInt64 := int64(256)
toIdxInt64 := int64(257)
@ -564,7 +603,8 @@ func TestRollupL1UserTxETHCreateAccountDepositTransfer(t *testing.T) {
}
L1UserTxs = append(L1UserTxs, l1Tx)
_, err = rollupClientAux.RollupL1UserTxERC20ETH(l1Tx.FromBJJ, fromIdxInt64, l1Tx.DepositAmount, l1Tx.Amount, tokenIDUint32, toIdxInt64)
_, err = rollupClientAux.RollupL1UserTxERC20ETH(l1Tx.FromBJJ, fromIdxInt64,
l1Tx.DepositAmount, l1Tx.Amount, tokenIDUint32, toIdxInt64)
require.NoError(t, err)
currentBlockNum, err := rollupClient.client.EthLastBlock()
@ -575,11 +615,13 @@ func TestRollupL1UserTxETHCreateAccountDepositTransfer(t *testing.T) {
assert.Equal(t, l1Tx.DepositAmount, rollupEvents.L1UserTx[0].L1UserTx.DepositAmount)
assert.Equal(t, l1Tx.TokenID, rollupEvents.L1UserTx[0].L1UserTx.TokenID)
assert.Equal(t, l1Tx.Amount, rollupEvents.L1UserTx[0].L1UserTx.Amount)
assert.Equal(t, rollupClientAux.client.account.Address, rollupEvents.L1UserTx[0].L1UserTx.FromEthAddr)
assert.Equal(t, rollupClientAux.client.account.Address,
rollupEvents.L1UserTx[0].L1UserTx.FromEthAddr)
}
func TestRollupL1UserTxERC20CreateAccountDepositTransfer(t *testing.T) {
rollupClientAux2, err := NewRollupClient(ethereumClientAux2, hermezRollupAddressConst, tokenHEZ)
rollupClientAux2, err := NewRollupClient(ethereumClientAux2, hermezRollupAddressConst,
tokenHEZ)
require.NoError(t, err)
fromIdxInt64 := int64(257)
toIdxInt64 := int64(258)
@ -594,7 +636,8 @@ func TestRollupL1UserTxERC20CreateAccountDepositTransfer(t *testing.T) {
}
L1UserTxs = append(L1UserTxs, l1Tx)
_, err = rollupClientAux2.RollupL1UserTxERC20ETH(l1Tx.FromBJJ, fromIdxInt64, l1Tx.DepositAmount, l1Tx.Amount, tokenHEZID, toIdxInt64)
_, err = rollupClientAux2.RollupL1UserTxERC20ETH(l1Tx.FromBJJ, fromIdxInt64,
l1Tx.DepositAmount, l1Tx.Amount, tokenHEZID, toIdxInt64)
require.NoError(t, err)
currentBlockNum, err := rollupClient.client.EthLastBlock()
@ -605,11 +648,13 @@ func TestRollupL1UserTxERC20CreateAccountDepositTransfer(t *testing.T) {
assert.Equal(t, l1Tx.DepositAmount, rollupEvents.L1UserTx[0].L1UserTx.DepositAmount)
assert.Equal(t, l1Tx.TokenID, rollupEvents.L1UserTx[0].L1UserTx.TokenID)
assert.Equal(t, l1Tx.Amount, rollupEvents.L1UserTx[0].L1UserTx.Amount)
assert.Equal(t, rollupClientAux2.client.account.Address, rollupEvents.L1UserTx[0].L1UserTx.FromEthAddr)
assert.Equal(t, rollupClientAux2.client.account.Address,
rollupEvents.L1UserTx[0].L1UserTx.FromEthAddr)
}
func TestRollupL1UserTxERC20PermitCreateAccountDepositTransfer(t *testing.T) {
rollupClientAux, err := NewRollupClient(ethereumClientAux, hermezRollupAddressConst, tokenHEZ)
rollupClientAux, err := NewRollupClient(ethereumClientAux, hermezRollupAddressConst,
tokenHEZ)
require.NoError(t, err)
fromIdxInt64 := int64(258)
toIdxInt64 := int64(259)
@ -624,7 +669,8 @@ func TestRollupL1UserTxERC20PermitCreateAccountDepositTransfer(t *testing.T) {
}
L1UserTxs = append(L1UserTxs, l1Tx)
_, err = rollupClientAux.RollupL1UserTxERC20Permit(l1Tx.FromBJJ, fromIdxInt64, l1Tx.DepositAmount, l1Tx.Amount, tokenIDERC777, toIdxInt64, deadline)
_, err = rollupClientAux.RollupL1UserTxERC20Permit(l1Tx.FromBJJ, fromIdxInt64,
l1Tx.DepositAmount, l1Tx.Amount, tokenIDERC777, toIdxInt64, deadline)
require.NoError(t, err)
currentBlockNum, err := rollupClient.client.EthLastBlock()
@ -635,11 +681,13 @@ func TestRollupL1UserTxERC20PermitCreateAccountDepositTransfer(t *testing.T) {
assert.Equal(t, l1Tx.DepositAmount, rollupEvents.L1UserTx[0].L1UserTx.DepositAmount)
assert.Equal(t, l1Tx.TokenID, rollupEvents.L1UserTx[0].L1UserTx.TokenID)
assert.Equal(t, l1Tx.Amount, rollupEvents.L1UserTx[0].L1UserTx.Amount)
assert.Equal(t, rollupClientAux.client.account.Address, rollupEvents.L1UserTx[0].L1UserTx.FromEthAddr)
assert.Equal(t, rollupClientAux.client.account.Address,
rollupEvents.L1UserTx[0].L1UserTx.FromEthAddr)
}
func TestRollupL1UserTxETHForceTransfer(t *testing.T) {
rollupClientAux, err := NewRollupClient(ethereumClientAux, hermezRollupAddressConst, tokenHEZ)
rollupClientAux, err := NewRollupClient(ethereumClientAux, hermezRollupAddressConst,
tokenHEZ)
require.NoError(t, err)
fromIdxInt64 := int64(256)
toIdxInt64 := int64(257)
@ -654,7 +702,8 @@ func TestRollupL1UserTxETHForceTransfer(t *testing.T) {
}
L1UserTxs = append(L1UserTxs, l1Tx)
_, err = rollupClientAux.RollupL1UserTxERC20ETH(l1Tx.FromBJJ, fromIdxInt64, l1Tx.DepositAmount, l1Tx.Amount, tokenIDUint32, toIdxInt64)
_, err = rollupClientAux.RollupL1UserTxERC20ETH(l1Tx.FromBJJ, fromIdxInt64,
l1Tx.DepositAmount, l1Tx.Amount, tokenIDUint32, toIdxInt64)
require.NoError(t, err)
currentBlockNum, err := rollupClient.client.EthLastBlock()
@ -665,11 +714,13 @@ func TestRollupL1UserTxETHForceTransfer(t *testing.T) {
assert.Equal(t, l1Tx.DepositAmount, rollupEvents.L1UserTx[0].L1UserTx.DepositAmount)
assert.Equal(t, l1Tx.TokenID, rollupEvents.L1UserTx[0].L1UserTx.TokenID)
assert.Equal(t, l1Tx.Amount, rollupEvents.L1UserTx[0].L1UserTx.Amount)
assert.Equal(t, rollupClientAux.client.account.Address, rollupEvents.L1UserTx[0].L1UserTx.FromEthAddr)
assert.Equal(t, rollupClientAux.client.account.Address,
rollupEvents.L1UserTx[0].L1UserTx.FromEthAddr)
}
func TestRollupL1UserTxERC20ForceTransfer(t *testing.T) {
rollupClientAux2, err := NewRollupClient(ethereumClientAux2, hermezRollupAddressConst, tokenHEZ)
rollupClientAux2, err := NewRollupClient(ethereumClientAux2, hermezRollupAddressConst,
tokenHEZ)
require.NoError(t, err)
fromIdxInt64 := int64(257)
toIdxInt64 := int64(258)
@ -683,7 +734,8 @@ func TestRollupL1UserTxERC20ForceTransfer(t *testing.T) {
}
L1UserTxs = append(L1UserTxs, l1Tx)
_, err = rollupClientAux2.RollupL1UserTxERC20ETH(l1Tx.FromBJJ, fromIdxInt64, l1Tx.DepositAmount, l1Tx.Amount, tokenHEZID, toIdxInt64)
_, err = rollupClientAux2.RollupL1UserTxERC20ETH(l1Tx.FromBJJ, fromIdxInt64,
l1Tx.DepositAmount, l1Tx.Amount, tokenHEZID, toIdxInt64)
require.NoError(t, err)
currentBlockNum, err := rollupClient.client.EthLastBlock()
@ -694,11 +746,13 @@ func TestRollupL1UserTxERC20ForceTransfer(t *testing.T) {
assert.Equal(t, l1Tx.DepositAmount, rollupEvents.L1UserTx[0].L1UserTx.DepositAmount)
assert.Equal(t, l1Tx.TokenID, rollupEvents.L1UserTx[0].L1UserTx.TokenID)
assert.Equal(t, l1Tx.Amount, rollupEvents.L1UserTx[0].L1UserTx.Amount)
assert.Equal(t, rollupClientAux2.client.account.Address, rollupEvents.L1UserTx[0].L1UserTx.FromEthAddr)
assert.Equal(t, rollupClientAux2.client.account.Address,
rollupEvents.L1UserTx[0].L1UserTx.FromEthAddr)
}
func TestRollupL1UserTxERC20PermitForceTransfer(t *testing.T) {
rollupClientAux, err := NewRollupClient(ethereumClientAux, hermezRollupAddressConst, tokenHEZ)
rollupClientAux, err := NewRollupClient(ethereumClientAux, hermezRollupAddressConst,
tokenHEZ)
require.NoError(t, err)
fromIdxInt64 := int64(259)
toIdxInt64 := int64(260)
@ -712,7 +766,8 @@ func TestRollupL1UserTxERC20PermitForceTransfer(t *testing.T) {
}
L1UserTxs = append(L1UserTxs, l1Tx)
_, err = rollupClientAux.RollupL1UserTxERC20Permit(l1Tx.FromBJJ, fromIdxInt64, l1Tx.DepositAmount, l1Tx.Amount, tokenIDERC777, toIdxInt64, deadline)
_, err = rollupClientAux.RollupL1UserTxERC20Permit(l1Tx.FromBJJ, fromIdxInt64,
l1Tx.DepositAmount, l1Tx.Amount, tokenIDERC777, toIdxInt64, deadline)
require.NoError(t, err)
currentBlockNum, err := rollupClient.client.EthLastBlock()
@ -723,11 +778,13 @@ func TestRollupL1UserTxERC20PermitForceTransfer(t *testing.T) {
assert.Equal(t, l1Tx.DepositAmount, rollupEvents.L1UserTx[0].L1UserTx.DepositAmount)
assert.Equal(t, l1Tx.TokenID, rollupEvents.L1UserTx[0].L1UserTx.TokenID)
assert.Equal(t, l1Tx.Amount, rollupEvents.L1UserTx[0].L1UserTx.Amount)
assert.Equal(t, rollupClientAux.client.account.Address, rollupEvents.L1UserTx[0].L1UserTx.FromEthAddr)
assert.Equal(t, rollupClientAux.client.account.Address,
rollupEvents.L1UserTx[0].L1UserTx.FromEthAddr)
}
func TestRollupL1UserTxETHForceExit(t *testing.T) {
rollupClientAux, err := NewRollupClient(ethereumClientAux, hermezRollupAddressConst, tokenHEZ)
rollupClientAux, err := NewRollupClient(ethereumClientAux, hermezRollupAddressConst,
tokenHEZ)
require.NoError(t, err)
fromIdxInt64 := int64(256)
toIdxInt64 := int64(1)
@ -742,7 +799,8 @@ func TestRollupL1UserTxETHForceExit(t *testing.T) {
}
L1UserTxs = append(L1UserTxs, l1Tx)
_, err = rollupClientAux.RollupL1UserTxERC20ETH(l1Tx.FromBJJ, fromIdxInt64, l1Tx.DepositAmount, l1Tx.Amount, tokenIDUint32, toIdxInt64)
_, err = rollupClientAux.RollupL1UserTxERC20ETH(l1Tx.FromBJJ, fromIdxInt64,
l1Tx.DepositAmount, l1Tx.Amount, tokenIDUint32, toIdxInt64)
require.NoError(t, err)
currentBlockNum, err := rollupClient.client.EthLastBlock()
@ -753,11 +811,13 @@ func TestRollupL1UserTxETHForceExit(t *testing.T) {
assert.Equal(t, l1Tx.DepositAmount, rollupEvents.L1UserTx[0].L1UserTx.DepositAmount)
assert.Equal(t, l1Tx.TokenID, rollupEvents.L1UserTx[0].L1UserTx.TokenID)
assert.Equal(t, l1Tx.Amount, rollupEvents.L1UserTx[0].L1UserTx.Amount)
assert.Equal(t, rollupClientAux.client.account.Address, rollupEvents.L1UserTx[0].L1UserTx.FromEthAddr)
assert.Equal(t, rollupClientAux.client.account.Address,
rollupEvents.L1UserTx[0].L1UserTx.FromEthAddr)
}
func TestRollupL1UserTxERC20ForceExit(t *testing.T) {
rollupClientAux2, err := NewRollupClient(ethereumClientAux2, hermezRollupAddressConst, tokenHEZ)
rollupClientAux2, err := NewRollupClient(ethereumClientAux2, hermezRollupAddressConst,
tokenHEZ)
require.NoError(t, err)
fromIdxInt64 := int64(257)
toIdxInt64 := int64(1)
@ -771,7 +831,8 @@ func TestRollupL1UserTxERC20ForceExit(t *testing.T) {
}
L1UserTxs = append(L1UserTxs, l1Tx)
_, err = rollupClientAux2.RollupL1UserTxERC20ETH(l1Tx.FromBJJ, fromIdxInt64, l1Tx.DepositAmount, l1Tx.Amount, tokenHEZID, toIdxInt64)
_, err = rollupClientAux2.RollupL1UserTxERC20ETH(l1Tx.FromBJJ, fromIdxInt64,
l1Tx.DepositAmount, l1Tx.Amount, tokenHEZID, toIdxInt64)
require.NoError(t, err)
currentBlockNum, err := rollupClient.client.EthLastBlock()
@ -782,11 +843,13 @@ func TestRollupL1UserTxERC20ForceExit(t *testing.T) {
assert.Equal(t, l1Tx.DepositAmount, rollupEvents.L1UserTx[0].L1UserTx.DepositAmount)
assert.Equal(t, l1Tx.TokenID, rollupEvents.L1UserTx[0].L1UserTx.TokenID)
assert.Equal(t, l1Tx.Amount, rollupEvents.L1UserTx[0].L1UserTx.Amount)
assert.Equal(t, rollupClientAux2.client.account.Address, rollupEvents.L1UserTx[0].L1UserTx.FromEthAddr)
assert.Equal(t, rollupClientAux2.client.account.Address,
rollupEvents.L1UserTx[0].L1UserTx.FromEthAddr)
}
func TestRollupL1UserTxERC20PermitForceExit(t *testing.T) {
rollupClientAux, err := NewRollupClient(ethereumClientAux, hermezRollupAddressConst, tokenHEZ)
rollupClientAux, err := NewRollupClient(ethereumClientAux, hermezRollupAddressConst,
tokenHEZ)
require.NoError(t, err)
fromIdxInt64 := int64(258)
toIdxInt64 := int64(1)
@ -802,7 +865,8 @@ func TestRollupL1UserTxERC20PermitForceExit(t *testing.T) {
}
L1UserTxs = append(L1UserTxs, l1Tx)
_, err = rollupClientAux.RollupL1UserTxERC20Permit(l1Tx.FromBJJ, fromIdxInt64, l1Tx.DepositAmount, l1Tx.Amount, tokenIDERC777, toIdxInt64, deadline)
_, err = rollupClientAux.RollupL1UserTxERC20Permit(l1Tx.FromBJJ, fromIdxInt64,
l1Tx.DepositAmount, l1Tx.Amount, tokenIDERC777, toIdxInt64, deadline)
require.NoError(t, err)
currentBlockNum, err := rollupClient.client.EthLastBlock()
@ -813,7 +877,8 @@ func TestRollupL1UserTxERC20PermitForceExit(t *testing.T) {
assert.Equal(t, l1Tx.DepositAmount, rollupEvents.L1UserTx[0].L1UserTx.DepositAmount)
assert.Equal(t, l1Tx.TokenID, rollupEvents.L1UserTx[0].L1UserTx.TokenID)
assert.Equal(t, l1Tx.Amount, rollupEvents.L1UserTx[0].L1UserTx.Amount)
assert.Equal(t, rollupClientAux.client.account.Address, rollupEvents.L1UserTx[0].L1UserTx.FromEthAddr)
assert.Equal(t, rollupClientAux.client.account.Address,
rollupEvents.L1UserTx[0].L1UserTx.FromEthAddr)
}
func TestRollupForgeBatch2(t *testing.T) {
@ -829,7 +894,8 @@ func TestRollupForgeBatch2(t *testing.T) {
// Forge Batch 3
args := new(RollupForgeBatchArgs)
args.FeeIdxCoordinator = []common.Idx{} // When encoded, 64 times the 0 idx means that no idx to collect fees is specified.
// When encoded, 64 times the 0 idx means that no idx to collect fees is specified.
args.FeeIdxCoordinator = []common.Idx{}
args.L1CoordinatorTxs = argsForge.L1CoordinatorTxs
args.L1CoordinatorTxsAuths = argsForge.L1CoordinatorTxsAuths
for i := 0; i < len(L1UserTxs); i++ {
@ -837,14 +903,19 @@ func TestRollupForgeBatch2(t *testing.T) {
l1UserTx.EffectiveAmount = l1UserTx.Amount
l1Bytes, err := l1UserTx.BytesDataAvailability(uint32(nLevels))
require.NoError(t, err)
l1UserTxDataAvailability, err := common.L1TxFromDataAvailability(l1Bytes, uint32(nLevels))
l1UserTxDataAvailability, err := common.L1TxFromDataAvailability(l1Bytes,
uint32(nLevels))
require.NoError(t, err)
args.L1UserTxs = append(args.L1UserTxs, *l1UserTxDataAvailability)
}
newStateRoot := new(big.Int)
newStateRoot.SetString("18317824016047294649053625209337295956588174734569560016974612130063629505228", 10)
newStateRoot.SetString(
"18317824016047294649053625209337295956588174734569560016974612130063629505228",
10)
newExitRoot := new(big.Int)
newExitRoot.SetString("1114281409737474688393837964161044726766678436313681099613347372031079422302", 10)
newExitRoot.SetString(
"1114281409737474688393837964161044726766678436313681099613347372031079422302",
10)
amount := new(big.Int)
amount.SetString("79000000", 10)
l2Tx := common.L2Tx{
@ -904,7 +975,8 @@ func TestRollupWithdrawMerkleProof(t *testing.T) {
require.NoError(t, err)
var pkComp babyjub.PublicKeyComp
pkCompBE, err := hex.DecodeString("adc3b754f8da621967b073a787bef8eec7052f2ba712b23af57d98f65beea8b2")
pkCompBE, err :=
hex.DecodeString("adc3b754f8da621967b073a787bef8eec7052f2ba712b23af57d98f65beea8b2")
require.NoError(t, err)
pkCompLE := common.SwapEndianness(pkCompBE)
copy(pkComp[:], pkCompLE)
@ -914,16 +986,20 @@ func TestRollupWithdrawMerkleProof(t *testing.T) {
numExitRoot := int64(3)
fromIdx := int64(256)
amount, _ := new(big.Int).SetString("20000000000000000000", 10)
// siblingBytes0, err := new(big.Int).SetString("19508838618377323910556678335932426220272947530531646682154552299216398748115", 10)
// siblingBytes0, err := new(big.Int).SetString(
// "19508838618377323910556678335932426220272947530531646682154552299216398748115",
// 10)
// require.NoError(t, err)
// siblingBytes1, err := new(big.Int).SetString("15198806719713909654457742294233381653226080862567104272457668857208564789571", 10)
// siblingBytes1, err := new(big.Int).SetString(
// "15198806719713909654457742294233381653226080862567104272457668857208564789571", 10)
// require.NoError(t, err)
var siblings []*big.Int
// siblings = append(siblings, siblingBytes0)
// siblings = append(siblings, siblingBytes1)
instantWithdraw := true
_, err = rollupClientAux.RollupWithdrawMerkleProof(pkComp, tokenID, numExitRoot, fromIdx, amount, siblings, instantWithdraw)
_, err = rollupClientAux.RollupWithdrawMerkleProof(pkComp, tokenID, numExitRoot, fromIdx,
amount, siblings, instantWithdraw)
require.NoError(t, err)
currentBlockNum, err := rollupClient.client.EthLastBlock()

+ 57
- 29
eth/wdelayer.go

@ -132,7 +132,8 @@ type WDelayerInterface interface {
WDelayerDepositInfo(owner, token ethCommon.Address) (depositInfo DepositState, err error)
WDelayerDeposit(onwer, token ethCommon.Address, amount *big.Int) (*types.Transaction, error)
WDelayerWithdrawal(owner, token ethCommon.Address) (*types.Transaction, error)
WDelayerEscapeHatchWithdrawal(to, token ethCommon.Address, amount *big.Int) (*types.Transaction, error)
WDelayerEscapeHatchWithdrawal(to, token ethCommon.Address,
amount *big.Int) (*types.Transaction, error)
WDelayerEventsByBlock(blockNum int64, blockHash *ethCommon.Hash) (*WDelayerEvents, error)
WDelayerConstants() (*common.WDelayerConstants, error)
@ -143,7 +144,8 @@ type WDelayerInterface interface {
// Implementation
//
// WDelayerClient is the implementation of the interface to the WithdrawDelayer Smart Contract in ethereum.
// WDelayerClient is the implementation of the interface to the WithdrawDelayer
// Smart Contract in ethereum.
type WDelayerClient struct {
client *EthereumClient
address ethCommon.Address
@ -172,7 +174,8 @@ func NewWDelayerClient(client *EthereumClient, address ethCommon.Address) (*WDel
}
// WDelayerGetHermezGovernanceAddress is the interface to call the smart contract function
func (c *WDelayerClient) WDelayerGetHermezGovernanceAddress() (hermezGovernanceAddress *ethCommon.Address, err error) {
func (c *WDelayerClient) WDelayerGetHermezGovernanceAddress() (
hermezGovernanceAddress *ethCommon.Address, err error) {
var _hermezGovernanceAddress ethCommon.Address
if err := c.client.Call(func(ec *ethclient.Client) error {
_hermezGovernanceAddress, err = c.wdelayer.GetHermezGovernanceAddress(c.opts)
@ -184,7 +187,8 @@ func (c *WDelayerClient) WDelayerGetHermezGovernanceAddress() (hermezGovernanceA
}
// WDelayerTransferGovernance is the interface to call the smart contract function
func (c *WDelayerClient) WDelayerTransferGovernance(newAddress ethCommon.Address) (tx *types.Transaction, err error) {
func (c *WDelayerClient) WDelayerTransferGovernance(newAddress ethCommon.Address) (
tx *types.Transaction, err error) {
if tx, err = c.client.CallAuth(
0,
func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) {
@ -210,7 +214,8 @@ func (c *WDelayerClient) WDelayerClaimGovernance() (tx *types.Transaction, err e
}
// WDelayerGetEmergencyCouncil is the interface to call the smart contract function
func (c *WDelayerClient) WDelayerGetEmergencyCouncil() (emergencyCouncilAddress *ethCommon.Address, err error) {
func (c *WDelayerClient) WDelayerGetEmergencyCouncil() (emergencyCouncilAddress *ethCommon.Address,
err error) {
var _emergencyCouncilAddress ethCommon.Address
if err := c.client.Call(func(ec *ethclient.Client) error {
_emergencyCouncilAddress, err = c.wdelayer.GetEmergencyCouncil(c.opts)
@ -222,7 +227,8 @@ func (c *WDelayerClient) WDelayerGetEmergencyCouncil() (emergencyCouncilAddress
}
// WDelayerTransferEmergencyCouncil is the interface to call the smart contract function
func (c *WDelayerClient) WDelayerTransferEmergencyCouncil(newAddress ethCommon.Address) (tx *types.Transaction, err error) {
func (c *WDelayerClient) WDelayerTransferEmergencyCouncil(newAddress ethCommon.Address) (
tx *types.Transaction, err error) {
if tx, err = c.client.CallAuth(
0,
func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) {
@ -271,7 +277,8 @@ func (c *WDelayerClient) WDelayerGetWithdrawalDelay() (withdrawalDelay int64, er
}
// WDelayerGetEmergencyModeStartingTime is the interface to call the smart contract function
func (c *WDelayerClient) WDelayerGetEmergencyModeStartingTime() (emergencyModeStartingTime int64, err error) {
func (c *WDelayerClient) WDelayerGetEmergencyModeStartingTime() (emergencyModeStartingTime int64,
err error) {
var _emergencyModeStartingTime uint64
if err := c.client.Call(func(ec *ethclient.Client) error {
_emergencyModeStartingTime, err = c.wdelayer.GetEmergencyModeStartingTime(c.opts)
@ -296,7 +303,8 @@ func (c *WDelayerClient) WDelayerEnableEmergencyMode() (tx *types.Transaction, e
}
// WDelayerChangeWithdrawalDelay is the interface to call the smart contract function
func (c *WDelayerClient) WDelayerChangeWithdrawalDelay(newWithdrawalDelay uint64) (tx *types.Transaction, err error) {
func (c *WDelayerClient) WDelayerChangeWithdrawalDelay(newWithdrawalDelay uint64) (
tx *types.Transaction, err error) {
if tx, err = c.client.CallAuth(
0,
func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) {
@ -309,7 +317,8 @@ func (c *WDelayerClient) WDelayerChangeWithdrawalDelay(newWithdrawalDelay uint64
}
// WDelayerDepositInfo is the interface to call the smart contract function
func (c *WDelayerClient) WDelayerDepositInfo(owner, token ethCommon.Address) (depositInfo DepositState, err error) {
func (c *WDelayerClient) WDelayerDepositInfo(owner, token ethCommon.Address) (
depositInfo DepositState, err error) {
if err := c.client.Call(func(ec *ethclient.Client) error {
amount, depositTimestamp, err := c.wdelayer.DepositInfo(c.opts, owner, token)
depositInfo.Amount = amount
@ -322,7 +331,8 @@ func (c *WDelayerClient) WDelayerDepositInfo(owner, token ethCommon.Address) (de
}
// WDelayerDeposit is the interface to call the smart contract function
func (c *WDelayerClient) WDelayerDeposit(owner, token ethCommon.Address, amount *big.Int) (tx *types.Transaction, err error) {
func (c *WDelayerClient) WDelayerDeposit(owner, token ethCommon.Address, amount *big.Int) (
tx *types.Transaction, err error) {
if tx, err = c.client.CallAuth(
0,
func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) {
@ -335,7 +345,8 @@ func (c *WDelayerClient) WDelayerDeposit(owner, token ethCommon.Address, amount
}
// WDelayerWithdrawal is the interface to call the smart contract function
func (c *WDelayerClient) WDelayerWithdrawal(owner, token ethCommon.Address) (tx *types.Transaction, err error) {
func (c *WDelayerClient) WDelayerWithdrawal(owner, token ethCommon.Address) (tx *types.Transaction,
err error) {
if tx, err = c.client.CallAuth(
0,
func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) {
@ -348,7 +359,8 @@ func (c *WDelayerClient) WDelayerWithdrawal(owner, token ethCommon.Address) (tx
}
// WDelayerEscapeHatchWithdrawal is the interface to call the smart contract function
func (c *WDelayerClient) WDelayerEscapeHatchWithdrawal(to, token ethCommon.Address, amount *big.Int) (tx *types.Transaction, err error) {
func (c *WDelayerClient) WDelayerEscapeHatchWithdrawal(to, token ethCommon.Address,
amount *big.Int) (tx *types.Transaction, err error) {
if tx, err = c.client.CallAuth(
0,
func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) {
@ -384,14 +396,21 @@ func (c *WDelayerClient) WDelayerConstants() (constants *common.WDelayerConstant
}
var (
logWDelayerDeposit = crypto.Keccak256Hash([]byte("Deposit(address,address,uint192,uint64)"))
logWDelayerWithdraw = crypto.Keccak256Hash([]byte("Withdraw(address,address,uint192)"))
logWDelayerEmergencyModeEnabled = crypto.Keccak256Hash([]byte("EmergencyModeEnabled()"))
logWDelayerNewWithdrawalDelay = crypto.Keccak256Hash([]byte("NewWithdrawalDelay(uint64)"))
logWDelayerEscapeHatchWithdrawal = crypto.Keccak256Hash([]byte("EscapeHatchWithdrawal(address,address,address,uint256)"))
logWDelayerNewEmergencyCouncil = crypto.Keccak256Hash([]byte("NewEmergencyCouncil(address)"))
logWDelayerNewHermezGovernanceAddress = crypto.Keccak256Hash([]byte("NewHermezGovernanceAddress(address)"))
logWDelayerInitialize = crypto.Keccak256Hash([]byte(
logWDelayerDeposit = crypto.Keccak256Hash([]byte(
"Deposit(address,address,uint192,uint64)"))
logWDelayerWithdraw = crypto.Keccak256Hash([]byte(
"Withdraw(address,address,uint192)"))
logWDelayerEmergencyModeEnabled = crypto.Keccak256Hash([]byte(
"EmergencyModeEnabled()"))
logWDelayerNewWithdrawalDelay = crypto.Keccak256Hash([]byte(
"NewWithdrawalDelay(uint64)"))
logWDelayerEscapeHatchWithdrawal = crypto.Keccak256Hash([]byte(
"EscapeHatchWithdrawal(address,address,address,uint256)"))
logWDelayerNewEmergencyCouncil = crypto.Keccak256Hash([]byte(
"NewEmergencyCouncil(address)"))
logWDelayerNewHermezGovernanceAddress = crypto.Keccak256Hash([]byte(
"NewHermezGovernanceAddress(address)"))
logWDelayerInitialize = crypto.Keccak256Hash([]byte(
"InitializeWithdrawalDelayerEvent(uint64,address,address)"))
)
@ -483,42 +502,51 @@ func (c *WDelayerClient) WDelayerEventsByBlock(blockNum int64,
case logWDelayerEmergencyModeEnabled:
var emergencyModeEnabled WDelayerEventEmergencyModeEnabled
wdelayerEvents.EmergencyModeEnabled = append(wdelayerEvents.EmergencyModeEnabled, emergencyModeEnabled)
wdelayerEvents.EmergencyModeEnabled =
append(wdelayerEvents.EmergencyModeEnabled, emergencyModeEnabled)
case logWDelayerNewWithdrawalDelay:
var withdrawalDelay WDelayerEventNewWithdrawalDelay
err := c.contractAbi.UnpackIntoInterface(&withdrawalDelay, "NewWithdrawalDelay", vLog.Data)
err := c.contractAbi.UnpackIntoInterface(&withdrawalDelay,
"NewWithdrawalDelay", vLog.Data)
if err != nil {
return nil, tracerr.Wrap(err)
}
wdelayerEvents.NewWithdrawalDelay = append(wdelayerEvents.NewWithdrawalDelay, withdrawalDelay)
wdelayerEvents.NewWithdrawalDelay =
append(wdelayerEvents.NewWithdrawalDelay, withdrawalDelay)
case logWDelayerEscapeHatchWithdrawal:
var escapeHatchWithdrawal WDelayerEventEscapeHatchWithdrawal
err := c.contractAbi.UnpackIntoInterface(&escapeHatchWithdrawal, "EscapeHatchWithdrawal", vLog.Data)
err := c.contractAbi.UnpackIntoInterface(&escapeHatchWithdrawal,
"EscapeHatchWithdrawal", vLog.Data)
if err != nil {
return nil, tracerr.Wrap(err)
}
escapeHatchWithdrawal.Who = ethCommon.BytesToAddress(vLog.Topics[1].Bytes())
escapeHatchWithdrawal.To = ethCommon.BytesToAddress(vLog.Topics[2].Bytes())
escapeHatchWithdrawal.Token = ethCommon.BytesToAddress(vLog.Topics[3].Bytes())
wdelayerEvents.EscapeHatchWithdrawal = append(wdelayerEvents.EscapeHatchWithdrawal, escapeHatchWithdrawal)
wdelayerEvents.EscapeHatchWithdrawal =
append(wdelayerEvents.EscapeHatchWithdrawal, escapeHatchWithdrawal)
case logWDelayerNewEmergencyCouncil:
var emergencyCouncil WDelayerEventNewEmergencyCouncil
err := c.contractAbi.UnpackIntoInterface(&emergencyCouncil, "NewEmergencyCouncil", vLog.Data)
err := c.contractAbi.UnpackIntoInterface(&emergencyCouncil,
"NewEmergencyCouncil", vLog.Data)
if err != nil {
return nil, tracerr.Wrap(err)
}
wdelayerEvents.NewEmergencyCouncil = append(wdelayerEvents.NewEmergencyCouncil, emergencyCouncil)
wdelayerEvents.NewEmergencyCouncil =
append(wdelayerEvents.NewEmergencyCouncil, emergencyCouncil)
case logWDelayerNewHermezGovernanceAddress:
var governanceAddress WDelayerEventNewHermezGovernanceAddress
err := c.contractAbi.UnpackIntoInterface(&governanceAddress, "NewHermezGovernanceAddress", vLog.Data)
err := c.contractAbi.UnpackIntoInterface(&governanceAddress,
"NewHermezGovernanceAddress", vLog.Data)
if err != nil {
return nil, tracerr.Wrap(err)
}
wdelayerEvents.NewHermezGovernanceAddress = append(wdelayerEvents.NewHermezGovernanceAddress, governanceAddress)
wdelayerEvents.NewHermezGovernanceAddress =
append(wdelayerEvents.NewHermezGovernanceAddress, governanceAddress)
}
}
return &wdelayerEvents, nil

+ 12
- 5
eth/wdelayer_test.go

@ -54,7 +54,8 @@ func TestWDelayerSetHermezGovernanceAddress(t *testing.T) {
require.Nil(t, err)
wdelayerEvents, err := wdelayerClientTest.WDelayerEventsByBlock(currentBlockNum, nil)
require.Nil(t, err)
assert.Equal(t, auxAddressConst, wdelayerEvents.NewHermezGovernanceAddress[0].NewHermezGovernanceAddress)
assert.Equal(t, auxAddressConst,
wdelayerEvents.NewHermezGovernanceAddress[0].NewHermezGovernanceAddress)
_, err = wdelayerClientAux.WDelayerTransferGovernance(governanceAddressConst)
require.Nil(t, err)
_, err = wdelayerClientTest.WDelayerClaimGovernance()
@ -68,7 +69,8 @@ func TestWDelayerGetEmergencyCouncil(t *testing.T) {
}
func TestWDelayerSetEmergencyCouncil(t *testing.T) {
wdelayerClientEmergencyCouncil, err := NewWDelayerClient(ethereumClientEmergencyCouncil, wdelayerTestAddressConst)
wdelayerClientEmergencyCouncil, err := NewWDelayerClient(ethereumClientEmergencyCouncil,
wdelayerTestAddressConst)
require.Nil(t, err)
wdelayerClientAux, err := NewWDelayerClient(ethereumClientAux, wdelayerTestAddressConst)
require.Nil(t, err)
@ -200,13 +202,18 @@ func TestWDelayerGetEmergencyModeStartingTime(t *testing.T) {
func TestWDelayerEscapeHatchWithdrawal(t *testing.T) {
amount := new(big.Int)
amount.SetString("10000000000000000", 10)
wdelayerClientEmergencyCouncil, err := NewWDelayerClient(ethereumClientEmergencyCouncil, wdelayerTestAddressConst)
wdelayerClientEmergencyCouncil, err := NewWDelayerClient(ethereumClientEmergencyCouncil,
wdelayerTestAddressConst)
require.Nil(t, err)
_, err = wdelayerClientEmergencyCouncil.WDelayerEscapeHatchWithdrawal(governanceAddressConst, tokenHEZAddressConst, amount)
_, err =
wdelayerClientEmergencyCouncil.WDelayerEscapeHatchWithdrawal(governanceAddressConst,
tokenHEZAddressConst, amount)
require.Contains(t, err.Error(), "NO_MAX_EMERGENCY_MODE_TIME")
seconds := maxEmergencyModeTime.Seconds()
addTime(seconds, ethClientDialURL)
_, err = wdelayerClientEmergencyCouncil.WDelayerEscapeHatchWithdrawal(governanceAddressConst, tokenHEZAddressConst, amount)
_, err =
wdelayerClientEmergencyCouncil.WDelayerEscapeHatchWithdrawal(governanceAddressConst,
tokenHEZAddressConst, amount)
require.Nil(t, err)
currentBlockNum, err := wdelayerClientTest.client.EthLastBlock()
require.Nil(t, err)

+ 8
- 5
node/node.go

@ -275,7 +275,8 @@ func NewNode(mode Mode, cfg *config.Node) (*Node, error) {
BJJ: cfg.Coordinator.FeeAccount.BJJ,
AccountCreationAuth: auth.Signature,
}
txSelector, err := txselector.NewTxSelector(coordAccount, cfg.Coordinator.TxSelector.Path, stateDB, l2DB)
txSelector, err := txselector.NewTxSelector(coordAccount,
cfg.Coordinator.TxSelector.Path, stateDB, l2DB)
if err != nil {
return nil, tracerr.Wrap(err)
}
@ -523,8 +524,8 @@ func (a *NodeAPI) Run(ctx context.Context) error {
return nil
}
func (n *Node) handleNewBlock(ctx context.Context, stats *synchronizer.Stats, vars synchronizer.SCVariablesPtr,
batches []common.BatchData) {
func (n *Node) handleNewBlock(ctx context.Context, stats *synchronizer.Stats,
vars synchronizer.SCVariablesPtr, batches []common.BatchData) {
if n.mode == ModeCoordinator {
n.coord.SendMsg(ctx, coordinator.MsgSyncBlock{
Stats: *stats,
@ -559,7 +560,8 @@ func (n *Node) handleNewBlock(ctx context.Context, stats *synchronizer.Stats, va
}
}
func (n *Node) handleReorg(ctx context.Context, stats *synchronizer.Stats, vars synchronizer.SCVariablesPtr) {
func (n *Node) handleReorg(ctx context.Context, stats *synchronizer.Stats,
vars synchronizer.SCVariablesPtr) {
if n.mode == ModeCoordinator {
n.coord.SendMsg(ctx, coordinator.MsgSyncReorg{
Stats: *stats,
@ -579,7 +581,8 @@ func (n *Node) handleReorg(ctx context.Context, stats *synchronizer.Stats, vars
// TODO(Edu): Consider keeping the `lastBlock` inside synchronizer so that we
// don't have to pass it around.
func (n *Node) syncLoopFn(ctx context.Context, lastBlock *common.Block) (*common.Block, time.Duration, error) {
func (n *Node) syncLoopFn(ctx context.Context, lastBlock *common.Block) (*common.Block,
time.Duration, error) {
blockData, discarded, err := n.sync.Sync(ctx, lastBlock)
stats := n.sync.Stats()
if err != nil {

+ 4
- 2
priceupdater/priceupdater.go

@ -43,7 +43,8 @@ type PriceUpdater struct {
}
// NewPriceUpdater is the constructor for the updater
func NewPriceUpdater(apiURL string, apiType APIType, db *historydb.HistoryDB) (*PriceUpdater, error) {
func NewPriceUpdater(apiURL string, apiType APIType, db *historydb.HistoryDB) (*PriceUpdater,
error) {
tokenSymbols := []string{}
if !apiType.valid() {
return nil, tracerr.Wrap(fmt.Errorf("Invalid apiType: %v", apiType))
@ -73,7 +74,8 @@ func getTokenPriceBitfinex(ctx context.Context, client *sling.Sling,
return state[6], nil
}
// 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(ctx context.Context) {
tr := &http.Transport{
MaxIdleConns: defaultMaxIdleConns,

+ 2
- 1
prover/prover.go

@ -256,7 +256,8 @@ func (p *ProofServerClient) GetProof(ctx context.Context) (*Proof, []*big.Int, e
}
return &proof, pubInputs, nil
}
return nil, nil, tracerr.Wrap(fmt.Errorf("status != %v, status = %v", StatusCodeSuccess, status.Status))
return nil, nil, tracerr.Wrap(fmt.Errorf("status != %v, status = %v", StatusCodeSuccess,
status.Status))
}
// Cancel cancels any current proof computation

+ 2
- 1
synchronizer/synchronizer.go

@ -925,7 +925,8 @@ func (s *Synchronizer) rollupSync(ethBlock *common.Block) (*common.RollupData, e
}
// Transform L2 txs to PoolL2Txs
poolL2Txs := common.L2TxsToPoolL2Txs(forgeBatchArgs.L2TxsData) // NOTE: This is a big ugly, find a better way
// NOTE: This is a big ugly, find a better way
poolL2Txs := common.L2TxsToPoolL2Txs(forgeBatchArgs.L2TxsData)
if int(forgeBatchArgs.VerifierIdx) >= len(s.consts.Rollup.Verifiers) {
return nil, tracerr.Wrap(fmt.Errorf("forgeBatchArgs.VerifierIdx (%v) >= "+

+ 8
- 4
synchronizer/synchronizer_test.go

@ -42,7 +42,8 @@ func accountsCmp(accounts []common.Account) func(i, j int) bool {
// Check Sync output and HistoryDB state against expected values generated by
// til
func checkSyncBlock(t *testing.T, s *Synchronizer, blockNum int, block, syncBlock *common.BlockData) {
func checkSyncBlock(t *testing.T, s *Synchronizer, blockNum int, block,
syncBlock *common.BlockData) {
// Check Blocks
dbBlocks, err := s.historyDB.GetAllBlocks()
require.NoError(t, err)
@ -308,7 +309,8 @@ func newTestModules(t *testing.T) (*statedb.StateDB, *historydb.HistoryDB) {
require.NoError(t, err)
deleteme = append(deleteme, dir)
stateDB, err := statedb.NewStateDB(statedb.Config{Path: dir, Keep: 128, Type: statedb.TypeSynchronizer, NLevels: 32})
stateDB, err := statedb.NewStateDB(statedb.Config{Path: dir, Keep: 128,
Type: statedb.TypeSynchronizer, NLevels: 32})
require.NoError(t, err)
// Init History DB
@ -514,9 +516,11 @@ func TestSyncGeneral(t *testing.T) {
// Block 4
// Generate 2 withdraws manually
_, err = client.RollupWithdrawMerkleProof(tc.Users["A"].BJJ.Public().Compress(), 1, 4, 256, big.NewInt(100), []*big.Int{}, true)
_, err = client.RollupWithdrawMerkleProof(tc.Users["A"].BJJ.Public().Compress(), 1, 4, 256,
big.NewInt(100), []*big.Int{}, true)
require.NoError(t, err)
_, err = client.RollupWithdrawMerkleProof(tc.Users["C"].BJJ.Public().Compress(), 1, 3, 258, big.NewInt(50), []*big.Int{}, false)
_, err = client.RollupWithdrawMerkleProof(tc.Users["C"].BJJ.Public().Compress(), 1, 3, 258,
big.NewInt(50), []*big.Int{}, false)
require.NoError(t, err)
client.CtlMineBlock()

+ 2
- 1
test/debugapi/debugapi_test.go

@ -44,7 +44,8 @@ func TestDebugAPI(t *testing.T) {
dir, err := ioutil.TempDir("", "tmpdb")
require.Nil(t, err)
sdb, err := statedb.NewStateDB(statedb.Config{Path: dir, Keep: 128, Type: statedb.TypeSynchronizer, NLevels: 32})
sdb, err := statedb.NewStateDB(statedb.Config{Path: dir, Keep: 128,
Type: statedb.TypeSynchronizer, NLevels: 32})
require.Nil(t, err)
err = sdb.MakeCheckpoint() // Make a checkpoint to increment the batchNum
require.Nil(t, err)

+ 89
- 48
test/ethclient.go

@ -48,7 +48,8 @@ func (w *WDelayerBlock) addTransaction(tx *types.Transaction) *types.Transaction
return tx
}
func (w *WDelayerBlock) deposit(txHash ethCommon.Hash, owner, token ethCommon.Address, amount *big.Int) {
func (w *WDelayerBlock) deposit(txHash ethCommon.Hash, owner, token ethCommon.Address,
amount *big.Int) {
w.Events.Deposit = append(w.Events.Deposit, eth.WDelayerEventDeposit{
Owner: owner,
Token: token,
@ -182,7 +183,8 @@ func (a *AuctionBlock) canForge(forger ethCommon.Address, blockNum int64) (bool,
slotToForge := a.getSlotNumber(blockNum)
// Get the relativeBlock to check if the slotDeadline has been exceeded
relativeBlock := blockNum - (a.Constants.GenesisBlockNum + (slotToForge * int64(a.Constants.BlocksPerSlot)))
relativeBlock := blockNum - (a.Constants.GenesisBlockNum + (slotToForge *
int64(a.Constants.BlocksPerSlot)))
// If the closedMinBid is 0 it means that we have to take as minBid the
// one that is set for this slot set, otherwise the one that has been
@ -281,10 +283,6 @@ type ClientSetup struct {
// and 1 will be premined.
//nolint:gomnd
func NewClientSetupExample() *ClientSetup {
// rfield, ok := new(big.Int).SetString("21888242871839275222246405745257275088548364400416034343698204186575808495617", 10)
// if !ok {
// panic("bad rfield")
// }
initialMinimalBidding, ok := new(big.Int).SetString("10000000000000000000", 10) // 10 * (1e18)
if !ok {
panic("bad initialMinimalBidding")
@ -626,7 +624,8 @@ func (c *Client) EthPendingNonceAt(ctx context.Context, account ethCommon.Addres
// EthNonceAt returns the account nonce of the given account. The block number can
// be nil, in which case the nonce is taken from the latest known block.
func (c *Client) EthNonceAt(ctx context.Context, account ethCommon.Address, blockNumber *big.Int) (uint64, error) {
func (c *Client) EthNonceAt(ctx context.Context, account ethCommon.Address,
blockNumber *big.Int) (uint64, error) {
// NOTE: For now Client doesn't simulate nonces
return 0, nil
}
@ -645,7 +644,8 @@ func (c *Client) EthKeyStore() *ethKeystore.KeyStore {
// EthCall runs the transaction as a call (without paying) in the local node at
// blockNum.
func (c *Client) EthCall(ctx context.Context, tx *types.Transaction, blockNum *big.Int) ([]byte, error) {
func (c *Client) EthCall(ctx context.Context, tx *types.Transaction,
blockNum *big.Int) ([]byte, error) {
return nil, tracerr.Wrap(common.ErrTODO)
}
@ -662,7 +662,8 @@ func (c *Client) EthLastBlock() (int64, error) {
}
// EthTransactionReceipt returns the transaction receipt of the given txHash
func (c *Client) EthTransactionReceipt(ctx context.Context, txHash ethCommon.Hash) (*types.Receipt, error) {
func (c *Client) EthTransactionReceipt(ctx context.Context,
txHash ethCommon.Hash) (*types.Receipt, error) {
c.rw.RLock()
defer c.rw.RUnlock()
@ -778,7 +779,9 @@ var errTODO = fmt.Errorf("TODO: Not implemented yet")
// }
// RollupL1UserTxERC20Permit is the interface to call the smart contract function
func (c *Client) RollupL1UserTxERC20Permit(fromBJJ babyjub.PublicKeyComp, fromIdx int64, depositAmount *big.Int, amount *big.Int, tokenID uint32, toIdx int64, deadline *big.Int) (tx *types.Transaction, err error) {
func (c *Client) RollupL1UserTxERC20Permit(fromBJJ babyjub.PublicKeyComp, fromIdx int64,
depositAmount *big.Int, amount *big.Int, tokenID uint32, toIdx int64,
deadline *big.Int) (tx *types.Transaction, err error) {
log.Error("TODO")
return nil, tracerr.Wrap(errTODO)
}
@ -845,7 +848,9 @@ func (c *Client) RollupL1UserTxERC20ETH(
}
// RollupL1UserTxERC777 is the interface to call the smart contract function
// func (c *Client) RollupL1UserTxERC777(fromBJJ *babyjub.PublicKey, fromIdx int64, depositAmount *big.Int, amount *big.Int, tokenID uint32, toIdx int64) (*types.Transaction, error) {
// func (c *Client) RollupL1UserTxERC777(fromBJJ *babyjub.PublicKey, fromIdx int64,
// depositAmount *big.Int, amount *big.Int, tokenID uint32,
// toIdx int64) (*types.Transaction, error) {
// log.Error("TODO")
// return nil, errTODO
// }
@ -867,13 +872,17 @@ func (c *Client) RollupLastForgedBatch() (int64, error) {
}
// RollupWithdrawCircuit is the interface to call the smart contract function
func (c *Client) RollupWithdrawCircuit(proofA, proofC [2]*big.Int, proofB [2][2]*big.Int, tokenID uint32, numExitRoot, idx int64, amount *big.Int, instantWithdraw bool) (*types.Transaction, error) {
func (c *Client) RollupWithdrawCircuit(proofA, proofC [2]*big.Int, proofB [2][2]*big.Int,
tokenID uint32, numExitRoot, idx int64, amount *big.Int,
instantWithdraw bool) (*types.Transaction, error) {
log.Error("TODO")
return nil, tracerr.Wrap(errTODO)
}
// RollupWithdrawMerkleProof is the interface to call the smart contract function
func (c *Client) RollupWithdrawMerkleProof(babyPubKey babyjub.PublicKeyComp, tokenID uint32, numExitRoot, idx int64, amount *big.Int, siblings []*big.Int, instantWithdraw bool) (tx *types.Transaction, err error) {
func (c *Client) RollupWithdrawMerkleProof(babyPubKey babyjub.PublicKeyComp,
tokenID uint32, numExitRoot, idx int64, amount *big.Int, siblings []*big.Int,
instantWithdraw bool) (tx *types.Transaction, err error) {
c.rw.Lock()
defer c.rw.Unlock()
cpy := c.nextBlock().copy()
@ -945,7 +954,8 @@ func (c *Client) newTransaction(name string, value interface{}) *types.Transacti
}
// RollupForgeBatch is the interface to call the smart contract function
func (c *Client) RollupForgeBatch(args *eth.RollupForgeBatchArgs, auth *bind.TransactOpts) (tx *types.Transaction, err error) {
func (c *Client) RollupForgeBatch(args *eth.RollupForgeBatchArgs,
auth *bind.TransactOpts) (tx *types.Transaction, err error) {
c.rw.Lock()
defer c.rw.Unlock()
cpy := c.nextBlock().copy()
@ -973,7 +983,8 @@ func (c *Client) RollupForgeBatch(args *eth.RollupForgeBatchArgs, auth *bind.Tra
// TODO: If successful, store the tx in a successful array.
// TODO: If failed, store the tx in a failed array.
// TODO: Add method to move the tx to another block, reapply it there, and possibly go from successful to failed.
// TODO: Add method to move the tx to another block, reapply it there, and possibly go from
// successful to failed.
return c.addBatch(args)
}
@ -1018,7 +1029,8 @@ func (c *Client) addBatch(args *eth.RollupForgeBatchArgs) (*types.Transaction, e
// RollupAddTokenSimple is a wrapper around RollupAddToken that automatically
// sets `deadlie`.
func (c *Client) RollupAddTokenSimple(tokenAddress ethCommon.Address, feeAddToken *big.Int) (tx *types.Transaction, err error) {
func (c *Client) RollupAddTokenSimple(tokenAddress ethCommon.Address,
feeAddToken *big.Int) (tx *types.Transaction, err error) {
return c.RollupAddToken(tokenAddress, feeAddToken, big.NewInt(9999)) //nolint:gomnd
}
@ -1039,13 +1051,16 @@ func (c *Client) RollupAddToken(tokenAddress ethCommon.Address, feeAddToken *big
return nil, tracerr.Wrap(fmt.Errorf("Token %v already registered", tokenAddress))
}
if feeAddToken.Cmp(r.Vars.FeeAddToken) != 0 {
return nil, tracerr.Wrap(fmt.Errorf("Expected fee: %v but got: %v", r.Vars.FeeAddToken, feeAddToken))
return nil,
tracerr.Wrap(fmt.Errorf("Expected fee: %v but got: %v",
r.Vars.FeeAddToken, feeAddToken))
}
r.State.TokenMap[tokenAddress] = true
r.State.TokenList = append(r.State.TokenList, tokenAddress)
r.Events.AddToken = append(r.Events.AddToken, eth.RollupEventAddToken{TokenAddress: tokenAddress,
TokenID: uint32(len(r.State.TokenList) - 1)})
r.Events.AddToken = append(r.Events.AddToken, eth.RollupEventAddToken{
TokenAddress: tokenAddress,
TokenID: uint32(len(r.State.TokenList) - 1)})
return r.addTransaction(c.newTransaction("addtoken", tokenAddress)), nil
}
@ -1059,7 +1074,8 @@ func (c *Client) RollupGetCurrentTokens() (*big.Int, error) {
}
// RollupUpdateForgeL1L2BatchTimeout is the interface to call the smart contract function
func (c *Client) RollupUpdateForgeL1L2BatchTimeout(newForgeL1Timeout int64) (tx *types.Transaction, err error) {
func (c *Client) RollupUpdateForgeL1L2BatchTimeout(newForgeL1Timeout int64) (tx *types.Transaction,
err error) {
c.rw.Lock()
defer c.rw.Unlock()
cpy := c.nextBlock().copy()
@ -1078,7 +1094,8 @@ func (c *Client) RollupUpdateForgeL1L2BatchTimeout(newForgeL1Timeout int64) (tx
}
// RollupUpdateFeeAddToken is the interface to call the smart contract function
func (c *Client) RollupUpdateFeeAddToken(newFeeAddToken *big.Int) (tx *types.Transaction, err error) {
func (c *Client) RollupUpdateFeeAddToken(newFeeAddToken *big.Int) (tx *types.Transaction,
err error) {
c.rw.Lock()
defer c.rw.Unlock()
cpy := c.nextBlock().copy()
@ -1092,7 +1109,8 @@ func (c *Client) RollupUpdateFeeAddToken(newFeeAddToken *big.Int) (tx *types.Tra
}
// RollupUpdateTokensHEZ is the interface to call the smart contract function
// func (c *Client) RollupUpdateTokensHEZ(newTokenHEZ ethCommon.Address) (tx *types.Transaction, err error) {
// func (c *Client) RollupUpdateTokensHEZ(newTokenHEZ ethCommon.Address) (tx *types.Transaction,
// err error) {
// c.rw.Lock()
// defer c.rw.Unlock()
// cpy := c.nextBlock().copy()
@ -1103,7 +1121,8 @@ func (c *Client) RollupUpdateFeeAddToken(newFeeAddToken *big.Int) (tx *types.Tra
// }
// RollupUpdateGovernance is the interface to call the smart contract function
// func (c *Client) RollupUpdateGovernance() (*types.Transaction, error) { // TODO (Not defined in Hermez.sol)
// func (c *Client) RollupUpdateGovernance() (*types.Transaction, error) {
// // TODO (Not defined in Hermez.sol)
// return nil, errTODO
// }
@ -1142,8 +1161,10 @@ func (c *Client) RollupEventInit() (*eth.RollupEventInitialize, int64, error) {
}, 1, nil
}
// RollupForgeBatchArgs returns the arguments used in a ForgeBatch call in the Rollup Smart Contract in the given transaction
func (c *Client) RollupForgeBatchArgs(ethTxHash ethCommon.Hash, l1UserTxsLen uint16) (*eth.RollupForgeBatchArgs, *ethCommon.Address, error) {
// RollupForgeBatchArgs returns the arguments used in a ForgeBatch call in the Rollup Smart Contract
// in the given transaction
func (c *Client) RollupForgeBatchArgs(ethTxHash ethCommon.Hash,
l1UserTxsLen uint16) (*eth.RollupForgeBatchArgs, *ethCommon.Address, error) {
c.rw.RLock()
defer c.rw.RUnlock()
@ -1182,7 +1203,8 @@ func (c *Client) AuctionGetSlotDeadline() (uint8, error) {
}
// AuctionSetOpenAuctionSlots is the interface to call the smart contract function
func (c *Client) AuctionSetOpenAuctionSlots(newOpenAuctionSlots uint16) (tx *types.Transaction, err error) {
func (c *Client) AuctionSetOpenAuctionSlots(newOpenAuctionSlots uint16) (tx *types.Transaction,
err error) {
c.rw.Lock()
defer c.rw.Unlock()
cpy := c.nextBlock().copy()
@ -1210,7 +1232,8 @@ func (c *Client) AuctionGetOpenAuctionSlots() (uint16, error) {
}
// AuctionSetClosedAuctionSlots is the interface to call the smart contract function
func (c *Client) AuctionSetClosedAuctionSlots(newClosedAuctionSlots uint16) (tx *types.Transaction, err error) {
func (c *Client) AuctionSetClosedAuctionSlots(newClosedAuctionSlots uint16) (tx *types.Transaction,
err error) {
c.rw.Lock()
defer c.rw.Unlock()
cpy := c.nextBlock().copy()
@ -1256,7 +1279,8 @@ func (c *Client) AuctionGetOutbidding() (uint16, error) {
}
// AuctionSetAllocationRatio is the interface to call the smart contract function
func (c *Client) AuctionSetAllocationRatio(newAllocationRatio [3]uint16) (tx *types.Transaction, err error) {
func (c *Client) AuctionSetAllocationRatio(newAllocationRatio [3]uint16) (tx *types.Transaction,
err error) {
c.rw.Lock()
defer c.rw.Unlock()
cpy := c.nextBlock().copy()
@ -1279,7 +1303,8 @@ func (c *Client) AuctionGetAllocationRatio() ([3]uint16, error) {
}
// AuctionSetDonationAddress is the interface to call the smart contract function
func (c *Client) AuctionSetDonationAddress(newDonationAddress ethCommon.Address) (tx *types.Transaction, err error) {
func (c *Client) AuctionSetDonationAddress(
newDonationAddress ethCommon.Address) (tx *types.Transaction, err error) {
c.rw.Lock()
defer c.rw.Unlock()
cpy := c.nextBlock().copy()
@ -1302,7 +1327,8 @@ func (c *Client) AuctionGetDonationAddress() (*ethCommon.Address, error) {
}
// AuctionSetBootCoordinator is the interface to call the smart contract function
func (c *Client) AuctionSetBootCoordinator(newBootCoordinator ethCommon.Address, newBootCoordinatorURL string) (tx *types.Transaction, err error) {
func (c *Client) AuctionSetBootCoordinator(newBootCoordinator ethCommon.Address,
newBootCoordinatorURL string) (tx *types.Transaction, err error) {
c.rw.Lock()
defer c.rw.Unlock()
cpy := c.nextBlock().copy()
@ -1327,7 +1353,8 @@ func (c *Client) AuctionGetBootCoordinator() (*ethCommon.Address, error) {
}
// AuctionChangeDefaultSlotSetBid is the interface to call the smart contract function
func (c *Client) AuctionChangeDefaultSlotSetBid(slotSet int64, newInitialMinBid *big.Int) (tx *types.Transaction, err error) {
func (c *Client) AuctionChangeDefaultSlotSetBid(slotSet int64,
newInitialMinBid *big.Int) (tx *types.Transaction, err error) {
c.rw.Lock()
defer c.rw.Unlock()
cpy := c.nextBlock().copy()
@ -1341,7 +1368,8 @@ func (c *Client) AuctionChangeDefaultSlotSetBid(slotSet int64, newInitialMinBid
}
// AuctionSetCoordinator is the interface to call the smart contract function
func (c *Client) AuctionSetCoordinator(forger ethCommon.Address, URL string) (tx *types.Transaction, err error) {
func (c *Client) AuctionSetCoordinator(forger ethCommon.Address,
URL string) (tx *types.Transaction, err error) {
c.rw.Lock()
defer c.rw.Unlock()
cpy := c.nextBlock().copy()
@ -1370,7 +1398,8 @@ func (c *Client) AuctionSetCoordinator(forger ethCommon.Address, URL string) (tx
ForgerAddress ethCommon.Address
URL string
}
return a.addTransaction(c.newTransaction("registercoordinator", data{*c.addr, forger, URL})), nil
return a.addTransaction(c.newTransaction("registercoordinator", data{*c.addr, forger, URL})),
nil
}
// AuctionIsRegisteredCoordinator is the interface to call the smart contract function
@ -1383,7 +1412,8 @@ func (c *Client) AuctionIsRegisteredCoordinator(forgerAddress ethCommon.Address)
}
// AuctionUpdateCoordinatorInfo is the interface to call the smart contract function
func (c *Client) AuctionUpdateCoordinatorInfo(forgerAddress ethCommon.Address, newWithdrawAddress ethCommon.Address, newURL string) (tx *types.Transaction, err error) {
func (c *Client) AuctionUpdateCoordinatorInfo(forgerAddress ethCommon.Address,
newWithdrawAddress ethCommon.Address, newURL string) (tx *types.Transaction, err error) {
c.rw.Lock()
defer c.rw.Unlock()
cpy := c.nextBlock().copy()
@ -1443,12 +1473,14 @@ func (c *Client) AuctionGetSlotSet(slot int64) (*big.Int, error) {
}
// AuctionTokensReceived is the interface to call the smart contract function
// func (c *Client) AuctionTokensReceived(operator, from, to ethCommon.Address, amount *big.Int, userData, operatorData []byte) error {
// func (c *Client) AuctionTokensReceived(operator, from, to ethCommon.Address, amount *big.Int,
// userData, operatorData []byte) error {
// return errTODO
// }
// AuctionBidSimple is a wrapper around AuctionBid that automatically sets `amount` and `deadline`.
func (c *Client) AuctionBidSimple(slot int64, bidAmount *big.Int) (tx *types.Transaction, err error) {
func (c *Client) AuctionBidSimple(slot int64, bidAmount *big.Int) (tx *types.Transaction,
err error) {
return c.AuctionBid(bidAmount, slot, bidAmount, big.NewInt(99999)) //nolint:gomnd
}
@ -1471,7 +1503,8 @@ func (c *Client) AuctionBid(amount *big.Int, slot int64, bidAmount *big.Int,
return nil, tracerr.Wrap(errBidClosed)
}
if slot > a.getCurrentSlotNumber()+int64(a.Vars.ClosedAuctionSlots)+int64(a.Vars.OpenAuctionSlots) {
if slot >
a.getCurrentSlotNumber()+int64(a.Vars.ClosedAuctionSlots)+int64(a.Vars.OpenAuctionSlots) {
return nil, tracerr.Wrap(errBidNotOpen)
}
@ -1508,8 +1541,8 @@ func (c *Client) AuctionBid(amount *big.Int, slot int64, bidAmount *big.Int,
// AuctionMultiBid is the interface to call the smart contract function. This
// implementation behaves as if any address has infinite tokens.
func (c *Client) AuctionMultiBid(amount *big.Int, startingSlot int64, endingSlot int64, slotSet [6]bool,
maxBid, closedMinBid, deadline *big.Int) (tx *types.Transaction, err error) {
func (c *Client) AuctionMultiBid(amount *big.Int, startingSlot int64, endingSlot int64,
slotSet [6]bool, maxBid, closedMinBid, deadline *big.Int) (tx *types.Transaction, err error) {
c.rw.Lock()
defer c.rw.Unlock()
cpy := c.nextBlock().copy()
@ -1623,7 +1656,8 @@ func (c *Client) WDelayerGetHermezGovernanceAddress() (*ethCommon.Address, error
}
// WDelayerTransferGovernance is the interface to call the smart contract function
func (c *Client) WDelayerTransferGovernance(newAddress ethCommon.Address) (tx *types.Transaction, err error) {
func (c *Client) WDelayerTransferGovernance(newAddress ethCommon.Address) (tx *types.Transaction,
err error) {
c.rw.Lock()
defer c.rw.Unlock()
cpy := c.nextBlock().copy()
@ -1660,7 +1694,8 @@ func (c *Client) WDelayerGetEmergencyCouncil() (*ethCommon.Address, error) {
}
// WDelayerTransferEmergencyCouncil is the interface to call the smart contract function
func (c *Client) WDelayerTransferEmergencyCouncil(newAddress ethCommon.Address) (tx *types.Transaction, err error) {
func (c *Client) WDelayerTransferEmergencyCouncil(newAddress ethCommon.Address) (
tx *types.Transaction, err error) {
c.rw.Lock()
defer c.rw.Unlock()
cpy := c.nextBlock().copy()
@ -1729,7 +1764,8 @@ func (c *Client) WDelayerEnableEmergencyMode() (tx *types.Transaction, err error
}
// WDelayerChangeWithdrawalDelay is the interface to call the smart contract function
func (c *Client) WDelayerChangeWithdrawalDelay(newWithdrawalDelay uint64) (tx *types.Transaction, err error) {
func (c *Client) WDelayerChangeWithdrawalDelay(newWithdrawalDelay uint64) (tx *types.Transaction,
err error) {
c.rw.Lock()
defer c.rw.Unlock()
cpy := c.nextBlock().copy()
@ -1757,7 +1793,8 @@ func (c *Client) WDelayerDepositInfo(owner, token ethCommon.Address) (eth.Deposi
}
// WDelayerDeposit is the interface to call the smart contract function
func (c *Client) WDelayerDeposit(onwer, token ethCommon.Address, amount *big.Int) (tx *types.Transaction, err error) {
func (c *Client) WDelayerDeposit(onwer, token ethCommon.Address, amount *big.Int) (
tx *types.Transaction, err error) {
c.rw.Lock()
defer c.rw.Unlock()
cpy := c.nextBlock().copy()
@ -1771,7 +1808,8 @@ func (c *Client) WDelayerDeposit(onwer, token ethCommon.Address, amount *big.Int
}
// WDelayerWithdrawal is the interface to call the smart contract function
func (c *Client) WDelayerWithdrawal(owner, token ethCommon.Address) (tx *types.Transaction, err error) {
func (c *Client) WDelayerWithdrawal(owner, token ethCommon.Address) (tx *types.Transaction,
err error) {
c.rw.Lock()
defer c.rw.Unlock()
cpy := c.nextBlock().copy()
@ -1785,7 +1823,8 @@ func (c *Client) WDelayerWithdrawal(owner, token ethCommon.Address) (tx *types.T
}
// WDelayerEscapeHatchWithdrawal is the interface to call the smart contract function
func (c *Client) WDelayerEscapeHatchWithdrawal(to, token ethCommon.Address, amount *big.Int) (tx *types.Transaction, err error) {
func (c *Client) WDelayerEscapeHatchWithdrawal(to, token ethCommon.Address, amount *big.Int) (
tx *types.Transaction, err error) {
c.rw.Lock()
defer c.rw.Unlock()
cpy := c.nextBlock().copy()
@ -1843,14 +1882,16 @@ func (c *Client) CtlAddBlocks(blocks []common.BlockData) (err error) {
rollup := nextBlock.Rollup
auction := nextBlock.Auction
for _, token := range block.Rollup.AddedTokens {
if _, err := c.RollupAddTokenSimple(token.EthAddr, rollup.Vars.FeeAddToken); err != nil {
if _, err := c.RollupAddTokenSimple(token.EthAddr,
rollup.Vars.FeeAddToken); err != nil {
return tracerr.Wrap(err)
}
}
for _, tx := range block.Rollup.L1UserTxs {
c.CtlSetAddr(tx.FromEthAddr)
if _, err := c.RollupL1UserTxERC20ETH(tx.FromBJJ, int64(tx.FromIdx), tx.DepositAmount, tx.Amount,
uint32(tx.TokenID), int64(tx.ToIdx)); err != nil {
if _, err := c.RollupL1UserTxERC20ETH(tx.FromBJJ, int64(tx.FromIdx),
tx.DepositAmount, tx.Amount, uint32(tx.TokenID),
int64(tx.ToIdx)); err != nil {
return tracerr.Wrap(err)
}
}

+ 3
- 1
test/ethclient_test.go

@ -49,7 +49,9 @@ func TestClientEth(t *testing.T) {
require.Nil(t, err)
assert.Equal(t, int64(0), block.Num)
assert.Equal(t, time.Unix(0, 0), block.Timestamp)
assert.Equal(t, "0x0000000000000000000000000000000000000000000000000000000000000000", block.Hash.Hex())
assert.Equal(t,
"0x0000000000000000000000000000000000000000000000000000000000000000",
block.Hash.Hex())
// Mine some empty blocks

+ 27
- 13
test/historydb.go

@ -40,7 +40,8 @@ var EthToken common.Token = common.Token{
// WARNING: the generators in this file doesn't necessary follow the protocol
// they are intended to check that the parsers between struct <==> DB are correct
// GenBlocks generates block from, to block numbers. WARNING: This is meant for DB/API testing, and may not be fully consistent with the protocol.
// GenBlocks generates block from, to block numbers. WARNING: This is meant for DB/API testing, and
// may not be fully consistent with the protocol.
func GenBlocks(from, to int64) []common.Block {
var blocks []common.Block
for i := from; i < to; i++ {
@ -54,8 +55,10 @@ func GenBlocks(from, to int64) []common.Block {
return blocks
}
// GenTokens generates tokens. WARNING: This is meant for DB/API testing, and may not be fully consistent with the protocol.
func GenTokens(nTokens int, blocks []common.Block) (tokensToAddInDB []common.Token, ethToken common.Token) {
// GenTokens generates tokens. WARNING: This is meant for DB/API testing, and may not be fully
// consistent with the protocol.
func GenTokens(nTokens int, blocks []common.Block) (tokensToAddInDB []common.Token,
ethToken common.Token) {
tokensToAddInDB = []common.Token{}
for i := 1; i < nTokens; i++ {
token := common.Token{
@ -78,7 +81,8 @@ func GenTokens(nTokens int, blocks []common.Block) (tokensToAddInDB []common.Tok
}
}
// GenBatches generates batches. WARNING: This is meant for DB/API testing, and may not be fully consistent with the protocol.
// GenBatches generates batches. WARNING: This is meant for DB/API testing, and may not be fully
// consistent with the protocol.
func GenBatches(nBatches int, blocks []common.Block) []common.Batch {
batches := []common.Batch{}
collectedFees := make(map[common.TokenID]*big.Int)
@ -108,8 +112,10 @@ func GenBatches(nBatches int, blocks []common.Block) []common.Batch {
return batches
}
// GenAccounts generates accounts. WARNING: This is meant for DB/API testing, and may not be fully consistent with the protocol.
func GenAccounts(totalAccounts, userAccounts int, tokens []common.Token, userAddr *ethCommon.Address, userBjj *babyjub.PublicKey, batches []common.Batch) []common.Account {
// GenAccounts generates accounts. WARNING: This is meant for DB/API testing, and may not be fully
// consistent with the protocol.
func GenAccounts(totalAccounts, userAccounts int, tokens []common.Token,
userAddr *ethCommon.Address, userBjj *babyjub.PublicKey, batches []common.Batch) []common.Account {
if totalAccounts < userAccounts {
panic("totalAccounts must be greater than userAccounts")
}
@ -137,7 +143,8 @@ func GenAccounts(totalAccounts, userAccounts int, tokens []common.Token, userAdd
return accs
}
// GenL1Txs generates L1 txs. WARNING: This is meant for DB/API testing, and may not be fully consistent with the protocol.
// GenL1Txs generates L1 txs. WARNING: This is meant for DB/API testing, and may not be fully
// consistent with the protocol.
func GenL1Txs(
fromIdx int,
totalTxs, nUserTxs int,
@ -263,7 +270,8 @@ func setFromToAndAppend(
}
}
// GenL2Txs generates L2 txs. WARNING: This is meant for DB/API testing, and may not be fully consistent with the protocol.
// GenL2Txs generates L2 txs. WARNING: This is meant for DB/API testing, and may not be fully
// consistent with the protocol.
func GenL2Txs(
fromIdx int,
totalTxs, nUserTxs int,
@ -282,7 +290,9 @@ func GenL2Txs(
amount := big.NewInt(int64(i + 1))
fee := common.FeeSelector(i % 256) //nolint:gomnd
tx := common.L2Tx{
TxID: common.TxID([common.TxIDLen]byte{2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, byte(i)}), // only for testing purposes
// only for testing purposes
TxID: common.TxID([common.TxIDLen]byte{2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, byte(i)}),
BatchNum: batches[i%len(batches)].BatchNum,
Position: i - fromIdx,
Amount: amount,
@ -337,7 +347,8 @@ func GenL2Txs(
return userTxs, othersTxs
}
// GenCoordinators generates coordinators. WARNING: This is meant for DB/API testing, and may not be fully consistent with the protocol.
// GenCoordinators generates coordinators. WARNING: This is meant for DB/API testing, and may not be
// fully consistent with the protocol.
func GenCoordinators(nCoords int, blocks []common.Block) []common.Coordinator {
coords := []common.Coordinator{}
for i := 0; i < nCoords; i++ {
@ -351,7 +362,8 @@ func GenCoordinators(nCoords int, blocks []common.Block) []common.Coordinator {
return coords
}
// GenBids generates bids. WARNING: This is meant for DB/API testing, and may not be fully consistent with the protocol.
// GenBids generates bids. WARNING: This is meant for DB/API testing, and may not be fully
// consistent with the protocol.
func GenBids(nBids int, blocks []common.Block, coords []common.Coordinator) []common.Bid {
bids := []common.Bid{}
for i := 0; i < nBids*2; i = i + 2 { //nolint:gomnd
@ -373,7 +385,8 @@ func GenBids(nBids int, blocks []common.Block, coords []common.Coordinator) []co
// GenExitTree generates an exitTree (as an array of Exits)
//nolint:gomnd
func GenExitTree(n int, batches []common.Batch, accounts []common.Account, blocks []common.Block) []common.ExitInfo {
func GenExitTree(n int, batches []common.Batch, accounts []common.Account,
blocks []common.Block) []common.ExitInfo {
exitTree := make([]common.ExitInfo, n)
for i := 0; i < n; i++ {
exitTree[i] = common.ExitInfo{
@ -412,7 +425,8 @@ func GenExitTree(n int, batches []common.Batch, accounts []common.Account, block
return exitTree
}
func randomAccount(seed int, userAccount bool, userAddr *ethCommon.Address, accs []common.Account) (*common.Account, error) {
func randomAccount(seed int, userAccount bool, userAddr *ethCommon.Address,
accs []common.Account) (*common.Account, error) {
i := seed % len(accs)
firstI := i
for {

+ 2
- 1
test/l2db.go

@ -67,7 +67,8 @@ func GenPoolTxs(n int, tokens []common.Token) []*common.PoolL2Tx {
}
// GenAuths generates account creation authorizations
func GenAuths(nAuths int, chainID uint16, hermezContractAddr ethCommon.Address) []*common.AccountCreationAuth {
func GenAuths(nAuths int, chainID uint16,
hermezContractAddr ethCommon.Address) []*common.AccountCreationAuth {
auths := []*common.AccountCreationAuth{}
for i := 0; i < nAuths; i++ {
// Generate keys

+ 1
- 0
test/proofserver/proofserver.go

@ -68,6 +68,7 @@ func (s *Mock) handleCancel(c *gin.Context) {
c.JSON(http.StatusOK, "OK")
}
//nolint:lll
/* Status example from the real server proof:
Status:

+ 14
- 5
test/til/lang.go

@ -310,7 +310,8 @@ func (p *parser) parseLine(setType setType) (*Instruction, error) {
} else if lit == "PoolL2" {
return &Instruction{Typ: "PoolL2"}, setTypeLine
} else {
return c, tracerr.Wrap(fmt.Errorf("Invalid set type: '%s'. Valid set types: 'Blockchain', 'PoolL2'", lit))
return c,
tracerr.Wrap(fmt.Errorf("Invalid set type: '%s'. Valid set types: 'Blockchain', 'PoolL2'", lit))
}
} else if lit == "AddToken" {
if err := p.expectChar(c, "("); err != nil {
@ -391,7 +392,9 @@ func (p *parser) parseLine(setType setType) (*Instruction, error) {
return c, tracerr.Wrap(fmt.Errorf("Unexpected PoolL2 tx type: %s", lit))
}
} else {
return c, tracerr.Wrap(fmt.Errorf("Invalid set type: '%s'. Valid set types: 'Blockchain', 'PoolL2'", setType))
return c,
tracerr.Wrap(fmt.Errorf("Invalid set type: '%s'. Valid set types: 'Blockchain', 'PoolL2'",
setType))
}
if err := p.expectChar(c, "("); err != nil {
@ -522,14 +525,18 @@ func (p *parser) parse() (*parsedSet, error) {
}
if tracerr.Unwrap(err) == setTypeLine {
if ps.typ != "" {
return ps, tracerr.Wrap(fmt.Errorf("Line %d: Instruction of 'Type: %s' when there is already a previous instruction 'Type: %s' defined", i, instruction.Typ, ps.typ))
return ps,
tracerr.Wrap(fmt.Errorf("Line %d: Instruction of 'Type: %s' when "+
"there is already a previous instruction 'Type: %s' defined",
i, instruction.Typ, ps.typ))
}
if instruction.Typ == "PoolL2" {
ps.typ = SetTypePoolL2
} else if instruction.Typ == "Blockchain" {
ps.typ = SetTypeBlockchain
} else {
log.Fatalf("Line %d: Invalid set type: '%s'. Valid set types: 'Blockchain', 'PoolL2'", i, instruction.Typ)
log.Fatalf("Line %d: Invalid set type: '%s'. Valid set types: "+
"'Blockchain', 'PoolL2'", i, instruction.Typ)
}
continue
}
@ -552,7 +559,9 @@ func (p *parser) parse() (*parsedSet, error) {
}
ps.instructions = append(ps.instructions, *instruction)
users[instruction.From] = true
if instruction.Typ == common.TxTypeTransfer || instruction.Typ == common.TxTypeTransferToEthAddr || instruction.Typ == common.TxTypeTransferToBJJ { // type: Transfer
if instruction.Typ == common.TxTypeTransfer ||
instruction.Typ == common.TxTypeTransferToEthAddr ||
instruction.Typ == common.TxTypeTransferToBJJ { // type: Transfer
users[instruction.To] = true
}
}

+ 29
- 10
test/til/lang_test.go

@ -72,12 +72,19 @@ func TestParseBlockchainTxs(t *testing.T) {
assert.Equal(t, TxTypeCreateAccountDepositCoordinator, instructions.instructions[7].Typ)
assert.Equal(t, TypeNewBatch, instructions.instructions[11].Typ)
assert.Equal(t, "Deposit(1)User0:20", instructions.instructions[16].raw())
assert.Equal(t, "Type: DepositTransfer, From: A, To: B, DepositAmount: 15, Amount: 10, Fee: 0, TokenID: 1\n", instructions.instructions[13].String())
assert.Equal(t, "Type: Transfer, From: User1, To: User0, Amount: 15, Fee: 1, TokenID: 3\n", instructions.instructions[19].String())
assert.Equal(t,
"Type: DepositTransfer, From: A, To: B, DepositAmount: 15, Amount: 10, Fee: 0, TokenID: 1\n",
instructions.instructions[13].String())
assert.Equal(t,
"Type: Transfer, From: User1, To: User0, Amount: 15, Fee: 1, TokenID: 3\n",
instructions.instructions[19].String())
assert.Equal(t, "Transfer(2)A-B:15(1)", instructions.instructions[15].raw())
assert.Equal(t, "Type: Transfer, From: A, To: B, Amount: 15, Fee: 1, TokenID: 2\n", instructions.instructions[15].String())
assert.Equal(t,
"Type: Transfer, From: A, To: B, Amount: 15, Fee: 1, TokenID: 2\n",
instructions.instructions[15].String())
assert.Equal(t, "Exit(1)A:5", instructions.instructions[24].raw())
assert.Equal(t, "Type: Exit, From: A, Amount: 5, TokenID: 1\n", instructions.instructions[24].String())
assert.Equal(t, "Type: Exit, From: A, Amount: 5, TokenID: 1\n",
instructions.instructions[24].String())
}
func TestParsePoolTxs(t *testing.T) {
@ -158,7 +165,9 @@ func TestParseErrors(t *testing.T) {
`
parser = newParser(strings.NewReader(s))
_, err = parser.parse()
assert.Equal(t, "Line 2: Transfer(1)A-B:10(256)\n, err: Fee 256 can not be bigger than 255", err.Error())
assert.Equal(t,
"Line 2: Transfer(1)A-B:10(256)\n, err: Fee 256 can not be bigger than 255",
err.Error())
// check that the PoolTransfer & Transfer are only accepted in the
// correct case case (PoolTxs/BlockchainTxs)
@ -175,7 +184,9 @@ func TestParseErrors(t *testing.T) {
`
parser = newParser(strings.NewReader(s))
_, err = parser.parse()
assert.Equal(t, "Line 2: PoolTransfer, err: Unexpected Blockchain tx type: PoolTransfer", err.Error())
assert.Equal(t,
"Line 2: PoolTransfer, err: Unexpected Blockchain tx type: PoolTransfer",
err.Error())
s = `
Type: Blockchain
@ -183,7 +194,9 @@ func TestParseErrors(t *testing.T) {
`
parser = newParser(strings.NewReader(s))
_, err = parser.parse()
assert.Equal(t, "Line 2: >, err: Unexpected '> btch', expected '> batch' or '> block'", err.Error())
assert.Equal(t,
"Line 2: >, err: Unexpected '> btch', expected '> batch' or '> block'",
err.Error())
// check definition of set Type
s = `PoolTransfer(1) A-B: 10 (1)`
@ -193,17 +206,23 @@ func TestParseErrors(t *testing.T) {
s = `Type: PoolL1`
parser = newParser(strings.NewReader(s))
_, err = parser.parse()
assert.Equal(t, "Line 1: Type:, err: Invalid set type: 'PoolL1'. Valid set types: 'Blockchain', 'PoolL2'", err.Error())
assert.Equal(t,
"Line 1: Type:, err: Invalid set type: 'PoolL1'. Valid set types: 'Blockchain', 'PoolL2'",
err.Error())
s = `Type: PoolL1
Type: Blockchain`
parser = newParser(strings.NewReader(s))
_, err = parser.parse()
assert.Equal(t, "Line 1: Type:, err: Invalid set type: 'PoolL1'. Valid set types: 'Blockchain', 'PoolL2'", err.Error())
assert.Equal(t,
"Line 1: Type:, err: Invalid set type: 'PoolL1'. Valid set types: 'Blockchain', 'PoolL2'",
err.Error())
s = `Type: PoolL2
Type: Blockchain`
parser = newParser(strings.NewReader(s))
_, err = parser.parse()
assert.Equal(t, "Line 2: Instruction of 'Type: Blockchain' when there is already a previous instruction 'Type: PoolL2' defined", err.Error())
assert.Equal(t,
"Line 2: Instruction of 'Type: Blockchain' when there is already a previous "+
"instruction 'Type: PoolL2' defined", err.Error())
s = `Type: Blockchain
AddToken(1)

+ 42
- 17
test/til/txs.go

@ -161,7 +161,9 @@ func (tc *Context) GenerateBlocks(set string) ([]common.BlockData, error) {
return nil, tracerr.Wrap(err)
}
if parsedSet.typ != SetTypeBlockchain {
return nil, tracerr.Wrap(fmt.Errorf("Expected set type: %s, found: %s", SetTypeBlockchain, parsedSet.typ))
return nil,
tracerr.Wrap(fmt.Errorf("Expected set type: %s, found: %s",
SetTypeBlockchain, parsedSet.typ))
}
tc.instructions = parsedSet.instructions
@ -209,7 +211,9 @@ func (tc *Context) generateBlocks() ([]common.BlockData, error) {
TokenID: inst.TokenID,
Amount: big.NewInt(0),
DepositAmount: big.NewInt(0),
Type: common.TxTypeCreateAccountDeposit, // as TxTypeCreateAccountDepositCoordinator is not valid oustide Til package
// as TxTypeCreateAccountDepositCoordinator is
// not valid oustide Til package
Type: common.TxTypeCreateAccountDeposit,
}
testTx := L1Tx{
lineNum: inst.LineNum,
@ -218,7 +222,8 @@ func (tc *Context) generateBlocks() ([]common.BlockData, error) {
}
tc.currBatchTest.l1CoordinatorTxs = append(tc.currBatchTest.l1CoordinatorTxs, testTx)
case common.TxTypeCreateAccountDeposit, common.TxTypeCreateAccountDepositTransfer: // tx source: L1UserTx
case common.TxTypeCreateAccountDeposit, common.TxTypeCreateAccountDepositTransfer:
// tx source: L1UserTx
if err := tc.checkIfTokenIsRegistered(inst); err != nil {
log.Error(err)
return nil, tracerr.Wrap(fmt.Errorf("Line %d: %s", inst.LineNum, err.Error()))
@ -281,7 +286,8 @@ func (tc *Context) generateBlocks() ([]common.BlockData, error) {
Type: common.TxTypeTransfer,
EthBlockNum: tc.blockNum,
}
tx.BatchNum = common.BatchNum(tc.currBatchNum) // when converted to PoolL2Tx BatchNum parameter is lost
// when converted to PoolL2Tx BatchNum parameter is lost
tx.BatchNum = common.BatchNum(tc.currBatchNum)
testTx := L2Tx{
lineNum: inst.LineNum,
fromIdxName: inst.From,
@ -322,7 +328,8 @@ func (tc *Context) generateBlocks() ([]common.BlockData, error) {
Type: common.TxTypeExit,
EthBlockNum: tc.blockNum,
}
tx.BatchNum = common.BatchNum(tc.currBatchNum) // when converted to PoolL2Tx BatchNum parameter is lost
// when converted to PoolL2Tx BatchNum parameter is lost
tx.BatchNum = common.BatchNum(tc.currBatchNum)
testTx := L2Tx{
lineNum: inst.LineNum,
fromIdxName: inst.From,
@ -395,7 +402,10 @@ func (tc *Context) generateBlocks() ([]common.BlockData, error) {
EthBlockNum: tc.blockNum,
}
if inst.TokenID != tc.LastRegisteredTokenID+1 {
return nil, tracerr.Wrap(fmt.Errorf("Line %d: AddToken TokenID should be sequential, expected TokenID: %d, defined TokenID: %d", inst.LineNum, tc.LastRegisteredTokenID+1, inst.TokenID))
return nil,
tracerr.Wrap(fmt.Errorf("Line %d: AddToken TokenID should be "+
"sequential, expected TokenID: %d, defined TokenID: %d",
inst.LineNum, tc.LastRegisteredTokenID+1, inst.TokenID))
}
tc.LastRegisteredTokenID++
tc.currBlock.Rollup.AddedTokens = append(tc.currBlock.Rollup.AddedTokens, newToken)
@ -413,9 +423,13 @@ func (tc *Context) calculateIdxForL1Txs(isCoordinatorTxs bool, txs []L1Tx) error
// for each batch.L1CoordinatorTxs of the Queues[ToForgeNum], calculate the Idx
for i := 0; i < len(txs); i++ {
tx := txs[i]
if tx.L1Tx.Type == common.TxTypeCreateAccountDeposit || tx.L1Tx.Type == common.TxTypeCreateAccountDepositTransfer {
if tc.Users[tx.fromIdxName].Accounts[tx.L1Tx.TokenID] != nil { // if account already exists, return error
return tracerr.Wrap(fmt.Errorf("Can not create same account twice (same User (%s) & same TokenID (%d)) (this is a design property of Til)", tx.fromIdxName, tx.L1Tx.TokenID))
if tx.L1Tx.Type == common.TxTypeCreateAccountDeposit ||
tx.L1Tx.Type == common.TxTypeCreateAccountDepositTransfer {
if tc.Users[tx.fromIdxName].Accounts[tx.L1Tx.TokenID] != nil {
// if account already exists, return error
return tracerr.Wrap(fmt.Errorf("Can not create same account twice "+
"(same User (%s) & same TokenID (%d)) (this is a design property of Til)",
tx.fromIdxName, tx.L1Tx.TokenID))
}
tc.Users[tx.fromIdxName].Accounts[tx.L1Tx.TokenID] = &Account{
Idx: common.Idx(tc.idx),
@ -423,7 +437,8 @@ func (tc *Context) calculateIdxForL1Txs(isCoordinatorTxs bool, txs []L1Tx) error
Nonce: common.Nonce(0),
BatchNum: tc.currBatchNum,
}
tc.l1CreatedAccounts[idxTokenIDToString(tx.fromIdxName, tx.L1Tx.TokenID)] = tc.Users[tx.fromIdxName].Accounts[tx.L1Tx.TokenID]
tc.l1CreatedAccounts[idxTokenIDToString(tx.fromIdxName, tx.L1Tx.TokenID)] =
tc.Users[tx.fromIdxName].Accounts[tx.L1Tx.TokenID]
tc.accountsByIdx[tc.idx] = tc.Users[tx.fromIdxName].Accounts[tx.L1Tx.TokenID]
tc.UsersByIdx[tc.idx] = tc.Users[tx.fromIdxName]
tc.idx++
@ -442,11 +457,15 @@ func (tc *Context) setIdxs() error {
testTx := &tc.currBatchTest.l2Txs[i]
if tc.Users[testTx.fromIdxName].Accounts[testTx.tokenID] == nil {
return tracerr.Wrap(fmt.Errorf("Line %d: %s from User %s for TokenID %d while account not created yet", testTx.lineNum, testTx.L2Tx.Type, testTx.fromIdxName, testTx.tokenID))
return tracerr.Wrap(fmt.Errorf("Line %d: %s from User %s for TokenID %d "+
"while account not created yet",
testTx.lineNum, testTx.L2Tx.Type, testTx.fromIdxName, testTx.tokenID))
}
if testTx.L2Tx.Type == common.TxTypeTransfer {
if _, ok := tc.l1CreatedAccounts[idxTokenIDToString(testTx.toIdxName, testTx.tokenID)]; !ok {
return tracerr.Wrap(fmt.Errorf("Line %d: Can not create Transfer for a non existing account. Batch %d, ToIdx name: %s, TokenID: %d", testTx.lineNum, tc.currBatchNum, testTx.toIdxName, testTx.tokenID))
return tracerr.Wrap(fmt.Errorf("Line %d: Can not create Transfer for a non "+
"existing account. Batch %d, ToIdx name: %s, TokenID: %d",
testTx.lineNum, tc.currBatchNum, testTx.toIdxName, testTx.tokenID))
}
}
tc.Users[testTx.fromIdxName].Accounts[testTx.tokenID].Nonce++
@ -498,7 +517,8 @@ func (tc *Context) addToL1UserQueue(tx L1Tx) error {
tx.L1Tx.Position = len(tc.Queues[tc.openToForge])
// When an L1UserTx is generated, all idxs must be available (except when idx == 0 or idx == 1)
if tx.L1Tx.Type != common.TxTypeCreateAccountDeposit && tx.L1Tx.Type != common.TxTypeCreateAccountDepositTransfer {
if tx.L1Tx.Type != common.TxTypeCreateAccountDeposit &&
tx.L1Tx.Type != common.TxTypeCreateAccountDepositTransfer {
tx.L1Tx.FromIdx = tc.Users[tx.fromIdxName].Accounts[tx.L1Tx.TokenID].Idx
}
tx.L1Tx.FromEthAddr = tc.Users[tx.fromIdxName].Addr
@ -530,14 +550,16 @@ func (tc *Context) addToL1UserQueue(tx L1Tx) error {
func (tc *Context) checkIfAccountExists(tf string, inst Instruction) error {
if tc.Users[tf].Accounts[inst.TokenID] == nil {
return tracerr.Wrap(fmt.Errorf("%s at User: %s, for TokenID: %d, while account not created yet", inst.Typ, tf, inst.TokenID))
return tracerr.Wrap(fmt.Errorf("%s at User: %s, for TokenID: %d, while account not created yet",
inst.Typ, tf, inst.TokenID))
}
return nil
}
func (tc *Context) checkIfTokenIsRegistered(inst Instruction) error {
if inst.TokenID > tc.LastRegisteredTokenID {
return tracerr.Wrap(fmt.Errorf("Can not process %s: TokenID %d not registered, last registered TokenID: %d", inst.Typ, inst.TokenID, tc.LastRegisteredTokenID))
return tracerr.Wrap(fmt.Errorf("Can not process %s: TokenID %d not registered, "+
"last registered TokenID: %d", inst.Typ, inst.TokenID, tc.LastRegisteredTokenID))
}
return nil
}
@ -551,7 +573,8 @@ func (tc *Context) GeneratePoolL2Txs(set string) ([]common.PoolL2Tx, error) {
return nil, tracerr.Wrap(err)
}
if parsedSet.typ != SetTypePoolL2 {
return nil, tracerr.Wrap(fmt.Errorf("Expected set type: %s, found: %s", SetTypePoolL2, parsedSet.typ))
return nil, tracerr.Wrap(fmt.Errorf("Expected set type: %s, found: %s",
SetTypePoolL2, parsedSet.typ))
}
tc.instructions = parsedSet.instructions
@ -668,7 +691,9 @@ func (tc *Context) generatePoolL2Txs() ([]common.PoolL2Tx, error) {
tx.Signature = sig.Compress()
txs = append(txs, tx)
default:
return nil, tracerr.Wrap(fmt.Errorf("Line %d: instruction type unrecognized: %s", inst.LineNum, inst.Typ))
return nil,
tracerr.Wrap(fmt.Errorf("Line %d: instruction type unrecognized: %s",
inst.LineNum, inst.Typ))
}
}

+ 58
- 33
test/til/txs_test.go

@ -119,49 +119,66 @@ func TestGenerateBlocks(t *testing.T) {
// Check expected values generated by each line
// #0: Deposit(1) A: 10
tc.checkL1TxParams(t, blocks[0].Rollup.L1UserTxs[0], common.TxTypeCreateAccountDeposit, 1, "A", "", big.NewInt(10), nil)
tc.checkL1TxParams(t, blocks[0].Rollup.L1UserTxs[0], common.TxTypeCreateAccountDeposit, 1,
"A", "", big.NewInt(10), nil)
// #1: Deposit(2) A: 20
tc.checkL1TxParams(t, blocks[0].Rollup.L1UserTxs[1], common.TxTypeCreateAccountDeposit, 2, "A", "", big.NewInt(20), nil)
tc.checkL1TxParams(t, blocks[0].Rollup.L1UserTxs[1], common.TxTypeCreateAccountDeposit, 2,
"A", "", big.NewInt(20), nil)
// // #2: Deposit(1) A: 20
tc.checkL1TxParams(t, blocks[0].Rollup.L1UserTxs[2], common.TxTypeCreateAccountDeposit, 1, "B", "", big.NewInt(5), nil)
tc.checkL1TxParams(t, blocks[0].Rollup.L1UserTxs[2], common.TxTypeCreateAccountDeposit, 1,
"B", "", big.NewInt(5), nil)
// // #3: CreateAccountDeposit(1) C: 5
tc.checkL1TxParams(t, blocks[0].Rollup.L1UserTxs[3], common.TxTypeCreateAccountDeposit, 1, "C", "", big.NewInt(5), nil)
tc.checkL1TxParams(t, blocks[0].Rollup.L1UserTxs[3], common.TxTypeCreateAccountDeposit, 1,
"C", "", big.NewInt(5), nil)
// // #4: CreateAccountDeposit(1) D: 5
tc.checkL1TxParams(t, blocks[0].Rollup.L1UserTxs[4], common.TxTypeCreateAccountDeposit, 1, "D", "", big.NewInt(5), nil)
tc.checkL1TxParams(t, blocks[0].Rollup.L1UserTxs[4], common.TxTypeCreateAccountDeposit, 1,
"D", "", big.NewInt(5), nil)
// #5: Transfer(1) A-B: 6 (1)
tc.checkL2TxParams(t, blocks[0].Rollup.Batches[2].L2Txs[0], common.TxTypeTransfer, 1, "A", "B", big.NewInt(6), common.BatchNum(3))
tc.checkL2TxParams(t, blocks[0].Rollup.Batches[2].L2Txs[0], common.TxTypeTransfer, 1, "A",
"B", big.NewInt(6), common.BatchNum(3))
// #6: Transfer(1) B-D: 3 (1)
tc.checkL2TxParams(t, blocks[0].Rollup.Batches[2].L2Txs[1], common.TxTypeTransfer, 1, "B", "D", big.NewInt(3), common.BatchNum(3))
tc.checkL2TxParams(t, blocks[0].Rollup.Batches[2].L2Txs[1], common.TxTypeTransfer, 1, "B",
"D", big.NewInt(3), common.BatchNum(3))
// #7: Transfer(1) A-D: 1 (1)
tc.checkL2TxParams(t, blocks[0].Rollup.Batches[2].L2Txs[2], common.TxTypeTransfer, 1, "A", "D", big.NewInt(1), common.BatchNum(3))
// change of Batch
// #8: CreateAccountDepositTransfer(1) F-A: 15, 10 (3)
tc.checkL1TxParams(t, blocks[0].Rollup.L1UserTxs[5], common.TxTypeCreateAccountDepositTransfer, 1, "F", "A", big.NewInt(15), big.NewInt(10))
tc.checkL2TxParams(t, blocks[0].Rollup.Batches[2].L2Txs[2], common.TxTypeTransfer, 1, "A",
"D", big.NewInt(1), common.BatchNum(3))
// change of Batch #8: CreateAccountDepositTransfer(1) F-A: 15, 10 (3)
tc.checkL1TxParams(t, blocks[0].Rollup.L1UserTxs[5],
common.TxTypeCreateAccountDepositTransfer, 1, "F", "A", big.NewInt(15), big.NewInt(10))
// #9: DepositTransfer(1) A-B: 15, 10 (1)
tc.checkL1TxParams(t, blocks[0].Rollup.L1UserTxs[6], common.TxTypeDepositTransfer, 1, "A", "B", big.NewInt(15), big.NewInt(10))
tc.checkL1TxParams(t, blocks[0].Rollup.L1UserTxs[6], common.TxTypeDepositTransfer, 1, "A",
"B", big.NewInt(15), big.NewInt(10))
// #11: Transfer(1) C-A : 3 (1)
tc.checkL2TxParams(t, blocks[0].Rollup.Batches[3].L2Txs[0], common.TxTypeTransfer, 1, "C", "A", big.NewInt(3), common.BatchNum(4))
tc.checkL2TxParams(t, blocks[0].Rollup.Batches[3].L2Txs[0], common.TxTypeTransfer, 1, "C",
"A", big.NewInt(3), common.BatchNum(4))
// #12: Transfer(2) A-B: 15 (1)
tc.checkL2TxParams(t, blocks[0].Rollup.Batches[3].L2Txs[1], common.TxTypeTransfer, 2, "A", "B", big.NewInt(15), common.BatchNum(4))
tc.checkL2TxParams(t, blocks[0].Rollup.Batches[3].L2Txs[1], common.TxTypeTransfer, 2, "A",
"B", big.NewInt(15), common.BatchNum(4))
// #13: Deposit(1) User0: 20
tc.checkL1TxParams(t, blocks[0].Rollup.L1UserTxs[7], common.TxTypeCreateAccountDeposit, 1, "User0", "", big.NewInt(20), nil)
tc.checkL1TxParams(t, blocks[0].Rollup.L1UserTxs[7], common.TxTypeCreateAccountDeposit, 1,
"User0", "", big.NewInt(20), nil)
// // #14: Deposit(3) User1: 20
tc.checkL1TxParams(t, blocks[0].Rollup.L1UserTxs[8], common.TxTypeCreateAccountDeposit, 3, "User1", "", big.NewInt(20), nil)
tc.checkL1TxParams(t, blocks[0].Rollup.L1UserTxs[8], common.TxTypeCreateAccountDeposit, 3,
"User1", "", big.NewInt(20), nil)
// #15: Transfer(1) User0-User1: 15 (1)
tc.checkL2TxParams(t, blocks[0].Rollup.Batches[4].L2Txs[0], common.TxTypeTransfer, 1, "User0", "User1", big.NewInt(15), common.BatchNum(5))
tc.checkL2TxParams(t, blocks[0].Rollup.Batches[4].L2Txs[0], common.TxTypeTransfer, 1,
"User0", "User1", big.NewInt(15), common.BatchNum(5))
// #16: Transfer(3) User1-User0: 15 (1)
tc.checkL2TxParams(t, blocks[0].Rollup.Batches[4].L2Txs[1], common.TxTypeTransfer, 3, "User1", "User0", big.NewInt(15), common.BatchNum(5))
tc.checkL2TxParams(t, blocks[0].Rollup.Batches[4].L2Txs[1], common.TxTypeTransfer, 3,
"User1", "User0", big.NewInt(15), common.BatchNum(5))
// #17: Transfer(1) A-C: 1 (1)
tc.checkL2TxParams(t, blocks[0].Rollup.Batches[4].L2Txs[2], common.TxTypeTransfer, 1, "A", "C", big.NewInt(1), common.BatchNum(5))
// change of Batch
// #18: Transfer(1) User1-User0: 1 (1)
tc.checkL2TxParams(t, blocks[1].Rollup.Batches[0].L2Txs[0], common.TxTypeTransfer, 1, "User1", "User0", big.NewInt(1), common.BatchNum(6))
// change of Block (implies also a change of batch)
// #19: Transfer(1) A-B: 1 (1)
tc.checkL2TxParams(t, blocks[1].Rollup.Batches[0].L2Txs[1], common.TxTypeTransfer, 1, "A", "B", big.NewInt(1), common.BatchNum(6))
tc.checkL2TxParams(t, blocks[0].Rollup.Batches[4].L2Txs[2], common.TxTypeTransfer, 1, "A",
"C", big.NewInt(1), common.BatchNum(5))
// change of Batch #18: Transfer(1) User1-User0: 1 (1)
tc.checkL2TxParams(t, blocks[1].Rollup.Batches[0].L2Txs[0], common.TxTypeTransfer, 1,
"User1", "User0", big.NewInt(1), common.BatchNum(6))
// change of Block (implies also a change of batch) #19: Transfer(1) A-B: 1 (1)
tc.checkL2TxParams(t, blocks[1].Rollup.Batches[0].L2Txs[1], common.TxTypeTransfer, 1, "A",
"B", big.NewInt(1), common.BatchNum(6))
}
func (tc *Context) checkL1TxParams(t *testing.T, tx common.L1Tx, typ common.TxType, tokenID common.TokenID, from, to string, depositAmount, amount *big.Int) {
func (tc *Context) checkL1TxParams(t *testing.T, tx common.L1Tx, typ common.TxType,
tokenID common.TokenID, from, to string, depositAmount, amount *big.Int) {
assert.Equal(t, typ, tx.Type)
if tx.FromIdx != common.Idx(0) {
assert.Equal(t, tc.Users[from].Accounts[tokenID].Idx, tx.FromIdx)
@ -179,7 +196,8 @@ func (tc *Context) checkL1TxParams(t *testing.T, tx common.L1Tx, typ common.TxTy
}
}
func (tc *Context) checkL2TxParams(t *testing.T, tx common.L2Tx, typ common.TxType, tokenID common.TokenID, from, to string, amount *big.Int, batchNum common.BatchNum) {
func (tc *Context) checkL2TxParams(t *testing.T, tx common.L2Tx, typ common.TxType,
tokenID common.TokenID, from, to string, amount *big.Int, batchNum common.BatchNum) {
assert.Equal(t, typ, tx.Type)
assert.Equal(t, tc.Users[from].Accounts[tokenID].Idx, tx.FromIdx)
if tx.Type != common.TxTypeExit {
@ -367,7 +385,9 @@ func TestGenerateErrors(t *testing.T) {
`
tc := NewContext(0, common.RollupConstMaxL1UserTx)
_, err := tc.GenerateBlocks(set)
assert.Equal(t, "Line 2: Can not process CreateAccountDeposit: TokenID 1 not registered, last registered TokenID: 0", err.Error())
assert.Equal(t,
"Line 2: Can not process CreateAccountDeposit: TokenID 1 not registered, "+
"last registered TokenID: 0", err.Error())
// ensure AddToken sequentiality and not using 0
set = `
@ -384,7 +404,8 @@ func TestGenerateErrors(t *testing.T) {
`
tc = NewContext(0, common.RollupConstMaxL1UserTx)
_, err = tc.GenerateBlocks(set)
require.Equal(t, "Line 2: AddToken TokenID should be sequential, expected TokenID: 1, defined TokenID: 2", err.Error())
require.Equal(t, "Line 2: AddToken TokenID should be sequential, expected TokenID: "+
"1, defined TokenID: 2", err.Error())
set = `
Type: Blockchain
@ -395,7 +416,8 @@ func TestGenerateErrors(t *testing.T) {
`
tc = NewContext(0, common.RollupConstMaxL1UserTx)
_, err = tc.GenerateBlocks(set)
require.Equal(t, "Line 5: AddToken TokenID should be sequential, expected TokenID: 4, defined TokenID: 5", err.Error())
require.Equal(t, "Line 5: AddToken TokenID should be sequential, expected TokenID: "+
"4, defined TokenID: 5", err.Error())
// check transactions when account is not created yet
set = `
@ -409,7 +431,8 @@ func TestGenerateErrors(t *testing.T) {
`
tc = NewContext(0, common.RollupConstMaxL1UserTx)
_, err = tc.GenerateBlocks(set)
require.Equal(t, "Line 5: CreateAccountDeposit(1)BTransfer(1) A-B: 6 (1)\n, err: Expected ':', found 'Transfer'", err.Error())
require.Equal(t, "Line 5: CreateAccountDeposit(1)BTransfer(1) A-B: 6 (1)\n, err: "+
"Expected ':', found 'Transfer'", err.Error())
set = `
Type: Blockchain
AddToken(1)
@ -434,7 +457,8 @@ func TestGenerateErrors(t *testing.T) {
CreateAccountCoordinator(1) B
> batchL1
Transfer(1) A-B: 6 (1)
Transfer(1) A-B: 6 (1) // on purpose this is moving more money that what it has in the account, Til should not fail
Transfer(1) A-B: 6 (1) // on purpose this is moving more money that
// what it has in the account, Til should not fail
Transfer(1) B-A: 6 (1)
Exit(1) A: 3 (1)
> batch
@ -558,7 +582,8 @@ func TestGenerateFromInstructions(t *testing.T) {
CreateAccountCoordinator(1) B
> batchL1
Transfer(1) A-B: 6 (1)
Transfer(1) A-B: 6 (1) // on purpose this is moving more money that what it has in the account, Til should not fail
Transfer(1) A-B: 6 (1) // on purpose this is moving more money that
// what it has in the account, Til should not fail
Transfer(1) B-A: 6 (1)
Exit(1) A: 3 (1)
> batch

+ 2
- 1
test/txsets/tilsets.go

@ -181,7 +181,8 @@ Transfer(1) H-O: 5 (1)
Transfer(1) I-H: 5 (1)
Exit(1) A: 5 (1)
// create CoordinatorTx CreateAccount for D, TokenId 2, used at SetPool0 for 'PoolTransfer(2) B-D: 3 (1)'
// create CoordinatorTx CreateAccount for D, TokenId 2, used at SetPool0 for
// 'PoolTransfer(2) B-D: 3 (1)'
CreateAccountCoordinator(2) D
> batchL1

+ 35
- 14
test/txsets/txhelpers.go

@ -25,8 +25,14 @@ import (
func GenerateJsUsers(t *testing.T) []til.User {
// same values than in the js test
// skJsHex is equivalent to the 0000...000i js private key in commonjs
skJsHex := []string{"7eb258e61862aae75c6c1d1f7efae5006ffc9e4d5596a6ff95f3df4ea209ea7f", "c005700f76f4b4cec710805c21595688648524df0a9d467afae537b7a7118819", "b373d14c67fb2a517bf4ac831c93341eec8e1b38dbc14e7d725b292a7cf84707", "2064b68d04a7aaae0ac3b36bf6f1850b380f1423be94a506c531940bd4a48b76"}
addrHex := []string{"0x7e5f4552091a69125d5dfcb7b8c2659029395bdf", "0x2b5ad5c4795c026514f8317c7a215e218dccd6cf", "0x6813eb9362372eef6200f3b1dbc3f819671cba69", "0x1eff47bc3a10a45d4b230b5d10e37751fe6aa718"}
skJsHex := []string{"7eb258e61862aae75c6c1d1f7efae5006ffc9e4d5596a6ff95f3df4ea209ea7f",
"c005700f76f4b4cec710805c21595688648524df0a9d467afae537b7a7118819",
"b373d14c67fb2a517bf4ac831c93341eec8e1b38dbc14e7d725b292a7cf84707",
"2064b68d04a7aaae0ac3b36bf6f1850b380f1423be94a506c531940bd4a48b76"}
addrHex := []string{"0x7e5f4552091a69125d5dfcb7b8c2659029395bdf",
"0x2b5ad5c4795c026514f8317c7a215e218dccd6cf",
"0x6813eb9362372eef6200f3b1dbc3f819671cba69",
"0x1eff47bc3a10a45d4b230b5d10e37751fe6aa718"}
var users []til.User
for i := 0; i < len(skJsHex); i++ {
skJs, err := hex.DecodeString(skJsHex[i])
@ -41,10 +47,14 @@ func GenerateJsUsers(t *testing.T) []til.User {
}
users = append(users, user)
}
assert.Equal(t, "d746824f7d0ac5044a573f51b278acb56d823bec39551d1d7bf7378b68a1b021", users[0].BJJ.Public().String())
assert.Equal(t, "4d05c307400c65795f02db96b1b81c60386fd53e947d9d3f749f3d99b1853909", users[1].BJJ.Public().String())
assert.Equal(t, "38ffa002724562eb2a952a2503e206248962406cf16392ff32759b6f2a41fe11", users[2].BJJ.Public().String())
assert.Equal(t, "c719e6401190be7fa7fbfcd3448fe2755233c01575341a3b09edadf5454f760b", users[3].BJJ.Public().String())
assert.Equal(t, "d746824f7d0ac5044a573f51b278acb56d823bec39551d1d7bf7378b68a1b021",
users[0].BJJ.Public().String())
assert.Equal(t, "4d05c307400c65795f02db96b1b81c60386fd53e947d9d3f749f3d99b1853909",
users[1].BJJ.Public().String())
assert.Equal(t, "38ffa002724562eb2a952a2503e206248962406cf16392ff32759b6f2a41fe11",
users[2].BJJ.Public().String())
assert.Equal(t, "c719e6401190be7fa7fbfcd3448fe2755233c01575341a3b09edadf5454f760b",
users[3].BJJ.Public().String())
return users
}
@ -58,7 +68,9 @@ func signL2Tx(t *testing.T, chainID uint16, user til.User, l2Tx common.PoolL2Tx)
}
// GenerateTxsZKInputsHash0 generates the transactions for the TestZKInputsHash0
func GenerateTxsZKInputsHash0(t *testing.T, chainID uint16) (users []til.User, coordIdxs []common.Idx, l1UserTxs []common.L1Tx, l1CoordTxs []common.L1Tx, l2Txs []common.PoolL2Tx) {
func GenerateTxsZKInputsHash0(t *testing.T, chainID uint16) (users []til.User,
coordIdxs []common.Idx, l1UserTxs []common.L1Tx, l1CoordTxs []common.L1Tx,
l2Txs []common.PoolL2Tx) {
// same values than in the js test
users = GenerateJsUsers(t)
@ -93,7 +105,9 @@ func GenerateTxsZKInputsHash0(t *testing.T, chainID uint16) (users []til.User, c
}
// GenerateTxsZKInputsHash1 generates the transactions for the TestZKInputsHash1
func GenerateTxsZKInputsHash1(t *testing.T, chainID uint16) (users []til.User, coordIdxs []common.Idx, l1UserTxs []common.L1Tx, l1CoordTxs []common.L1Tx, l2Txs []common.PoolL2Tx) {
func GenerateTxsZKInputsHash1(t *testing.T, chainID uint16) (users []til.User,
coordIdxs []common.Idx, l1UserTxs []common.L1Tx, l1CoordTxs []common.L1Tx,
l2Txs []common.PoolL2Tx) {
// same values than in the js test
users = GenerateJsUsers(t)
l1UserTxs = []common.L1Tx{
@ -138,7 +152,9 @@ func GenerateTxsZKInputsHash1(t *testing.T, chainID uint16) (users []til.User, c
}
// GenerateTxsZKInputs0 generates the transactions for the TestZKInputs0
func GenerateTxsZKInputs0(t *testing.T, chainID uint16) (users []til.User, coordIdxs []common.Idx, l1UserTxs []common.L1Tx, l1CoordTxs []common.L1Tx, l2Txs []common.PoolL2Tx) {
func GenerateTxsZKInputs0(t *testing.T, chainID uint16) (users []til.User,
coordIdxs []common.Idx, l1UserTxs []common.L1Tx, l1CoordTxs []common.L1Tx,
l2Txs []common.PoolL2Tx) {
// same values than in the js test
users = GenerateJsUsers(t)
@ -175,7 +191,8 @@ func GenerateTxsZKInputs0(t *testing.T, chainID uint16) (users []til.User, coord
}
// GenerateTxsZKInputs1 generates the transactions for the TestZKInputs1
func GenerateTxsZKInputs1(t *testing.T, chainID uint16) (users []til.User, coordIdxs []common.Idx, l1UserTxs []common.L1Tx, l1CoordTxs []common.L1Tx, l2Txs []common.PoolL2Tx) {
func GenerateTxsZKInputs1(t *testing.T, chainID uint16) (users []til.User, coordIdxs []common.Idx,
l1UserTxs []common.L1Tx, l1CoordTxs []common.L1Tx, l2Txs []common.PoolL2Tx) {
// same values than in the js test
users = GenerateJsUsers(t)
@ -222,7 +239,8 @@ func GenerateTxsZKInputs1(t *testing.T, chainID uint16) (users []til.User, coord
}
// GenerateTxsZKInputs2 generates the transactions for the TestZKInputs2
func GenerateTxsZKInputs2(t *testing.T, chainID uint16) (users []til.User, coordIdxs []common.Idx, l1UserTxs []common.L1Tx, l1CoordTxs []common.L1Tx, l2Txs []common.PoolL2Tx) {
func GenerateTxsZKInputs2(t *testing.T, chainID uint16) (users []til.User, coordIdxs []common.Idx,
l1UserTxs []common.L1Tx, l1CoordTxs []common.L1Tx, l2Txs []common.PoolL2Tx) {
// same values than in the js test
users = GenerateJsUsers(t)
@ -301,7 +319,8 @@ func GenerateTxsZKInputs2(t *testing.T, chainID uint16) (users []til.User, coord
}
// GenerateTxsZKInputs3 generates the transactions for the TestZKInputs3
func GenerateTxsZKInputs3(t *testing.T, chainID uint16) (users []til.User, coordIdxs []common.Idx, l1UserTxs []common.L1Tx, l1CoordTxs []common.L1Tx, l2Txs []common.PoolL2Tx) {
func GenerateTxsZKInputs3(t *testing.T, chainID uint16) (users []til.User, coordIdxs []common.Idx,
l1UserTxs []common.L1Tx, l1CoordTxs []common.L1Tx, l2Txs []common.PoolL2Tx) {
// same values than in the js test
users = GenerateJsUsers(t)
@ -380,7 +399,8 @@ func GenerateTxsZKInputs3(t *testing.T, chainID uint16) (users []til.User, coord
}
// GenerateTxsZKInputs4 generates the transactions for the TestZKInputs4
func GenerateTxsZKInputs4(t *testing.T, chainID uint16) (users []til.User, coordIdxs []common.Idx, l1UserTxs []common.L1Tx, l1CoordTxs []common.L1Tx, l2Txs []common.PoolL2Tx) {
func GenerateTxsZKInputs4(t *testing.T, chainID uint16) (users []til.User, coordIdxs []common.Idx,
l1UserTxs []common.L1Tx, l1CoordTxs []common.L1Tx, l2Txs []common.PoolL2Tx) {
// same values than in the js test
users = GenerateJsUsers(t)
@ -469,7 +489,8 @@ func GenerateTxsZKInputs4(t *testing.T, chainID uint16) (users []til.User, coord
}
// GenerateTxsZKInputs5 generates the transactions for the TestZKInputs5
func GenerateTxsZKInputs5(t *testing.T, chainID uint16) (users []til.User, coordIdxs []common.Idx, l1UserTxs []common.L1Tx, l1CoordTxs []common.L1Tx, l2Txs []common.PoolL2Tx) {
func GenerateTxsZKInputs5(t *testing.T, chainID uint16) (users []til.User, coordIdxs []common.Idx,
l1UserTxs []common.L1Tx, l1CoordTxs []common.L1Tx, l2Txs []common.PoolL2Tx) {
// same values than in the js test
users = GenerateJsUsers(t)

+ 55
- 22
test/zkproof/flows_test.go

@ -55,7 +55,8 @@ func addL2Txs(t *testing.T, l2DB *l2db.L2DB, poolL2Txs []common.PoolL2Tx) {
}
}
func addAccCreationAuth(t *testing.T, tc *til.Context, l2DB *l2db.L2DB, chainID uint16, hermezContractAddr ethCommon.Address, username string) []byte {
func addAccCreationAuth(t *testing.T, tc *til.Context, l2DB *l2db.L2DB, chainID uint16,
hermezContractAddr ethCommon.Address, username string) []byte {
user := tc.Users[username]
auth := &common.AccountCreationAuth{
EthAddr: user.Addr,
@ -71,7 +72,8 @@ func addAccCreationAuth(t *testing.T, tc *til.Context, l2DB *l2db.L2DB, chainID
return auth.Signature
}
func initTxSelector(t *testing.T, chainID uint16, hermezContractAddr ethCommon.Address, coordUser *til.User) (*txselector.TxSelector, *l2db.L2DB, *statedb.StateDB) {
func initTxSelector(t *testing.T, chainID uint16, hermezContractAddr ethCommon.Address,
coordUser *til.User) (*txselector.TxSelector, *l2db.L2DB, *statedb.StateDB) {
pass := os.Getenv("POSTGRES_PASS")
db, err := dbUtils.InitSQLDB(5432, "localhost", "hermez", pass, "hermez")
require.NoError(t, err)
@ -145,7 +147,11 @@ func TestTxSelectorBatchBuilderZKInputsMinimumFlow0(t *testing.T) {
}
// loop over the first 6 batches
expectedRoots := []string{"0", "0", "13644148972047617726265275926674266298636745191961029124811988256139761111521", "12433441613247342495680642890662773367605896324555599297255745922589338651261", "12433441613247342495680642890662773367605896324555599297255745922589338651261", "4191361650490017591061467288209836928064232431729236465872209988325272262963"}
expectedRoots := []string{"0", "0",
"13644148972047617726265275926674266298636745191961029124811988256139761111521",
"12433441613247342495680642890662773367605896324555599297255745922589338651261",
"12433441613247342495680642890662773367605896324555599297255745922589338651261",
"4191361650490017591061467288209836928064232431729236465872209988325272262963"}
for i := 0; i < 6; i++ {
log.Debugf("block:0 batch:%d", i+1)
var l1UserTxs []common.L1Tx
@ -153,7 +159,8 @@ func TestTxSelectorBatchBuilderZKInputsMinimumFlow0(t *testing.T) {
l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[i].Batch.ForgeL1TxsNum])
}
// TxSelector select the transactions for the next Batch
coordIdxs, _, oL1UserTxs, oL1CoordTxs, oL2Txs, _, err := txsel.GetL1L2TxSelection(selectionConfig, l1UserTxs)
coordIdxs, _, oL1UserTxs, oL1CoordTxs, oL2Txs, _, err :=
txsel.GetL1L2TxSelection(selectionConfig, l1UserTxs)
require.NoError(t, err)
// BatchBuilder build Batch
zki, err := bb.BuildBatch(coordIdxs, configBatch, oL1UserTxs, oL1CoordTxs, oL2Txs)
@ -176,14 +183,18 @@ func TestTxSelectorBatchBuilderZKInputsMinimumFlow0(t *testing.T) {
addL2Txs(t, l2DBTxSel, l2Txs) // Add L2s to TxSelector.L2DB
l1UserTxs := til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[6].Batch.ForgeL1TxsNum])
// TxSelector select the transactions for the next Batch
coordIdxs, _, oL1UserTxs, oL1CoordTxs, oL2Txs, discardedL2Txs, err := txsel.GetL1L2TxSelection(selectionConfig, l1UserTxs)
coordIdxs, _, oL1UserTxs, oL1CoordTxs, oL2Txs, discardedL2Txs, err :=
txsel.GetL1L2TxSelection(selectionConfig, l1UserTxs)
require.NoError(t, err)
// BatchBuilder build Batch
zki, err := bb.BuildBatch(coordIdxs, configBatch, oL1UserTxs, oL1CoordTxs, oL2Txs)
require.NoError(t, err)
assert.Equal(t, "7614010373759339299470010949167613050707822522530721724565424494781010548240", bb.LocalStateDB().MT.Root().BigInt().String())
assert.Equal(t,
"7614010373759339299470010949167613050707822522530721724565424494781010548240",
bb.LocalStateDB().MT.Root().BigInt().String())
sendProofAndCheckResp(t, zki)
err = l2DBTxSel.StartForging(common.TxIDsFromPoolL2Txs(oL2Txs), txsel.LocalAccountsDB().CurrentBatch())
err = l2DBTxSel.StartForging(common.TxIDsFromPoolL2Txs(oL2Txs),
txsel.LocalAccountsDB().CurrentBatch())
require.NoError(t, err)
err = l2DBTxSel.UpdateTxsInfo(discardedL2Txs)
require.NoError(t, err)
@ -201,14 +212,18 @@ func TestTxSelectorBatchBuilderZKInputsMinimumFlow0(t *testing.T) {
addL2Txs(t, l2DBTxSel, l2Txs) // Add L2s to TxSelector.L2DB
l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[7].Batch.ForgeL1TxsNum])
// TxSelector select the transactions for the next Batch
coordIdxs, _, oL1UserTxs, oL1CoordTxs, oL2Txs, discardedL2Txs, err = txsel.GetL1L2TxSelection(selectionConfig, l1UserTxs)
coordIdxs, _, oL1UserTxs, oL1CoordTxs, oL2Txs, discardedL2Txs, err =
txsel.GetL1L2TxSelection(selectionConfig, l1UserTxs)
require.NoError(t, err)
// BatchBuilder build Batch
zki, err = bb.BuildBatch(coordIdxs, configBatch, oL1UserTxs, oL1CoordTxs, oL2Txs)
require.NoError(t, err)
assert.Equal(t, "21231789250434471575486264439945776732824482207853465397552873521865656677689", bb.LocalStateDB().MT.Root().BigInt().String())
assert.Equal(t,
"21231789250434471575486264439945776732824482207853465397552873521865656677689",
bb.LocalStateDB().MT.Root().BigInt().String())
sendProofAndCheckResp(t, zki)
err = l2DBTxSel.StartForging(common.TxIDsFromPoolL2Txs(l2Txs), txsel.LocalAccountsDB().CurrentBatch())
err = l2DBTxSel.StartForging(common.TxIDsFromPoolL2Txs(l2Txs),
txsel.LocalAccountsDB().CurrentBatch())
require.NoError(t, err)
err = l2DBTxSel.UpdateTxsInfo(discardedL2Txs)
require.NoError(t, err)
@ -224,14 +239,18 @@ func TestTxSelectorBatchBuilderZKInputsMinimumFlow0(t *testing.T) {
addL2Txs(t, l2DBTxSel, l2Txs) // Add L2s to TxSelector.L2DB
l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[1].Rollup.Batches[0].Batch.ForgeL1TxsNum])
// TxSelector select the transactions for the next Batch
coordIdxs, _, oL1UserTxs, oL1CoordTxs, oL2Txs, discardedL2Txs, err = txsel.GetL1L2TxSelection(selectionConfig, l1UserTxs)
coordIdxs, _, oL1UserTxs, oL1CoordTxs, oL2Txs, discardedL2Txs, err =
txsel.GetL1L2TxSelection(selectionConfig, l1UserTxs)
require.NoError(t, err)
// BatchBuilder build Batch
zki, err = bb.BuildBatch(coordIdxs, configBatch, oL1UserTxs, oL1CoordTxs, oL2Txs)
require.NoError(t, err)
assert.Equal(t, "11289313644810782435120113035387729451095637380468777086895109386127538554246", bb.LocalStateDB().MT.Root().BigInt().String())
assert.Equal(t,
"11289313644810782435120113035387729451095637380468777086895109386127538554246",
bb.LocalStateDB().MT.Root().BigInt().String())
sendProofAndCheckResp(t, zki)
err = l2DBTxSel.StartForging(common.TxIDsFromPoolL2Txs(l2Txs), txsel.LocalAccountsDB().CurrentBatch())
err = l2DBTxSel.StartForging(common.TxIDsFromPoolL2Txs(l2Txs),
txsel.LocalAccountsDB().CurrentBatch())
require.NoError(t, err)
err = l2DBTxSel.UpdateTxsInfo(discardedL2Txs)
require.NoError(t, err)
@ -240,16 +259,20 @@ func TestTxSelectorBatchBuilderZKInputsMinimumFlow0(t *testing.T) {
l2Txs = []common.PoolL2Tx{}
l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[1].Rollup.Batches[1].Batch.ForgeL1TxsNum])
// TxSelector select the transactions for the next Batch
coordIdxs, _, oL1UserTxs, oL1CoordTxs, oL2Txs, discardedL2Txs, err = txsel.GetL1L2TxSelection(selectionConfig, l1UserTxs)
coordIdxs, _, oL1UserTxs, oL1CoordTxs, oL2Txs, discardedL2Txs, err =
txsel.GetL1L2TxSelection(selectionConfig, l1UserTxs)
require.NoError(t, err)
// BatchBuilder build Batch
zki, err = bb.BuildBatch(coordIdxs, configBatch, oL1UserTxs, oL1CoordTxs, oL2Txs)
require.NoError(t, err)
// same root as previous batch, as the L1CoordinatorTxs created by the
// Til set is not created by the TxSelector in this test
assert.Equal(t, "11289313644810782435120113035387729451095637380468777086895109386127538554246", bb.LocalStateDB().MT.Root().BigInt().String())
assert.Equal(t,
"11289313644810782435120113035387729451095637380468777086895109386127538554246",
bb.LocalStateDB().MT.Root().BigInt().String())
sendProofAndCheckResp(t, zki)
err = l2DBTxSel.StartForging(common.TxIDsFromPoolL2Txs(l2Txs), txsel.LocalAccountsDB().CurrentBatch())
err = l2DBTxSel.StartForging(common.TxIDsFromPoolL2Txs(l2Txs),
txsel.LocalAccountsDB().CurrentBatch())
require.NoError(t, err)
err = l2DBTxSel.UpdateTxsInfo(discardedL2Txs)
require.NoError(t, err)
@ -303,15 +326,20 @@ func TestZKInputsExitWithFee0(t *testing.T) {
// batch2
// TxSelector select the transactions for the next Batch
l1UserTxs := til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[1].Batch.ForgeL1TxsNum])
coordIdxs, _, oL1UserTxs, oL1CoordTxs, oL2Txs, _, err := txsel.GetL1L2TxSelection(selectionConfig, l1UserTxs)
coordIdxs, _, oL1UserTxs, oL1CoordTxs, oL2Txs, _, err :=
txsel.GetL1L2TxSelection(selectionConfig, l1UserTxs)
require.NoError(t, err)
// BatchBuilder build Batch
zki, err := bb.BuildBatch(coordIdxs, configBatch, oL1UserTxs, oL1CoordTxs, oL2Txs)
require.NoError(t, err)
assert.Equal(t, "8737171572459172806192626402462788826264011087579491137542380589998149683116", bb.LocalStateDB().MT.Root().BigInt().String())
assert.Equal(t,
"8737171572459172806192626402462788826264011087579491137542380589998149683116",
bb.LocalStateDB().MT.Root().BigInt().String())
h, err := zki.HashGlobalData()
require.NoError(t, err)
assert.Equal(t, "18608843755023673022528019960628191162333429206359207449879743919826610006009", h.String())
assert.Equal(t,
"18608843755023673022528019960628191162333429206359207449879743919826610006009",
h.String())
sendProofAndCheckResp(t, zki)
// batch3
@ -321,7 +349,8 @@ func TestZKInputsExitWithFee0(t *testing.T) {
l2Txs, err := tc.GeneratePoolL2Txs(batchPoolL2)
require.NoError(t, err)
addL2Txs(t, l2DBTxSel, l2Txs) // Add L2s to TxSelector.L2DB
coordIdxs, _, oL1UserTxs, oL1CoordTxs, oL2Txs, discardedL2Txs, err := txsel.GetL1L2TxSelection(selectionConfig, nil)
coordIdxs, _, oL1UserTxs, oL1CoordTxs, oL2Txs, discardedL2Txs, err :=
txsel.GetL1L2TxSelection(selectionConfig, nil)
require.NoError(t, err)
assert.Equal(t, 1, len(coordIdxs))
assert.Equal(t, 0, len(oL1UserTxs))
@ -331,10 +360,14 @@ func TestZKInputsExitWithFee0(t *testing.T) {
// BatchBuilder build Batch
zki, err = bb.BuildBatch(coordIdxs, configBatch, oL1UserTxs, oL1CoordTxs, oL2Txs)
require.NoError(t, err)
assert.Equal(t, "18306761925365215381387147754881756804475668085493847010988306480531520370130", bb.LocalStateDB().MT.Root().BigInt().String())
assert.Equal(t,
"18306761925365215381387147754881756804475668085493847010988306480531520370130",
bb.LocalStateDB().MT.Root().BigInt().String())
h, err = zki.HashGlobalData()
require.NoError(t, err)
assert.Equal(t, "6651837443119278772088559395433504719862425648816904171510845286897104469889", h.String())
assert.Equal(t,
"6651837443119278772088559395433504719862425648816904171510845286897104469889",
h.String())
assert.Equal(t, common.EthAddrToBigInt(tc.Users["Coord"].Addr), zki.EthAddr3[0])
assert.Equal(t, "0", zki.EthAddr3[1].String())
sendProofAndCheckResp(t, zki)

+ 8
- 4
test/zkproof/zkproof_test.go

@ -246,7 +246,8 @@ func TestZKInputs6(t *testing.T) {
coordIdxs := []common.Idx{261, 262}
l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[6].Batch.ForgeL1TxsNum])
l2Txs = poolL2Txs
ptOut, err = tp.ProcessTxs(coordIdxs, l1UserTxs, blocks[0].Rollup.Batches[6].L1CoordinatorTxs, l2Txs)
ptOut, err = tp.ProcessTxs(coordIdxs, l1UserTxs,
blocks[0].Rollup.Batches[6].L1CoordinatorTxs, l2Txs)
require.NoError(t, err)
sendProofAndCheckResp(t, ptOut.ZKInputs)
@ -264,7 +265,8 @@ func TestZKInputs6(t *testing.T) {
l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[7].Batch.ForgeL1TxsNum])
l2Txs = poolL2Txs
ptOut, err = tp.ProcessTxs(coordIdxs, l1UserTxs, blocks[0].Rollup.Batches[7].L1CoordinatorTxs, l2Txs)
ptOut, err = tp.ProcessTxs(coordIdxs, l1UserTxs,
blocks[0].Rollup.Batches[7].L1CoordinatorTxs, l2Txs)
require.NoError(t, err)
sendProofAndCheckResp(t, ptOut.ZKInputs)
@ -281,7 +283,8 @@ func TestZKInputs6(t *testing.T) {
l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[1].Rollup.Batches[0].Batch.ForgeL1TxsNum])
l2Txs = poolL2Txs
coordIdxs = []common.Idx{262}
ptOut, err = tp.ProcessTxs(coordIdxs, l1UserTxs, blocks[1].Rollup.Batches[0].L1CoordinatorTxs, l2Txs)
ptOut, err = tp.ProcessTxs(coordIdxs, l1UserTxs,
blocks[1].Rollup.Batches[0].L1CoordinatorTxs, l2Txs)
require.NoError(t, err)
sendProofAndCheckResp(t, ptOut.ZKInputs)
@ -290,7 +293,8 @@ func TestZKInputs6(t *testing.T) {
l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[1].Rollup.Batches[1].Batch.ForgeL1TxsNum])
l2Txs = []common.PoolL2Tx{}
coordIdxs = []common.Idx{}
ptOut, err = tp.ProcessTxs(coordIdxs, l1UserTxs, blocks[1].Rollup.Batches[1].L1CoordinatorTxs, l2Txs)
ptOut, err = tp.ProcessTxs(coordIdxs, l1UserTxs,
blocks[1].Rollup.Batches[1].L1CoordinatorTxs, l2Txs)
require.NoError(t, err)
sendProofAndCheckResp(t, ptOut.ZKInputs)

+ 52
- 22
txprocessor/txprocessor.go

@ -66,10 +66,12 @@ type ProcessTxOutput struct {
func newErrorNotEnoughBalance(tx common.Tx) error {
var msg error
if tx.IsL1 {
msg = fmt.Errorf("Invalid transaction, not enough balance on sender account. TxID: %s, TxType: %s, FromIdx: %d, ToIdx: %d, Amount: %d",
msg = fmt.Errorf("Invalid transaction, not enough balance on sender account. "+
"TxID: %s, TxType: %s, FromIdx: %d, ToIdx: %d, Amount: %d",
tx.TxID, tx.Type, tx.FromIdx, tx.ToIdx, tx.Amount)
} else {
msg = fmt.Errorf("Invalid transaction, not enough balance on sender account. TxID: %s, TxType: %s, FromIdx: %d, ToIdx: %d, Amount: %d, Fee: %d",
msg = fmt.Errorf("Invalid transaction, not enough balance on sender account. "+
"TxID: %s, TxType: %s, FromIdx: %d, ToIdx: %d, Amount: %d, Fee: %d",
tx.TxID, tx.Type, tx.FromIdx, tx.ToIdx, tx.Amount, tx.Fee)
}
return tracerr.Wrap(msg)
@ -116,21 +118,28 @@ func (tp *TxProcessor) ProcessTxs(coordIdxs []common.Idx, l1usertxs, l1coordinat
var createdAccounts []common.Account
if tp.zki != nil {
return nil, tracerr.Wrap(errors.New("Expected StateDB.zki==nil, something went wrong and it's not empty"))
return nil, tracerr.Wrap(
errors.New("Expected StateDB.zki==nil, something went wrong and it's not empty"))
}
defer tp.resetZKInputs()
if len(coordIdxs) >= int(tp.config.MaxFeeTx) {
return nil, tracerr.Wrap(fmt.Errorf("CoordIdxs (%d) length must be smaller than MaxFeeTx (%d)", len(coordIdxs), tp.config.MaxFeeTx))
return nil, tracerr.Wrap(
fmt.Errorf("CoordIdxs (%d) length must be smaller than MaxFeeTx (%d)",
len(coordIdxs), tp.config.MaxFeeTx))
}
nTx := len(l1usertxs) + len(l1coordinatortxs) + len(l2txs)
if nTx > int(tp.config.MaxTx) {
return nil, tracerr.Wrap(fmt.Errorf("L1UserTx + L1CoordinatorTx + L2Tx (%d) can not be bigger than MaxTx (%d)", nTx, tp.config.MaxTx))
return nil, tracerr.Wrap(
fmt.Errorf("L1UserTx + L1CoordinatorTx + L2Tx (%d) can not be bigger than MaxTx (%d)",
nTx, tp.config.MaxTx))
}
if len(l1usertxs)+len(l1coordinatortxs) > int(tp.config.MaxL1Tx) {
return nil, tracerr.Wrap(fmt.Errorf("L1UserTx + L1CoordinatorTx (%d) can not be bigger than MaxL1Tx (%d)", len(l1usertxs)+len(l1coordinatortxs), tp.config.MaxTx))
return nil,
tracerr.Wrap(fmt.Errorf("L1UserTx + L1CoordinatorTx (%d) can not be bigger than MaxL1Tx (%d)",
len(l1usertxs)+len(l1coordinatortxs), tp.config.MaxTx))
}
if tp.s.Type() == statedb.TypeSynchronizer {
@ -377,7 +386,8 @@ func (tp *TxProcessor) ProcessTxs(coordIdxs []common.Idx, l1usertxs, l1coordinat
// works)
accCoord, err := tp.s.GetAccount(idx)
if err != nil {
log.Errorw("Can not distribute accumulated fees to coordinator account: No coord Idx to receive fee", "idx", idx)
log.Errorw("Can not distribute accumulated fees to coordinator account: "+
"No coord Idx to receive fee", "idx", idx)
return nil, tracerr.Wrap(err)
}
if tp.zki != nil {
@ -483,7 +493,8 @@ func (tp *TxProcessor) getFeePlanTokens(coordIdxs []common.Idx) ([]*big.Int, err
for i := 0; i < len(coordIdxs); i++ {
acc, err := tp.s.GetAccount(coordIdxs[i])
if err != nil {
log.Errorf("could not get account to determine TokenID of CoordIdx %d not found: %s", coordIdxs[i], err.Error())
log.Errorf("could not get account to determine TokenID of CoordIdx %d not found: %s",
coordIdxs[i], err.Error())
return nil, tracerr.Wrap(err)
}
tBI = append(tBI, acc.TokenID.BigInt())
@ -642,7 +653,8 @@ func (tp *TxProcessor) ProcessL2Tx(coordIdxsMap map[common.TokenID]common.Idx,
if tp.s.Type() == statedb.TypeSynchronizer {
// thisTypeould never be reached
log.Error("WARNING: In StateDB with Synchronizer mode L2.ToIdx can't be 0")
return nil, nil, false, tracerr.Wrap(fmt.Errorf("In StateDB with Synchronizer mode L2.ToIdx can't be 0"))
return nil, nil, false,
tracerr.Wrap(fmt.Errorf("In StateDB with Synchronizer mode L2.ToIdx can't be 0"))
}
// case when tx.Type== common.TxTypeTransferToEthAddr or common.TxTypeTransferToBJJ
@ -730,7 +742,8 @@ func (tp *TxProcessor) ProcessL2Tx(coordIdxsMap map[common.TokenID]common.Idx,
}
case common.TxTypeExit:
// execute exit flow
exitAccount, newExit, err := tp.applyExit(coordIdxsMap, collectedFees, exitTree, tx.Tx(), tx.Amount)
exitAccount, newExit, err := tp.applyExit(coordIdxsMap, collectedFees, exitTree,
tx.Tx(), tx.Amount)
if err != nil {
log.Error(err)
return nil, nil, false, tracerr.Wrap(err)
@ -790,7 +803,8 @@ func (tp *TxProcessor) applyCreateAccount(tx *common.L1Tx) error {
// createAccount is a wrapper over the StateDB.CreateAccount method that also
// stores the created account in the updatedAccounts map in case the StateDB is
// of TypeSynchronizer
func (tp *TxProcessor) createAccount(idx common.Idx, account *common.Account) (*merkletree.CircomProcessorProof, error) {
func (tp *TxProcessor) createAccount(idx common.Idx, account *common.Account) (
*merkletree.CircomProcessorProof, error) {
if tp.s.Type() == statedb.TypeSynchronizer {
account.Idx = idx
tp.updatedAccounts[idx] = account
@ -801,7 +815,8 @@ func (tp *TxProcessor) createAccount(idx common.Idx, account *common.Account) (*
// updateAccount is a wrapper over the StateDB.UpdateAccount method that also
// stores the updated account in the updatedAccounts map in case the StateDB is
// of TypeSynchronizer
func (tp *TxProcessor) updateAccount(idx common.Idx, account *common.Account) (*merkletree.CircomProcessorProof, error) {
func (tp *TxProcessor) updateAccount(idx common.Idx, account *common.Account) (
*merkletree.CircomProcessorProof, error) {
if tp.s.Type() == statedb.TypeSynchronizer {
account.Idx = idx
tp.updatedAccounts[idx] = account
@ -937,7 +952,9 @@ func (tp *TxProcessor) applyTransfer(coordIdxsMap map[common.TokenID]common.Idx,
if _, ok := coordIdxsMap[accSender.TokenID]; ok {
accCoord, err := tp.s.GetAccount(coordIdxsMap[accSender.TokenID])
if err != nil {
return tracerr.Wrap(fmt.Errorf("Can not use CoordIdx that does not exist in the tree. TokenID: %d, CoordIdx: %d", accSender.TokenID, coordIdxsMap[accSender.TokenID]))
return tracerr.Wrap(
fmt.Errorf("Can not use CoordIdx that does not exist in the tree. TokenID: %d, CoordIdx: %d",
accSender.TokenID, coordIdxsMap[accSender.TokenID]))
}
// accumulate the fee for the Coord account
accumulated := tp.AccumulatedFees[accCoord.Idx]
@ -1141,7 +1158,9 @@ func (tp *TxProcessor) applyExit(coordIdxsMap map[common.TokenID]common.Idx,
if _, ok := coordIdxsMap[acc.TokenID]; ok {
accCoord, err := tp.s.GetAccount(coordIdxsMap[acc.TokenID])
if err != nil {
return nil, false, tracerr.Wrap(fmt.Errorf("Can not use CoordIdx that does not exist in the tree. TokenID: %d, CoordIdx: %d", acc.TokenID, coordIdxsMap[acc.TokenID]))
return nil, false, tracerr.Wrap(
fmt.Errorf("Can not use CoordIdx that does not exist in the tree. TokenID: %d, CoordIdx: %d",
acc.TokenID, coordIdxsMap[acc.TokenID]))
}
// accumulate the fee for the Coord account
@ -1301,13 +1320,15 @@ func (tp *TxProcessor) computeEffectiveAmounts(tx *common.L1Tx) {
// check if tx.TokenID==receiver.TokenID
accReceiver, err := tp.s.GetAccount(tx.ToIdx)
if err != nil {
log.Debugf("EffectiveAmount & EffectiveDepositAmount = 0: can not get account for tx.ToIdx: %d", tx.ToIdx)
log.Debugf("EffectiveAmount & EffectiveDepositAmount = 0: can not get account for tx.ToIdx: %d",
tx.ToIdx)
tx.EffectiveDepositAmount = big.NewInt(0)
tx.EffectiveAmount = big.NewInt(0)
return
}
if tx.TokenID != accReceiver.TokenID {
log.Debugf("EffectiveAmount = 0: tx TokenID (%d) != receiver account TokenID (%d)", tx.TokenID, accReceiver.TokenID)
log.Debugf("EffectiveAmount = 0: tx TokenID (%d) != receiver account TokenID (%d)",
tx.TokenID, accReceiver.TokenID)
tx.EffectiveAmount = big.NewInt(0)
return
}
@ -1316,7 +1337,8 @@ func (tp *TxProcessor) computeEffectiveAmounts(tx *common.L1Tx) {
accSender, err := tp.s.GetAccount(tx.FromIdx)
if err != nil {
log.Debugf("EffectiveAmount & EffectiveDepositAmount = 0: can not get account for tx.FromIdx: %d", tx.FromIdx)
log.Debugf("EffectiveAmount & EffectiveDepositAmount = 0: can not get account for tx.FromIdx: %d",
tx.FromIdx)
tx.EffectiveDepositAmount = big.NewInt(0)
tx.EffectiveAmount = big.NewInt(0)
return
@ -1324,7 +1346,9 @@ func (tp *TxProcessor) computeEffectiveAmounts(tx *common.L1Tx) {
// check that tx.TokenID corresponds to the Sender account TokenID
if tx.TokenID != accSender.TokenID {
log.Debugf("EffectiveAmount & EffectiveDepositAmount = 0: tx.TokenID (%d) !=sender account TokenID (%d)", tx.TokenID, accSender.TokenID)
log.Debugf("EffectiveAmount & EffectiveDepositAmount = 0: "+
"tx.TokenID (%d) !=sender account TokenID (%d)",
tx.TokenID, accSender.TokenID)
tx.EffectiveDepositAmount = big.NewInt(0)
tx.EffectiveAmount = big.NewInt(0)
return
@ -1345,7 +1369,9 @@ func (tp *TxProcessor) computeEffectiveAmounts(tx *common.L1Tx) {
// check that the tx.FromEthAddr is the same than the EthAddress of the
// Sender
if !bytes.Equal(tx.FromEthAddr.Bytes(), accSender.EthAddr.Bytes()) {
log.Debugf("EffectiveAmount = 0: tx.FromEthAddr (%s) must be the same EthAddr of the sender account by the Idx (%s)", tx.FromEthAddr.Hex(), accSender.EthAddr.Hex())
log.Debugf("EffectiveAmount = 0: tx.FromEthAddr (%s) must be the same EthAddr of "+
"the sender account by the Idx (%s)",
tx.FromEthAddr.Hex(), accSender.EthAddr.Hex())
tx.EffectiveAmount = big.NewInt(0)
}
@ -1357,18 +1383,22 @@ func (tp *TxProcessor) computeEffectiveAmounts(tx *common.L1Tx) {
// check that TokenID is the same for Sender & Receiver account
accReceiver, err := tp.s.GetAccount(tx.ToIdx)
if err != nil {
log.Debugf("EffectiveAmount & EffectiveDepositAmount = 0: can not get account for tx.ToIdx: %d", tx.ToIdx)
log.Debugf("EffectiveAmount & EffectiveDepositAmount = 0: can not get account for tx.ToIdx: %d",
tx.ToIdx)
tx.EffectiveDepositAmount = big.NewInt(0)
tx.EffectiveAmount = big.NewInt(0)
return
}
if accSender.TokenID != accReceiver.TokenID {
log.Debugf("EffectiveAmount = 0: sender account TokenID (%d) != receiver account TokenID (%d)", accSender.TokenID, accReceiver.TokenID)
log.Debugf("EffectiveAmount = 0: sender account TokenID (%d) != receiver account TokenID (%d)",
accSender.TokenID, accReceiver.TokenID)
tx.EffectiveAmount = big.NewInt(0)
return
}
if tx.TokenID != accReceiver.TokenID {
log.Debugf("EffectiveAmount & EffectiveDepositAmount = 0: tx TokenID (%d) != receiver account TokenID (%d)", tx.TokenID, accReceiver.TokenID)
log.Debugf("EffectiveAmount & EffectiveDepositAmount = 0: "+
"tx TokenID (%d) != receiver account TokenID (%d)",
tx.TokenID, accReceiver.TokenID)
tx.EffectiveAmount = big.NewInt(0)
return
}

+ 52
- 21
txprocessor/txprocessor_test.go

@ -17,7 +17,8 @@ import (
"github.com/stretchr/testify/require"
)
func checkBalance(t *testing.T, tc *til.Context, sdb *statedb.StateDB, username string, tokenid int, expected string) {
func checkBalance(t *testing.T, tc *til.Context, sdb *statedb.StateDB, username string,
tokenid int, expected string) {
idx := tc.Users[username].Accounts[common.TokenID(tokenid)].Idx
acc, err := sdb.GetAccount(idx)
require.NoError(t, err)
@ -249,7 +250,9 @@ func TestProcessTxsBalances(t *testing.T) {
_, err = tp.ProcessTxs(nil, l1UserTxs, blocks[0].Rollup.Batches[2].L1CoordinatorTxs, l2Txs)
require.NoError(t, err)
checkBalance(t, tc, sdb, "A", 0, "500")
assert.Equal(t, "13644148972047617726265275926674266298636745191961029124811988256139761111521", tp.s.MT.Root().BigInt().String())
assert.Equal(t,
"13644148972047617726265275926674266298636745191961029124811988256139761111521",
tp.s.MT.Root().BigInt().String())
log.Debug("block:0 batch:4")
l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[3].Batch.ForgeL1TxsNum])
@ -258,7 +261,9 @@ func TestProcessTxsBalances(t *testing.T) {
require.NoError(t, err)
checkBalance(t, tc, sdb, "A", 0, "500")
checkBalance(t, tc, sdb, "A", 1, "500")
assert.Equal(t, "12433441613247342495680642890662773367605896324555599297255745922589338651261", tp.s.MT.Root().BigInt().String())
assert.Equal(t,
"12433441613247342495680642890662773367605896324555599297255745922589338651261",
tp.s.MT.Root().BigInt().String())
log.Debug("block:0 batch:5")
l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[4].Batch.ForgeL1TxsNum])
@ -267,7 +272,9 @@ func TestProcessTxsBalances(t *testing.T) {
require.NoError(t, err)
checkBalance(t, tc, sdb, "A", 0, "500")
checkBalance(t, tc, sdb, "A", 1, "500")
assert.Equal(t, "12433441613247342495680642890662773367605896324555599297255745922589338651261", tp.s.MT.Root().BigInt().String())
assert.Equal(t,
"12433441613247342495680642890662773367605896324555599297255745922589338651261",
tp.s.MT.Root().BigInt().String())
log.Debug("block:0 batch:6")
l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[5].Batch.ForgeL1TxsNum])
@ -277,7 +284,9 @@ func TestProcessTxsBalances(t *testing.T) {
checkBalance(t, tc, sdb, "A", 0, "600")
checkBalance(t, tc, sdb, "A", 1, "500")
checkBalance(t, tc, sdb, "B", 0, "400")
assert.Equal(t, "4191361650490017591061467288209836928064232431729236465872209988325272262963", tp.s.MT.Root().BigInt().String())
assert.Equal(t,
"4191361650490017591061467288209836928064232431729236465872209988325272262963",
tp.s.MT.Root().BigInt().String())
coordIdxs := []common.Idx{261, 262}
log.Debug("block:0 batch:7")
@ -293,7 +302,9 @@ func TestProcessTxsBalances(t *testing.T) {
checkBalance(t, tc, sdb, "B", 1, "200")
checkBalance(t, tc, sdb, "C", 0, "100")
checkBalance(t, tc, sdb, "D", 0, "800")
assert.Equal(t, "7614010373759339299470010949167613050707822522530721724565424494781010548240", tp.s.MT.Root().BigInt().String())
assert.Equal(t,
"7614010373759339299470010949167613050707822522530721724565424494781010548240",
tp.s.MT.Root().BigInt().String())
log.Debug("block:0 batch:8")
l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[7].Batch.ForgeL1TxsNum])
@ -309,7 +320,9 @@ func TestProcessTxsBalances(t *testing.T) {
checkBalance(t, tc, sdb, "C", 0, "45")
checkBalance(t, tc, sdb, "C", 1, "100")
checkBalance(t, tc, sdb, "D", 0, "800")
assert.Equal(t, "21231789250434471575486264439945776732824482207853465397552873521865656677689", tp.s.MT.Root().BigInt().String())
assert.Equal(t,
"21231789250434471575486264439945776732824482207853465397552873521865656677689",
tp.s.MT.Root().BigInt().String())
coordIdxs = []common.Idx{262}
log.Debug("block:1 batch:1")
@ -326,7 +339,9 @@ func TestProcessTxsBalances(t *testing.T) {
checkBalance(t, tc, sdb, "C", 0, "845")
checkBalance(t, tc, sdb, "C", 1, "100")
checkBalance(t, tc, sdb, "D", 0, "470")
assert.Equal(t, "11289313644810782435120113035387729451095637380468777086895109386127538554246", tp.s.MT.Root().BigInt().String())
assert.Equal(t,
"11289313644810782435120113035387729451095637380468777086895109386127538554246",
tp.s.MT.Root().BigInt().String())
coordIdxs = []common.Idx{}
log.Debug("block:1 batch:2")
@ -334,7 +349,9 @@ func TestProcessTxsBalances(t *testing.T) {
l2Txs = common.L2TxsToPoolL2Txs(blocks[1].Rollup.Batches[1].L2Txs)
_, err = tp.ProcessTxs(coordIdxs, l1UserTxs, blocks[1].Rollup.Batches[1].L1CoordinatorTxs, l2Txs)
require.NoError(t, err)
assert.Equal(t, "10342681351319338354912862547249967104198317571995055517008223832276478908482", tp.s.MT.Root().BigInt().String())
assert.Equal(t,
"10342681351319338354912862547249967104198317571995055517008223832276478908482",
tp.s.MT.Root().BigInt().String())
// use Set of PoolL2 txs
poolL2Txs, err := tc.GeneratePoolL2Txs(txsets.SetPoolL2MinimumFlow1)
@ -446,8 +463,8 @@ func TestProcessTxsSynchronizer(t *testing.T) {
assert.Equal(t, common.Nonce(5), l2Txs[0].Nonce)
assert.Equal(t, common.Nonce(6), l2Txs[1].Nonce)
assert.Equal(t, common.Nonce(7), l2Txs[2].Nonce)
assert.Equal(t, 4, len(ptOut.ExitInfos)) // the 'ForceExit(1)' is not computed yet, as the batch is without L1UserTxs
// the 'ForceExit(1)' is not computed yet, as the batch is without L1UserTxs
assert.Equal(t, 4, len(ptOut.ExitInfos))
assert.Equal(t, 1, len(ptOut.CreatedAccounts))
assert.Equal(t, 4, len(ptOut.CollectedFees))
assert.Equal(t, "0", ptOut.CollectedFees[common.TokenID(0)].String())
@ -463,8 +480,10 @@ func TestProcessTxsSynchronizer(t *testing.T) {
ptOut, err = tp.ProcessTxs(coordIdxs, blocks[1].Rollup.L1UserTxs,
blocks[1].Rollup.Batches[1].L1CoordinatorTxs, l2Txs)
require.NoError(t, err)
assert.Equal(t, 1, len(ptOut.ExitInfos)) // 1, as previous batch was without L1UserTxs, and has pending the 'ForceExit(1) A: 5', and the 2 exit transactions get grouped under 1 ExitInfo
// 1, as previous batch was without L1UserTxs, and has pending the
// 'ForceExit(1) A: 5', and the 2 exit transactions get grouped under 1
// ExitInfo
assert.Equal(t, 1, len(ptOut.ExitInfos))
assert.Equal(t, 1, len(ptOut.CreatedAccounts))
assert.Equal(t, 4, len(ptOut.CollectedFees))
assert.Equal(t, "0", ptOut.CollectedFees[common.TokenID(0)].String())
@ -526,7 +545,8 @@ func TestProcessTxsBatchBuilder(t *testing.T) {
log.Debug("block:0 batch:2")
l2Txs := common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[1].L2Txs)
ptOut, err = tp.ProcessTxs(coordIdxs, blocks[0].Rollup.L1UserTxs, blocks[0].Rollup.Batches[1].L1CoordinatorTxs, l2Txs)
ptOut, err = tp.ProcessTxs(coordIdxs, blocks[0].Rollup.L1UserTxs,
blocks[0].Rollup.Batches[1].L1CoordinatorTxs, l2Txs)
require.NoError(t, err)
assert.Equal(t, 0, len(ptOut.ExitInfos))
assert.Equal(t, 0, len(ptOut.CreatedAccounts))
@ -554,7 +574,8 @@ func TestProcessTxsBatchBuilder(t *testing.T) {
log.Debug("block:1 batch:2")
l2Txs = common.L2TxsToPoolL2Txs(blocks[1].Rollup.Batches[1].L2Txs)
_, err = tp.ProcessTxs(coordIdxs, blocks[1].Rollup.L1UserTxs, blocks[1].Rollup.Batches[1].L1CoordinatorTxs, l2Txs)
_, err = tp.ProcessTxs(coordIdxs, blocks[1].Rollup.L1UserTxs,
blocks[1].Rollup.Batches[1].L1CoordinatorTxs, l2Txs)
require.NoError(t, err)
acc, err = sdb.GetAccount(idxA1)
assert.NoError(t, err)
@ -575,7 +596,9 @@ func TestProcessTxsBatchBuilder(t *testing.T) {
assert.Equal(t, common.TokenID(1), acc.TokenID)
assert.Equal(t, "2", acc.Balance.String())
assert.Equal(t, "18894163991492573893706613133132363559300580460789469708968288074813925659539", sdb.MT.Root().BigInt().String())
assert.Equal(t,
"18894163991492573893706613133132363559300580460789469708968288074813925659539",
sdb.MT.Root().BigInt().String())
}
func TestProcessTxsRootTestVectors(t *testing.T) {
@ -588,7 +611,8 @@ func TestProcessTxsRootTestVectors(t *testing.T) {
assert.NoError(t, err)
// same values than in the js test
bjj0, err := common.BJJFromStringWithChecksum("21b0a1688b37f77b1d1d5539ec3b826db5ac78b2513f574a04c50a7d4f8246d7")
bjj0, err := common.BJJFromStringWithChecksum(
"21b0a1688b37f77b1d1d5539ec3b826db5ac78b2513f574a04c50a7d4f8246d7")
assert.NoError(t, err)
l1Txs := []common.L1Tx{
{
@ -626,7 +650,9 @@ func TestProcessTxsRootTestVectors(t *testing.T) {
tp := NewTxProcessor(sdb, config)
_, err = tp.ProcessTxs(nil, l1Txs, nil, l2Txs)
require.NoError(t, err)
assert.Equal(t, "9827704113668630072730115158977131501210702363656902211840117643154933433410", sdb.MT.Root().BigInt().String())
assert.Equal(t,
"9827704113668630072730115158977131501210702363656902211840117643154933433410",
sdb.MT.Root().BigInt().String())
}
func TestCreateAccountDepositMaxValue(t *testing.T) {
@ -699,7 +725,8 @@ func TestCreateAccountDepositMaxValue(t *testing.T) {
assert.Equal(t, daMax1BI, acc.Balance)
}
func initTestMultipleCoordIdxForTokenID(t *testing.T) (*TxProcessor, *til.Context, []common.BlockData) {
func initTestMultipleCoordIdxForTokenID(t *testing.T) (*TxProcessor, *til.Context,
[]common.BlockData) {
dir, err := ioutil.TempDir("", "tmpdb")
require.NoError(t, err)
defer assert.NoError(t, os.RemoveAll(dir))
@ -1049,13 +1076,17 @@ func TestExitOf0Amount(t *testing.T) {
// process Batch4:
ptOut, err := tp.ProcessTxs(nil, blocks[0].Rollup.Batches[3].L1UserTxs, nil, nil)
require.NoError(t, err)
assert.Equal(t, "14329759303391468223438874789317921522067594445474390443816827472846339238908", ptOut.ZKInputs.Metadata.NewExitRootRaw.BigInt().String())
assert.Equal(t,
"14329759303391468223438874789317921522067594445474390443816827472846339238908",
ptOut.ZKInputs.Metadata.NewExitRootRaw.BigInt().String())
exitRootBatch4 := ptOut.ZKInputs.Metadata.NewExitRootRaw.BigInt().String()
// process Batch6:
ptOut, err = tp.ProcessTxs(nil, blocks[0].Rollup.Batches[5].L1UserTxs, nil, nil)
require.NoError(t, err)
assert.Equal(t, "14329759303391468223438874789317921522067594445474390443816827472846339238908", ptOut.ZKInputs.Metadata.NewExitRootRaw.BigInt().String())
assert.Equal(t,
"14329759303391468223438874789317921522067594445474390443816827472846339238908",
ptOut.ZKInputs.Metadata.NewExitRootRaw.BigInt().String())
// Expect that the ExitRoot for the Batch6 will be equal than for the
// Batch4, as the Batch4 & Batch6 have the same tx with Exit Amount=10,
// and Batch4 has a 2nd tx with Exit Amount=0.

+ 3
- 3
txprocessor/utils.go

@ -23,7 +23,7 @@ func BJJCompressedTo256BigInts(pkComp babyjub.PublicKeyComp) [256]*big.Int {
b := pkComp[:]
for i := 0; i < 256; i++ {
if b[i/8]&(1<<(i%8)) == 0 {
if b[i/8]&(1<<(i%8)) == 0 { //nolint:gomnd
r[i] = big.NewInt(0)
} else {
r[i] = big.NewInt(1)
@ -36,8 +36,8 @@ func BJJCompressedTo256BigInts(pkComp babyjub.PublicKeyComp) [256]*big.Int {
// formatAccumulatedFees returns an array of [nFeeAccounts]*big.Int containing
// the balance of each FeeAccount, taken from the 'collectedFees' map, in the
// order of the 'orderTokenIDs'
// func formatAccumulatedFees(collectedFees map[common.TokenID]*big.Int, orderTokenIDs []*big.Int) []*big.Int {
func formatAccumulatedFees(collectedFees map[common.TokenID]*big.Int, orderTokenIDs []*big.Int, coordIdxs []common.Idx) []*big.Int {
func formatAccumulatedFees(collectedFees map[common.TokenID]*big.Int, orderTokenIDs []*big.Int,
coordIdxs []common.Idx) []*big.Int {
accFeeOut := make([]*big.Int, len(orderTokenIDs))
for i := 0; i < len(accFeeOut); i++ {
accFeeOut[i] = big.NewInt(0)

+ 164
- 78
txprocessor/zkinputsgen_test.go
File diff suppressed because it is too large
View File


+ 16
- 7
txselector/txselector.go

@ -447,7 +447,8 @@ func (txsel *TxSelector) getL1L2TxSelection(selectionConfig *SelectionConfig,
// send the fee to the Idx of the Coordinator for the TokenID
accCoord, err := txsel.localAccountsDB.GetAccount(idx)
if err != nil {
log.Errorw("Can not distribute accumulated fees to coordinator account: No coord Idx to receive fee", "idx", idx)
log.Errorw("Can not distribute accumulated fees to coordinator "+
"account: No coord Idx to receive fee", "idx", idx)
return nil, nil, nil, nil, nil, nil, tracerr.Wrap(err)
}
accCoord.Balance = new(big.Int).Add(accCoord.Balance, accumulatedFee)
@ -511,14 +512,19 @@ func (txsel *TxSelector) processTxToEthAddrBJJ(validTxs []common.PoolL2Tx,
accAuth, err = txsel.l2db.GetAccountCreationAuth(l2Tx.ToEthAddr)
if err != nil {
// not found, l2Tx will not be added in the selection
return nil, nil, nil, tracerr.Wrap(fmt.Errorf("invalid L2Tx: ToIdx not found in StateDB, neither ToEthAddr found in AccountCreationAuths L2DB. ToIdx: %d, ToEthAddr: %s",
l2Tx.ToIdx, l2Tx.ToEthAddr.Hex()))
return nil, nil, nil,
tracerr.Wrap(fmt.Errorf("invalid L2Tx: ToIdx not found "+
"in StateDB, neither ToEthAddr found in AccountCreationAuths L2DB. ToIdx: %d, ToEthAddr: %s",
l2Tx.ToIdx, l2Tx.ToEthAddr.Hex()))
}
if accAuth.BJJ != l2Tx.ToBJJ {
// if AccountCreationAuth.BJJ is not the same
// than in the tx, tx is not accepted
return nil, nil, nil, tracerr.Wrap(fmt.Errorf("invalid L2Tx: ToIdx not found in StateDB, neither ToEthAddr & ToBJJ found in AccountCreationAuths L2DB. ToIdx: %d, ToEthAddr: %s, ToBJJ: %s",
l2Tx.ToIdx, l2Tx.ToEthAddr.Hex(), l2Tx.ToBJJ.String()))
return nil, nil, nil,
tracerr.Wrap(fmt.Errorf("invalid L2Tx: ToIdx not found in StateDB, "+
"neither ToEthAddr & ToBJJ found in AccountCreationAuths L2DB. "+
"ToIdx: %d, ToEthAddr: %s, ToBJJ: %s",
l2Tx.ToIdx, l2Tx.ToEthAddr.Hex(), l2Tx.ToBJJ.String()))
}
} else {
// case: ToBJJ==0:
@ -534,8 +540,11 @@ func (txsel *TxSelector) processTxToEthAddrBJJ(validTxs []common.PoolL2Tx,
accAuth, err = txsel.l2db.GetAccountCreationAuth(l2Tx.ToEthAddr)
if err != nil {
// not found, l2Tx will not be added in the selection
return nil, nil, nil, tracerr.Wrap(fmt.Errorf("invalid L2Tx: ToIdx not found in StateDB, neither ToEthAddr found in AccountCreationAuths L2DB. ToIdx: %d, ToEthAddr: %s",
l2Tx.ToIdx, l2Tx.ToEthAddr))
return nil, nil, nil,
tracerr.Wrap(fmt.Errorf("invalid L2Tx: ToIdx not found in "+
"StateDB, neither ToEthAddr found in "+
"AccountCreationAuths L2DB. ToIdx: %d, ToEthAddr: %s",
l2Tx.ToIdx, l2Tx.ToEthAddr))
}
}
// create L1CoordinatorTx for the accountCreation

+ 70
- 36
txselector/txselector_test.go

@ -25,7 +25,8 @@ import (
"github.com/stretchr/testify/require"
)
func initTest(t *testing.T, chainID uint16, hermezContractAddr ethCommon.Address, coordUser *til.User) *TxSelector {
func initTest(t *testing.T, chainID uint16, hermezContractAddr ethCommon.Address,
coordUser *til.User) *TxSelector {
pass := os.Getenv("POSTGRES_PASS")
db, err := dbUtils.InitSQLDB(5432, "localhost", "hermez", pass, "hermez")
require.NoError(t, err)
@ -67,7 +68,8 @@ func initTest(t *testing.T, chainID uint16, hermezContractAddr ethCommon.Address
return txsel
}
func addAccCreationAuth(t *testing.T, tc *til.Context, txsel *TxSelector, chainID uint16, hermezContractAddr ethCommon.Address, username string) []byte {
func addAccCreationAuth(t *testing.T, tc *til.Context, txsel *TxSelector, chainID uint16,
hermezContractAddr ethCommon.Address, username string) []byte {
user := tc.Users[username]
auth := &common.AccountCreationAuth{
EthAddr: user.Addr,
@ -113,13 +115,15 @@ func addTokens(t *testing.T, tc *til.Context, db *sqlx.DB) {
assert.NoError(t, hdb.AddTokens(tokens))
}
func checkBalance(t *testing.T, tc *til.Context, txsel *TxSelector, username string, tokenid int, expected string) {
func checkBalance(t *testing.T, tc *til.Context, txsel *TxSelector, username string,
tokenid int, expected string) {
// Accounts.Idx does not match with the TxSelector tests as we are not
// using the Til L1CoordinatorTxs (as are generated by the TxSelector
// itself when processing the txs, so the Idxs does not match the Til
// idxs). But the Idx is obtained through StateDB.GetIdxByEthAddrBJJ
user := tc.Users[username]
idx, err := txsel.localAccountsDB.GetIdxByEthAddrBJJ(user.Addr, user.BJJ.Public().Compress(), common.TokenID(tokenid))
idx, err := txsel.localAccountsDB.GetIdxByEthAddrBJJ(user.Addr, user.BJJ.Public().Compress(),
common.TokenID(tokenid))
require.NoError(t, err)
checkBalanceByIdx(t, txsel, idx, expected)
}
@ -133,7 +137,8 @@ func checkBalanceByIdx(t *testing.T, txsel *TxSelector, idx common.Idx, expected
// checkSortedByNonce takes as input testAccNonces map, and the array of
// common.PoolL2Txs, and checks if the nonces correspond to the accumulated
// values of the map. Also increases the Nonces computed on the map.
func checkSortedByNonce(t *testing.T, testAccNonces map[common.Idx]common.Nonce, txs []common.PoolL2Tx) {
func checkSortedByNonce(t *testing.T, testAccNonces map[common.Idx]common.Nonce,
txs []common.PoolL2Tx) {
for _, tx := range txs {
assert.True(t, testAccNonces[tx.FromIdx] == tx.Nonce,
fmt.Sprintf("Idx: %d, expected: %d, tx.Nonce: %d",
@ -178,7 +183,8 @@ func TestGetL2TxSelectionMinimumFlow0(t *testing.T) {
log.Debug("block:0 batch:1")
l1UserTxs := []common.L1Tx{}
_, _, oL1UserTxs, oL1CoordTxs, oL2Txs, _, err := txsel.GetL1L2TxSelection(selectionConfig, l1UserTxs)
_, _, oL1UserTxs, oL1CoordTxs, oL2Txs, _, err :=
txsel.GetL1L2TxSelection(selectionConfig, l1UserTxs)
require.NoError(t, err)
assert.Equal(t, 0, len(oL1UserTxs))
assert.Equal(t, 0, len(oL1CoordTxs))
@ -188,7 +194,8 @@ func TestGetL2TxSelectionMinimumFlow0(t *testing.T) {
log.Debug("block:0 batch:2")
l1UserTxs = []common.L1Tx{}
_, _, oL1UserTxs, oL1CoordTxs, oL2Txs, _, err = txsel.GetL1L2TxSelection(selectionConfig, l1UserTxs)
_, _, oL1UserTxs, oL1CoordTxs, oL2Txs, _, err =
txsel.GetL1L2TxSelection(selectionConfig, l1UserTxs)
require.NoError(t, err)
assert.Equal(t, 0, len(oL1UserTxs))
assert.Equal(t, 0, len(oL1CoordTxs))
@ -198,7 +205,8 @@ func TestGetL2TxSelectionMinimumFlow0(t *testing.T) {
log.Debug("block:0 batch:3")
l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[2].Batch.ForgeL1TxsNum])
_, _, oL1UserTxs, oL1CoordTxs, oL2Txs, _, err = txsel.GetL1L2TxSelection(selectionConfig, l1UserTxs)
_, _, oL1UserTxs, oL1CoordTxs, oL2Txs, _, err =
txsel.GetL1L2TxSelection(selectionConfig, l1UserTxs)
require.NoError(t, err)
assert.Equal(t, 2, len(oL1UserTxs))
assert.Equal(t, 0, len(oL1CoordTxs))
@ -210,7 +218,8 @@ func TestGetL2TxSelectionMinimumFlow0(t *testing.T) {
log.Debug("block:0 batch:4")
l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[3].Batch.ForgeL1TxsNum])
_, _, oL1UserTxs, oL1CoordTxs, oL2Txs, _, err = txsel.GetL1L2TxSelection(selectionConfig, l1UserTxs)
_, _, oL1UserTxs, oL1CoordTxs, oL2Txs, _, err =
txsel.GetL1L2TxSelection(selectionConfig, l1UserTxs)
require.NoError(t, err)
assert.Equal(t, 1, len(oL1UserTxs))
assert.Equal(t, 0, len(oL1CoordTxs))
@ -223,7 +232,8 @@ func TestGetL2TxSelectionMinimumFlow0(t *testing.T) {
log.Debug("block:0 batch:5")
l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[4].Batch.ForgeL1TxsNum])
_, _, oL1UserTxs, oL1CoordTxs, oL2Txs, _, err = txsel.GetL1L2TxSelection(selectionConfig, l1UserTxs)
_, _, oL1UserTxs, oL1CoordTxs, oL2Txs, _, err =
txsel.GetL1L2TxSelection(selectionConfig, l1UserTxs)
require.NoError(t, err)
assert.Equal(t, 0, len(oL1UserTxs))
assert.Equal(t, 0, len(oL1CoordTxs))
@ -236,7 +246,8 @@ func TestGetL2TxSelectionMinimumFlow0(t *testing.T) {
log.Debug("block:0 batch:6")
l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[5].Batch.ForgeL1TxsNum])
_, _, oL1UserTxs, oL1CoordTxs, oL2Txs, _, err = txsel.GetL1L2TxSelection(selectionConfig, l1UserTxs)
_, _, oL1UserTxs, oL1CoordTxs, oL2Txs, _, err =
txsel.GetL1L2TxSelection(selectionConfig, l1UserTxs)
require.NoError(t, err)
assert.Equal(t, 1, len(oL1UserTxs))
assert.Equal(t, 0, len(oL1CoordTxs))
@ -269,7 +280,8 @@ func TestGetL2TxSelectionMinimumFlow0(t *testing.T) {
assert.True(t, l2TxsFromDB[0].VerifySignature(chainID, tc.Users["A"].BJJ.Public().Compress()))
assert.True(t, l2TxsFromDB[1].VerifySignature(chainID, tc.Users["B"].BJJ.Public().Compress()))
l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[6].Batch.ForgeL1TxsNum])
coordIdxs, accAuths, oL1UserTxs, oL1CoordTxs, oL2Txs, _, err := txsel.GetL1L2TxSelection(selectionConfig, l1UserTxs)
coordIdxs, accAuths, oL1UserTxs, oL1CoordTxs, oL2Txs, _, err :=
txsel.GetL1L2TxSelection(selectionConfig, l1UserTxs)
require.NoError(t, err)
assert.Equal(t, []common.Idx{261, 262}, coordIdxs)
assert.Equal(t, txsel.coordAccount.AccountCreationAuth, accAuths[0])
@ -291,7 +303,8 @@ func TestGetL2TxSelectionMinimumFlow0(t *testing.T) {
checkBalance(t, tc, txsel, "C", 0, "100")
checkBalance(t, tc, txsel, "D", 0, "800")
checkSortedByNonce(t, testAccNonces, oL2Txs)
err = txsel.l2db.StartForging(common.TxIDsFromPoolL2Txs(poolL2Txs), txsel.localAccountsDB.CurrentBatch())
err = txsel.l2db.StartForging(common.TxIDsFromPoolL2Txs(poolL2Txs),
txsel.localAccountsDB.CurrentBatch())
require.NoError(t, err)
log.Debug("block:0 batch:8")
@ -315,7 +328,8 @@ func TestGetL2TxSelectionMinimumFlow0(t *testing.T) {
assert.True(t, l2TxsFromDB[2].VerifySignature(chainID, tc.Users["B"].BJJ.Public().Compress()))
assert.True(t, l2TxsFromDB[3].VerifySignature(chainID, tc.Users["A"].BJJ.Public().Compress()))
l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[7].Batch.ForgeL1TxsNum])
coordIdxs, accAuths, oL1UserTxs, oL1CoordTxs, oL2Txs, _, err = txsel.GetL1L2TxSelection(selectionConfig, l1UserTxs)
coordIdxs, accAuths, oL1UserTxs, oL1CoordTxs, oL2Txs, _, err =
txsel.GetL1L2TxSelection(selectionConfig, l1UserTxs)
require.NoError(t, err)
assert.Equal(t, []common.Idx{261, 262}, coordIdxs)
assert.Equal(t, 0, len(accAuths))
@ -335,7 +349,8 @@ func TestGetL2TxSelectionMinimumFlow0(t *testing.T) {
checkBalance(t, tc, txsel, "C", 1, "100")
checkBalance(t, tc, txsel, "D", 0, "800")
checkSortedByNonce(t, testAccNonces, oL2Txs)
err = txsel.l2db.StartForging(common.TxIDsFromPoolL2Txs(poolL2Txs), txsel.localAccountsDB.CurrentBatch())
err = txsel.l2db.StartForging(common.TxIDsFromPoolL2Txs(poolL2Txs),
txsel.localAccountsDB.CurrentBatch())
require.NoError(t, err)
log.Debug("(batch9)block:1 batch:1")
@ -356,7 +371,8 @@ func TestGetL2TxSelectionMinimumFlow0(t *testing.T) {
assert.True(t, l2TxsFromDB[0].VerifySignature(chainID, tc.Users["D"].BJJ.Public().Compress()))
assert.True(t, l2TxsFromDB[1].VerifySignature(chainID, tc.Users["B"].BJJ.Public().Compress()))
l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[1].Rollup.Batches[0].Batch.ForgeL1TxsNum])
coordIdxs, accAuths, oL1UserTxs, oL1CoordTxs, oL2Txs, _, err = txsel.GetL1L2TxSelection(selectionConfig, l1UserTxs)
coordIdxs, accAuths, oL1UserTxs, oL1CoordTxs, oL2Txs, _, err =
txsel.GetL1L2TxSelection(selectionConfig, l1UserTxs)
require.NoError(t, err)
assert.Equal(t, []common.Idx{262}, coordIdxs)
assert.Equal(t, 0, len(accAuths))
@ -376,7 +392,8 @@ func TestGetL2TxSelectionMinimumFlow0(t *testing.T) {
checkBalance(t, tc, txsel, "C", 1, "100")
checkBalance(t, tc, txsel, "D", 0, "470")
checkSortedByNonce(t, testAccNonces, oL2Txs)
err = txsel.l2db.StartForging(common.TxIDsFromPoolL2Txs(poolL2Txs), txsel.localAccountsDB.CurrentBatch())
err = txsel.l2db.StartForging(common.TxIDsFromPoolL2Txs(poolL2Txs),
txsel.localAccountsDB.CurrentBatch())
require.NoError(t, err)
}
@ -423,10 +440,12 @@ func TestPoolL2TxsWithoutEnoughBalance(t *testing.T) {
l1UserTxs := []common.L1Tx{}
_, _, _, _, _, _, err = txsel.GetL1L2TxSelection(selectionConfig, l1UserTxs)
require.NoError(t, err)
expectedTxID0 := "0x028847b86613c0b70be18c8622119ed045b42e4e47d7938fa90bb3d1dc14928965" // 1st TransferToEthAddr
expectedTxID1 := "0x0200b18773dcf56f770d65870fb02041cb59a088fd35b7c3f3df69f8a250b99a42" // 1st Exit
expectedTxID2 := "0x029720ff506153f970f120ac638cd7ee759eeff2c2012e7634a78e4fdc05c04a90" // 2nd TransferToEthAddr
// 1st TransferToEthAddr
expectedTxID0 := "0x028847b86613c0b70be18c8622119ed045b42e4e47d7938fa90bb3d1dc14928965"
// 1st Exit
expectedTxID1 := "0x0200b18773dcf56f770d65870fb02041cb59a088fd35b7c3f3df69f8a250b99a42"
// 2nd TransferToEthAddr
expectedTxID2 := "0x029720ff506153f970f120ac638cd7ee759eeff2c2012e7634a78e4fdc05c04a90"
// batch2
// prepare the PoolL2Txs
@ -440,7 +459,8 @@ func TestPoolL2TxsWithoutEnoughBalance(t *testing.T) {
addL2Txs(t, txsel, poolL2Txs)
l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[1].Batch.ForgeL1TxsNum])
_, _, oL1UserTxs, oL1CoordTxs, oL2Txs, discardedL2Txs, err := txsel.GetL1L2TxSelection(selectionConfig, l1UserTxs)
_, _, oL1UserTxs, oL1CoordTxs, oL2Txs, discardedL2Txs, err :=
txsel.GetL1L2TxSelection(selectionConfig, l1UserTxs)
require.NoError(t, err)
assert.Equal(t, 3, len(oL1UserTxs))
assert.Equal(t, 0, len(oL1CoordTxs))
@ -448,7 +468,8 @@ func TestPoolL2TxsWithoutEnoughBalance(t *testing.T) {
assert.Equal(t, 2, len(discardedL2Txs))
assert.Equal(t, expectedTxID0, discardedL2Txs[0].TxID.String())
assert.Equal(t, expectedTxID1, discardedL2Txs[1].TxID.String())
err = txsel.l2db.StartForging(common.TxIDsFromPoolL2Txs(oL2Txs), txsel.localAccountsDB.CurrentBatch())
err = txsel.l2db.StartForging(common.TxIDsFromPoolL2Txs(oL2Txs),
txsel.localAccountsDB.CurrentBatch())
require.NoError(t, err)
// as the PoolL2Txs have not been really processed, restart nonces
@ -468,7 +489,8 @@ func TestPoolL2TxsWithoutEnoughBalance(t *testing.T) {
addL2Txs(t, txsel, poolL2Txs)
l1UserTxs = []common.L1Tx{}
_, _, oL1UserTxs, oL1CoordTxs, oL2Txs, discardedL2Txs, err = txsel.GetL1L2TxSelection(selectionConfig, l1UserTxs)
_, _, oL1UserTxs, oL1CoordTxs, oL2Txs, discardedL2Txs, err =
txsel.GetL1L2TxSelection(selectionConfig, l1UserTxs)
require.NoError(t, err)
assert.Equal(t, 0, len(oL1UserTxs))
assert.Equal(t, 0, len(oL1CoordTxs))
@ -478,23 +500,27 @@ func TestPoolL2TxsWithoutEnoughBalance(t *testing.T) {
assert.Equal(t, expectedTxID0, discardedL2Txs[0].TxID.String())
assert.Equal(t, expectedTxID1, discardedL2Txs[1].TxID.String())
assert.Equal(t, common.TxTypeTransferToEthAddr, oL2Txs[0].Type)
err = txsel.l2db.StartForging(common.TxIDsFromPoolL2Txs(oL2Txs), txsel.localAccountsDB.CurrentBatch())
err = txsel.l2db.StartForging(common.TxIDsFromPoolL2Txs(oL2Txs),
txsel.localAccountsDB.CurrentBatch())
require.NoError(t, err)
// batch4
// make the selection of another batch, which should include the
// initial PoolExit, which now is valid as B has enough Balance
l1UserTxs = []common.L1Tx{}
_, _, oL1UserTxs, oL1CoordTxs, oL2Txs, discardedL2Txs, err = txsel.GetL1L2TxSelection(selectionConfig, l1UserTxs)
_, _, oL1UserTxs, oL1CoordTxs, oL2Txs, discardedL2Txs, err =
txsel.GetL1L2TxSelection(selectionConfig, l1UserTxs)
require.NoError(t, err)
assert.Equal(t, 0, len(oL1UserTxs))
assert.Equal(t, 0, len(oL1CoordTxs))
assert.Equal(t, 1, len(oL2Txs))
assert.Equal(t, 1, len(discardedL2Txs))
assert.Equal(t, expectedTxID1, oL2Txs[0].TxID.String()) // the Exit that was not accepted at the batch2
// the Exit that was not accepted at the batch2
assert.Equal(t, expectedTxID1, oL2Txs[0].TxID.String())
assert.Equal(t, expectedTxID0, discardedL2Txs[0].TxID.String())
assert.Equal(t, common.TxTypeExit, oL2Txs[0].Type)
err = txsel.l2db.StartForging(common.TxIDsFromPoolL2Txs(oL2Txs), txsel.localAccountsDB.CurrentBatch())
err = txsel.l2db.StartForging(common.TxIDsFromPoolL2Txs(oL2Txs),
txsel.localAccountsDB.CurrentBatch())
require.NoError(t, err)
}
@ -558,7 +584,8 @@ func TestTransferToBjj(t *testing.T) {
addL2Txs(t, txsel, poolL2Txs)
l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[1].Batch.ForgeL1TxsNum])
_, _, oL1UserTxs, oL1CoordTxs, oL2Txs, discardedL2Txs, err := txsel.GetL1L2TxSelection(selectionConfig, l1UserTxs)
_, _, oL1UserTxs, oL1CoordTxs, oL2Txs, discardedL2Txs, err :=
txsel.GetL1L2TxSelection(selectionConfig, l1UserTxs)
require.NoError(t, err)
assert.Equal(t, 4, len(oL1UserTxs))
// We expect the coordinator to add an L1CoordTx to create an account for the recipient of the l2tx
@ -568,7 +595,8 @@ func TestTransferToBjj(t *testing.T) {
// fmt.Printf("DBG l1CoordTx[0]: %+v\n", oL1CoordTxs[0])
assert.Equal(t, 1, len(oL2Txs))
assert.Equal(t, 0, len(discardedL2Txs))
err = txsel.l2db.StartForging(common.TxIDsFromPoolL2Txs(oL2Txs), txsel.localAccountsDB.CurrentBatch())
err = txsel.l2db.StartForging(common.TxIDsFromPoolL2Txs(oL2Txs),
txsel.localAccountsDB.CurrentBatch())
require.NoError(t, err)
// Now the BJJ-only account for B is already created, so the transfer
@ -584,14 +612,16 @@ func TestTransferToBjj(t *testing.T) {
addL2Txs(t, txsel, poolL2Txs)
l1UserTxs = []common.L1Tx{}
_, _, oL1UserTxs, oL1CoordTxs, oL2Txs, discardedL2Txs, err = txsel.GetL1L2TxSelection(selectionConfig, l1UserTxs)
_, _, oL1UserTxs, oL1CoordTxs, oL2Txs, discardedL2Txs, err =
txsel.GetL1L2TxSelection(selectionConfig, l1UserTxs)
require.NoError(t, err)
assert.Equal(t, 0, len(oL1UserTxs))
// Since the BJJ-only account B already exists, the coordinator doesn't add any L1CoordTxs
assert.Equal(t, 0, len(oL1CoordTxs))
assert.Equal(t, 1, len(oL2Txs))
assert.Equal(t, 0, len(discardedL2Txs))
err = txsel.l2db.StartForging(common.TxIDsFromPoolL2Txs(oL2Txs), txsel.localAccountsDB.CurrentBatch())
err = txsel.l2db.StartForging(common.TxIDsFromPoolL2Txs(oL2Txs),
txsel.localAccountsDB.CurrentBatch())
require.NoError(t, err)
// The transfer now is ToBJJ to a BJJ-only account that doesn't exist
@ -610,7 +640,8 @@ func TestTransferToBjj(t *testing.T) {
addL2Txs(t, txsel, poolL2Txs)
l1UserTxs = []common.L1Tx{}
_, _, oL1UserTxs, oL1CoordTxs, oL2Txs, discardedL2Txs, err = txsel.GetL1L2TxSelection(selectionConfig, l1UserTxs)
_, _, oL1UserTxs, oL1CoordTxs, oL2Txs, discardedL2Txs, err =
txsel.GetL1L2TxSelection(selectionConfig, l1UserTxs)
require.NoError(t, err)
assert.Equal(t, 0, len(oL1UserTxs))
// We expect the coordinator to add an L1CoordTx to create an account
@ -626,7 +657,8 @@ func TestTransferToBjj(t *testing.T) {
assert.Equal(t, 1, len(oL2Txs))
assert.Equal(t, 0, len(discardedL2Txs))
err = txsel.l2db.StartForging(common.TxIDsFromPoolL2Txs(oL2Txs), txsel.localAccountsDB.CurrentBatch())
err = txsel.l2db.StartForging(common.TxIDsFromPoolL2Txs(oL2Txs),
txsel.localAccountsDB.CurrentBatch())
require.NoError(t, err)
}
@ -699,13 +731,15 @@ func TestTransferManyFromSameAccount(t *testing.T) {
addL2Txs(t, txsel, poolL2Txs)
// batch 2 to crate some accounts with positive balance, and do 8 L2Tx transfers from account A
l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[1].Batch.ForgeL1TxsNum])
_, _, oL1UserTxs, oL1CoordTxs, oL2Txs, discardedL2Txs, err := txsel.GetL1L2TxSelection(selectionConfig, l1UserTxs)
_, _, oL1UserTxs, oL1CoordTxs, oL2Txs, discardedL2Txs, err :=
txsel.GetL1L2TxSelection(selectionConfig, l1UserTxs)
require.NoError(t, err)
assert.Equal(t, 3, len(oL1UserTxs))
require.Equal(t, 0, len(oL1CoordTxs))
assert.Equal(t, 7, len(oL2Txs))
assert.Equal(t, 1, len(discardedL2Txs))
err = txsel.l2db.StartForging(common.TxIDsFromPoolL2Txs(oL2Txs), txsel.localAccountsDB.CurrentBatch())
err = txsel.l2db.StartForging(common.TxIDsFromPoolL2Txs(oL2Txs),
txsel.localAccountsDB.CurrentBatch())
require.NoError(t, err)
}

Loading…
Cancel
Save