Compare commits

...

37 Commits

Author SHA1 Message Date
arnaucube
cde300077a WIP temp fast fix, the final fix will be at: https://github.com/hermeznetwork/hermez-node/pull/617 2021-03-10 13:52:49 +01:00
Eduard S
b724348ddc Merge pull request #630 from hermeznetwork/feature/update-poseidon
Update to last Poseidon & go-merkletree versions
2021-03-10 12:18:59 +01:00
arnau
0b6911052a Merge pull request #611 from hermeznetwork/feature/sync-l1-account-creation-auth
Synchronize the AccountCreationAuths from L1CoordinatorTxs
2021-03-09 17:24:54 +01:00
arnaucube
a39d880fd4 Update to last Poseidon & go-merkletree versions
Update to last Poseidon (go-iden3-crypto) & go-merkletree versions,
update the affected test vectors, and check ZKInputs compatibility with
last version of circuits.

Update to last Poseidon version (which includes the changes of the
reference implementation from
26ddaa91db)

Compatible with update at circomlib
(cf853c1cc9)
2021-03-09 14:43:08 +01:00
Pantani
efb23950db Synchronize the AccountCreationAuths from L1CoordinatorTxs 2021-03-08 14:41:19 -03:00
Eduard S
06b271fc47 Merge pull request #620 from hermeznetwork/feature/priceupdater-by-SC-addr
Add coingecko client to price updater
2021-03-08 16:42:07 +01:00
arnaubennassar
ac66ede917 Add coingecko client to price updater 2021-03-08 16:34:49 +01:00
Eduard S
7305a8d7f1 Merge pull request #615 from hermeznetwork/fix/l2txs-all-tonull
API doesnt accept pool txs without to
2021-03-08 15:24:35 +01:00
arnaubennassar
81690039da API doesnt accept pool txs without to 2021-03-08 15:16:49 +01:00
Eduard S
661da0d53e Merge pull request #619 from hermeznetwork/fix/floor-float40-helper
Fix NewFloat40Floor helper method
2021-03-08 15:16:45 +01:00
arnau
d0ace0773d Merge pull request #616 from hermeznetwork/fix/typos-and-lint
fix some code typos
2021-03-08 14:35:30 +01:00
arnaucube
4fd757a03c Fix NewFloat40Floor helper method 2021-03-08 14:32:05 +01:00
arnau
1778b08043 Merge pull request #618 from hermeznetwork/fix/poolL2-signature
Fix tx signature when toEthAddr starts with 0x0
2021-03-05 17:26:56 +01:00
arnaubennassar
dcd40f1943 Fix tx signature when toEthAddr starts with 0x0 2021-03-05 17:21:14 +01:00
Danilo Pantani
7833cb11de fix some code and comment typos 2021-03-04 18:26:00 -03:00
Eduard S
9e96bc89f0 Merge pull request #613 from hermeznetwork/fix/zkinputs-ISExitRoot-L1CoordTxs
Fix ZKInputs.ISExitRoot for case of L1CoordTxs
2021-03-04 16:44:43 +01:00
arnaucube
7bc83d7f70 Fix ZKInputs.ISExitRoot for case of L1CoordTxs
For the cases when there are Exit L1UserTxs and also there are
L1CoordinatorTxs, the ISExitRoot should have the expected value (!=0)
for the L1CoordinatorTxs slots.
2021-03-04 14:57:08 +01:00
Eduard S
6bf8584a82 Merge pull request #612 from hermeznetwork/fix/txselector-unselectedtx-nonce
Fix TxSel for unselected tx update internal Nonce
2021-03-04 14:14:00 +01:00
arnaucube
18e9e437da Fix TxSel for unselected tx update internal Nonce
Fix TxSelector for unselected tx update internal Nonce.
Also updated TxSelector config parameter.
2021-03-04 14:09:13 +01:00
Eduard S
e4343a73ad Merge pull request #610 from hermeznetwork/feature/float40-floor
Add NewFloor40Floor helper method
2021-03-03 12:07:50 +01:00
arnau
59558e5a4b Merge pull request #609 from hermeznetwork/feature/wipestatedb
Wipe StateDB in cli command wipesql
2021-03-03 12:02:21 +01:00
arnaucube
dfd49164f4 Add NewFloor40Floor helper method
Also added tracerr.Wrap(...) to missing places.
2021-03-03 11:58:17 +01:00
Eduard S
1050da350a Wipe StateDB in cli command wipesql
Also, in the cli commands `wipesql` and `discard`, always rebuild the current
checkpoint of the stateDBs to make sure it's in a consistent non-corrupted
state and do a reset afterwards.  These commands will allow reverting the
StateDB to a valid and consistent state in case a crash leaves the StateDB in a
corrupted state.
2021-03-03 11:33:22 +01:00
Eduard S
e460a7e58b Merge pull request #608 from hermeznetwork/feature/txprocessor-doc
Extend TxProcessor documentation and explanation
2021-03-02 14:19:49 +01:00
arnaucube
97fdbfe037 Extend TxProcessor documentation and explanation 2021-03-02 14:13:45 +01:00
arnau
2e2d5a3c29 Merge pull request #607 from hermeznetwork/feature/updateconfig
Update example config with working values
2021-03-02 12:08:36 +01:00
Eduard S
f762fbdc4d Update example config with working values
The `ForgeBatchGasCost` parameters work for the current version of the smart
contracts.
2021-03-02 12:00:18 +01:00
Eduard S
4390fd8346 Merge pull request #603 from hermeznetwork/feature/update-linter-lll
Add lll to linter checks
2021-03-01 18:07:09 +01:00
arnaucube
93b7866d3e Add lll to linter checks
Updated:
	batchbuilder
	common
	coordinator
	db/statedb
	eth
	log
	node
	priceupdater
	prover
	synchronizer
	test/*
	txprocessor
	txselector

Pending (once
https://github.com/hermeznetwork/hermez-node/tree/feature/serveapicli is
merged to master):
	Update golangci-lint version to v1.37.1
	api
	apitypes
	cli
	config
	db/historydb
	db/l2db
2021-03-01 18:02:10 +01:00
a_bennassar
059a3556fb Merge pull request #604 from hermeznetwork/fix/meddler
Don't select extra columns in SQL, fix metrics query
2021-03-01 17:18:53 +01:00
Eduard S
8b88e1fbd0 Don't select extra columns in SQL, fix metrics query
In the metrics query, the estimatedTimeToForgeL1 was probably not being read
from the SQL query because it contained upper case letters, and in PostgreSQL
when identifiers are not double quoted they are case insensitive:
https://stackoverflow.com/a/20880247
2021-03-01 16:31:26 +01:00
arnau
1de0b08bac Merge pull request #593 from hermeznetwork/fix/addgaspriceresend
When resending an eth tx, always increase gas price
2021-03-01 15:05:36 +01:00
arnau
73c3a91746 Merge pull request #602 from hermeznetwork/fix/forgebatch
Fix unforged L1UserTxs query in forgeBatch
2021-03-01 14:47:18 +01:00
Eduard S
74769da5ba Fix unforged L1UserTxs query in forgeBatch
Previously the code was only querying the unforged L1UserTxs of a particular
queue, but this was incorrect because there are always two non-forged queues:
the frozen one and the open one.

Replace it by a query to all the unforged L1UserTxs via a new HistoryDB method.
2021-03-01 13:02:06 +01:00
Eduard S
65b007d59c When resending an eth tx, always increase gas price
Incrementing the gas price unconditionally avoids sending the exact same
transaction, which geth will reject because that transaction already exists in
the pool
2021-03-01 12:06:25 +01:00
arnau
6e4bd56c1a Merge pull request #595 from hermeznetwork/fix/print-balance
fix forge address balance printing removing the int64 casting
2021-03-01 11:44:45 +01:00
Danilo Pantani
4a75c35abf fix forge address balance printing removing the int64 casting 2021-02-26 15:15:37 -03:00
101 changed files with 2554 additions and 1047 deletions

View File

@@ -44,7 +44,7 @@ func (a *API) getAccounts(c *gin.Context) {
return
}
// Build succesfull response
// Build successful response
type accountResponse struct {
Accounts []historydb.AccountAPI `json:"accounts"`
PendingItems uint64 `json:"pendingItems"`

View File

@@ -47,7 +47,7 @@ func (a *API) getAccountCreationAuth(c *gin.Context) {
retSQLErr(err, c)
return
}
// Build succesfull response
// Build successful response
c.JSON(http.StatusOK, auth)
}

View File

@@ -201,7 +201,7 @@ func TestMain(m *testing.M) {
if err != nil {
panic(err)
}
apiConnCon := db.NewAPICnnectionController(1, time.Second)
apiConnCon := db.NewAPIConnectionController(1, time.Second)
hdb := historydb.NewHistoryDB(database, database, apiConnCon)
if err != nil {
panic(err)
@@ -260,7 +260,7 @@ func TestMain(m *testing.M) {
// Reset DB
test.WipeDB(api.h.DB())
// Genratre blockchain data with til
// Generate blockchain data with til
tcc := til.NewContext(chainID, common.RollupConstMaxL1UserTx)
tilCfgExtra := til.ConfigExtra{
BootCoordAddr: ethCommon.HexToAddress("0xE39fEc6224708f0772D2A74fd3f9055A90E0A9f2"),
@@ -512,7 +512,7 @@ func TestMain(m *testing.M) {
WithdrawalDelay: uint64(3000),
}
// Generate test data, as expected to be received/sended from/to the API
// Generate test data, as expected to be received/sent from/to the API
testCoords := genTestCoordinators(commonCoords)
testBids := genTestBids(commonBlocks, testCoords, bids)
testExits := genTestExits(commonExitTree, testTokens, commonAccounts)
@@ -599,7 +599,7 @@ func TestTimeout(t *testing.T) {
pass := os.Getenv("POSTGRES_PASS")
databaseTO, err := db.InitSQLDB(5432, "localhost", "hermez", pass, "hermez")
require.NoError(t, err)
apiConnConTO := db.NewAPICnnectionController(1, 100*time.Millisecond)
apiConnConTO := db.NewAPIConnectionController(1, 100*time.Millisecond)
hdbTO := historydb.NewHistoryDB(databaseTO, databaseTO, apiConnConTO)
require.NoError(t, err)
// L2DB

View File

@@ -52,7 +52,7 @@ func (a *API) getBatches(c *gin.Context) {
return
}
// Build succesfull response
// Build successful response
type batchesResponse struct {
Batches []historydb.BatchAPI `json:"batches"`
PendingItems uint64 `json:"pendingItems"`

View File

@@ -34,7 +34,7 @@ func (a *API) getBids(c *gin.Context) {
return
}
// Build succesfull response
// Build successful response
type bidsResponse struct {
Bids []historydb.BidAPI `json:"bids"`
PendingItems uint64 `json:"pendingItems"`

View File

@@ -32,7 +32,7 @@ func (a *API) getCoordinators(c *gin.Context) {
return
}
// Build succesfull response
// Build successful response
type coordinatorsResponse struct {
Coordinators []historydb.CoordinatorAPI `json:"coordinators"`
PendingItems uint64 `json:"pendingItems"`

View File

@@ -43,7 +43,7 @@ func (a *API) getExits(c *gin.Context) {
return
}
// Build succesfull response
// Build successful response
type exitsResponse struct {
Exits []historydb.ExitAPI `json:"exits"`
PendingItems uint64 `json:"pendingItems"`
@@ -72,6 +72,6 @@ func (a *API) getExit(c *gin.Context) {
retSQLErr(err, c)
return
}
// Build succesfull response
// Build successful response
c.JSON(http.StatusOK, exit)
}

View File

@@ -14,7 +14,7 @@ import (
)
const (
// maxLimit is the max permited items to be returned in paginated responses
// maxLimit is the max permitted items to be returned in paginated responses
maxLimit uint = 2049
// dfltOrder indicates how paginated endpoints are ordered if not specified
@@ -40,8 +40,8 @@ const (
)
var (
// ErrNillBidderAddr is used when a nil bidderAddr is received in the getCoordinator method
ErrNillBidderAddr = errors.New("biderAddr can not be nil")
// ErrNilBidderAddr is used when a nil bidderAddr is received in the getCoordinator method
ErrNilBidderAddr = errors.New("biderAddr can not be nil")
)
func retSQLErr(err error, c *gin.Context) {

View File

@@ -50,19 +50,19 @@ func parsePagination(c querier) (fromItem *uint, order string, limit *uint, err
return fromItem, order, limit, nil
}
// nolint reason: res may be not overwriten
// nolint reason: res may be not overwritten
func parseQueryUint(name string, dflt *uint, min, max uint, c querier) (*uint, error) { //nolint:SA4009
str := c.Query(name)
return stringToUint(str, name, dflt, min, max)
}
// nolint reason: res may be not overwriten
// nolint reason: res may be not overwritten
func parseQueryInt64(name string, dflt *int64, min, max int64, c querier) (*int64, error) { //nolint:SA4009
str := c.Query(name)
return stringToInt64(str, name, dflt, min, max)
}
// nolint reason: res may be not overwriten
// nolint reason: res may be not overwritten
func parseQueryBool(name string, dflt *bool, c querier) (*bool, error) { //nolint:SA4009
str := c.Query(name)
if str == "" {
@@ -295,13 +295,13 @@ func parseParamIdx(c paramer) (*common.Idx, error) {
return stringToIdx(idxStr, name)
}
// nolint reason: res may be not overwriten
// nolint reason: res may be not overwritten
func parseParamUint(name string, dflt *uint, min, max uint, c paramer) (*uint, error) { //nolint:SA4009
str := c.Param(name)
return stringToUint(str, name, dflt, min, max)
}
// nolint reason: res may be not overwriten
// nolint reason: res may be not overwritten
func parseParamInt64(name string, dflt *int64, min, max int64, c paramer) (*int64, error) { //nolint:SA4009
str := c.Param(name)
return stringToInt64(str, name, dflt, min, max)

View File

@@ -11,7 +11,7 @@ import (
"github.com/hermeznetwork/tracerr"
)
// SlotAPI is a repesentation of a slot information
// SlotAPI is a representation of a slot information
type SlotAPI struct {
ItemID uint64 `json:"itemId"`
SlotNum int64 `json:"slotNum"`
@@ -316,7 +316,7 @@ func (a *API) getSlots(c *gin.Context) {
return
}
// Build succesfull response
// Build successful response
type slotsResponse struct {
Slots []SlotAPI `json:"slots"`
PendingItems uint64 `json:"pendingItems"`

View File

@@ -53,7 +53,7 @@ func (a *API) getTokens(c *gin.Context) {
return
}
// Build succesfull response
// Build successful response
type tokensResponse struct {
Tokens []historydb.TokenWithUSD `json:"tokens"`
PendingItems uint64 `json:"pendingItems"`

View File

@@ -42,7 +42,7 @@ func (a *API) getHistoryTxs(c *gin.Context) {
return
}
// Build succesfull response
// Build successful response
type txsResponse struct {
Txs []historydb.TxAPI `json:"transactions"`
PendingItems uint64 `json:"pendingItems"`
@@ -66,6 +66,6 @@ func (a *API) getHistoryTx(c *gin.Context) {
retSQLErr(err, c)
return
}
// Build succesfull response
// Build successful response
c.JSON(http.StatusOK, tx)
}

View File

@@ -455,7 +455,7 @@ func TestGetHistoryTx(t *testing.T) {
// 400, due invalid TxID
err := doBadReq("GET", endpoint+"0x001", nil, 400)
assert.NoError(t, err)
// 404, due inexistent TxID in DB
// 404, due nonexistent TxID in DB
err = doBadReq("GET", endpoint+"0x00eb5e95e1ce5e9f6c4ed402d415e8d0bdd7664769cfd2064d28da04a2c76be432", nil, 404)
assert.NoError(t, err)
}

View File

@@ -51,7 +51,7 @@ func (a *API) getPoolTx(c *gin.Context) {
retSQLErr(err, c)
return
}
// Build succesfull response
// Build successful response
c.JSON(http.StatusOK, tx)
}

View File

@@ -2,10 +2,15 @@ package api
import (
"bytes"
"crypto/ecdsa"
"encoding/binary"
"encoding/hex"
"encoding/json"
"math/big"
"testing"
"time"
ethCrypto "github.com/ethereum/go-ethereum/crypto"
"github.com/hermeznetwork/hermez-node/common"
"github.com/hermeznetwork/hermez-node/db/historydb"
"github.com/iden3/go-iden3-crypto/babyjub"
@@ -235,7 +240,7 @@ func TestPoolTxs(t *testing.T) {
// 400, due invalid TxID
err = doBadReq("GET", endpoint+"0xG2241b6f2b1dd772dba391f4a1a3407c7c21f598d86e2585a14e616fb4a255f823", nil, 400)
require.NoError(t, err)
// 404, due inexistent TxID in DB
// 404, due nonexistent TxID in DB
err = doBadReq("GET", endpoint+"0x02241b6f2b1dd772dba391f4a1a3407c7c21f598d86e2585a14e616fb4a255f823", nil, 404)
require.NoError(t, err)
}
@@ -257,3 +262,73 @@ func assertPoolTx(t *testing.T, expected, actual testPoolTxReceive) {
}
assert.Equal(t, expected, actual)
}
// TestAllTosNull test that the API doesn't accept txs with all the TOs set to null (to eth, to bjj, to idx)
func TestAllTosNull(t *testing.T) {
// Generate account:
// Ethereum private key
var key ecdsa.PrivateKey
key.D = big.NewInt(int64(4444)) // only for testing
key.PublicKey.X, key.PublicKey.Y = ethCrypto.S256().ScalarBaseMult(key.D.Bytes())
key.Curve = ethCrypto.S256()
addr := ethCrypto.PubkeyToAddress(key.PublicKey)
// BJJ private key
var sk babyjub.PrivateKey
var iBytes [8]byte
binary.LittleEndian.PutUint64(iBytes[:], 4444)
copy(sk[:], iBytes[:]) // only for testing
account := common.Account{
Idx: 4444,
TokenID: 0,
BatchNum: 1,
BJJ: sk.Public().Compress(),
EthAddr: addr,
Nonce: 0,
Balance: big.NewInt(1000000),
}
// Add account to history DB (required to verify signature)
err := api.h.AddAccounts([]common.Account{account})
assert.NoError(t, err)
// Genrate tx with all tos set to nil (to eth, to bjj, to idx)
tx := common.PoolL2Tx{
FromIdx: account.Idx,
TokenID: account.TokenID,
Amount: big.NewInt(1000),
Fee: 200,
Nonce: 0,
}
// Set idx and type manually, and check that the function doesn't allow it
_, err = common.NewPoolL2Tx(&tx)
assert.Error(t, err)
tx.Type = common.TxTypeTransfer
var txID common.TxID
txIDRaw, err := hex.DecodeString("02e66e24f7f25272906647c8fd1d7fe8acf3cf3e9b38ffc9f94bbb5090dc275073")
assert.NoError(t, err)
copy(txID[:], txIDRaw)
tx.TxID = txID
// Sign tx
toSign, err := tx.HashToSign(0)
assert.NoError(t, err)
sig := sk.SignPoseidon(toSign)
tx.Signature = sig.Compress()
// Transform common.PoolL2Tx ==> testPoolTxSend
txToSend := testPoolTxSend{
TxID: tx.TxID,
Type: tx.Type,
TokenID: tx.TokenID,
FromIdx: idxToHez(tx.FromIdx, "ETH"),
Amount: tx.Amount.String(),
Fee: tx.Fee,
Nonce: tx.Nonce,
Signature: tx.Signature,
}
// Send tx to the API
jsonTxBytes, err := json.Marshal(txToSend)
require.NoError(t, err)
jsonTxReader := bytes.NewReader(jsonTxBytes)
err = doBadReq("POST", apiURL+"transactions-pool", jsonTxReader, 400)
require.NoError(t, err)
// Clean historyDB: the added account shouldn't be there for other tests
_, err = api.h.DB().DB.Exec("delete from account where idx = 4444")
assert.NoError(t, err)
}

View File

@@ -91,7 +91,7 @@ func (c *CollectedFees) UnmarshalJSON(text []byte) error {
return nil
}
// HezEthAddr is used to scan/value Ethereum Address directly into strings that follow the Ethereum address hez fotmat (^hez:0x[a-fA-F0-9]{40}$) from/to sql DBs.
// HezEthAddr is used to scan/value Ethereum Address directly into strings that follow the Ethereum address hez format (^hez:0x[a-fA-F0-9]{40}$) from/to sql DBs.
// It assumes that Ethereum Address are inserted/fetched to/from the DB using the default Scan/Value interface
type HezEthAddr string
@@ -143,7 +143,7 @@ func (s *StrHezEthAddr) UnmarshalText(text []byte) error {
return nil
}
// HezBJJ is used to scan/value *babyjub.PublicKeyComp directly into strings that follow the BJJ public key hez fotmat (^hez:[A-Za-z0-9_-]{44}$) from/to sql DBs.
// HezBJJ is used to scan/value *babyjub.PublicKeyComp directly into strings that follow the BJJ public key hez format (^hez:[A-Za-z0-9_-]{44}$) from/to sql DBs.
// It assumes that *babyjub.PublicKeyComp are inserted/fetched to/from the DB using the default Scan/Value interface
type HezBJJ string
@@ -216,7 +216,7 @@ func (b HezBJJ) Value() (driver.Value, error) {
// StrHezBJJ is used to unmarshal HezBJJ directly into an alias of babyjub.PublicKeyComp
type StrHezBJJ babyjub.PublicKeyComp
// UnmarshalText unmarshals a StrHezBJJ
// UnmarshalText unmarshalls a StrHezBJJ
func (s *StrHezBJJ) UnmarshalText(text []byte) error {
bjj, err := hezStrToBJJ(string(text))
if err != nil {
@@ -226,8 +226,8 @@ func (s *StrHezBJJ) UnmarshalText(text []byte) error {
return nil
}
// HezIdx is used to value common.Idx directly into strings that follow the Idx key hez fotmat (hez:tokenSymbol:idx) to sql DBs.
// Note that this can only be used to insert to DB since there is no way to automaticaly read from the DB since it needs the tokenSymbol
// HezIdx is used to value common.Idx directly into strings that follow the Idx key hez format (hez:tokenSymbol:idx) to sql DBs.
// Note that this can only be used to insert to DB since there is no way to automatically read from the DB since it needs the tokenSymbol
type HezIdx string
// StrHezIdx is used to unmarshal HezIdx directly into an alias of common.Idx

View File

@@ -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,

View File

@@ -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")

View File

@@ -10,6 +10,8 @@ SQLConnectionTimeout = "2s"
Interval = "10s"
URL = "https://api-pub.bitfinex.com/v2/"
Type = "bitfinexV2"
# URL = "https://api.coingecko.com/api/v3/"
# Type = "coingeckoV3"
[Debug]
APIAddress = "localhost:12345"
@@ -51,7 +53,7 @@ ForgerAddress = "0x05c23b938a85ab26A36E6314a0D02080E9ca6BeD" # Non-Boot Coordina
# ForgerAddressPrivateKey = "0x30f5fddb34cd4166adb2c6003fa6b18f380fd2341376be42cf1c7937004ac7a3"
# ForgerAddress = "0xb4124ceb3451635dacedd11767f004d8a28c6ee7" # Boot Coordinator
# ForgerAddressPrivateKey = "0xa8a54b2d8197bc0b19bb8a084031be71835580a01e70a45a13babd16c9bc1563"
MinimumForgeAddressBalance = 0
MinimumForgeAddressBalance = "0"
ConfirmBlocks = 10
L1BatchTimeoutPerc = 0.6
StartSlotBlocksDelay = 2
@@ -107,10 +109,10 @@ Path = "/tmp/iden3-test/hermez/ethkeystore"
Password = "yourpasswordhere"
[Coordinator.EthClient.ForgeBatchGasCost]
Fixed = 500000
L1UserTx = 8000
L1CoordTx = 9000
L2Tx = 1
Fixed = 600000
L1UserTx = 15000
L1CoordTx = 8000
L2Tx = 250
[Coordinator.API]
Coordinator = true

View File

@@ -5,13 +5,16 @@ import (
"fmt"
"os"
"os/signal"
"path"
"strings"
ethKeystore "github.com/ethereum/go-ethereum/accounts/keystore"
"github.com/ethereum/go-ethereum/crypto"
"github.com/hermeznetwork/hermez-node/common"
"github.com/hermeznetwork/hermez-node/config"
dbUtils "github.com/hermeznetwork/hermez-node/db"
"github.com/hermeznetwork/hermez-node/db/historydb"
"github.com/hermeznetwork/hermez-node/db/kvdb"
"github.com/hermeznetwork/hermez-node/db/l2db"
"github.com/hermeznetwork/hermez-node/log"
"github.com/hermeznetwork/hermez-node/node"
@@ -72,6 +75,86 @@ func cmdImportKey(c *cli.Context) error {
return nil
}
func resetStateDBs(cfg *Config, batchNum common.BatchNum) error {
log.Infof("Reset Synchronizer StateDB to batchNum %v...", batchNum)
// Manually make a checkpoint from batchNum to current to force current
// to be a valid checkpoint. This is useful because in case of a
// crash, current can be corrupted and the first thing that
// `kvdb.NewKVDB` does is read the current checkpoint, which wouldn't
// succeed in case of corruption.
dbPath := cfg.node.StateDB.Path
source := path.Join(dbPath, fmt.Sprintf("%s%d", kvdb.PathBatchNum, batchNum))
current := path.Join(dbPath, kvdb.PathCurrent)
last := path.Join(dbPath, kvdb.PathLast)
if err := os.RemoveAll(last); err != nil {
return tracerr.Wrap(fmt.Errorf("os.RemoveAll: %w", err))
}
if batchNum == 0 {
if err := os.RemoveAll(current); err != nil {
return tracerr.Wrap(fmt.Errorf("os.RemoveAll: %w", err))
}
} else {
if err := kvdb.PebbleMakeCheckpoint(source, current); err != nil {
return tracerr.Wrap(fmt.Errorf("kvdb.PebbleMakeCheckpoint: %w", err))
}
}
db, err := kvdb.NewKVDB(kvdb.Config{
Path: dbPath,
NoGapsCheck: true,
NoLast: true,
})
if err != nil {
return tracerr.Wrap(fmt.Errorf("kvdb.NewKVDB: %w", err))
}
if err := db.Reset(batchNum); err != nil {
return tracerr.Wrap(fmt.Errorf("db.Reset: %w", err))
}
if cfg.mode == node.ModeCoordinator {
log.Infof("Wipe Coordinator StateDBs...")
// We wipe the Coordinator StateDBs entirely (by deleting
// current and resetting to batchNum 0) because the Coordinator
// StateDBs are always reset from Synchronizer when the
// coordinator pipeline starts.
dbPath := cfg.node.Coordinator.TxSelector.Path
current := path.Join(dbPath, kvdb.PathCurrent)
if err := os.RemoveAll(current); err != nil {
return tracerr.Wrap(fmt.Errorf("os.RemoveAll: %w", err))
}
db, err := kvdb.NewKVDB(kvdb.Config{
Path: dbPath,
NoGapsCheck: true,
NoLast: true,
})
if err != nil {
return tracerr.Wrap(fmt.Errorf("kvdb.NewKVDB: %w", err))
}
if err := db.Reset(0); err != nil {
return tracerr.Wrap(fmt.Errorf("db.Reset: %w", err))
}
dbPath = cfg.node.Coordinator.BatchBuilder.Path
current = path.Join(dbPath, kvdb.PathCurrent)
if err := os.RemoveAll(current); err != nil {
return tracerr.Wrap(fmt.Errorf("os.RemoveAll: %w", err))
}
db, err = kvdb.NewKVDB(kvdb.Config{
Path: dbPath,
NoGapsCheck: true,
NoLast: true,
})
if err != nil {
return tracerr.Wrap(fmt.Errorf("statedb.NewKVDB: %w", err))
}
if err := db.Reset(0); err != nil {
return tracerr.Wrap(fmt.Errorf("db.Reset: %w", err))
}
}
return nil
}
func cmdWipeSQL(c *cli.Context) error {
_cfg, err := parseCli(c)
if err != nil {
@@ -80,7 +163,8 @@ func cmdWipeSQL(c *cli.Context) error {
cfg := _cfg.node
yes := c.Bool(flagYes)
if !yes {
fmt.Print("*WARNING* Are you sure you want to delete the SQL DB? [y/N]: ")
fmt.Print("*WARNING* Are you sure you want to delete " +
"the SQL DB and StateDBs? [y/N]: ")
var input string
if _, err := fmt.Scanln(&input); err != nil {
return tracerr.Wrap(err)
@@ -102,7 +186,12 @@ func cmdWipeSQL(c *cli.Context) error {
}
log.Info("Wiping SQL DB...")
if err := dbUtils.MigrationsDown(db.DB); err != nil {
return tracerr.Wrap(err)
return tracerr.Wrap(fmt.Errorf("dbUtils.MigrationsDown: %w", err))
}
log.Info("Wiping StateDBs...")
if err := resetStateDBs(_cfg, 0); err != nil {
return tracerr.Wrap(fmt.Errorf("resetStateDBs: %w", err))
}
return nil
}
@@ -201,6 +290,11 @@ func cmdDiscard(c *cli.Context) error {
return tracerr.Wrap(fmt.Errorf("l2DB.Reorg: %w", err))
}
log.Info("Resetting StateDBs...")
if err := resetStateDBs(_cfg, batchNum); err != nil {
return tracerr.Wrap(fmt.Errorf("resetStateDBs: %w", err))
}
return nil
}
@@ -288,7 +382,7 @@ func main() {
{
Name: "wipesql",
Aliases: []string{},
Usage: "Wipe the SQL DB (HistoryDB and L2DB), " +
Usage: "Wipe the SQL DB (HistoryDB and L2DB) and the StateDBs, " +
"leaving the DB in a clean state",
Action: cmdWipeSQL,
Flags: []cli.Flag{

View File

@@ -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 {

View File

@@ -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,
"447675324273474410516096114710387312413478475468606444107594732044698919451",
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,
"13265203488631320682117942952393454767418777767637549409684833552016769103047",
h.String())
v, err := account.HashValue()
assert.NoError(t, err)
assert.Equal(t, "4550823210217540218403400309533329186487982452461145263910122718498735057257", v.String())
assert.Equal(t,
"13265203488631320682117942952393454767418777767637549409684833552016769103047",
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,
"2351654555892372227640888372176282444150254868378439619268573230312091195718",
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,
"15036148928138382129196903417666258171042923749783835283230591475172197254845",
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))

View File

@@ -84,7 +84,7 @@ func (a *AccountCreationAuth) toHash(chainID uint16,
return rawData, nil
}
// HashToSign returns the hash to be signed by the Etherum address to authorize
// HashToSign returns the hash to be signed by the Ethereum address to authorize
// the account creation, which follows the EIP-712 encoding
func (a *AccountCreationAuth) HashToSign(chainID uint16,
hermezContractAddr ethCommon.Address) ([]byte, error) {
@@ -96,9 +96,9 @@ func (a *AccountCreationAuth) HashToSign(chainID uint16,
}
// Sign signs the account creation authorization message using the provided
// `signHash` function, and stores the signaure in `a.Signature`. `signHash`
// `signHash` function, and stores the signature in `a.Signature`. `signHash`
// should do an ethereum signature using the account corresponding to
// `a.EthAddr`. The `signHash` function is used to make signig flexible: in
// `a.EthAddr`. The `signHash` function is used to make signing flexible: in
// tests we sign directly using the private key, outside tests we sign using
// the keystore (which never exposes the private key). Sign follows the EIP-712
// encoding.

View File

@@ -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",

View File

@@ -14,7 +14,8 @@ 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
// 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,7 +23,9 @@ 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.
// 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"`
}
@@ -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

View File

@@ -34,7 +34,7 @@ type Slot struct {
// BatchesLen int
BidValue *big.Int
BootCoord bool
// Bidder, Forer and URL correspond to the winner of the slot (which is
// Bidder, Forger and URL correspond to the winner of the slot (which is
// not always the highest bidder). These are the values of the
// coordinator that is able to forge exclusively before the deadline.
Bidder ethCommon.Address

View File

@@ -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"`
}

View File

@@ -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"`
}

View File

@@ -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)
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")
// 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"`

View File

@@ -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"`

View File

@@ -1,4 +1,4 @@
// Package common Float40 provides methods to work with Hermez custom half
// Package common float40.go provides methods to work with Hermez custom half
// float precision, 40 bits, codification internally called Float40 has been
// adopted to encode large integers. This is done in order to save bits when L2
// transactions are published.
@@ -32,6 +32,8 @@ var (
// ErrFloat40NotEnoughPrecission is used when the given *big.Int can
// not be represented as Float40 due not enough precission
ErrFloat40NotEnoughPrecission = errors.New("Float40 error, not enough precission")
thres = big.NewInt(0x08_00_00_00_00)
)
// Float40 represents a float in a 64 bit format
@@ -68,7 +70,7 @@ func (f40 Float40) BigInt() (*big.Int, error) {
var f40Uint64 uint64 = uint64(f40) & 0x00_00_00_FF_FF_FF_FF_FF
f40Bytes, err := f40.Bytes()
if err != nil {
return nil, err
return nil, tracerr.Wrap(err)
}
e := f40Bytes[0] & 0xF8 >> 3 // take first 5 bits
@@ -86,18 +88,41 @@ func NewFloat40(f *big.Int) (Float40, error) {
e := big.NewInt(0)
zero := big.NewInt(0)
ten := big.NewInt(10)
thres := big.NewInt(0x08_00_00_00_00)
for new(big.Int).Mod(m, ten).Cmp(zero) == 0 && m.Cmp(thres) >= 0 {
m = new(big.Int).Div(m, ten)
e = new(big.Int).Add(e, big.NewInt(1))
}
if e.Int64() > 31 {
return 0, ErrFloat40E31
return 0, tracerr.Wrap(ErrFloat40E31)
}
if m.Cmp(thres) >= 0 {
return 0, ErrFloat40NotEnoughPrecission
return 0, tracerr.Wrap(ErrFloat40NotEnoughPrecission)
}
r := new(big.Int).Add(m,
new(big.Int).Mul(e, thres))
return Float40(r.Uint64()), nil
}
// NewFloat40Floor encodes a *big.Int integer as a Float40, rounding down in
// case of loss during the encoding. It returns an error in case that the number
// is too big (e>31). Warning: this method should not be used inside the
// hermez-node, it's a helper for external usage to generate valid Float40
// values.
func NewFloat40Floor(f *big.Int) (Float40, error) {
m := f
e := big.NewInt(0)
// zero := big.NewInt(0)
ten := big.NewInt(10)
for m.Cmp(thres) >= 0 {
m = new(big.Int).Div(m, ten)
e = new(big.Int).Add(e, big.NewInt(1))
}
if e.Int64() > 31 {
return 0, tracerr.Wrap(ErrFloat40E31)
}
r := new(big.Int).Add(m,
new(big.Int).Mul(e, thres))
return Float40(r.Uint64()), nil
}

View File

@@ -1,9 +1,11 @@
package common
import (
"fmt"
"math/big"
"testing"
"github.com/hermeznetwork/tracerr"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
@@ -55,7 +57,56 @@ func TestExpectError(t *testing.T) {
bi, ok := new(big.Int).SetString(test, 10)
require.True(t, ok)
_, err := NewFloat40(bi)
assert.Equal(t, testVector[test], err)
assert.Equal(t, testVector[test], tracerr.Unwrap(err))
}
}
func TestNewFloat40Floor(t *testing.T) {
testVector := map[string][]string{
// []int contains [Float40 value, Flot40 Floor value], when
// Float40 value is expected to be 0, is because is expected to
// be an error
"9922334455000000000000000000000000000000": {
"1040714485495", "1040714485495", "9922334455000000000000000000000000000000"},
"9922334455000000000000000000000000000001": { // Floor [2] will be same as prev line
"0", "1040714485495", "9922334455000000000000000000000000000000"},
"9922334454999999999999999999999999999999": {
"0", "1040714485494", "9922334454000000000000000000000000000000"},
"42949672950000000000000000000000000000000": {
"1069446856703", "1069446856703", "42949672950000000000000000000000000000000"},
"99223344556573838487575": {
"0", "456598933239", "99223344550000000000000"},
"992233445500000000000000000000000000000000": {
"0", "0", "0"}, // e>31, returns 0, err
"343597383670000000000000000000000000000000": {
"1099511627775", "1099511627775", "343597383670000000000000000000000000000000"},
"343597383680000000000000000000000000000000": {
"0", "0", "0"}, // e>31, returns 0, err
"1157073197879933027": {
"0", "286448638922", "1157073197800000000"},
}
for test := range testVector {
bi, ok := new(big.Int).SetString(test, 10)
require.True(t, ok)
f40, err := NewFloat40(bi)
if f40 == 0 {
assert.Error(t, err)
} else {
assert.NoError(t, err)
}
assert.Equal(t, testVector[test][0], fmt.Sprint(uint64(f40)))
f40, err = NewFloat40Floor(bi)
if f40 == 0 {
assert.Equal(t, ErrFloat40E31, tracerr.Unwrap(err))
} else {
assert.NoError(t, err)
}
assert.Equal(t, testVector[test][1], fmt.Sprint(uint64(f40)))
bi2, err := f40.BigInt()
require.NoError(t, err)
assert.Equal(t, fmt.Sprint(testVector[test][2]), bi2.String())
}
}

View File

@@ -22,14 +22,21 @@ type L1Tx struct {
// - 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
// ToForgeL1TxsNum indicates in which the tx was forged / will be forged
ToForgeL1TxsNum *int64 `meddler:"to_forge_l1_txs_num"`
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)
// 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
// 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.
@@ -37,7 +44,8 @@ type L1Tx struct {
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
// 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"`
}
@@ -251,7 +259,7 @@ func L1TxFromDataAvailability(b []byte, nLevels uint32) (*L1Tx, error) {
}
l1tx.ToIdx = toIdx
l1tx.EffectiveAmount, err = Float40FromBytes(amountBytes).BigInt()
return &l1tx, err
return &l1tx, tracerr.Wrap(err)
}
// BytesGeneric returns the generic representation of a L1Tx. This method is
@@ -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{

View File

@@ -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)

View File

@@ -10,7 +10,7 @@ import (
// L2Tx is a struct that represents an already forged L2 tx
type L2Tx struct {
// Stored in DB: mandatory fileds
// Stored in DB: mandatory fields
TxID TxID `meddler:"id"`
BatchNum BatchNum `meddler:"batch_num"` // batchNum in which this tx was forged.
Position int `meddler:"position"`
@@ -23,7 +23,8 @@ type L2Tx struct {
// 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
// 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

View File

@@ -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) {

View File

@@ -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
@@ -100,6 +101,8 @@ func (tx *PoolL2Tx) SetType() error {
tx.Type = TxTypeTransferToBJJ
} else if tx.ToEthAddr != FFAddr && tx.ToEthAddr != EmptyAddr {
tx.Type = TxTypeTransferToEthAddr
} else {
return tracerr.Wrap(errors.New("malformed transaction"))
}
} else {
return tracerr.Wrap(errors.New("malformed transaction"))
@@ -303,10 +306,8 @@ func (tx *PoolL2Tx) HashToSign(chainID uint16) (*big.Int, error) {
return nil, tracerr.Wrap(err)
}
copy(e1B[0:5], amountFloat40Bytes)
toEthAddr := EthAddrToBigInt(tx.ToEthAddr)
copy(e1B[5:25], toEthAddr.Bytes())
copy(e1B[5:25], tx.ToEthAddr[:])
e1 := new(big.Int).SetBytes(e1B[:])
rqToEthAddr := EthAddrToBigInt(tx.RqToEthAddr)
_, toBJJY := babyjub.UnpackSignY(tx.ToBJJ)
@@ -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

View File

@@ -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, "0b8abaf6b7933464e4450df2514da8b72606c02bf7f89bf6e54816fbda9d9d57",
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,18 +184,49 @@ func TestVerifyTxSignature(t *testing.T) {
}
toSign, err := tx.HashToSign(chainID)
assert.NoError(t, err)
assert.Equal(t, "1571327027383224465388301747239444557034990637650927918405777653988509342917", toSign.String())
assert.Equal(t,
"3144939470626721092564692894890580265754250231349521601298746071096761507003",
toSign.String())
sig := sk.SignPoseidon(toSign)
tx.Signature = sig.Compress()
assert.True(t, tx.VerifySignature(chainID, sk.Public().Compress()))
}
func TestVerifyTxSignatureEthAddrWith0(t *testing.T) {
chainID := uint16(5)
var sk babyjub.PrivateKey
_, err := hex.Decode(sk[:],
[]byte("02f0b4f87065af3797aaaf934e8b5c31563c17f2272fa71bd0146535bfbb4184"))
assert.NoError(t, err)
tx := PoolL2Tx{
FromIdx: 10659,
ToIdx: 0,
ToEthAddr: ethCommon.HexToAddress("0x0004308BD15Ead4F1173624dC289DBdcC806a309"),
Amount: big.NewInt(5000),
TokenID: 0,
Nonce: 946,
Fee: 231,
}
toSign, err := tx.HashToSign(chainID)
assert.NoError(t, err)
sig := sk.SignPoseidon(toSign)
assert.Equal(t,
"f208b8298d5f37148ac3c0c03703272ea47b9f836851bcf8dd5f7e4e3b336ca1d2f6e92ad85dc25f174daf7a0abfd5f71dead3f059b783f4c4b2f56a18a47000",
sig.Compress().String(),
)
tx.Signature = sig.Compress()
assert.True(t, tx.VerifySignature(chainID, sk.Public().Compress()))
}
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())
}

View File

@@ -16,7 +16,8 @@ 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
// 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

View File

@@ -15,12 +15,12 @@ import (
)
const (
// TXIDPrefixL1UserTx is the prefix that determines that the TxID is
// for a L1UserTx
// TxIDPrefixL1UserTx is the prefix that determines that the TxID is for
// a L1UserTx
//nolinter:gomnd
TxIDPrefixL1UserTx = byte(0)
// TXIDPrefixL1CoordTx is the prefix that determines that the TxID is
// TxIDPrefixL1CoordTx is the prefix that determines that the TxID is
// for a L1CoordinatorTx
//nolinter:gomnd
TxIDPrefixL1CoordTx = byte(1)
@@ -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
@@ -87,7 +88,7 @@ func (txid TxID) MarshalText() ([]byte, error) {
return []byte(txid.String()), nil
}
// UnmarshalText unmarshals a TxID
// UnmarshalText unmarshalls a TxID
func (txid *TxID) UnmarshalText(data []byte) error {
idStr := string(data)
id, err := NewTxIDFromString(idStr)
@@ -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,7 +127,8 @@ 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"`
@@ -137,11 +141,17 @@ type Tx struct {
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
// 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"`

View File

@@ -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[:])

View File

@@ -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

View File

@@ -1,4 +1,4 @@
// Package common contains all the common data structures used at the
// Package common zk.go contains all the common data structures used at the
// hermez-node, zk.go contains the zkSnark inputs used to generate the proof
package common
@@ -67,7 +67,7 @@ type ZKInputs struct {
// accumulate fees
// FeePlanTokens contains all the tokenIDs for which the fees are being
// accumulated and those fees accoumulated will be paid to the FeeIdxs
// accumulated and those fees accumulated will be paid to the FeeIdxs
// array. The order of FeeIdxs & FeePlanTokens & State3 must match.
// Coordinator fees are processed correlated such as:
// [FeePlanTokens[i], FeeIdxs[i]]
@@ -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

View File

@@ -73,7 +73,7 @@ type Coordinator struct {
// checking the next block), used to decide when to stop scheduling new
// batches (by stopping the pipeline).
// For example, if we are at block 10 and ScheduleBatchBlocksAheadCheck
// is 5, eventhough at block 11 we canForge, the pipeline will be
// is 5, even though at block 11 we canForge, the pipeline will be
// stopped if we can't forge at block 15.
// This value should be the expected number of blocks it takes between
// scheduling a batch and having it mined.
@@ -83,7 +83,7 @@ type Coordinator struct {
// from the next block; used to decide when to stop sending batches to
// the smart contract.
// For example, if we are at block 10 and SendBatchBlocksMarginCheck is
// 5, eventhough at block 11 we canForge, the batch will be discarded
// 5, even though at block 11 we canForge, the batch will be discarded
// if we can't forge at block 15.
SendBatchBlocksMarginCheck int64
// ProofServerPollInterval is the waiting interval between polling the
@@ -126,7 +126,7 @@ type Coordinator struct {
// L2Txs is reached, L2Txs older than TTL will be deleted.
TTL Duration `validate:"required"`
// PurgeBatchDelay is the delay between batches to purge
// outdated transactions. Oudated L2Txs are those that have
// outdated transactions. Outdated L2Txs are those that have
// been forged or marked as invalid for longer than the
// SafetyPeriod and pending L2Txs that have been in the pool
// for longer than TTL once there are MaxTxs.
@@ -136,7 +136,7 @@ type Coordinator struct {
// nonce.
InvalidateBatchDelay int64 `validate:"required"`
// PurgeBlockDelay is the delay between blocks to purge
// outdated transactions. Oudated L2Txs are those that have
// outdated transactions. Outdated L2Txs are those that have
// been forged or marked as invalid for longer than the
// SafetyPeriod and pending L2Txs that have been in the pool
// for longer than TTL once there are MaxTxs.
@@ -168,7 +168,7 @@ type Coordinator struct {
MaxGasPrice *big.Int `validate:"required"`
// GasPriceIncPerc is the percentage increase of gas price set
// in an ethereum transaction from the suggested gas price by
// the ehtereum node
// the ethereum node
GasPriceIncPerc int64
// CheckLoopInterval is the waiting interval between receipt
// checks of ethereum transactions in the TxManager

View File

@@ -8,6 +8,7 @@ import (
"path"
"time"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/core/types"
"github.com/hermeznetwork/hermez-node/common"
"github.com/hermeznetwork/hermez-node/eth"
@@ -90,7 +91,7 @@ type BatchInfo struct {
L2Txs []common.L2Tx
CoordIdxs []common.Idx
ForgeBatchArgs *eth.RollupForgeBatchArgs
// FeesInfo
Auth *bind.TransactOpts `json:"-"`
EthTx *types.Transaction
EthTxErr error
// SendTimestamp the time of batch sent to ethereum

View File

@@ -25,7 +25,8 @@ 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")
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")
)
@@ -53,7 +54,7 @@ type Config struct {
// checking the next block), used to decide when to stop scheduling new
// batches (by stopping the pipeline).
// For example, if we are at block 10 and ScheduleBatchBlocksAheadCheck
// is 5, eventhough at block 11 we canForge, the pipeline will be
// is 5, even though at block 11 we canForge, the pipeline will be
// stopped if we can't forge at block 15.
// This value should be the expected number of blocks it takes between
// scheduling a batch and having it mined.
@@ -63,7 +64,7 @@ type Config struct {
// from the next block; used to decide when to stop sending batches to
// the smart contract.
// For example, if we are at block 10 and SendBatchBlocksMarginCheck is
// 5, eventhough at block 11 we canForge, the batch will be discarded
// 5, even though at block 11 we canForge, the batch will be discarded
// if we can't forge at block 15.
// This value should be the expected number of blocks it takes between
// sending a batch and having it mined.
@@ -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

View File

@@ -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{
@@ -205,7 +206,7 @@ func newTestCoordinator(t *testing.T, forgerAddr ethCommon.Address, ethClient *t
func newTestSynchronizer(t *testing.T, ethClient *test.Client, ethClientSetup *test.ClientSetup,
modules modules) *synchronizer.Synchronizer {
sync, err := synchronizer.NewSynchronizer(ethClient, modules.historyDB, modules.stateDB,
sync, err := synchronizer.NewSynchronizer(ethClient, modules.historyDB, modules.l2DB, modules.stateDB,
synchronizer.Config{
StatsRefreshPeriod: 0 * time.Second,
})

View File

@@ -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():
@@ -209,7 +210,7 @@ func (p *Pipeline) handleForgeBatch(ctx context.Context,
return nil, ctx.Err()
} else if err != nil {
log.Errorw("proversPool.Get", "err", err)
return nil, err
return nil, tracerr.Wrap(err)
}
defer func() {
// If we encounter any error (notice that this function returns
@@ -239,7 +240,7 @@ func (p *Pipeline) handleForgeBatch(ctx context.Context,
} else {
log.Errorw("forgeBatch", "err", err)
}
return nil, err
return nil, tracerr.Wrap(err)
}
// 3. Send the ZKInputs to the proof server
@@ -248,7 +249,7 @@ func (p *Pipeline) handleForgeBatch(ctx context.Context,
return nil, ctx.Err()
} else if err != nil {
log.Errorw("sendServerProof", "err", err)
return nil, err
return nil, tracerr.Wrap(err)
}
return batchInfo, nil
}
@@ -406,11 +407,6 @@ func (p *Pipeline) forgeBatch(batchNum common.BatchNum) (batchInfo *BatchInfo, e
batchInfo.Debug.StartTimestamp = now
batchInfo.Debug.StartBlockNum = p.stats.Eth.LastBlock.Num + 1
selectionCfg := &txselector.SelectionConfig{
MaxL1UserTxs: common.RollupConstMaxL1UserTx,
TxProcessorConfig: p.cfg.TxProcessorConfig,
}
var poolL2Txs []common.PoolL2Tx
var discardedL2Txs []common.PoolL2Tx
var l1UserTxsExtra, l1CoordTxs []common.L1Tx
@@ -426,7 +422,7 @@ func (p *Pipeline) forgeBatch(batchNum common.BatchNum) (batchInfo *BatchInfo, e
// If we haven't reached the ForgeDelay, skip forging the batch
if slotCommitted && now.Sub(p.lastForgeTime) < p.cfg.ForgeDelay {
return nil, errForgeBeforeDelay
return nil, tracerr.Wrap(errForgeBeforeDelay)
}
// 1. Decide if we forge L2Tx or L1+L2Tx
@@ -441,14 +437,14 @@ func (p *Pipeline) forgeBatch(batchNum common.BatchNum) (batchInfo *BatchInfo, e
return nil, tracerr.Wrap(err)
}
coordIdxs, auths, l1UserTxsExtra, l1CoordTxs, poolL2Txs, discardedL2Txs, err =
p.txSelector.GetL1L2TxSelection(selectionCfg, l1UserTxs)
p.txSelector.GetL1L2TxSelection(p.cfg.TxProcessorConfig, l1UserTxs)
if err != nil {
return nil, tracerr.Wrap(err)
}
} else {
// 2b: only L2 txs
coordIdxs, auths, l1CoordTxs, poolL2Txs, discardedL2Txs, err =
p.txSelector.GetL2TxSelection(selectionCfg)
p.txSelector.GetL2TxSelection(p.cfg.TxProcessorConfig)
if err != nil {
return nil, tracerr.Wrap(err)
}
@@ -462,17 +458,18 @@ func (p *Pipeline) forgeBatch(batchNum common.BatchNum) (batchInfo *BatchInfo, e
noTxs := false
if len(l1UserTxsExtra) == 0 && len(l1CoordTxs) == 0 && len(poolL2Txs) == 0 {
if batchInfo.L1Batch {
// Query the L1UserTxs in the queue following
// the one we are trying to forge.
nextL1UserTxs, err := p.historyDB.GetUnforgedL1UserTxs(
p.state.lastForgeL1TxsNum + 1)
// Query the number of unforged L1UserTxs
// (either in a open queue or in a frozen
// not-yet-forged queue).
count, err := p.historyDB.GetUnforgedL1UserTxsCount()
if err != nil {
return nil, tracerr.Wrap(err)
}
// If there are future L1UserTxs, we forge a
// batch to advance the queues and forge the
// L1UserTxs in the future. Otherwise, skip.
if len(nextL1UserTxs) == 0 {
// batch to advance the queues to be able to
// forge the L1UserTxs in the future.
// Otherwise, skip.
if count == 0 {
noTxs = true
}
} else {
@@ -483,7 +480,7 @@ func (p *Pipeline) forgeBatch(batchNum common.BatchNum) (batchInfo *BatchInfo, e
if err := p.txSelector.Reset(batchInfo.BatchNum-1, false); err != nil {
return nil, tracerr.Wrap(err)
}
return nil, errForgeNoTxsBeforeDelay
return nil, tracerr.Wrap(errForgeNoTxsBeforeDelay)
}
}
@@ -499,14 +496,15 @@ 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 {
return nil, tracerr.Wrap(err)
}
// Invalidate transactions that become invalid beause of
// Invalidate transactions that become invalid because of
// the poolL2Txs selected. Will mark as invalid the txs that have a
// (fromIdx, nonce) which already appears in the selected txs (includes
// all the nonces smaller than the current one)
@@ -543,7 +541,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)
}

View File

@@ -140,7 +140,7 @@ func preloadSync(t *testing.T, ethClient *test.Client, sync *synchronizer.Synchr
blocks[0].Rollup.Batches[0].Batch.StateRoot =
newBigInt("0")
blocks[0].Rollup.Batches[1].Batch.StateRoot =
newBigInt("10941365282189107056349764238909072001483688090878331371699519307087372995595")
newBigInt("6860514559199319426609623120853503165917774887908204288119245630904770452486")
ethAddTokens(blocks, ethClient)
err = ethClient.CtlAddBlocks(blocks)

View File

@@ -14,7 +14,7 @@ import (
// PurgerCfg is the purger configuration
type PurgerCfg struct {
// PurgeBatchDelay is the delay between batches to purge outdated
// transactions. Oudated L2Txs are those that have been forged or
// transactions. Outdated L2Txs are those that have been forged or
// marked as invalid for longer than the SafetyPeriod and pending L2Txs
// that have been in the pool for longer than TTL once there are
// MaxTxs.
@@ -23,7 +23,7 @@ type PurgerCfg struct {
// transactions due to nonce lower than the account nonce.
InvalidateBatchDelay int64
// PurgeBlockDelay is the delay between blocks to purge outdated
// transactions. Oudated L2Txs are those that have been forged or
// transactions. Outdated L2Txs are those that have been forged or
// marked as invalid for longer than the SafetyPeriod and pending L2Txs
// that have been in the pool for longer than TTL once there are
// MaxTxs.

View File

@@ -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)
@@ -66,7 +67,7 @@ func NewTxManager(ctx context.Context, cfg *Config, ethClient eth.ClientInterfac
}
accNonce, err := ethClient.EthNonceAt(ctx, *address, nil)
if err != nil {
return nil, err
return nil, tracerr.Wrap(err)
}
log.Infow("TxManager started", "nonce", accNonce)
return &TxManager{
@@ -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():
@@ -182,19 +184,30 @@ func addPerc(v *big.Int, p int64) *big.Int {
r.Mul(r, big.NewInt(p))
// nolint reason: to calculate percentages we divide by 100
r.Div(r, big.NewInt(100)) //nolit:gomnd
// If the increase is 0, force it to be 1 so that a gas increase
// doesn't result in the same value, making the transaction to be equal
// than before.
if r.Cmp(big.NewInt(0)) == 0 {
r = big.NewInt(1)
}
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
auth, err := t.NewAuth(ctx, batchInfo)
var auth *bind.TransactOpts
if resend {
auth = batchInfo.Auth
auth.GasPrice = addPerc(auth.GasPrice, 10)
} else {
auth, err = t.NewAuth(ctx, batchInfo)
if err != nil {
return tracerr.Wrap(err)
}
batchInfo.Auth = auth
auth.Nonce = big.NewInt(int64(t.accNextNonce))
if resend {
auth.Nonce = big.NewInt(int64(batchInfo.EthTx.Nonce()))
}
for attempt := 0; attempt < t.cfg.EthClientAttempts; attempt++ {
if auth.GasPrice.Cmp(t.cfg.MaxGasPrice) > 0 {
@@ -265,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
@@ -297,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)
@@ -487,7 +503,7 @@ func (t *TxManager) Run(ctx context.Context) {
// Our ethNode is giving an error different
// than "not found" when getting the receipt
// for the transaction, so we can't figure out
// if it was not mined, mined and succesfull or
// if it was not mined, mined and successful or
// mined and failed. This could be due to the
// ethNode failure.
t.coord.SendMsg(ctx, MsgStopPipeline{
@@ -552,7 +568,7 @@ func (t *TxManager) removeBadBatchInfos(ctx context.Context) error {
// Our ethNode is giving an error different
// than "not found" when getting the receipt
// for the transaction, so we can't figure out
// if it was not mined, mined and succesfull or
// if it was not mined, mined and successful or
// mined and failed. This could be due to the
// ethNode failure.
next++

View File

@@ -1010,7 +1010,8 @@ func (hdb *HistoryDB) GetMetricsAPI(lastBatchNum common.BatchNum) (*Metrics, err
}
err = meddler.QueryRow(
hdb.dbRead, metrics,
`SELECT COALESCE (AVG(EXTRACT(EPOCH FROM (forged.timestamp - added.timestamp))), 0) AS estimatedTimeToForgeL1 FROM tx
`SELECT COALESCE (AVG(EXTRACT(EPOCH FROM (forged.timestamp - added.timestamp))), 0)
AS estimated_time_to_forge_l1 FROM tx
INNER JOIN block AS added ON tx.eth_block_num = added.eth_block_num
INNER JOIN batch AS forged_batch ON tx.batch_num = forged_batch.batch_num
INNER JOIN block AS forged ON forged_batch.eth_block_num = forged.eth_block_num
@@ -1069,7 +1070,8 @@ func (hdb *HistoryDB) GetCommonAccountAPI(idx common.Idx) (*common.Account, erro
defer hdb.apiConnCon.Release()
account := &common.Account{}
err = meddler.QueryRow(
hdb.dbRead, account, `SELECT * FROM account WHERE idx = $1;`, idx,
hdb.dbRead, account, `SELECT idx, token_id, batch_num, bjj, eth_addr
FROM account WHERE idx = $1;`, idx,
)
return account, tracerr.Wrap(err)
}

View File

@@ -179,7 +179,7 @@ func (hdb *HistoryDB) GetBatch(batchNum common.BatchNum) (*common.Batch, error)
batch.slot_num, batch.total_fees_usd FROM batch WHERE batch_num = $1;`,
batchNum,
)
return &batch, err
return &batch, tracerr.Wrap(err)
}
// GetAllBatches retrieve all batches from the DB
@@ -235,7 +235,7 @@ func (hdb *HistoryDB) GetLastBatch() (*common.Batch, error) {
batch.num_accounts, batch.last_idx, batch.exit_root, batch.forge_l1_txs_num,
batch.slot_num, batch.total_fees_usd FROM batch ORDER BY batch_num DESC LIMIT 1;`,
)
return &batch, err
return &batch, tracerr.Wrap(err)
}
// GetLastL1BatchBlockNum returns the blockNum of the latest forged l1Batch
@@ -486,23 +486,14 @@ func (hdb *HistoryDB) GetAllTokens() ([]TokenWithUSD, error) {
return db.SlicePtrsToSlice(tokens).([]TokenWithUSD), tracerr.Wrap(err)
}
// GetTokenSymbols returns all the token symbols from the DB
func (hdb *HistoryDB) GetTokenSymbols() ([]string, error) {
var tokenSymbols []string
rows, err := hdb.dbRead.Query("SELECT symbol FROM token;")
if err != nil {
return nil, tracerr.Wrap(err)
}
defer db.RowsClose(rows)
sym := new(string)
for rows.Next() {
err = rows.Scan(sym)
if err != nil {
return nil, tracerr.Wrap(err)
}
tokenSymbols = append(tokenSymbols, *sym)
}
return tokenSymbols, nil
// GetTokenSymbolsAndAddrs returns all the token symbols and addresses from the DB
func (hdb *HistoryDB) GetTokenSymbolsAndAddrs() ([]TokenSymbolAndAddr, error) {
var tokens []*TokenSymbolAndAddr
err := meddler.QueryAll(
hdb.dbRead, &tokens,
"SELECT symbol, eth_addr FROM token;",
)
return db.SlicePtrsToSlice(tokens).([]TokenSymbolAndAddr), tracerr.Wrap(err)
}
// AddAccounts insert accounts into the DB
@@ -763,6 +754,16 @@ func (hdb *HistoryDB) GetUnforgedL1UserTxs(toForgeL1TxsNum int64) ([]common.L1Tx
return db.SlicePtrsToSlice(txs).([]common.L1Tx), tracerr.Wrap(err)
}
// GetUnforgedL1UserTxsCount returns the count of unforged L1Txs (either in
// open or frozen queues that are not yet forged)
func (hdb *HistoryDB) GetUnforgedL1UserTxsCount() (int, error) {
row := hdb.dbRead.QueryRow(
`SELECT COUNT(*) FROM tx WHERE batch_num IS NULL;`,
)
var count int
return count, tracerr.Wrap(row.Scan(&count))
}
// TODO: Think about chaning all the queries that return a last value, to queries that return the next valid value.
// GetLastTxsPosition for a given to_forge_l1_txs_num

View File

@@ -43,7 +43,7 @@ func TestMain(m *testing.M) {
if err != nil {
panic(err)
}
apiConnCon := dbUtils.NewAPICnnectionController(1, time.Second)
apiConnCon := dbUtils.NewAPIConnectionController(1, time.Second)
historyDBWithACC = NewHistoryDB(db, db, apiConnCon)
// Run tests
result := m.Run()
@@ -720,6 +720,10 @@ func TestGetUnforgedL1UserTxs(t *testing.T) {
assert.Equal(t, 5, len(l1UserTxs))
assert.Equal(t, blocks[0].Rollup.L1UserTxs, l1UserTxs)
count, err := historyDB.GetUnforgedL1UserTxsCount()
require.NoError(t, err)
assert.Equal(t, 5, count)
// No l1UserTxs for this toForgeL1TxsNum
l1UserTxs, err = historyDB.GetUnforgedL1UserTxs(2)
require.NoError(t, err)

View File

@@ -147,6 +147,12 @@ type txWrite struct {
Nonce *common.Nonce `meddler:"nonce"`
}
// TokenSymbolAndAddr token representation with only Eth addr and symbol
type TokenSymbolAndAddr struct {
Symbol string `meddler:"symbol"`
Addr ethCommon.Address `meddler:"eth_addr"`
}
// TokenWithUSD add USD info to common.Token
type TokenWithUSD struct {
ItemID uint64 `json:"itemId" meddler:"item_id"`
@@ -310,7 +316,7 @@ type Metrics struct {
TotalAccounts int64 `json:"totalAccounts" meddler:"total_accounts"`
TotalBJJs int64 `json:"totalBJJs" meddler:"total_bjjs"`
AvgTransactionFee float64 `json:"avgTransactionFee"`
EstimatedTimeToForgeL1 float64 `json:"estimatedTimeToForgeL1" meddler:"estimatedTimeToForgeL1"`
EstimatedTimeToForgeL1 float64 `json:"estimatedTimeToForgeL1" meddler:"estimated_time_to_forge_l1"`
}
// MetricsTotals is used to get temporal information from HistoryDB

View File

@@ -316,7 +316,7 @@ func (k *KVDB) ResetFromSynchronizer(batchNum common.BatchNum, synchronizerKVDB
checkpointPath := path.Join(k.cfg.Path, fmt.Sprintf("%s%d", PathBatchNum, batchNum))
// copy synchronizer'BatchNumX' to 'BatchNumX'
// copy synchronizer 'BatchNumX' to 'BatchNumX'
if err := synchronizerKVDB.MakeCheckpointFromTo(batchNum, checkpointPath); err != nil {
return tracerr.Wrap(err)
}
@@ -458,7 +458,7 @@ func (k *KVDB) CheckpointExists(batchNum common.BatchNum) (bool, error) {
if _, err := os.Stat(source); os.IsNotExist(err) {
return false, nil
} else if err != nil {
return false, err
return false, tracerr.Wrap(err)
}
return true, nil
}
@@ -544,10 +544,12 @@ func (k *KVDB) MakeCheckpointFromTo(fromBatchNum common.BatchNum, dest string) e
// synchronizer to the same batchNum
k.m.Lock()
defer k.m.Unlock()
return pebbleMakeCheckpoint(source, dest)
return PebbleMakeCheckpoint(source, dest)
}
func pebbleMakeCheckpoint(source, dest string) error {
// PebbleMakeCheckpoint is a hepler function to make a pebble checkpoint from
// source to dest.
func PebbleMakeCheckpoint(source, dest string) error {
// Remove dest folder (if it exists) before doing the checkpoint
if _, err := os.Stat(dest); os.IsNotExist(err) {
} else if err != nil {

View File

@@ -74,6 +74,16 @@ func (l2db *L2DB) AddAccountCreationAuth(auth *common.AccountCreationAuth) error
return tracerr.Wrap(err)
}
// AddManyAccountCreationAuth inserts a batch of accounts creation authorization
// if not exist into the DB
func (l2db *L2DB) AddManyAccountCreationAuth(auths []common.AccountCreationAuth) error {
_, err := sqlx.NamedExec(l2db.dbWrite,
`INSERT INTO account_creation_auth (eth_addr, bjj, signature)
VALUES (:ethaddr, :bjj, :signature)
ON CONFLICT (eth_addr) DO NOTHING`, auths)
return tracerr.Wrap(err)
}
// GetAccountCreationAuth returns an account creation authorization from the DB
func (l2db *L2DB) GetAccountCreationAuth(addr ethCommon.Address) (*common.AccountCreationAuth, error) {
auth := new(common.AccountCreationAuth)
@@ -310,7 +320,7 @@ func (l2db *L2DB) InvalidateOldNonces(updatedAccounts []common.IdxNonce, batchNu
return nil
}
// Fill the batch_num in the query with Sprintf because we are using a
// named query which works with slices, and doens't handle an extra
// named query which works with slices, and doesn't handle an extra
// individual argument.
query := fmt.Sprintf(invalidateOldNoncesQuery, batchNum)
if _, err := sqlx.NamedExec(l2db.dbWrite, query, updatedAccounts); err != nil {

View File

@@ -38,7 +38,7 @@ func TestMain(m *testing.M) {
panic(err)
}
l2DB = NewL2DB(db, db, 10, 1000, 0.0, 24*time.Hour, nil)
apiConnCon := dbUtils.NewAPICnnectionController(1, time.Second)
apiConnCon := dbUtils.NewAPIConnectionController(1, time.Second)
l2DBWithACC = NewL2DB(db, db, 10, 1000, 0.0, 24*time.Hour, apiConnCon)
test.WipeDB(l2DB.DB())
historyDB = historydb.NewHistoryDB(db, db, nil)
@@ -725,6 +725,43 @@ func TestAuth(t *testing.T) {
}
}
func TestManyAuth(t *testing.T) {
test.WipeDB(l2DB.DB())
const nAuths = 5
chainID := uint16(0)
hermezContractAddr := ethCommon.HexToAddress("0xc344E203a046Da13b0B4467EB7B3629D0C99F6E6")
// Generate authorizations
genAuths := test.GenAuths(nAuths, chainID, hermezContractAddr)
auths := make([]common.AccountCreationAuth, len(genAuths))
// Convert to a non-pointer slice
for i := 0; i < len(genAuths); i++ {
auths[i] = *genAuths[i]
}
// Add a duplicate one to check the not exist condition
err := l2DB.AddAccountCreationAuth(genAuths[0])
require.NoError(t, err)
// Add to the DB
err = l2DB.AddManyAccountCreationAuth(auths)
require.NoError(t, err)
// Assert the result
for i := 0; i < len(auths); i++ {
// Fetch from DB
auth, err := l2DB.GetAccountCreationAuth(auths[i].EthAddr)
require.NoError(t, err)
// Check fetched vs generated
assert.Equal(t, auths[i].EthAddr, auth.EthAddr)
assert.Equal(t, auths[i].BJJ, auth.BJJ)
assert.Equal(t, auths[i].Signature, auth.Signature)
assert.Equal(t, auths[i].Timestamp.Unix(), auths[i].Timestamp.Unix())
nameZone, offset := auths[i].Timestamp.Zone()
assert.Equal(t, "UTC", nameZone)
assert.Equal(t, 0, offset)
}
}
func TestAddGet(t *testing.T) {
err := prepareHistoryDB(historyDB)
if err != nil {

View File

@@ -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 {
@@ -503,7 +510,7 @@ func (l *LocalStateDB) CheckpointExists(batchNum common.BatchNum) (bool, error)
return l.db.CheckpointExists(batchNum)
}
// Reset performs a reset in the LocaStateDB. If fromSynchronizer is true, it
// Reset performs a reset in the LocalStateDB. If fromSynchronizer is true, it
// gets the state from LocalStateDB.synchronizerStateDB for the given batchNum.
// If fromSynchronizer is false, get the state from LocalStateDB checkpoints.
func (l *LocalStateDB) Reset(batchNum common.BatchNum, fromSynchronizer bool) error {

View File

@@ -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,
"13174362770971232417413036794215823584762073355951212910715422236001731746065",
sdb.MT.Root().BigInt().String())
}
// TestListCheckpoints performs almost the same test than kvdb/kvdb_test.go

View File

@@ -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]
}

View File

@@ -93,8 +93,8 @@ type APIConnectionController struct {
timeout time.Duration
}
// NewAPICnnectionController initialize APIConnectionController
func NewAPICnnectionController(maxConnections int, timeout time.Duration) *APIConnectionController {
// NewAPIConnectionController initialize APIConnectionController
func NewAPIConnectionController(maxConnections int, timeout time.Duration) *APIConnectionController {
return &APIConnectionController{
smphr: semaphore.NewWeighted(int64(maxConnections)),
timeout: timeout,

View File

@@ -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)"))
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])"))
"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())

View File

@@ -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))

View File

@@ -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)
}

View File

@@ -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

View File

@@ -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

View File

@@ -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)
}

View File

@@ -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

View File

@@ -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()

View File

@@ -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,13 +396,20 @@ 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)"))
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

View File

@@ -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)

4
go.mod
View File

@@ -11,8 +11,8 @@ require (
github.com/gin-gonic/gin v1.5.0
github.com/gobuffalo/packr/v2 v2.8.1
github.com/hermeznetwork/tracerr v0.3.1-0.20210120162744-5da60b576169
github.com/iden3/go-iden3-crypto v0.0.6-0.20201221160344-58e589b6eb4c
github.com/iden3/go-merkletree v0.0.0-20210119155851-bb53e6ad1a12
github.com/iden3/go-iden3-crypto v0.0.6-0.20210308142348-8f85683b2cef
github.com/iden3/go-merkletree v0.0.0-20210308143313-8b63ca866189
github.com/jinzhu/copier v0.0.0-20190924061706-b57f9002281a
github.com/jmoiron/sqlx v1.2.1-0.20200615141059-0794cb1f47ee
github.com/joho/godotenv v1.3.0

19
go.sum
View File

@@ -24,8 +24,6 @@ github.com/DataDog/zstd v1.3.6-0.20190409195224-796139022798/go.mod h1:1jcaCB/uf
github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY=
github.com/Joker/jade v1.0.1-0.20190614124447-d475f43051e7/go.mod h1:6E6s8o2AE4KhCrqr6GRJjdC/gNfTdxkIXvuGZZda2VM=
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc=
github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/OneOfOne/xxhash v1.2.5/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q=
github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0=
@@ -87,8 +85,6 @@ github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QH
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/cp v0.1.0 h1:SE+dxFebS7Iik5LK0tsi1k9ZCxEaFX4AjQmoyA+1dJk=
github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s=
github.com/cespare/cp v1.1.1 h1:nCb6ZLdB7NRaqsm91JtQTAme2SKJzXVsdPIPkyJr1MU=
github.com/cespare/cp v1.1.1/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s=
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/cespare/xxhash/v2 v2.0.1-0.20190104013014-3767db7a7e18/go.mod h1:HD5P3vAIAh+Y2GAxg0PrPN1P8WkepXGpjbUPDHJqqKM=
@@ -174,8 +170,6 @@ github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5Kwzbycv
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
github.com/fjl/memsize v0.0.0-20180418122429-ca190fb6ffbc h1:jtW8jbpkO4YirRSyepBOH8E+2HEw6/hKkBvFPwhUN8c=
github.com/fjl/memsize v0.0.0-20180418122429-ca190fb6ffbc/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0=
github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 h1:FtmdgXiUlNeRsoNMFlKLDt+S+6hbjVMEW6RGQ7aUf7c=
github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0=
github.com/flosch/pongo2 v0.0.0-20190707114632-bbf5a6c351f4/go.mod h1:T9YF2M40nIgbVgp3rreNmTged+9HrbNTIQf1PsaIiTA=
github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4=
github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20=
@@ -336,11 +330,10 @@ github.com/huin/goupnp v1.0.0 h1:wg75sLpL6DZqwHQN6E1Cfk6mtfzS45z8OV+ic+DtHRo=
github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc=
github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o=
github.com/hydrogen18/memlistener v0.0.0-20141126152155-54553eb933fb/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE=
github.com/iden3/go-iden3-crypto v0.0.6-0.20201218111145-a2015adb2f1b/go.mod h1:oBgthFLboAWi9feaBUFy7OxEcyn9vA1khHSL/WwWFyg=
github.com/iden3/go-iden3-crypto v0.0.6-0.20201221160344-58e589b6eb4c h1:D2u8FFYey6iFXLsqqJZ8R7ch8gZum+/b98whvoSDbyg=
github.com/iden3/go-iden3-crypto v0.0.6-0.20201221160344-58e589b6eb4c/go.mod h1:oBgthFLboAWi9feaBUFy7OxEcyn9vA1khHSL/WwWFyg=
github.com/iden3/go-merkletree v0.0.0-20210119155851-bb53e6ad1a12 h1:DXWT0BLCSm7cJmTMQy7+iOlxkA1/5ADglufhLK52e10=
github.com/iden3/go-merkletree v0.0.0-20210119155851-bb53e6ad1a12/go.mod h1:FdUFTW2qJiwHyy5R70uErwq7Kaq1uskyFdTfodcUJqA=
github.com/iden3/go-iden3-crypto v0.0.6-0.20210308142348-8f85683b2cef h1:72PG9b2eDlLqKszJVLrsoJbpt4CtgJLhKOjH1MJqCVY=
github.com/iden3/go-iden3-crypto v0.0.6-0.20210308142348-8f85683b2cef/go.mod h1:oBgthFLboAWi9feaBUFy7OxEcyn9vA1khHSL/WwWFyg=
github.com/iden3/go-merkletree v0.0.0-20210308143313-8b63ca866189 h1:hoarWk/SwNwnMXE0kiskcZULW0XBLQIUGYK4C39ozfs=
github.com/iden3/go-merkletree v0.0.0-20210308143313-8b63ca866189/go.mod h1:56abMeBKD4BIFe346rk+yuJ4MQgfMHe28sRx4o2gOpk=
github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/influxdata/influxdb v1.2.3-0.20180221223340-01288bdb0883/go.mod h1:qZna6X/4elxqT3yI9iZYdZrWWdeFOOprn86kgg4+IzY=
@@ -608,8 +601,6 @@ github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeV
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/sirupsen/logrus v1.5.0 h1:1N5EYkVAPEywqZRJd7cwnRtCb6xJx7NH3T3WUTF980Q=
github.com/sirupsen/logrus v1.5.0/go.mod h1:+F7Ogzej0PZc/94MaYx/nvG9jOFMD2osvC3s+Squfpo=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
@@ -628,8 +619,6 @@ github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DM
github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4 h1:Gb2Tyox57NRNuZ2d3rmvB3pcmbu7O1RS3m8WRx7ilrg=
github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4/go.mod h1:RZLeN1LMWmRsyYjvAu+I6Dm9QmlDaIIt+Y+4Kd7Tp+Q=
github.com/status-im/keycard-go v0.0.0-20190424133014-d95853db0f48 h1:ju5UTwk5Odtm4trrY+4Ca4RMj5OyXbmVeDAVad2T0Jw=
github.com/status-im/keycard-go v0.0.0-20190424133014-d95853db0f48/go.mod h1:RZLeN1LMWmRsyYjvAu+I6Dm9QmlDaIIt+Y+4Kd7Tp+Q=
github.com/steakknife/bloomfilter v0.0.0-20180922174646-6819c0d2a570 h1:gIlAHnH1vJb5vwEjIp5kBj/eu99p/bl0Ay2goiPe5xE=
github.com/steakknife/bloomfilter v0.0.0-20180922174646-6819c0d2a570/go.mod h1:8OR4w3TdeIHIh1g6EMY5p0gVNOovcWC+1vpc7naMuAw=
github.com/steakknife/hamming v0.0.0-20180906055917-c99c65617cd3 h1:njlZPzLwU639dk2kqnCPPv+wNjq7Xb6EfUxe/oX0/NM=

View File

@@ -107,7 +107,7 @@ func NewNode(mode Mode, cfg *config.Node) (*Node, error) {
}
var apiConnCon *dbUtils.APIConnectionController
if cfg.API.Explorer || mode == ModeCoordinator {
apiConnCon = dbUtils.NewAPICnnectionController(
apiConnCon = dbUtils.NewAPIConnectionController(
cfg.API.MaxSQLConnections,
cfg.API.SQLConnectionTimeout.Duration,
)
@@ -146,12 +146,12 @@ func NewNode(mode Mode, cfg *config.Node) (*Node, error) {
if minForgeBalance != nil && balance.Cmp(minForgeBalance) == -1 {
return nil, tracerr.Wrap(fmt.Errorf(
"forger account balance is less than cfg.Coordinator.MinimumForgeAddressBalance: %v < %v",
balance.Int64(), minForgeBalance))
balance, minForgeBalance))
}
log.Infow("forger ethereum account balance",
"addr", cfg.Coordinator.ForgerAddress,
"balance", balance.Int64(),
"minForgeBalance", minForgeBalance.Int64(),
"balance", balance,
"minForgeBalance", minForgeBalance,
)
// Unlock Coordinator ForgerAddr in the keystore to make calls
@@ -220,7 +220,19 @@ func NewNode(mode Mode, cfg *config.Node) (*Node, error) {
return nil, tracerr.Wrap(err)
}
sync, err := synchronizer.NewSynchronizer(client, historyDB, stateDB, synchronizer.Config{
var l2DB *l2db.L2DB
if mode == ModeCoordinator {
l2DB = l2db.NewL2DB(
dbRead, dbWrite,
cfg.Coordinator.L2DB.SafetyPeriod,
cfg.Coordinator.L2DB.MaxTxs,
cfg.Coordinator.L2DB.MinFeeUSD,
cfg.Coordinator.L2DB.TTL.Duration,
apiConnCon,
)
}
sync, err := synchronizer.NewSynchronizer(client, historyDB, l2DB, stateDB, synchronizer.Config{
StatsRefreshPeriod: cfg.Synchronizer.StatsRefreshPeriod.Duration,
ChainID: chainIDU16,
})
@@ -236,17 +248,7 @@ func NewNode(mode Mode, cfg *config.Node) (*Node, error) {
}
var coord *coordinator.Coordinator
var l2DB *l2db.L2DB
if mode == ModeCoordinator {
l2DB = l2db.NewL2DB(
dbRead, dbWrite,
cfg.Coordinator.L2DB.SafetyPeriod,
cfg.Coordinator.L2DB.MaxTxs,
cfg.Coordinator.L2DB.MinFeeUSD,
cfg.Coordinator.L2DB.TTL.Duration,
apiConnCon,
)
// Unlock FeeAccount EthAddr in the keystore to generate the
// account creation authorization
if !keyStore.HasAddress(cfg.Coordinator.FeeAccount.Address) {
@@ -268,14 +270,15 @@ func NewNode(mode Mode, cfg *config.Node) (*Node, error) {
if err := auth.Sign(func(msg []byte) ([]byte, error) {
return keyStore.SignHash(feeAccount, msg)
}, chainIDU16, cfg.SmartContracts.Rollup); err != nil {
return nil, err
return nil, tracerr.Wrap(err)
}
coordAccount := &txselector.CoordAccount{
Addr: cfg.Coordinator.FeeAccount.Address,
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)
}
@@ -490,8 +493,8 @@ func NewNodeAPI(
}, nil
}
// Run starts the http server of the NodeAPI. To stop it, pass a context with
// cancelation.
// Run starts the http server of the NodeAPI. To stop it, pass a context
// with cancellation.
func (a *NodeAPI) Run(ctx context.Context) error {
server := &http.Server{
Handler: a.engine,
@@ -523,8 +526,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 +562,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 +583,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 {

View File

@@ -4,9 +4,12 @@ import (
"context"
"fmt"
"net/http"
"strings"
"time"
"github.com/dghubble/sling"
ethCommon "github.com/ethereum/go-ethereum/common"
"github.com/hermeznetwork/hermez-node/common"
"github.com/hermeznetwork/hermez-node/db/historydb"
"github.com/hermeznetwork/hermez-node/log"
"github.com/hermeznetwork/tracerr"
@@ -23,12 +26,16 @@ type APIType string
const (
// APITypeBitFinexV2 is the http API used by bitfinex V2
APITypeBitFinexV2 APIType = "bitfinexV2"
// APITypeCoingeckoV3 is the http API used by copingecko V3
APITypeCoingeckoV3 APIType = "coingeckoV3"
)
func (t *APIType) valid() bool {
switch *t {
case APITypeBitFinexV2:
return true
case APITypeCoingeckoV3:
return true
default:
return false
}
@@ -39,12 +46,12 @@ type PriceUpdater struct {
db *historydb.HistoryDB
apiURL string
apiType APIType
tokenSymbols []string
tokens []historydb.TokenSymbolAndAddr
}
// NewPriceUpdater is the constructor for the updater
func NewPriceUpdater(apiURL string, apiType APIType, db *historydb.HistoryDB) (*PriceUpdater, error) {
tokenSymbols := []string{}
func NewPriceUpdater(apiURL string, apiType APIType, db *historydb.HistoryDB) (*PriceUpdater,
error) {
if !apiType.valid() {
return nil, tracerr.Wrap(fmt.Errorf("Invalid apiType: %v", apiType))
}
@@ -52,7 +59,7 @@ func NewPriceUpdater(apiURL string, apiType APIType, db *historydb.HistoryDB) (*
db: db,
apiURL: apiURL,
apiType: apiType,
tokenSymbols: tokenSymbols,
tokens: []historydb.TokenSymbolAndAddr{},
}, nil
}
@@ -73,7 +80,39 @@ 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
func getTokenPriceCoingecko(ctx context.Context, client *sling.Sling,
tokenAddr ethCommon.Address) (float64, error) {
responseObject := make(map[string]map[string]float64)
var url string
var id string
if tokenAddr == common.EmptyAddr { // Special case for Ether
url = "simple/price?ids=ethereum&vs_currencies=usd"
id = "ethereum"
} else { // Common case (ERC20)
id = strings.ToLower(tokenAddr.String())
url = "simple/token_price/ethereum?contract_addresses=" +
id + "&vs_currencies=usd"
}
req, err := client.New().Get(url).Request()
if err != nil {
return 0, tracerr.Wrap(err)
}
res, err := client.Do(req.WithContext(ctx), &responseObject, nil)
if err != nil {
return 0, tracerr.Wrap(err)
}
if res.StatusCode != http.StatusOK {
return 0, tracerr.Wrap(fmt.Errorf("http response is not is %v", res.StatusCode))
}
price := responseObject[id]["usd"]
if price <= 0 {
return 0, tracerr.Wrap(fmt.Errorf("price not found for %v", id))
}
return price, nil
}
// 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,
@@ -83,33 +122,35 @@ func (p *PriceUpdater) UpdatePrices(ctx context.Context) {
httpClient := &http.Client{Transport: tr}
client := sling.New().Base(p.apiURL).Client(httpClient)
for _, tokenSymbol := range p.tokenSymbols {
for _, token := range p.tokens {
var tokenPrice float64
var err error
switch p.apiType {
case APITypeBitFinexV2:
tokenPrice, err = getTokenPriceBitfinex(ctx, client, tokenSymbol)
tokenPrice, err = getTokenPriceBitfinex(ctx, client, token.Symbol)
case APITypeCoingeckoV3:
tokenPrice, err = getTokenPriceCoingecko(ctx, client, token.Addr)
}
if ctx.Err() != nil {
return
}
if err != nil {
log.Warnw("token price not updated (get error)",
"err", err, "token", tokenSymbol, "apiType", p.apiType)
"err", err, "token", token.Symbol, "apiType", p.apiType)
}
if err = p.db.UpdateTokenValue(tokenSymbol, tokenPrice); err != nil {
if err = p.db.UpdateTokenValue(token.Symbol, tokenPrice); err != nil {
log.Errorw("token price not updated (db error)",
"err", err, "token", tokenSymbol, "apiType", p.apiType)
"err", err, "token", token.Symbol, "apiType", p.apiType)
}
}
}
// UpdateTokenList get the registered token symbols from HistoryDB
func (p *PriceUpdater) UpdateTokenList() error {
tokenSymbols, err := p.db.GetTokenSymbols()
tokens, err := p.db.GetTokenSymbolsAndAddrs()
if err != nil {
return tracerr.Wrap(err)
}
p.tokenSymbols = tokenSymbols
p.tokens = tokens
return nil
}

View File

@@ -2,7 +2,6 @@ package priceupdater
import (
"context"
"math/big"
"os"
"testing"
@@ -15,29 +14,45 @@ import (
"github.com/stretchr/testify/require"
)
func TestPriceUpdater(t *testing.T) {
var historyDB *historydb.HistoryDB
func TestMain(m *testing.M) {
// Init DB
pass := os.Getenv("POSTGRES_PASS")
db, err := dbUtils.InitSQLDB(5432, "localhost", "hermez", pass, "hermez")
assert.NoError(t, err)
historyDB := historydb.NewHistoryDB(db, db, nil)
if err != nil {
panic(err)
}
historyDB = historydb.NewHistoryDB(db, db, nil)
// Clean DB
test.WipeDB(historyDB.DB())
// Populate DB
// Gen blocks and add them to DB
blocks := test.GenBlocks(1, 2)
assert.NoError(t, historyDB.AddBlocks(blocks))
err = historyDB.AddBlocks(blocks)
if err != nil {
panic(err)
}
// Gen tokens and add them to DB
tokens := []common.Token{}
tokens = append(tokens, common.Token{
TokenID: 1,
EthBlockNum: blocks[0].Num,
EthAddr: ethCommon.BigToAddress(big.NewInt(2)),
EthAddr: ethCommon.HexToAddress("0x6b175474e89094c44da98b954eedeac495271d0f"),
Name: "DAI",
Symbol: "DAI",
Decimals: 18,
})
assert.NoError(t, historyDB.AddTokens(tokens))
err = historyDB.AddTokens(tokens)
if err != nil {
panic(err)
}
result := m.Run()
os.Exit(result)
}
func TestPriceUpdaterBitfinex(t *testing.T) {
// Init price updater
pu, err := NewPriceUpdater("https://api-pub.bitfinex.com/v2/", APITypeBitFinexV2, historyDB)
require.NoError(t, err)
@@ -45,13 +60,29 @@ func TestPriceUpdater(t *testing.T) {
assert.NoError(t, pu.UpdateTokenList())
// Update prices
pu.UpdatePrices(context.Background())
assertTokenHasPriceAndClean(t)
}
func TestPriceUpdaterCoingecko(t *testing.T) {
// Init price updater
pu, err := NewPriceUpdater("https://api.coingecko.com/api/v3/", APITypeCoingeckoV3, historyDB)
require.NoError(t, err)
// Update token list
assert.NoError(t, pu.UpdateTokenList())
// Update prices
pu.UpdatePrices(context.Background())
assertTokenHasPriceAndClean(t)
}
func assertTokenHasPriceAndClean(t *testing.T) {
// Check that prices have been updated
fetchedTokens, err := historyDB.GetTokensTest()
require.NoError(t, err)
// TokenID 0 (ETH) is always on the DB
assert.Equal(t, 2, len(fetchedTokens))
for _, token := range fetchedTokens {
assert.NotNil(t, token.USD)
assert.NotNil(t, token.USDUpdate)
require.NotNil(t, token.USD)
require.NotNil(t, token.USDUpdate)
assert.Greater(t, *token.USD, 0.0)
}
}

View File

@@ -235,7 +235,7 @@ func (p *ProofServerClient) CalculateProof(ctx context.Context, zkInputs *common
return tracerr.Wrap(p.apiInput(ctx, zkInputs))
}
// GetProof retreives the Proof and Public Data (public inputs) from the
// GetProof retrieves the Proof and Public Data (public inputs) from the
// ServerProof, blocking until the proof is ready.
func (p *ProofServerClient) GetProof(ctx context.Context) (*Proof, []*big.Int, error) {
if err := p.WaitReady(ctx); err != nil {
@@ -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
@@ -297,7 +298,7 @@ func (p *MockClient) CalculateProof(ctx context.Context, zkInputs *common.ZKInpu
return nil
}
// GetProof retreives the Proof from the ServerProof
// GetProof retrieves the Proof from the ServerProof
func (p *MockClient) GetProof(ctx context.Context) (*Proof, []*big.Int, error) {
// Simulate a delay
select {

View File

@@ -11,6 +11,7 @@ import (
"github.com/ethereum/go-ethereum"
"github.com/hermeznetwork/hermez-node/common"
"github.com/hermeznetwork/hermez-node/db/historydb"
"github.com/hermeznetwork/hermez-node/db/l2db"
"github.com/hermeznetwork/hermez-node/db/statedb"
"github.com/hermeznetwork/hermez-node/eth"
"github.com/hermeznetwork/hermez-node/log"
@@ -31,7 +32,7 @@ var (
ErrUnknownBlock = fmt.Errorf("unknown block")
)
// Stats of the syncrhonizer
// Stats of the synchronizer
type Stats struct {
Eth struct {
RefreshPeriod time.Duration
@@ -215,6 +216,7 @@ type Synchronizer struct {
ethClient eth.ClientInterface
consts SCConsts
historyDB *historydb.HistoryDB
l2DB *l2db.L2DB
stateDB *statedb.StateDB
cfg Config
initVars SCVariables
@@ -226,7 +228,7 @@ type Synchronizer struct {
// NewSynchronizer creates a new Synchronizer
func NewSynchronizer(ethClient eth.ClientInterface, historyDB *historydb.HistoryDB,
stateDB *statedb.StateDB, cfg Config) (*Synchronizer, error) {
l2DB *l2db.L2DB, stateDB *statedb.StateDB, cfg Config) (*Synchronizer, error) {
auctionConstants, err := ethClient.AuctionConstants()
if err != nil {
return nil, tracerr.Wrap(fmt.Errorf("NewSynchronizer ethClient.AuctionConstants(): %w",
@@ -271,6 +273,7 @@ func NewSynchronizer(ethClient eth.ClientInterface, historyDB *historydb.History
ethClient: ethClient,
consts: consts,
historyDB: historyDB,
l2DB: l2DB,
stateDB: stateDB,
cfg: cfg,
initVars: *initVars,
@@ -347,7 +350,7 @@ func (s *Synchronizer) setSlotCoordinator(slot *common.Slot) error {
}
// updateCurrentSlot updates the slot with information of the current slot.
// The information abouth which coordinator is allowed to forge is only updated
// The information about which coordinator is allowed to forge is only updated
// when we are Synced.
// hasBatch is true when the last synced block contained at least one batch.
func (s *Synchronizer) updateCurrentSlot(slot *common.Slot, reset bool, hasBatch bool) error {
@@ -400,7 +403,7 @@ func (s *Synchronizer) updateCurrentSlot(slot *common.Slot, reset bool, hasBatch
}
// updateNextSlot updates the slot with information of the next slot.
// The information abouth which coordinator is allowed to forge is only updated
// The information about which coordinator is allowed to forge is only updated
// when we are Synced.
func (s *Synchronizer) updateNextSlot(slot *common.Slot) error {
// We want the next block because the current one is already mined
@@ -503,9 +506,9 @@ func (s *Synchronizer) resetIntermediateState() error {
return nil
}
// Sync attems to synchronize an ethereum block starting from lastSavedBlock.
// Sync attempts to synchronize an ethereum block starting from lastSavedBlock.
// If lastSavedBlock is nil, the lastSavedBlock value is obtained from de DB.
// If a block is synched, it will be returned and also stored in the DB. If a
// If a block is synced, it will be returned and also stored in the DB. If a
// reorg is detected, the number of discarded blocks will be returned and no
// synchronization will be made.
// TODO: Be smart about locking: only lock during the read/write operations
@@ -558,7 +561,7 @@ func (s *Synchronizer) Sync(ctx context.Context,
"ethLastBlock", s.stats.Eth.LastBlock,
)
// Check that the obtianed ethBlock.ParentHash == prevEthBlock.Hash; if not, reorg!
// Check that the obtained ethBlock.ParentHash == prevEthBlock.Hash; if not, reorg!
if lastSavedBlock != nil {
if lastSavedBlock.Hash != ethBlock.ParentHash {
// Reorg detected
@@ -578,7 +581,7 @@ func (s *Synchronizer) Sync(ctx context.Context,
// If there was an error during sync, reset to the last block
// in the historyDB because the historyDB is written last in
// the Sync method and is the source of consistency. This
// allows reseting the stateDB in the case a batch was
// allows resetting the stateDB in the case a batch was
// processed but the historyDB block was not committed due to an
// error.
if err != nil {
@@ -657,7 +660,7 @@ func (s *Synchronizer) Sync(ctx context.Context,
if len(rollupData.Batches) > 0 {
hasBatch = true
}
if err := s.updateCurrentNextSlotIfSync(false, hasBatch); err != nil {
if err = s.updateCurrentNextSlotIfSync(false, hasBatch); err != nil {
return nil, nil, tracerr.Wrap(err)
}
@@ -818,7 +821,7 @@ func (s *Synchronizer) resetState(block *common.Block) error {
return nil
}
// rollupSync retreives all the Rollup Smart Contract Data that happened at
// rollupSync retrieves all the Rollup Smart Contract Data that happened at
// ethBlock.blockNum with ethBlock.Hash.
func (s *Synchronizer) rollupSync(ethBlock *common.Block) (*common.RollupData, error) {
blockNum := ethBlock.Num
@@ -895,6 +898,9 @@ func (s *Synchronizer) rollupSync(ethBlock *common.Block) (*common.RollupData, e
position = len(l1UserTxs)
}
l1TxsAuth := make([]common.AccountCreationAuth,
0, len(forgeBatchArgs.L1CoordinatorTxsAuths))
// Get L1 Coordinator Txs
for i := range forgeBatchArgs.L1CoordinatorTxs {
l1CoordinatorTx := forgeBatchArgs.L1CoordinatorTxs[i]
@@ -910,9 +916,30 @@ func (s *Synchronizer) rollupSync(ethBlock *common.Block) (*common.RollupData, e
batchData.L1CoordinatorTxs = append(batchData.L1CoordinatorTxs, *l1Tx)
position++
// Create a slice of account creation auth to be
// inserted later if not exists
if l1CoordinatorTx.FromEthAddr != common.RollupConstEthAddressInternalOnly {
l1CoordinatorTxAuth := forgeBatchArgs.L1CoordinatorTxsAuths[i]
l1TxsAuth = append(l1TxsAuth, common.AccountCreationAuth{
EthAddr: l1CoordinatorTx.FromEthAddr,
BJJ: l1CoordinatorTx.FromBJJ,
Signature: l1CoordinatorTxAuth,
})
}
// fmt.Println("DGB l1coordtx")
}
// Insert the slice of account creation auth
// only if the node run as a coordinator
if s.l2DB != nil && len(l1TxsAuth) > 0 {
err = s.l2DB.AddManyAccountCreationAuth(l1TxsAuth)
if err != nil {
return nil, tracerr.Wrap(err)
}
}
// Insert all the txs forged in this batch (l1UserTxs,
// L1CoordinatorTxs, PoolL2Txs) into stateDB so that they are
// processed.
@@ -925,7 +952,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) >= "+

View File

@@ -15,6 +15,7 @@ import (
"github.com/hermeznetwork/hermez-node/common"
dbUtils "github.com/hermeznetwork/hermez-node/db"
"github.com/hermeznetwork/hermez-node/db/historydb"
"github.com/hermeznetwork/hermez-node/db/l2db"
"github.com/hermeznetwork/hermez-node/db/statedb"
"github.com/hermeznetwork/hermez-node/eth"
"github.com/hermeznetwork/hermez-node/test"
@@ -42,7 +43,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)
@@ -302,13 +304,14 @@ func TestMain(m *testing.M) {
os.Exit(exitVal)
}
func newTestModules(t *testing.T) (*statedb.StateDB, *historydb.HistoryDB) {
func newTestModules(t *testing.T) (*statedb.StateDB, *historydb.HistoryDB, *l2db.L2DB) {
// Int State DB
dir, err := ioutil.TempDir("", "tmpdb")
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
@@ -319,7 +322,10 @@ func newTestModules(t *testing.T) (*statedb.StateDB, *historydb.HistoryDB) {
// Clear DB
test.WipeDB(historyDB.DB())
return stateDB, historyDB
// Init L2 DB
l2DB := l2db.NewL2DB(db, db, 10, 100, 0.0, 24*time.Hour, nil)
return stateDB, historyDB, l2DB
}
func newBigInt(s string) *big.Int {
@@ -335,7 +341,7 @@ func TestSyncGeneral(t *testing.T) {
// Setup
//
stateDB, historyDB := newTestModules(t)
stateDB, historyDB, l2DB := newTestModules(t)
// Init eth client
var timer timer
@@ -345,7 +351,7 @@ func TestSyncGeneral(t *testing.T) {
client := test.NewClient(true, &timer, &ethCommon.Address{}, clientSetup)
// Create Synchronizer
s, err := NewSynchronizer(client, historyDB, stateDB, Config{
s, err := NewSynchronizer(client, historyDB, l2DB, stateDB, Config{
StatsRefreshPeriod: 0 * time.Second,
})
require.NoError(t, err)
@@ -444,9 +450,9 @@ func TestSyncGeneral(t *testing.T) {
require.Equal(t, 2, len(blocks[i].Rollup.Batches[0].L1CoordinatorTxs))
// Set StateRoots for batches manually (til doesn't set it)
blocks[i].Rollup.Batches[0].Batch.StateRoot =
newBigInt("18906357591508007884273218035694076596537737437965299189312069102730480717391")
newBigInt("11432094872416618651837327395264042968926668786266585816625577088890451620254")
blocks[i].Rollup.Batches[1].Batch.StateRoot =
newBigInt("9513185123401321669660637227182204000277156839501731093239187625486561933297")
newBigInt("16914212635847451457076355431350059348585556180740555407203882688922702410093")
// blocks 1 (blockNum=3)
i = 1
require.Equal(t, 3, int(blocks[i].Block.Num))
@@ -455,9 +461,9 @@ func TestSyncGeneral(t *testing.T) {
require.Equal(t, 3, len(blocks[i].Rollup.Batches[0].L2Txs))
// Set StateRoots for batches manually (til doesn't set it)
blocks[i].Rollup.Batches[0].Batch.StateRoot =
newBigInt("13060270878200012606074130020925677466793317216609491464427188889005039616594")
newBigInt("13535760140937349829640752733057594576151546047374619177689224612061148090678")
blocks[i].Rollup.Batches[1].Batch.StateRoot =
newBigInt("21427104994652624302859637783375978708867165042357535792408500519060088086054")
newBigInt("19413739476363469870744893742469056615496274423228302914851564791727474664804")
// Generate extra required data
ethAddTokens(blocks, client)
@@ -514,9 +520,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()
@@ -634,9 +642,9 @@ func TestSyncGeneral(t *testing.T) {
// Set StateRoots for batches manually (til doesn't set it)
blocks[0].Rollup.Batches[0].Batch.StateRoot =
newBigInt("11218510534825843475100588932060366395781087435899915642332104464234485046683")
newBigInt("14095767774967159269372103336737817266053275274769794195030162905513860477094")
blocks[0].Rollup.Batches[1].Batch.StateRoot =
newBigInt("20283020730369146334077598087403837297563965802277806438205710455191646998983")
newBigInt("2095674348545184674850951945506660952512376416769035169971006930847780339914")
for i := 0; i < 4; i++ {
client.CtlRollback()
@@ -723,7 +731,7 @@ func TestSyncGeneral(t *testing.T) {
}
func TestSyncForgerCommitment(t *testing.T) {
stateDB, historyDB := newTestModules(t)
stateDB, historyDB, l2DB := newTestModules(t)
// Init eth client
var timer timer
@@ -736,7 +744,7 @@ func TestSyncForgerCommitment(t *testing.T) {
client := test.NewClient(true, &timer, &ethCommon.Address{}, clientSetup)
// Create Synchronizer
s, err := NewSynchronizer(client, historyDB, stateDB, Config{
s, err := NewSynchronizer(client, historyDB, l2DB, stateDB, Config{
StatsRefreshPeriod: 0 * time.Second,
})
require.NoError(t, err)
@@ -819,7 +827,7 @@ func TestSyncForgerCommitment(t *testing.T) {
// Store ForgerComitmnent observed at every block by the live synchronizer
syncCommitment := map[int64]bool{}
// Store ForgerComitmnent observed at every block by a syncrhonizer that is restarted
// Store ForgerComitmnent observed at every block by a synchronizer that is restarted
syncRestartedCommitment := map[int64]bool{}
for _, block := range blocks {
// Add block data to the smart contracts
@@ -836,7 +844,7 @@ func TestSyncForgerCommitment(t *testing.T) {
require.True(t, stats.Synced())
syncCommitment[syncBlock.Block.Num] = stats.Sync.Auction.CurrentSlot.ForgerCommitment
s2, err := NewSynchronizer(client, historyDB, stateDB, Config{
s2, err := NewSynchronizer(client, historyDB, l2DB, stateDB, Config{
StatsRefreshPeriod: 0 * time.Second,
})
require.NoError(t, err)

View File

@@ -101,8 +101,8 @@ func (a *DebugAPI) handleSyncStats(c *gin.Context) {
c.JSON(http.StatusOK, stats)
}
// Run starts the http server of the DebugAPI. To stop it, pass a context with
// cancelation (see `debugapi_test.go` for an example).
// Run starts the http server of the DebugAPI. To stop it, pass a context
// with cancellation (see `debugapi_test.go` for an example).
func (a *DebugAPI) Run(ctx context.Context) error {
api := gin.Default()
api.NoRoute(handleNoRoute)

View File

@@ -44,13 +44,14 @@ 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)
addr := "localhost:12345"
// We won't test the sync/stats endpoint, so we can se the Syncrhonizer to nil
// We won't test the sync/stats endpoint, so we can se the synchronizer to nil
debugAPI := NewDebugAPI(addr, sdb, nil)
ctx, cancel := context.WithCancel(context.Background())
@@ -84,7 +85,7 @@ func TestDebugAPI(t *testing.T) {
require.Nil(t, err)
// Testing against a hardcoded value obtained by running the test and
// printing the value previously.
assert.Equal(t, "21765339739823365993496282904432398015268846626944509989242908567129545640185",
assert.Equal(t, "5705124827515775272209811244650636195377535115082365089650934878384850534213",
mtroot.String())
var accountAPI common.Account

View File

@@ -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,12 +1051,15 @@ 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,
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,25 +1882,31 @@ 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)
}
}
c.CtlSetAddr(auction.Vars.BootCoordinator)
for _, batch := range block.Rollup.Batches {
auths := make([][]byte, len(batch.L1CoordinatorTxs))
for i := range auths {
auths[i] = make([]byte, 65)
}
if _, err := c.RollupForgeBatch(&eth.RollupForgeBatchArgs{
NewLastIdx: batch.Batch.LastIdx,
NewStRoot: batch.Batch.StateRoot,
NewExitRoot: batch.Batch.ExitRoot,
L1CoordinatorTxs: batch.L1CoordinatorTxs,
L1CoordinatorTxsAuths: [][]byte{}, // Intentionally empty
L1CoordinatorTxsAuths: auths,
L2TxsData: batch.L2Txs,
FeeIdxCoordinator: batch.Batch.FeeIdxsCoordinator,
// Circuit selector

View File

@@ -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

View File

@@ -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 {

View File

@@ -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

View File

@@ -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:

View File

@@ -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
}
}

View File

@@ -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)

View File

@@ -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))
}
}

View File

@@ -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

View File

@@ -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

View File

@@ -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)

View File

@@ -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)
@@ -135,17 +137,17 @@ func TestTxSelectorBatchBuilderZKInputsMinimumFlow0(t *testing.T) {
// add tokens to HistoryDB to avoid breaking FK constrains
addTokens(t, tc, l2DBTxSel.DB())
selectionConfig := &txselector.SelectionConfig{
MaxL1UserTxs: 100, // TODO
TxProcessorConfig: txprocConfig,
}
configBatch := &batchbuilder.ConfigBatch{
// ForgerAddress:
TxProcessorConfig: txprocConfig,
}
// loop over the first 6 batches
expectedRoots := []string{"0", "0", "13644148972047617726265275926674266298636745191961029124811988256139761111521", "12433441613247342495680642890662773367605896324555599297255745922589338651261", "12433441613247342495680642890662773367605896324555599297255745922589338651261", "4191361650490017591061467288209836928064232431729236465872209988325272262963"}
expectedRoots := []string{"0", "0",
"10303926118213025243660668481827257778714122989909761705455084995854999537039",
"8530501758307821623834726627056947648600328521261384179220598288701741436285",
"8530501758307821623834726627056947648600328521261384179220598288701741436285",
"9061858435528794221929846392270405504056106238451760714188625065949729889651"}
for i := 0; i < 6; i++ {
log.Debugf("block:0 batch:%d", i+1)
var l1UserTxs []common.L1Tx
@@ -153,7 +155,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(txprocConfig, l1UserTxs)
require.NoError(t, err)
// BatchBuilder build Batch
zki, err := bb.BuildBatch(coordIdxs, configBatch, oL1UserTxs, oL1CoordTxs, oL2Txs)
@@ -176,14 +179,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(txprocConfig, 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,
"3844339393304253264418296322137281996442345663805792718218845145754742722151",
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 +208,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(txprocConfig, 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,
"2537294203394018451170116789946369404362093672592091326351037700505720139801",
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 +235,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(txprocConfig, 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,
"13463929859122729344499006353544877221550995454069650137270994940730475267399",
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 +255,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(txprocConfig, 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,
"13463929859122729344499006353544877221550995454069650137270994940730475267399",
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)
@@ -292,10 +311,6 @@ func TestZKInputsExitWithFee0(t *testing.T) {
// add tokens to HistoryDB to avoid breaking FK constrains
addTokens(t, tc, l2DBTxSel.DB())
selectionConfig := &txselector.SelectionConfig{
MaxL1UserTxs: 100,
TxProcessorConfig: txprocConfig,
}
configBatch := &batchbuilder.ConfigBatch{
TxProcessorConfig: txprocConfig,
}
@@ -303,15 +318,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(txprocConfig, 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,
"3050252508378236752695438107925920517579600844238792454632938959089837319058",
bb.LocalStateDB().MT.Root().BigInt().String())
h, err := zki.HashGlobalData()
require.NoError(t, err)
assert.Equal(t, "18608843755023673022528019960628191162333429206359207449879743919826610006009", h.String())
assert.Equal(t,
"136173330006576039857485697813777018179965431269591881328654192642028135989",
h.String())
sendProofAndCheckResp(t, zki)
// batch3
@@ -321,7 +341,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(txprocConfig, nil)
require.NoError(t, err)
assert.Equal(t, 1, len(coordIdxs))
assert.Equal(t, 0, len(oL1UserTxs))
@@ -331,10 +352,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,
"2941150582529643425331223235752941075548157545257982041291886277157404095484",
bb.LocalStateDB().MT.Root().BigInt().String())
h, err = zki.HashGlobalData()
require.NoError(t, err)
assert.Equal(t, "6651837443119278772088559395433504719862425648816904171510845286897104469889", h.String())
assert.Equal(t,
"11526955144859107275861838429358092025337347677758832533226842081116224550335",
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)

View File

@@ -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)

View File

@@ -1,3 +1,81 @@
/*
Package txprocessor is the module that takes the transactions from the input and
processes them, updating the Balances and Nonces of the Accounts in the StateDB.
It's a package used by 3 other different packages, and its behaviour will differ
depending on the Type of the StateDB of the TxProcessor:
- TypeSynchronizer:
- The StateDB contains the full State MerkleTree, where the leafs are
the accounts
- Updates the StateDB and as output returns: ExitInfos, CreatedAccounts,
CoordinatorIdxsMap, CollectedFees, UpdatedAccounts
- Internally computes the ExitTree
- TypeTxSelector:
- The StateDB contains only the Accounts, which are the equivalent to
only the leafs of the State MerkleTree
- Updates the Accounts from the StateDB
- TypeBatchBuilder:
- The StateDB contains the full State MerkleTree, where the leafs are
the accounts
- Updates the StateDB. As output returns: ZKInputs, CoordinatorIdxsMap
- Internally computes the ZKInputs
Packages dependency overview:
Outputs: + ExitInfos + + +
| CreatedAccounts | | |
| CoordinatorIdxsMap | | ZKInputs |
| CollectedFees | | CoordinatorIdxsMap |
| UpdatedAccounts | | |
+------------------------+----------------+ +-----------------------+
+------------+ +----------+ +------------+
|Synchronizer| |TxSelector| |BatchBuilder|
+-----+------+ +-----+----+ +-----+------+
| | |
v v v
TxProcessor TxProcessor TxProcessor
+ + +
| | |
+----+----+ v +----+----+
| | StateDB | |
v v + v v
StateDB ExitTree | StateDB ExitTree
+ +----+----+ +
| | | |
+----+----+ v v +----+----+
| | KVDB AccountsDB | |
v v v v
KVDB MerkleTree KVDB MerkleTree
The structure of the TxProcessor can be understand as:
- StateDB: where the Rollup state is stored. It contains the Accounts &
MerkleTree.
- Config: parameters of the configuration of the circuit
- ZKInputs: computed inputs for the circuit, depends on the Config parameters
- ExitTree: only in the TypeSynchronizer & TypeBatchBuilder, contains
the MerkleTree with the processed Exits of the Batch
The main exposed method of the TxProcessor is `ProcessTxs`, which as general
lines does:
- if type==(Synchronizer || BatchBuilder), creates an ephemeral ExitTree
- processes:
- L1UserTxs --> for each tx calls ProcessL1Tx()
- L1CoordinatorTxs --> for each tx calls ProcessL1Tx()
- L2Txs --> for each tx calls ProcessL2Tx()
- internally, it computes the Fees
- each transaction processment includes:
- updating the Account Balances (for sender & receiver, and in
case that there is fee, updates the fee receiver account)
- which includes updating the State MerkleTree (except
for the type==TxSelector, which only updates the
Accounts (leafs))
- in case of Synchronizer & BatchBuilder, updates the ExitTree
for the txs of type Exit (L1 & L2)
- in case of BatchBuilder, computes the ZKInputs while processing the txs
- if type==Synchronizer, once all the txs are processed, for each Exit
it generates the ExitInfo data
*/
package txprocessor
import (
@@ -66,10 +144,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 +196,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 {
@@ -253,6 +340,7 @@ func (tp *TxProcessor) ProcessTxs(coordIdxs []common.Idx, l1usertxs, l1coordinat
tp.zki.ISOutIdx[tp.i] = tp.s.CurrentIdx().BigInt()
tp.zki.ISStateRoot[tp.i] = tp.s.MT.Root().BigInt()
tp.zki.ISExitRoot[tp.i] = exitTree.Root().BigInt()
tp.i++
}
}
@@ -343,6 +431,8 @@ func (tp *TxProcessor) ProcessTxs(coordIdxs []common.Idx, l1usertxs, l1coordinat
}
if tp.zki != nil {
// Fill the empty slots in the ZKInputs remaining after
// processing all L1 & L2 txs
txCompressedDataEmpty := common.TxCompressedDataEmpty(tp.config.ChainID)
last := tp.i - 1
if tp.i == 0 {
@@ -377,7 +467,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 +574,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 +734,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 +823,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 +884,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 +896,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 +1033,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 +1239,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
@@ -1234,7 +1334,7 @@ func (tp *TxProcessor) applyExit(coordIdxsMap map[common.TokenID]common.Idx,
}
return exitAccount, true, nil
} else if err != nil {
return exitAccount, false, tracerr.Wrap(err)
return nil, false, tracerr.Wrap(err)
}
// 1b. if idx already exist in exitTree:
@@ -1301,13 +1401,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 +1418,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 +1427,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 +1450,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 +1464,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
}

View File

@@ -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,
"10303926118213025243660668481827257778714122989909761705455084995854999537039",
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,
"8530501758307821623834726627056947648600328521261384179220598288701741436285",
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,
"8530501758307821623834726627056947648600328521261384179220598288701741436285",
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,
"9061858435528794221929846392270405504056106238451760714188625065949729889651",
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,
"3844339393304253264418296322137281996442345663805792718218845145754742722151",
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,
"2537294203394018451170116789946369404362093672592091326351037700505720139801",
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,
"13463929859122729344499006353544877221550995454069650137270994940730475267399",
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,
"21058792089669864857092637997959333050678445584244682889041632034478049099916",
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,
"18702154359941252155463263732782081721632595649781775986280568467618682348921",
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,
"16181420716631932805604732887923905079487577323947343079740042260791593140221",
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,
"17688031540912620894848983912708704736922099609001460827147265569563156468242",
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,
"17688031540912620894848983912708704736922099609001460827147265569563156468242",
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.

View File

@@ -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)

