mirror of
https://github.com/arnaucube/hermez-node.git
synced 2026-02-07 11:26:44 +01:00
Move logic to extend til blocks to til
Previously, the synchronizer test was extending the output from til to precalculate many fields to compare it with the synchronizer and BD output. Since this is useful outside of the syncrhonizer testing: move this functionality to til via a function that extends the output (til.Context.FillBlocksExtra). Also, add new functionality: calculate fee idxs dynamically by setting a user name, and calculate collected fees.
This commit is contained in:
@@ -16,6 +16,7 @@ type Batch struct {
|
|||||||
EthBlockNum int64 `meddler:"eth_block_num"` // Ethereum block in which the batch is forged
|
EthBlockNum int64 `meddler:"eth_block_num"` // Ethereum block in which the batch is forged
|
||||||
ForgerAddr ethCommon.Address `meddler:"forger_addr"`
|
ForgerAddr ethCommon.Address `meddler:"forger_addr"`
|
||||||
CollectedFees map[TokenID]*big.Int `meddler:"fees_collected,json"`
|
CollectedFees map[TokenID]*big.Int `meddler:"fees_collected,json"`
|
||||||
|
FeeIdxsCoordinator []Idx `meddler:"fee_idxs_coordinator,json"`
|
||||||
StateRoot *big.Int `meddler:"state_root,bigint"`
|
StateRoot *big.Int `meddler:"state_root,bigint"`
|
||||||
NumAccounts int `meddler:"num_accounts"`
|
NumAccounts int `meddler:"num_accounts"`
|
||||||
LastIdx int64 `meddler:"last_idx"`
|
LastIdx int64 `meddler:"last_idx"`
|
||||||
|
|||||||
@@ -279,7 +279,7 @@ func (hdb *HistoryDB) GetAllBatches() ([]common.Batch, error) {
|
|||||||
err := meddler.QueryAll(
|
err := meddler.QueryAll(
|
||||||
hdb.db, &batches,
|
hdb.db, &batches,
|
||||||
`SELECT batch.batch_num, batch.eth_block_num, batch.forger_addr, batch.fees_collected,
|
`SELECT batch.batch_num, batch.eth_block_num, batch.forger_addr, batch.fees_collected,
|
||||||
batch.state_root, batch.num_accounts, batch.last_idx, batch.exit_root,
|
batch.fee_idxs_coordinator, batch.state_root, batch.num_accounts, batch.last_idx, batch.exit_root,
|
||||||
batch.forge_l1_txs_num, batch.slot_num, batch.total_fees_usd FROM batch;`,
|
batch.forge_l1_txs_num, batch.slot_num, batch.total_fees_usd FROM batch;`,
|
||||||
)
|
)
|
||||||
return db.SlicePtrsToSlice(batches).([]common.Batch), err
|
return db.SlicePtrsToSlice(batches).([]common.Batch), err
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ CREATE TABLE batch (
|
|||||||
eth_block_num BIGINT NOT NULL REFERENCES block (eth_block_num) ON DELETE CASCADE,
|
eth_block_num BIGINT NOT NULL REFERENCES block (eth_block_num) ON DELETE CASCADE,
|
||||||
forger_addr BYTEA NOT NULL, -- fake foreign key for coordinator
|
forger_addr BYTEA NOT NULL, -- fake foreign key for coordinator
|
||||||
fees_collected BYTEA NOT NULL,
|
fees_collected BYTEA NOT NULL,
|
||||||
|
fee_idxs_coordinator BYTEA NOT NULL,
|
||||||
state_root BYTEA NOT NULL,
|
state_root BYTEA NOT NULL,
|
||||||
num_accounts BIGINT NOT NULL,
|
num_accounts BIGINT NOT NULL,
|
||||||
last_idx BIGINT NOT NULL,
|
last_idx BIGINT NOT NULL,
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"math/big"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum"
|
"github.com/ethereum/go-ethereum"
|
||||||
"github.com/hermeznetwork/hermez-node/common"
|
"github.com/hermeznetwork/hermez-node/common"
|
||||||
@@ -467,6 +468,8 @@ func (s *Synchronizer) rollupSync(ethBlock *common.Block) (*common.RollupData, e
|
|||||||
|
|
||||||
for i := range processTxsOut.CreatedAccounts {
|
for i := range processTxsOut.CreatedAccounts {
|
||||||
createdAccount := &processTxsOut.CreatedAccounts[i]
|
createdAccount := &processTxsOut.CreatedAccounts[i]
|
||||||
|
createdAccount.Nonce = 0
|
||||||
|
createdAccount.Balance = big.NewInt(0)
|
||||||
createdAccount.BatchNum = batchNum
|
createdAccount.BatchNum = batchNum
|
||||||
}
|
}
|
||||||
batchData.CreatedAccounts = processTxsOut.CreatedAccounts
|
batchData.CreatedAccounts = processTxsOut.CreatedAccounts
|
||||||
@@ -478,11 +481,13 @@ func (s *Synchronizer) rollupSync(ethBlock *common.Block) (*common.RollupData, e
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get Batch information
|
// Get Batch information
|
||||||
|
// fmt.Printf("DBG: %#v\n", forgeBatchArgs.FeeIdxCoordinator)
|
||||||
batch := common.Batch{
|
batch := common.Batch{
|
||||||
BatchNum: batchNum,
|
BatchNum: batchNum,
|
||||||
EthBlockNum: blockNum,
|
EthBlockNum: blockNum,
|
||||||
ForgerAddr: *sender,
|
ForgerAddr: *sender,
|
||||||
CollectedFees: processTxsOut.CollectedFees,
|
CollectedFees: processTxsOut.CollectedFees,
|
||||||
|
FeeIdxsCoordinator: forgeBatchArgs.FeeIdxCoordinator,
|
||||||
StateRoot: forgeBatchArgs.NewStRoot,
|
StateRoot: forgeBatchArgs.NewStRoot,
|
||||||
NumAccounts: len(batchData.CreatedAccounts),
|
NumAccounts: len(batchData.CreatedAccounts),
|
||||||
LastIdx: forgeBatchArgs.NewLastIdx,
|
LastIdx: forgeBatchArgs.NewLastIdx,
|
||||||
|
|||||||
@@ -23,8 +23,6 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var tokenConsts = map[common.TokenID]eth.ERC20Consts{}
|
var tokenConsts = map[common.TokenID]eth.ERC20Consts{}
|
||||||
var forceExits = map[int64][]common.ExitInfo{} // ForgeL1TxsNum -> []exit
|
|
||||||
var nonces = map[common.Idx]common.Nonce{}
|
|
||||||
|
|
||||||
type timer struct {
|
type timer struct {
|
||||||
time int64
|
time int64
|
||||||
@@ -103,10 +101,8 @@ func checkSyncBlock(t *testing.T, s *Synchronizer, blockNum int, block, syncBloc
|
|||||||
|
|
||||||
dbL1CoordinatorTxs, err := s.historyDB.GetAllL1CoordinatorTxs()
|
dbL1CoordinatorTxs, err := s.historyDB.GetAllL1CoordinatorTxs()
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
// fmt.Printf("DBG dbL1CoordinatorTxs: %+v\n", dbL1CoordinatorTxs)
|
|
||||||
dbL2Txs, err := s.historyDB.GetAllL2Txs()
|
dbL2Txs, err := s.historyDB.GetAllL2Txs()
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
// fmt.Printf("DBG dbL2Txs: %+v\n", dbL2Txs)
|
|
||||||
dbExits, err := s.historyDB.GetAllExits()
|
dbExits, err := s.historyDB.GetAllExits()
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
// dbL1CoordinatorTxs := []common.L1Tx{}
|
// dbL1CoordinatorTxs := []common.L1Tx{}
|
||||||
@@ -125,7 +121,7 @@ func checkSyncBlock(t *testing.T, s *Synchronizer, blockNum int, block, syncBloc
|
|||||||
// We don't care about TotalFeesUSD. Use the syncBatch that
|
// We don't care about TotalFeesUSD. Use the syncBatch that
|
||||||
// has a TotalFeesUSD inserted by the HistoryDB
|
// has a TotalFeesUSD inserted by the HistoryDB
|
||||||
batch.Batch.TotalFeesUSD = syncBatch.Batch.TotalFeesUSD
|
batch.Batch.TotalFeesUSD = syncBatch.Batch.TotalFeesUSD
|
||||||
batch.CreatedAccounts = syncBatch.CreatedAccounts // til doesn't output CreatedAccounts
|
assert.Equal(t, batch.CreatedAccounts, syncBatch.CreatedAccounts)
|
||||||
batch.Batch.NumAccounts = len(batch.CreatedAccounts)
|
batch.Batch.NumAccounts = len(batch.CreatedAccounts)
|
||||||
|
|
||||||
// Test field by field to facilitate debugging of errors
|
// Test field by field to facilitate debugging of errors
|
||||||
@@ -139,12 +135,6 @@ func checkSyncBlock(t *testing.T, s *Synchronizer, blockNum int, block, syncBloc
|
|||||||
assert.Equal(t, exit.Balance, syncBatch.ExitTree[j].Balance)
|
assert.Equal(t, exit.Balance, syncBatch.ExitTree[j].Balance)
|
||||||
*exit = syncBatch.ExitTree[j]
|
*exit = syncBatch.ExitTree[j]
|
||||||
}
|
}
|
||||||
// We are collecting fees after blockNum=2 in 2 idxs
|
|
||||||
if block.Block.EthBlockNum > 2 {
|
|
||||||
// fmt.Printf("DBG collectedFees: %+v\n", syncBatch.Batch.CollectedFees)
|
|
||||||
assert.Equal(t, 2, len(syncBatch.Batch.CollectedFees))
|
|
||||||
}
|
|
||||||
batch.Batch.CollectedFees = syncBatch.Batch.CollectedFees
|
|
||||||
assert.Equal(t, batch.Batch, syncBatch.Batch)
|
assert.Equal(t, batch.Batch, syncBatch.Batch)
|
||||||
assert.Equal(t, batch, syncBatch)
|
assert.Equal(t, batch, syncBatch)
|
||||||
assert.Equal(t, &batch.Batch, dbBatch) //nolint:gosec
|
assert.Equal(t, &batch.Batch, dbBatch) //nolint:gosec
|
||||||
@@ -305,9 +295,12 @@ func TestSync(t *testing.T) {
|
|||||||
> batchL1 // forge L1UserTxs{nil}, freeze defined L1UserTxs{2}
|
> batchL1 // forge L1UserTxs{nil}, freeze defined L1UserTxs{2}
|
||||||
> batchL1 // forge L1UserTxs{2}, freeze defined L1UserTxs{nil}
|
> batchL1 // forge L1UserTxs{2}, freeze defined L1UserTxs{nil}
|
||||||
> block // blockNum=3
|
> block // blockNum=3
|
||||||
|
|
||||||
`
|
`
|
||||||
tc := til.NewContext(common.RollupConstMaxL1UserTx)
|
tc := til.NewContext(common.RollupConstMaxL1UserTx)
|
||||||
|
tilCfgExtra := til.ConfigExtra{
|
||||||
|
BootCoordAddr: bootCoordAddr,
|
||||||
|
CoordUser: "A",
|
||||||
|
}
|
||||||
blocks, err := tc.GenerateBlocks(set1)
|
blocks, err := tc.GenerateBlocks(set1)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
// Sanity check
|
// Sanity check
|
||||||
@@ -339,6 +332,9 @@ func TestSync(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err = tc.FillBlocksExtra(blocks, &tilCfgExtra)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
|
||||||
// Add block data to the smart contracts
|
// Add block data to the smart contracts
|
||||||
for _, block := range blocks {
|
for _, block := range blocks {
|
||||||
for _, token := range block.Rollup.AddedTokens {
|
for _, token := range block.Rollup.AddedTokens {
|
||||||
@@ -352,12 +348,12 @@ func TestSync(t *testing.T) {
|
|||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
}
|
}
|
||||||
client.CtlSetAddr(bootCoordAddr)
|
client.CtlSetAddr(bootCoordAddr)
|
||||||
feeIdxCoordinator := []common.Idx{}
|
// feeIdxCoordinator := []common.Idx{}
|
||||||
if block.Block.EthBlockNum > 2 {
|
// if block.Block.EthBlockNum > 2 {
|
||||||
// After blockNum=2 we have some accounts, use them as
|
// // After blockNum=2 we have some accounts, use them as
|
||||||
// coordinator owned to receive fees.
|
// // coordinator owned to receive fees.
|
||||||
feeIdxCoordinator = []common.Idx{common.Idx(256), common.Idx(259)}
|
// feeIdxCoordinator = []common.Idx{common.Idx(256), common.Idx(259)}
|
||||||
}
|
// }
|
||||||
for _, batch := range block.Rollup.Batches {
|
for _, batch := range block.Rollup.Batches {
|
||||||
_, err := client.RollupForgeBatch(ð.RollupForgeBatchArgs{
|
_, err := client.RollupForgeBatch(ð.RollupForgeBatchArgs{
|
||||||
NewLastIdx: batch.Batch.LastIdx,
|
NewLastIdx: batch.Batch.LastIdx,
|
||||||
@@ -366,7 +362,7 @@ func TestSync(t *testing.T) {
|
|||||||
L1CoordinatorTxs: batch.L1CoordinatorTxs,
|
L1CoordinatorTxs: batch.L1CoordinatorTxs,
|
||||||
L1CoordinatorTxsAuths: [][]byte{}, // Intentionally empty
|
L1CoordinatorTxsAuths: [][]byte{}, // Intentionally empty
|
||||||
L2TxsData: batch.L2Txs,
|
L2TxsData: batch.L2Txs,
|
||||||
FeeIdxCoordinator: feeIdxCoordinator,
|
FeeIdxCoordinator: batch.Batch.FeeIdxsCoordinator,
|
||||||
// Circuit selector
|
// Circuit selector
|
||||||
VerifierIdx: 0, // Intentionally empty
|
VerifierIdx: 0, // Intentionally empty
|
||||||
L1Batch: batch.L1Batch,
|
L1Batch: batch.L1Batch,
|
||||||
@@ -380,113 +376,6 @@ func TestSync(t *testing.T) {
|
|||||||
client.CtlMineBlock()
|
client.CtlMineBlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fill extra fields not generated by til in til block
|
|
||||||
openToForge := int64(0)
|
|
||||||
toForgeL1TxsNum := int64(0)
|
|
||||||
l1UserTxsLen := map[int64]int{} // ForgeL1TxsNum -> len(L1UserTxs)
|
|
||||||
for i := range blocks {
|
|
||||||
block := &blocks[i]
|
|
||||||
// Count number of L1UserTxs in each queue, to figure out later
|
|
||||||
// position of L1CoordinatorTxs and L2Txs
|
|
||||||
for j := range block.Rollup.L1UserTxs {
|
|
||||||
tx := &block.Rollup.L1UserTxs[j]
|
|
||||||
l1UserTxsLen[*tx.ToForgeL1TxsNum]++
|
|
||||||
if tx.Type == common.TxTypeForceExit {
|
|
||||||
forceExits[*tx.ToForgeL1TxsNum] = append(forceExits[*tx.ToForgeL1TxsNum],
|
|
||||||
common.ExitInfo{
|
|
||||||
AccountIdx: tx.FromIdx,
|
|
||||||
Balance: tx.Amount,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for j := range block.Rollup.Batches {
|
|
||||||
batch := &block.Rollup.Batches[j]
|
|
||||||
if batch.L1Batch {
|
|
||||||
// Set BatchNum for forged L1UserTxs to til blocks
|
|
||||||
bn := batch.Batch.BatchNum
|
|
||||||
for k := range blocks {
|
|
||||||
block := &blocks[k]
|
|
||||||
for l := range block.Rollup.L1UserTxs {
|
|
||||||
tx := &block.Rollup.L1UserTxs[l]
|
|
||||||
if *tx.ToForgeL1TxsNum == openToForge {
|
|
||||||
tx.BatchNum = &bn
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
openToForge++
|
|
||||||
}
|
|
||||||
|
|
||||||
batch.Batch.EthBlockNum = block.Block.EthBlockNum
|
|
||||||
batch.Batch.ForgerAddr = bootCoordAddr // til doesn't fill the batch forger addr
|
|
||||||
if batch.L1Batch {
|
|
||||||
toForgeL1TxsNumCpy := toForgeL1TxsNum
|
|
||||||
batch.Batch.ForgeL1TxsNum = &toForgeL1TxsNumCpy // til doesn't fill the ForgeL1TxsNum
|
|
||||||
toForgeL1TxsNum++
|
|
||||||
}
|
|
||||||
|
|
||||||
batchNum := batch.Batch.BatchNum
|
|
||||||
for k := range batch.L1CoordinatorTxs {
|
|
||||||
tx := &batch.L1CoordinatorTxs[k]
|
|
||||||
tx.BatchNum = &batchNum
|
|
||||||
tx.EthBlockNum = batch.Batch.EthBlockNum
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fill expected positions in L1CoordinatorTxs and L2Txs
|
|
||||||
for i := range blocks {
|
|
||||||
block := &blocks[i]
|
|
||||||
for j := range block.Rollup.Batches {
|
|
||||||
batch := &block.Rollup.Batches[j]
|
|
||||||
position := 0
|
|
||||||
if batch.L1Batch {
|
|
||||||
position = l1UserTxsLen[*batch.Batch.ForgeL1TxsNum]
|
|
||||||
}
|
|
||||||
for k := range batch.L1CoordinatorTxs {
|
|
||||||
tx := &batch.L1CoordinatorTxs[k]
|
|
||||||
tx.Position = position
|
|
||||||
position++
|
|
||||||
nTx, err := common.NewL1Tx(tx)
|
|
||||||
require.Nil(t, err)
|
|
||||||
*tx = *nTx
|
|
||||||
}
|
|
||||||
for k := range batch.L2Txs {
|
|
||||||
tx := &batch.L2Txs[k]
|
|
||||||
tx.Position = position
|
|
||||||
position++
|
|
||||||
nonces[tx.FromIdx]++
|
|
||||||
tx.Nonce = nonces[tx.FromIdx]
|
|
||||||
nTx, err := common.NewL2Tx(tx)
|
|
||||||
require.Nil(t, err)
|
|
||||||
*tx = *nTx
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fill ExitTree (only AccountIdx and Balance)
|
|
||||||
for i := range blocks {
|
|
||||||
block := &blocks[i]
|
|
||||||
for j := range block.Rollup.Batches {
|
|
||||||
batch := &block.Rollup.Batches[j]
|
|
||||||
if batch.L1Batch {
|
|
||||||
for forgeL1TxsNum, exits := range forceExits {
|
|
||||||
if forgeL1TxsNum == *batch.Batch.ForgeL1TxsNum {
|
|
||||||
batch.ExitTree = append(batch.ExitTree, exits...)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for k := range batch.L2Txs {
|
|
||||||
tx := &batch.L2Txs[k]
|
|
||||||
if tx.Type == common.TxTypeExit {
|
|
||||||
batch.ExitTree = append(batch.ExitTree, common.ExitInfo{
|
|
||||||
AccountIdx: tx.FromIdx,
|
|
||||||
Balance: tx.Amount,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Sync to synchronize the current state from the test smart contracts,
|
// Sync to synchronize the current state from the test smart contracts,
|
||||||
// and check the outcome
|
// and check the outcome
|
||||||
|
|||||||
238
test/til/txs.go
238
test/til/txs.go
@@ -21,7 +21,10 @@ func newBatchData(batchNum int) common.BatchData {
|
|||||||
L2Txs: []common.L2Tx{},
|
L2Txs: []common.L2Tx{},
|
||||||
Batch: common.Batch{
|
Batch: common.Batch{
|
||||||
BatchNum: common.BatchNum(batchNum),
|
BatchNum: common.BatchNum(batchNum),
|
||||||
StateRoot: big.NewInt(0), ExitRoot: big.NewInt(0)},
|
StateRoot: big.NewInt(0), ExitRoot: big.NewInt(0),
|
||||||
|
FeeIdxsCoordinator: make([]common.Idx, 0),
|
||||||
|
CollectedFees: make(map[common.TokenID]*big.Int),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -36,13 +39,22 @@ func newBlock(blockNum int64) common.BlockData {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type contextExtra struct {
|
||||||
|
openToForge int64
|
||||||
|
toForgeL1TxsNum int64
|
||||||
|
nonces map[common.Idx]common.Nonce
|
||||||
|
idx int
|
||||||
|
}
|
||||||
|
|
||||||
// Context contains the data of the test
|
// Context contains the data of the test
|
||||||
type Context struct {
|
type Context struct {
|
||||||
Instructions []instruction
|
Instructions []instruction
|
||||||
userNames []string
|
userNames []string
|
||||||
Users map[string]*User
|
Users map[string]*User // Name -> *User
|
||||||
|
usersByIdx map[int]*User
|
||||||
|
accountsByIdx map[int]*Account
|
||||||
LastRegisteredTokenID common.TokenID
|
LastRegisteredTokenID common.TokenID
|
||||||
l1CreatedAccounts map[string]*Account
|
l1CreatedAccounts map[string]*Account // (Name, TokenID) -> *Account
|
||||||
|
|
||||||
// rollupConstMaxL1UserTx Maximum L1-user transactions allowed to be queued in a batch
|
// rollupConstMaxL1UserTx Maximum L1-user transactions allowed to be queued in a batch
|
||||||
rollupConstMaxL1UserTx int
|
rollupConstMaxL1UserTx int
|
||||||
@@ -59,6 +71,8 @@ type Context struct {
|
|||||||
l2Txs []L2Tx
|
l2Txs []L2Tx
|
||||||
}
|
}
|
||||||
blockNum int64
|
blockNum int64
|
||||||
|
|
||||||
|
extra contextExtra
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewContext returns a new Context
|
// NewContext returns a new Context
|
||||||
@@ -67,6 +81,8 @@ func NewContext(rollupConstMaxL1UserTx int) *Context {
|
|||||||
return &Context{
|
return &Context{
|
||||||
Users: make(map[string]*User),
|
Users: make(map[string]*User),
|
||||||
l1CreatedAccounts: make(map[string]*Account),
|
l1CreatedAccounts: make(map[string]*Account),
|
||||||
|
usersByIdx: make(map[int]*User),
|
||||||
|
accountsByIdx: make(map[int]*Account),
|
||||||
LastRegisteredTokenID: 0,
|
LastRegisteredTokenID: 0,
|
||||||
|
|
||||||
rollupConstMaxL1UserTx: rollupConstMaxL1UserTx,
|
rollupConstMaxL1UserTx: rollupConstMaxL1UserTx,
|
||||||
@@ -82,17 +98,26 @@ func NewContext(rollupConstMaxL1UserTx int) *Context {
|
|||||||
openToForge: 1,
|
openToForge: 1,
|
||||||
//nolint:gomnd
|
//nolint:gomnd
|
||||||
blockNum: 2, // rollup genesis blockNum
|
blockNum: 2, // rollup genesis blockNum
|
||||||
|
extra: contextExtra{
|
||||||
|
openToForge: 0,
|
||||||
|
toForgeL1TxsNum: 0,
|
||||||
|
nonces: make(map[common.Idx]common.Nonce),
|
||||||
|
idx: common.UserThreshold,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Account contains the data related to the account for a specific TokenID of a User
|
// Account contains the data related to the account for a specific TokenID of a User
|
||||||
type Account struct {
|
type Account struct {
|
||||||
Idx common.Idx
|
Idx common.Idx
|
||||||
|
TokenID common.TokenID
|
||||||
Nonce common.Nonce
|
Nonce common.Nonce
|
||||||
|
BatchNum int
|
||||||
}
|
}
|
||||||
|
|
||||||
// User contains the data related to a testing user
|
// User contains the data related to a testing user
|
||||||
type User struct {
|
type User struct {
|
||||||
|
Name string
|
||||||
BJJ *babyjub.PrivateKey
|
BJJ *babyjub.PrivateKey
|
||||||
Addr ethCommon.Address
|
Addr ethCommon.Address
|
||||||
Accounts map[common.TokenID]*Account
|
Accounts map[common.TokenID]*Account
|
||||||
@@ -362,9 +387,13 @@ func (tc *Context) calculateIdxForL1Txs(isCoordinatorTxs bool, txs []L1Tx) error
|
|||||||
}
|
}
|
||||||
tc.Users[tx.fromIdxName].Accounts[tx.L1Tx.TokenID] = &Account{
|
tc.Users[tx.fromIdxName].Accounts[tx.L1Tx.TokenID] = &Account{
|
||||||
Idx: common.Idx(tc.idx),
|
Idx: common.Idx(tc.idx),
|
||||||
|
TokenID: tx.L1Tx.TokenID,
|
||||||
Nonce: common.Nonce(0),
|
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++
|
tc.idx++
|
||||||
}
|
}
|
||||||
if isCoordinatorTxs {
|
if isCoordinatorTxs {
|
||||||
@@ -606,6 +635,7 @@ func (tc *Context) generateKeys(userNames []string) {
|
|||||||
addr := ethCrypto.PubkeyToAddress(key.PublicKey)
|
addr := ethCrypto.PubkeyToAddress(key.PublicKey)
|
||||||
|
|
||||||
u := User{
|
u := User{
|
||||||
|
Name: userNames[i-1],
|
||||||
BJJ: &sk,
|
BJJ: &sk,
|
||||||
Addr: addr,
|
Addr: addr,
|
||||||
Accounts: make(map[common.TokenID]*Account),
|
Accounts: make(map[common.TokenID]*Account),
|
||||||
@@ -622,3 +652,205 @@ func L1TxsToCommonL1Txs(l1 []L1Tx) []common.L1Tx {
|
|||||||
}
|
}
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ConfigExtra is the configuration used in FillBlocksExtra to extend the
|
||||||
|
// blocks returned by til.
|
||||||
|
type ConfigExtra struct {
|
||||||
|
// Address to set as forger for each batch
|
||||||
|
BootCoordAddr ethCommon.Address
|
||||||
|
// Coordinator user name used to select the corresponding accounts to
|
||||||
|
// collect coordinator fees
|
||||||
|
CoordUser string
|
||||||
|
}
|
||||||
|
|
||||||
|
// FillBlocksExtra fills extra fields not generated by til in each block, so
|
||||||
|
// that the blockData is closer to what the HistoryDB stores. The filled fields are:
|
||||||
|
// - blocks[].Rollup.L1UserTxs[].BatchNum
|
||||||
|
// - blocks[].Rollup.Batch.EthBlockNum
|
||||||
|
// - blocks[].Rollup.Batch.ForgerAddr
|
||||||
|
// - blocks[].Rollup.Batch.ForgeL1TxsNum
|
||||||
|
// - blocks[].Rollup.Batch.L1CoordinatorTxs[].TxID
|
||||||
|
// - blocks[].Rollup.Batch.L1CoordinatorTxs[].BatchNum
|
||||||
|
// - blocks[].Rollup.Batch.L1CoordinatorTxs[].EthBlockNum
|
||||||
|
// - blocks[].Rollup.Batch.L1CoordinatorTxs[].Position
|
||||||
|
// - blocks[].Rollup.Batch.L2Txs[].TxID
|
||||||
|
// - blocks[].Rollup.Batch.L2Txs[].Position
|
||||||
|
// - blocks[].Rollup.Batch.L2Txs[].Nonce
|
||||||
|
// - blocks[].Rollup.Batch.ExitTree
|
||||||
|
// - blocks[].Rollup.Batch.CreatedAccounts
|
||||||
|
// - blocks[].Rollup.Batch.FeeIdxCoordinator
|
||||||
|
// - blocks[].Rollup.Batch.CollectedFees
|
||||||
|
func (tc *Context) FillBlocksExtra(blocks []common.BlockData, cfg *ConfigExtra) error {
|
||||||
|
// Fill extra fields not generated by til in til block
|
||||||
|
for i := range blocks {
|
||||||
|
block := &blocks[i]
|
||||||
|
for j := range block.Rollup.Batches {
|
||||||
|
batch := &block.Rollup.Batches[j]
|
||||||
|
if batch.L1Batch {
|
||||||
|
// Set BatchNum for forged L1UserTxs to til blocks
|
||||||
|
bn := batch.Batch.BatchNum
|
||||||
|
for k := range blocks {
|
||||||
|
block := &blocks[k]
|
||||||
|
for l := range block.Rollup.L1UserTxs {
|
||||||
|
tx := &block.Rollup.L1UserTxs[l]
|
||||||
|
if *tx.ToForgeL1TxsNum == tc.extra.openToForge {
|
||||||
|
tx.BatchNum = &bn
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tc.extra.openToForge++
|
||||||
|
}
|
||||||
|
|
||||||
|
batch.Batch.EthBlockNum = block.Block.EthBlockNum
|
||||||
|
// til doesn't fill the batch forger addr
|
||||||
|
batch.Batch.ForgerAddr = cfg.BootCoordAddr
|
||||||
|
if batch.L1Batch {
|
||||||
|
toForgeL1TxsNumCpy := tc.extra.toForgeL1TxsNum
|
||||||
|
// til doesn't fill the ForgeL1TxsNum
|
||||||
|
batch.Batch.ForgeL1TxsNum = &toForgeL1TxsNumCpy
|
||||||
|
tc.extra.toForgeL1TxsNum++
|
||||||
|
}
|
||||||
|
|
||||||
|
batchNum := batch.Batch.BatchNum
|
||||||
|
for k := range batch.L1CoordinatorTxs {
|
||||||
|
tx := &batch.L1CoordinatorTxs[k]
|
||||||
|
tx.BatchNum = &batchNum
|
||||||
|
tx.EthBlockNum = batch.Batch.EthBlockNum
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fill CreatedAccounts
|
||||||
|
for i := range blocks {
|
||||||
|
block := &blocks[i]
|
||||||
|
for j := range block.Rollup.Batches {
|
||||||
|
batch := &block.Rollup.Batches[j]
|
||||||
|
l1Txs := []common.L1Tx{}
|
||||||
|
if batch.L1Batch {
|
||||||
|
for _, tx := range tc.Queues[*batch.Batch.ForgeL1TxsNum] {
|
||||||
|
l1Txs = append(l1Txs, tx.L1Tx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
l1Txs = append(l1Txs, batch.L1CoordinatorTxs...)
|
||||||
|
for k := range l1Txs {
|
||||||
|
tx := &l1Txs[k]
|
||||||
|
if tx.Type == common.TxTypeCreateAccountDeposit ||
|
||||||
|
tx.Type == common.TxTypeCreateAccountDepositTransfer {
|
||||||
|
user, ok := tc.usersByIdx[tc.extra.idx]
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("Created account with idx: %v not found", tc.extra.idx)
|
||||||
|
}
|
||||||
|
batch.CreatedAccounts = append(batch.CreatedAccounts,
|
||||||
|
common.Account{
|
||||||
|
Idx: common.Idx(tc.extra.idx),
|
||||||
|
TokenID: tx.TokenID,
|
||||||
|
BatchNum: batch.Batch.BatchNum,
|
||||||
|
PublicKey: user.BJJ.Public(),
|
||||||
|
EthAddr: user.Addr,
|
||||||
|
Nonce: 0,
|
||||||
|
Balance: big.NewInt(0),
|
||||||
|
})
|
||||||
|
tc.extra.idx++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fill expected positions in L1CoordinatorTxs and L2Txs
|
||||||
|
for i := range blocks {
|
||||||
|
block := &blocks[i]
|
||||||
|
for j := range block.Rollup.Batches {
|
||||||
|
batch := &block.Rollup.Batches[j]
|
||||||
|
position := 0
|
||||||
|
if batch.L1Batch {
|
||||||
|
position = len(tc.Queues[*batch.Batch.ForgeL1TxsNum])
|
||||||
|
}
|
||||||
|
for k := range batch.L1CoordinatorTxs {
|
||||||
|
tx := &batch.L1CoordinatorTxs[k]
|
||||||
|
tx.Position = position
|
||||||
|
position++
|
||||||
|
nTx, err := common.NewL1Tx(tx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
*tx = *nTx
|
||||||
|
}
|
||||||
|
for k := range batch.L2Txs {
|
||||||
|
tx := &batch.L2Txs[k]
|
||||||
|
tx.Position = position
|
||||||
|
position++
|
||||||
|
tc.extra.nonces[tx.FromIdx]++
|
||||||
|
tx.Nonce = tc.extra.nonces[tx.FromIdx]
|
||||||
|
nTx, err := common.NewL2Tx(tx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
*tx = *nTx
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fill ExitTree (only AccountIdx and Balance)
|
||||||
|
for i := range blocks {
|
||||||
|
block := &blocks[i]
|
||||||
|
for j := range block.Rollup.Batches {
|
||||||
|
batch := &block.Rollup.Batches[j]
|
||||||
|
if batch.L1Batch {
|
||||||
|
for _, _tx := range tc.Queues[*batch.Batch.ForgeL1TxsNum] {
|
||||||
|
tx := _tx.L1Tx
|
||||||
|
if tx.Type == common.TxTypeForceExit {
|
||||||
|
batch.ExitTree =
|
||||||
|
append(batch.ExitTree,
|
||||||
|
common.ExitInfo{
|
||||||
|
AccountIdx: tx.FromIdx,
|
||||||
|
Balance: tx.Amount,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for k := range batch.L2Txs {
|
||||||
|
tx := &batch.L2Txs[k]
|
||||||
|
if tx.Type == common.TxTypeExit {
|
||||||
|
batch.ExitTree = append(batch.ExitTree, common.ExitInfo{
|
||||||
|
AccountIdx: tx.FromIdx,
|
||||||
|
Balance: tx.Amount,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
fee, err := common.CalcFeeAmount(tx.Amount, tx.Fee)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find the TokenID of the tx
|
||||||
|
fromAcc, ok := tc.accountsByIdx[int(tx.FromIdx)]
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("L2tx.FromIdx idx: %v not found", tx.FromIdx)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find the idx of the CoordUser for the
|
||||||
|
// TokenID, and if it exists, add the fee to
|
||||||
|
// the collectedFees. Only consider the
|
||||||
|
// coordinator account to receive fee if it was
|
||||||
|
// created in this or a previous batch
|
||||||
|
if acc, ok := tc.l1CreatedAccounts[idxTokenIDToString(cfg.CoordUser, fromAcc.TokenID)]; ok &&
|
||||||
|
common.BatchNum(acc.BatchNum) <= batch.Batch.BatchNum {
|
||||||
|
found := false
|
||||||
|
for _, idx := range batch.Batch.FeeIdxsCoordinator {
|
||||||
|
if idx == common.Idx(acc.Idx) {
|
||||||
|
found = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !found {
|
||||||
|
batch.Batch.FeeIdxsCoordinator = append(batch.Batch.FeeIdxsCoordinator,
|
||||||
|
common.Idx(acc.Idx))
|
||||||
|
batch.Batch.CollectedFees[fromAcc.TokenID] = big.NewInt(0)
|
||||||
|
}
|
||||||
|
collected := batch.Batch.CollectedFees[fromAcc.TokenID]
|
||||||
|
collected.Add(collected, fee)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user