File diff suppressed because one or more lines are too long

View File

@@ -27,16 +27,6 @@ type CoordAccount struct {
AccountCreationAuth []byte // signature in byte array format
}
// SelectionConfig contains the parameters of configuration of the selection of
// transactions for the next batch
type SelectionConfig struct {
// MaxL1UserTxs is the maximum L1-user-tx for a batch
MaxL1UserTxs uint64
// TxProcessorConfig contains the config for ProcessTxs
TxProcessorConfig txprocessor.Config
}
// TxSelector implements all the functionalities to select the txs for the next
// batch
type TxSelector struct {
@@ -131,7 +121,7 @@ func (txsel *TxSelector) coordAccountForTokenID(l1CoordinatorTxs []common.L1Tx,
// but there is a transactions to them and the authorization of account
// creation exists. The L1UserTxs, L1CoordinatorTxs, PoolL2Txs that will be
// included in the next batch.
func (txsel *TxSelector) GetL2TxSelection(selectionConfig *SelectionConfig) ([]common.Idx,
func (txsel *TxSelector) GetL2TxSelection(selectionConfig txprocessor.Config) ([]common.Idx,
[][]byte, []common.L1Tx, []common.PoolL2Tx, []common.PoolL2Tx, error) {
metricGetL2TxSelection.Inc()
coordIdxs, accCreationAuths, _, l1CoordinatorTxs, l2Txs,
@@ -148,7 +138,7 @@ func (txsel *TxSelector) GetL2TxSelection(selectionConfig *SelectionConfig) ([]c
// but there is a transactions to them and the authorization of account
// creation exists. The L1UserTxs, L1CoordinatorTxs, PoolL2Txs that will be
// included in the next batch.
func (txsel *TxSelector) GetL1L2TxSelection(selectionConfig *SelectionConfig,
func (txsel *TxSelector) GetL1L2TxSelection(selectionConfig txprocessor.Config,
l1UserTxs []common.L1Tx) ([]common.Idx, [][]byte, []common.L1Tx,
[]common.L1Tx, []common.PoolL2Tx, []common.PoolL2Tx, error) {
metricGetL1L2TxSelection.Inc()
@@ -158,7 +148,7 @@ func (txsel *TxSelector) GetL1L2TxSelection(selectionConfig *SelectionConfig,
discardedL2Txs, tracerr.Wrap(err)
}
func (txsel *TxSelector) getL1L2TxSelection(selectionConfig *SelectionConfig,
func (txsel *TxSelector) getL1L2TxSelection(selectionConfig txprocessor.Config,
l1UserTxs []common.L1Tx) ([]common.Idx, [][]byte, []common.L1Tx,
[]common.L1Tx, []common.PoolL2Tx, []common.PoolL2Tx, error) {
// WIP.0: the TxSelector is not optimized and will need a redesign. The
@@ -177,7 +167,7 @@ func (txsel *TxSelector) getL1L2TxSelection(selectionConfig *SelectionConfig,
}
txselStateDB := txsel.localAccountsDB.StateDB
tp := txprocessor.NewTxProcessor(txselStateDB, selectionConfig.TxProcessorConfig)
tp := txprocessor.NewTxProcessor(txselStateDB, selectionConfig)
// Process L1UserTxs
for i := 0; i < len(l1UserTxs); i++ {
@@ -188,16 +178,16 @@ func (txsel *TxSelector) getL1L2TxSelection(selectionConfig *SelectionConfig,
}
}
// discardedL2Txs contains an array of the L2Txs that have not been selected in this Batch
var l1CoordinatorTxs []common.L1Tx
positionL1 := len(l1UserTxs)
var accAuths [][]byte
// sort l2TxsRaw (cropping at MaxTx at this point)
l2Txs0, discardedL2Txs := txsel.getL2Profitable(l2TxsRaw, selectionConfig.TxProcessorConfig.MaxTx)
// Sort l2TxsRaw (cropping at MaxTx at this point).
// discardedL2Txs contains an array of the L2Txs that have not been
// selected in this Batch.
l2Txs0, discardedL2Txs := txsel.getL2Profitable(l2TxsRaw, selectionConfig.MaxTx)
for i := range discardedL2Txs {
discardedL2Txs[i].Info = "Tx not selected due to low absolute fee"
discardedL2Txs[i].Info = "Tx not selected due to low absolute fee (does not fit inside the profitable set)"
}
noncesMap := make(map[common.Idx]common.Nonce)
@@ -229,7 +219,7 @@ func (txsel *TxSelector) getL1L2TxSelection(selectionConfig *SelectionConfig,
}
if newL1CoordTx != nil {
// if there is no space for the L1CoordinatorTx, discard the L2Tx
if len(l1CoordinatorTxs) >= int(selectionConfig.MaxL1UserTxs)-len(l1UserTxs) {
if len(l1CoordinatorTxs) >= int(selectionConfig.MaxL1Tx)-len(l1UserTxs) {
// discard L2Tx, and update Info parameter of
// the tx, and add it to the discardedTxs array
l2Txs0[i].Info = "Tx not selected because the L2Tx depends on a " +
@@ -266,9 +256,7 @@ func (txsel *TxSelector) getL1L2TxSelection(selectionConfig *SelectionConfig,
}
// check if Nonce is correct
nonce := noncesMap[l2Txs[i].FromIdx]
if l2Txs[i].Nonce == nonce {
noncesMap[l2Txs[i].FromIdx]++
} else {
if l2Txs[i].Nonce != nonce {
// not valid Nonce at tx. Discard L2Tx, and update Info
// parameter of the tx, and add it to the discardedTxs
// array
@@ -371,6 +359,7 @@ func (txsel *TxSelector) getL1L2TxSelection(selectionConfig *SelectionConfig,
// valid txs (of Exit type)
validTxs = append(validTxs, l2Txs[i])
}
noncesMap[l2Txs[i].FromIdx]++
}
// Process L1CoordinatorTxs
@@ -413,7 +402,7 @@ func (txsel *TxSelector) getL1L2TxSelection(selectionConfig *SelectionConfig,
})
// get most profitable L2-tx
maxL2Txs := int(selectionConfig.TxProcessorConfig.MaxTx) -
maxL2Txs := int(selectionConfig.MaxTx) -
len(l1UserTxs) - len(l1CoordinatorTxs)
selectedL2Txs := validTxs
@@ -427,13 +416,14 @@ func (txsel *TxSelector) getL1L2TxSelection(selectionConfig *SelectionConfig,
// the error can be due not valid tx data, or due other
// cases (such as StateDB error). At this initial
// version of the TxSelector, we discard the L2Tx and
// log the error, assuming that this will be iterated
// in a near future.
// log the error, assuming that this will be iterated in
// a near future.
log.Error(err)
// Discard L2Tx, and update Info parameter of the tx,
// and add it to the discardedTxs array
selectedL2Txs[i].Info = fmt.Sprintf("Tx not selected (in ProcessL2Tx) due to %s", err.Error())
discardedL2Txs = append(discardedL2Txs, selectedL2Txs[i])
noncesMap[selectedL2Txs[i].FromIdx]--
continue
}
finalL2Txs = append(finalL2Txs, selectedL2Txs[i])
@@ -447,7 +437,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)
@@ -479,7 +470,7 @@ func (txsel *TxSelector) getL1L2TxSelection(selectionConfig *SelectionConfig,
// l1CoordinatorTxs array, and then the PoolL2Tx is added into the validTxs
// array.
func (txsel *TxSelector) processTxToEthAddrBJJ(validTxs []common.PoolL2Tx,
selectionConfig *SelectionConfig, nL1UserTxs int, l1CoordinatorTxs []common.L1Tx,
selectionConfig txprocessor.Config, nL1UserTxs int, l1CoordinatorTxs []common.L1Tx,
positionL1 int, l2Tx common.PoolL2Tx) (*common.PoolL2Tx, *common.L1Tx,
*common.AccountCreationAuth, error) {
// if L2Tx needs a new L1CoordinatorTx of CreateAccount type, and a
@@ -511,13 +502,18 @@ 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",
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",
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 {
@@ -534,7 +530,10 @@ 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",
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))
}
}
@@ -573,7 +572,7 @@ func (txsel *TxSelector) processTxToEthAddrBJJ(validTxs []common.PoolL2Tx,
Type: common.TxTypeCreateAccountDeposit,
}
}
if len(l1CoordinatorTxs) >= int(selectionConfig.MaxL1UserTxs)-nL1UserTxs {
if len(l1CoordinatorTxs) >= int(selectionConfig.MaxL1Tx)-nL1UserTxs {
// L2Tx discarded
return nil, nil, nil, tracerr.Wrap(fmt.Errorf("L2Tx discarded due to no available slots " +
"for L1CoordinatorTx to create a new account for receiver of L2Tx"))

Some files were not shown because too many files have changed in this diff Show More