Update missing parts, improve til, and more
- Node
- Updated configuration to initialize the interface to all the smart
contracts
- Common
- Moved BlockData and BatchData types to common so that they can be
shared among: historydb, til and synchronizer
- Remove hash.go (it was never used)
- Remove slot.go (it was never used)
- Remove smartcontractparams.go (it was never used, and appropriate
structs are defined in `eth/`)
- Comment state / status method until requirements of this method are
properly defined, and move it to Synchronizer
- Synchronizer
- Simplify `Sync` routine to only sync one block per call, and return
useful information.
- Use BlockData and BatchData from common
- Check that events belong to the expected block hash
- In L1Batch, query L1UserTxs from HistoryDB
- Fill ERC20 token information
- Test AddTokens with test.Client
- HistryDB
- Use BlockData and BatchData from common
- Add `GetAllTokens` method
- Uncomment and update GetL1UserTxs (with corresponding tests)
- Til
- Rename all instances of RegisterToken to AddToken (to follow the smart
contract implementation naming)
- Use BlockData and BatchData from common
- Move testL1CoordinatorTxs and testL2Txs to a separate struct
from BatchData in Context
- Start Context with BatchNum = 1 (which the protocol defines to be the
first batchNum)
- In every Batch, set StateRoot and ExitRoot to a non-nil big.Int
(zero).
- In all L1Txs, if LoadAmount is not used, set it to 0; if Amount is not
used, set it to 0; so that no *big.Int is nil.
- In L1UserTx, don't set BatchNum, because when L1UserTxs are created
and obtained by the synchronizer, the BatchNum is not known yet (it's
a synchronizer job to set it)
- In L1UserTxs, set `UserOrigin` and set `ToForgeL1TxsNum`.
4 years ago Update missing parts, improve til, and more
- Node
- Updated configuration to initialize the interface to all the smart
contracts
- Common
- Moved BlockData and BatchData types to common so that they can be
shared among: historydb, til and synchronizer
- Remove hash.go (it was never used)
- Remove slot.go (it was never used)
- Remove smartcontractparams.go (it was never used, and appropriate
structs are defined in `eth/`)
- Comment state / status method until requirements of this method are
properly defined, and move it to Synchronizer
- Synchronizer
- Simplify `Sync` routine to only sync one block per call, and return
useful information.
- Use BlockData and BatchData from common
- Check that events belong to the expected block hash
- In L1Batch, query L1UserTxs from HistoryDB
- Fill ERC20 token information
- Test AddTokens with test.Client
- HistryDB
- Use BlockData and BatchData from common
- Add `GetAllTokens` method
- Uncomment and update GetL1UserTxs (with corresponding tests)
- Til
- Rename all instances of RegisterToken to AddToken (to follow the smart
contract implementation naming)
- Use BlockData and BatchData from common
- Move testL1CoordinatorTxs and testL2Txs to a separate struct
from BatchData in Context
- Start Context with BatchNum = 1 (which the protocol defines to be the
first batchNum)
- In every Batch, set StateRoot and ExitRoot to a non-nil big.Int
(zero).
- In all L1Txs, if LoadAmount is not used, set it to 0; if Amount is not
used, set it to 0; so that no *big.Int is nil.
- In L1UserTx, don't set BatchNum, because when L1UserTxs are created
and obtained by the synchronizer, the BatchNum is not known yet (it's
a synchronizer job to set it)
- In L1UserTxs, set `UserOrigin` and set `ToForgeL1TxsNum`.
4 years ago Update coordinator, call all api update functions
- Common:
- Rename Block.EthBlockNum to Block.Num to avoid unneeded repetition
- API:
- Add UpdateNetworkInfoBlock to update just block information, to be
used when the node is not yet synchronized
- Node:
- Call API.UpdateMetrics and UpdateRecommendedFee in a loop, with
configurable time intervals
- Synchronizer:
- When mapping events by TxHash, use an array to support the possibility
of multiple calls of the same function happening in the same
transaction (for example, a smart contract in a single transaction
could call withdraw with delay twice, which would generate 2 withdraw
events, and 2 deposit events).
- In Stats, keep entire LastBlock instead of just the blockNum
- In Stats, add lastL1BatchBlock
- Test Stats and SCVars
- Coordinator:
- Enable writing the BatchInfo in every step of the pipeline to disk
(with JSON text files) for debugging purposes.
- Move the Pipeline functionality from the Coordinator to its own struct
(Pipeline)
- Implement shouldL1lL2Batch
- In TxManager, implement logic to perform several attempts when doing
ethereum node RPC calls before considering the error. (Both for calls
to forgeBatch and transaction receipt)
- In TxManager, reorganize the flow and note the specific points in
which actions are made when err != nil
- HistoryDB:
- Implement GetLastL1BatchBlockNum: returns the blockNum of the latest
forged l1Batch, to help the coordinator decide when to forge an
L1Batch.
- EthereumClient and test.Client:
- Update EthBlockByNumber to return the last block when the passed
number is -1.
4 years ago Update coordinator, call all api update functions
- Common:
- Rename Block.EthBlockNum to Block.Num to avoid unneeded repetition
- API:
- Add UpdateNetworkInfoBlock to update just block information, to be
used when the node is not yet synchronized
- Node:
- Call API.UpdateMetrics and UpdateRecommendedFee in a loop, with
configurable time intervals
- Synchronizer:
- When mapping events by TxHash, use an array to support the possibility
of multiple calls of the same function happening in the same
transaction (for example, a smart contract in a single transaction
could call withdraw with delay twice, which would generate 2 withdraw
events, and 2 deposit events).
- In Stats, keep entire LastBlock instead of just the blockNum
- In Stats, add lastL1BatchBlock
- Test Stats and SCVars
- Coordinator:
- Enable writing the BatchInfo in every step of the pipeline to disk
(with JSON text files) for debugging purposes.
- Move the Pipeline functionality from the Coordinator to its own struct
(Pipeline)
- Implement shouldL1lL2Batch
- In TxManager, implement logic to perform several attempts when doing
ethereum node RPC calls before considering the error. (Both for calls
to forgeBatch and transaction receipt)
- In TxManager, reorganize the flow and note the specific points in
which actions are made when err != nil
- HistoryDB:
- Implement GetLastL1BatchBlockNum: returns the blockNum of the latest
forged l1Batch, to help the coordinator decide when to forge an
L1Batch.
- EthereumClient and test.Client:
- Update EthBlockByNumber to return the last block when the passed
number is -1.
4 years ago Update coordinator, call all api update functions
- Common:
- Rename Block.EthBlockNum to Block.Num to avoid unneeded repetition
- API:
- Add UpdateNetworkInfoBlock to update just block information, to be
used when the node is not yet synchronized
- Node:
- Call API.UpdateMetrics and UpdateRecommendedFee in a loop, with
configurable time intervals
- Synchronizer:
- When mapping events by TxHash, use an array to support the possibility
of multiple calls of the same function happening in the same
transaction (for example, a smart contract in a single transaction
could call withdraw with delay twice, which would generate 2 withdraw
events, and 2 deposit events).
- In Stats, keep entire LastBlock instead of just the blockNum
- In Stats, add lastL1BatchBlock
- Test Stats and SCVars
- Coordinator:
- Enable writing the BatchInfo in every step of the pipeline to disk
(with JSON text files) for debugging purposes.
- Move the Pipeline functionality from the Coordinator to its own struct
(Pipeline)
- Implement shouldL1lL2Batch
- In TxManager, implement logic to perform several attempts when doing
ethereum node RPC calls before considering the error. (Both for calls
to forgeBatch and transaction receipt)
- In TxManager, reorganize the flow and note the specific points in
which actions are made when err != nil
- HistoryDB:
- Implement GetLastL1BatchBlockNum: returns the blockNum of the latest
forged l1Batch, to help the coordinator decide when to forge an
L1Batch.
- EthereumClient and test.Client:
- Update EthBlockByNumber to return the last block when the passed
number is -1.
4 years ago Update coordinator, call all api update functions
- Common:
- Rename Block.EthBlockNum to Block.Num to avoid unneeded repetition
- API:
- Add UpdateNetworkInfoBlock to update just block information, to be
used when the node is not yet synchronized
- Node:
- Call API.UpdateMetrics and UpdateRecommendedFee in a loop, with
configurable time intervals
- Synchronizer:
- When mapping events by TxHash, use an array to support the possibility
of multiple calls of the same function happening in the same
transaction (for example, a smart contract in a single transaction
could call withdraw with delay twice, which would generate 2 withdraw
events, and 2 deposit events).
- In Stats, keep entire LastBlock instead of just the blockNum
- In Stats, add lastL1BatchBlock
- Test Stats and SCVars
- Coordinator:
- Enable writing the BatchInfo in every step of the pipeline to disk
(with JSON text files) for debugging purposes.
- Move the Pipeline functionality from the Coordinator to its own struct
(Pipeline)
- Implement shouldL1lL2Batch
- In TxManager, implement logic to perform several attempts when doing
ethereum node RPC calls before considering the error. (Both for calls
to forgeBatch and transaction receipt)
- In TxManager, reorganize the flow and note the specific points in
which actions are made when err != nil
- HistoryDB:
- Implement GetLastL1BatchBlockNum: returns the blockNum of the latest
forged l1Batch, to help the coordinator decide when to forge an
L1Batch.
- EthereumClient and test.Client:
- Update EthBlockByNumber to return the last block when the passed
number is -1.
4 years ago Fix exit table, set delayed_withdrawn in exits
- In exit table, `instant_withdrawn`, `delayed_withdraw_request`, and
`delayed_withdrawn` were referencing batch_num. But these actions happen
outside a batch, so they should reference a block_num.
- Process delayed withdrawns:
- In Synchronizer, first match a Rollup delayed withdrawn request, with the
WDelayer deposit (via TxHash), and store the owner and token associated
with the delayed withdrawn.
- In HistoryDB: store the owner and token of a delayed withdrawal request
in the exit_tree, and set delayed_withdrawn when the withdraw is done in
the WDelayer.
- Update dependency of sqlx to master
- Last release of sqlx is from 2018 October, and it doesn't support
`NamedQuery` with a slice of structs, which is used in this commit.
4 years ago Update missing parts, improve til, and more
- Node
- Updated configuration to initialize the interface to all the smart
contracts
- Common
- Moved BlockData and BatchData types to common so that they can be
shared among: historydb, til and synchronizer
- Remove hash.go (it was never used)
- Remove slot.go (it was never used)
- Remove smartcontractparams.go (it was never used, and appropriate
structs are defined in `eth/`)
- Comment state / status method until requirements of this method are
properly defined, and move it to Synchronizer
- Synchronizer
- Simplify `Sync` routine to only sync one block per call, and return
useful information.
- Use BlockData and BatchData from common
- Check that events belong to the expected block hash
- In L1Batch, query L1UserTxs from HistoryDB
- Fill ERC20 token information
- Test AddTokens with test.Client
- HistryDB
- Use BlockData and BatchData from common
- Add `GetAllTokens` method
- Uncomment and update GetL1UserTxs (with corresponding tests)
- Til
- Rename all instances of RegisterToken to AddToken (to follow the smart
contract implementation naming)
- Use BlockData and BatchData from common
- Move testL1CoordinatorTxs and testL2Txs to a separate struct
from BatchData in Context
- Start Context with BatchNum = 1 (which the protocol defines to be the
first batchNum)
- In every Batch, set StateRoot and ExitRoot to a non-nil big.Int
(zero).
- In all L1Txs, if LoadAmount is not used, set it to 0; if Amount is not
used, set it to 0; so that no *big.Int is nil.
- In L1UserTx, don't set BatchNum, because when L1UserTxs are created
and obtained by the synchronizer, the BatchNum is not known yet (it's
a synchronizer job to set it)
- In L1UserTxs, set `UserOrigin` and set `ToForgeL1TxsNum`.
4 years ago Update missing parts, improve til, and more
- Node
- Updated configuration to initialize the interface to all the smart
contracts
- Common
- Moved BlockData and BatchData types to common so that they can be
shared among: historydb, til and synchronizer
- Remove hash.go (it was never used)
- Remove slot.go (it was never used)
- Remove smartcontractparams.go (it was never used, and appropriate
structs are defined in `eth/`)
- Comment state / status method until requirements of this method are
properly defined, and move it to Synchronizer
- Synchronizer
- Simplify `Sync` routine to only sync one block per call, and return
useful information.
- Use BlockData and BatchData from common
- Check that events belong to the expected block hash
- In L1Batch, query L1UserTxs from HistoryDB
- Fill ERC20 token information
- Test AddTokens with test.Client
- HistryDB
- Use BlockData and BatchData from common
- Add `GetAllTokens` method
- Uncomment and update GetL1UserTxs (with corresponding tests)
- Til
- Rename all instances of RegisterToken to AddToken (to follow the smart
contract implementation naming)
- Use BlockData and BatchData from common
- Move testL1CoordinatorTxs and testL2Txs to a separate struct
from BatchData in Context
- Start Context with BatchNum = 1 (which the protocol defines to be the
first batchNum)
- In every Batch, set StateRoot and ExitRoot to a non-nil big.Int
(zero).
- In all L1Txs, if LoadAmount is not used, set it to 0; if Amount is not
used, set it to 0; so that no *big.Int is nil.
- In L1UserTx, don't set BatchNum, because when L1UserTxs are created
and obtained by the synchronizer, the BatchNum is not known yet (it's
a synchronizer job to set it)
- In L1UserTxs, set `UserOrigin` and set `ToForgeL1TxsNum`.
4 years ago Update missing parts, improve til, and more
- Node
- Updated configuration to initialize the interface to all the smart
contracts
- Common
- Moved BlockData and BatchData types to common so that they can be
shared among: historydb, til and synchronizer
- Remove hash.go (it was never used)
- Remove slot.go (it was never used)
- Remove smartcontractparams.go (it was never used, and appropriate
structs are defined in `eth/`)
- Comment state / status method until requirements of this method are
properly defined, and move it to Synchronizer
- Synchronizer
- Simplify `Sync` routine to only sync one block per call, and return
useful information.
- Use BlockData and BatchData from common
- Check that events belong to the expected block hash
- In L1Batch, query L1UserTxs from HistoryDB
- Fill ERC20 token information
- Test AddTokens with test.Client
- HistryDB
- Use BlockData and BatchData from common
- Add `GetAllTokens` method
- Uncomment and update GetL1UserTxs (with corresponding tests)
- Til
- Rename all instances of RegisterToken to AddToken (to follow the smart
contract implementation naming)
- Use BlockData and BatchData from common
- Move testL1CoordinatorTxs and testL2Txs to a separate struct
from BatchData in Context
- Start Context with BatchNum = 1 (which the protocol defines to be the
first batchNum)
- In every Batch, set StateRoot and ExitRoot to a non-nil big.Int
(zero).
- In all L1Txs, if LoadAmount is not used, set it to 0; if Amount is not
used, set it to 0; so that no *big.Int is nil.
- In L1UserTx, don't set BatchNum, because when L1UserTxs are created
and obtained by the synchronizer, the BatchNum is not known yet (it's
a synchronizer job to set it)
- In L1UserTxs, set `UserOrigin` and set `ToForgeL1TxsNum`.
4 years ago Update missing parts, improve til, and more
- Node
- Updated configuration to initialize the interface to all the smart
contracts
- Common
- Moved BlockData and BatchData types to common so that they can be
shared among: historydb, til and synchronizer
- Remove hash.go (it was never used)
- Remove slot.go (it was never used)
- Remove smartcontractparams.go (it was never used, and appropriate
structs are defined in `eth/`)
- Comment state / status method until requirements of this method are
properly defined, and move it to Synchronizer
- Synchronizer
- Simplify `Sync` routine to only sync one block per call, and return
useful information.
- Use BlockData and BatchData from common
- Check that events belong to the expected block hash
- In L1Batch, query L1UserTxs from HistoryDB
- Fill ERC20 token information
- Test AddTokens with test.Client
- HistryDB
- Use BlockData and BatchData from common
- Add `GetAllTokens` method
- Uncomment and update GetL1UserTxs (with corresponding tests)
- Til
- Rename all instances of RegisterToken to AddToken (to follow the smart
contract implementation naming)
- Use BlockData and BatchData from common
- Move testL1CoordinatorTxs and testL2Txs to a separate struct
from BatchData in Context
- Start Context with BatchNum = 1 (which the protocol defines to be the
first batchNum)
- In every Batch, set StateRoot and ExitRoot to a non-nil big.Int
(zero).
- In all L1Txs, if LoadAmount is not used, set it to 0; if Amount is not
used, set it to 0; so that no *big.Int is nil.
- In L1UserTx, don't set BatchNum, because when L1UserTxs are created
and obtained by the synchronizer, the BatchNum is not known yet (it's
a synchronizer job to set it)
- In L1UserTxs, set `UserOrigin` and set `ToForgeL1TxsNum`.
4 years ago Update missing parts, improve til, and more
- Node
- Updated configuration to initialize the interface to all the smart
contracts
- Common
- Moved BlockData and BatchData types to common so that they can be
shared among: historydb, til and synchronizer
- Remove hash.go (it was never used)
- Remove slot.go (it was never used)
- Remove smartcontractparams.go (it was never used, and appropriate
structs are defined in `eth/`)
- Comment state / status method until requirements of this method are
properly defined, and move it to Synchronizer
- Synchronizer
- Simplify `Sync` routine to only sync one block per call, and return
useful information.
- Use BlockData and BatchData from common
- Check that events belong to the expected block hash
- In L1Batch, query L1UserTxs from HistoryDB
- Fill ERC20 token information
- Test AddTokens with test.Client
- HistryDB
- Use BlockData and BatchData from common
- Add `GetAllTokens` method
- Uncomment and update GetL1UserTxs (with corresponding tests)
- Til
- Rename all instances of RegisterToken to AddToken (to follow the smart
contract implementation naming)
- Use BlockData and BatchData from common
- Move testL1CoordinatorTxs and testL2Txs to a separate struct
from BatchData in Context
- Start Context with BatchNum = 1 (which the protocol defines to be the
first batchNum)
- In every Batch, set StateRoot and ExitRoot to a non-nil big.Int
(zero).
- In all L1Txs, if LoadAmount is not used, set it to 0; if Amount is not
used, set it to 0; so that no *big.Int is nil.
- In L1UserTx, don't set BatchNum, because when L1UserTxs are created
and obtained by the synchronizer, the BatchNum is not known yet (it's
a synchronizer job to set it)
- In L1UserTxs, set `UserOrigin` and set `ToForgeL1TxsNum`.
4 years ago Update missing parts, improve til, and more
- Node
- Updated configuration to initialize the interface to all the smart
contracts
- Common
- Moved BlockData and BatchData types to common so that they can be
shared among: historydb, til and synchronizer
- Remove hash.go (it was never used)
- Remove slot.go (it was never used)
- Remove smartcontractparams.go (it was never used, and appropriate
structs are defined in `eth/`)
- Comment state / status method until requirements of this method are
properly defined, and move it to Synchronizer
- Synchronizer
- Simplify `Sync` routine to only sync one block per call, and return
useful information.
- Use BlockData and BatchData from common
- Check that events belong to the expected block hash
- In L1Batch, query L1UserTxs from HistoryDB
- Fill ERC20 token information
- Test AddTokens with test.Client
- HistryDB
- Use BlockData and BatchData from common
- Add `GetAllTokens` method
- Uncomment and update GetL1UserTxs (with corresponding tests)
- Til
- Rename all instances of RegisterToken to AddToken (to follow the smart
contract implementation naming)
- Use BlockData and BatchData from common
- Move testL1CoordinatorTxs and testL2Txs to a separate struct
from BatchData in Context
- Start Context with BatchNum = 1 (which the protocol defines to be the
first batchNum)
- In every Batch, set StateRoot and ExitRoot to a non-nil big.Int
(zero).
- In all L1Txs, if LoadAmount is not used, set it to 0; if Amount is not
used, set it to 0; so that no *big.Int is nil.
- In L1UserTx, don't set BatchNum, because when L1UserTxs are created
and obtained by the synchronizer, the BatchNum is not known yet (it's
a synchronizer job to set it)
- In L1UserTxs, set `UserOrigin` and set `ToForgeL1TxsNum`.
4 years ago Redo coordinator structure, connect API to node
- API:
- Modify the constructor so that hardcoded rollup constants don't need
to be passed (introduce a `Config` and use `configAPI` internally)
- Common:
- Update rollup constants with proper *big.Int when required
- Add BidCoordinator and Slot structs used by the HistoryDB and
Synchronizer.
- Add helper methods to AuctionConstants
- AuctionVariables: Add column `DefaultSlotSetBidSlotNum` (in the SQL
table: `default_slot_set_bid_slot_num`), which indicates at which
slotNum does the `DefaultSlotSetBid` specified starts applying.
- Config:
- Move coordinator exclusive configuration from the node config to the
coordinator config
- Coordinator:
- Reorganize the code towards having the goroutines started and stopped
from the coordinator itself instead of the node.
- Remove all stop and stopped channels, and use context.Context and
sync.WaitGroup instead.
- Remove BatchInfo setters and assing variables directly
- In ServerProof and ServerProofPool use context instead stop channel.
- Use message passing to notify the coordinator about sync updates and
reorgs
- Introduce the Pipeline, which can be started and stopped by the
Coordinator
- Introduce the TxManager, which manages ethereum transactions (the
TxManager is also in charge of making the forge call to the rollup
smart contract). The TxManager keeps ethereum transactions and:
1. Waits for the transaction to be accepted
2. Waits for the transaction to be confirmed for N blocks
- In forge logic, first prepare a batch and then wait for an available
server proof to have all work ready once the proof server is ready.
- Remove the `isForgeSequence` method which was querying the smart
contract, and instead use notifications sent by the Synchronizer to
figure out if it's forging time.
- Update test (which is a minimal test to manually see if the
coordinator starts)
- HistoryDB:
- Add method to get the number of batches in a slot (used to detect when
a slot has passed the bid winner forging deadline)
- Add method to get the best bid and associated coordinator of a slot
(used to detect the forgerAddress that can forge the slot)
- General:
- Rename some instances of `currentBlock` to `lastBlock` to be more
clear.
- Node:
- Connect the API to the node and call the methods to update cached
state when the sync advances blocks.
- Call methods to update Coordinator state when the sync advances blocks
and finds reorgs.
- Synchronizer:
- Add Auction field in the Stats, which contain the current slot with
info about highest bidder and other related info required to know who
can forge in the current block.
- Better organization of cached state:
- On Sync, update the internal cached state
- On Init or Reorg, load the state from HistoryDB into the
internal cached state.
4 years ago Redo coordinator structure, connect API to node
- API:
- Modify the constructor so that hardcoded rollup constants don't need
to be passed (introduce a `Config` and use `configAPI` internally)
- Common:
- Update rollup constants with proper *big.Int when required
- Add BidCoordinator and Slot structs used by the HistoryDB and
Synchronizer.
- Add helper methods to AuctionConstants
- AuctionVariables: Add column `DefaultSlotSetBidSlotNum` (in the SQL
table: `default_slot_set_bid_slot_num`), which indicates at which
slotNum does the `DefaultSlotSetBid` specified starts applying.
- Config:
- Move coordinator exclusive configuration from the node config to the
coordinator config
- Coordinator:
- Reorganize the code towards having the goroutines started and stopped
from the coordinator itself instead of the node.
- Remove all stop and stopped channels, and use context.Context and
sync.WaitGroup instead.
- Remove BatchInfo setters and assing variables directly
- In ServerProof and ServerProofPool use context instead stop channel.
- Use message passing to notify the coordinator about sync updates and
reorgs
- Introduce the Pipeline, which can be started and stopped by the
Coordinator
- Introduce the TxManager, which manages ethereum transactions (the
TxManager is also in charge of making the forge call to the rollup
smart contract). The TxManager keeps ethereum transactions and:
1. Waits for the transaction to be accepted
2. Waits for the transaction to be confirmed for N blocks
- In forge logic, first prepare a batch and then wait for an available
server proof to have all work ready once the proof server is ready.
- Remove the `isForgeSequence` method which was querying the smart
contract, and instead use notifications sent by the Synchronizer to
figure out if it's forging time.
- Update test (which is a minimal test to manually see if the
coordinator starts)
- HistoryDB:
- Add method to get the number of batches in a slot (used to detect when
a slot has passed the bid winner forging deadline)
- Add method to get the best bid and associated coordinator of a slot
(used to detect the forgerAddress that can forge the slot)
- General:
- Rename some instances of `currentBlock` to `lastBlock` to be more
clear.
- Node:
- Connect the API to the node and call the methods to update cached
state when the sync advances blocks.
- Call methods to update Coordinator state when the sync advances blocks
and finds reorgs.
- Synchronizer:
- Add Auction field in the Stats, which contain the current slot with
info about highest bidder and other related info required to know who
can forge in the current block.
- Better organization of cached state:
- On Sync, update the internal cached state
- On Init or Reorg, load the state from HistoryDB into the
internal cached state.
4 years ago Redo coordinator structure, connect API to node
- API:
- Modify the constructor so that hardcoded rollup constants don't need
to be passed (introduce a `Config` and use `configAPI` internally)
- Common:
- Update rollup constants with proper *big.Int when required
- Add BidCoordinator and Slot structs used by the HistoryDB and
Synchronizer.
- Add helper methods to AuctionConstants
- AuctionVariables: Add column `DefaultSlotSetBidSlotNum` (in the SQL
table: `default_slot_set_bid_slot_num`), which indicates at which
slotNum does the `DefaultSlotSetBid` specified starts applying.
- Config:
- Move coordinator exclusive configuration from the node config to the
coordinator config
- Coordinator:
- Reorganize the code towards having the goroutines started and stopped
from the coordinator itself instead of the node.
- Remove all stop and stopped channels, and use context.Context and
sync.WaitGroup instead.
- Remove BatchInfo setters and assing variables directly
- In ServerProof and ServerProofPool use context instead stop channel.
- Use message passing to notify the coordinator about sync updates and
reorgs
- Introduce the Pipeline, which can be started and stopped by the
Coordinator
- Introduce the TxManager, which manages ethereum transactions (the
TxManager is also in charge of making the forge call to the rollup
smart contract). The TxManager keeps ethereum transactions and:
1. Waits for the transaction to be accepted
2. Waits for the transaction to be confirmed for N blocks
- In forge logic, first prepare a batch and then wait for an available
server proof to have all work ready once the proof server is ready.
- Remove the `isForgeSequence` method which was querying the smart
contract, and instead use notifications sent by the Synchronizer to
figure out if it's forging time.
- Update test (which is a minimal test to manually see if the
coordinator starts)
- HistoryDB:
- Add method to get the number of batches in a slot (used to detect when
a slot has passed the bid winner forging deadline)
- Add method to get the best bid and associated coordinator of a slot
(used to detect the forgerAddress that can forge the slot)
- General:
- Rename some instances of `currentBlock` to `lastBlock` to be more
clear.
- Node:
- Connect the API to the node and call the methods to update cached
state when the sync advances blocks.
- Call methods to update Coordinator state when the sync advances blocks
and finds reorgs.
- Synchronizer:
- Add Auction field in the Stats, which contain the current slot with
info about highest bidder and other related info required to know who
can forge in the current block.
- Better organization of cached state:
- On Sync, update the internal cached state
- On Init or Reorg, load the state from HistoryDB into the
internal cached state.
4 years ago Redo coordinator structure, connect API to node
- API:
- Modify the constructor so that hardcoded rollup constants don't need
to be passed (introduce a `Config` and use `configAPI` internally)
- Common:
- Update rollup constants with proper *big.Int when required
- Add BidCoordinator and Slot structs used by the HistoryDB and
Synchronizer.
- Add helper methods to AuctionConstants
- AuctionVariables: Add column `DefaultSlotSetBidSlotNum` (in the SQL
table: `default_slot_set_bid_slot_num`), which indicates at which
slotNum does the `DefaultSlotSetBid` specified starts applying.
- Config:
- Move coordinator exclusive configuration from the node config to the
coordinator config
- Coordinator:
- Reorganize the code towards having the goroutines started and stopped
from the coordinator itself instead of the node.
- Remove all stop and stopped channels, and use context.Context and
sync.WaitGroup instead.
- Remove BatchInfo setters and assing variables directly
- In ServerProof and ServerProofPool use context instead stop channel.
- Use message passing to notify the coordinator about sync updates and
reorgs
- Introduce the Pipeline, which can be started and stopped by the
Coordinator
- Introduce the TxManager, which manages ethereum transactions (the
TxManager is also in charge of making the forge call to the rollup
smart contract). The TxManager keeps ethereum transactions and:
1. Waits for the transaction to be accepted
2. Waits for the transaction to be confirmed for N blocks
- In forge logic, first prepare a batch and then wait for an available
server proof to have all work ready once the proof server is ready.
- Remove the `isForgeSequence` method which was querying the smart
contract, and instead use notifications sent by the Synchronizer to
figure out if it's forging time.
- Update test (which is a minimal test to manually see if the
coordinator starts)
- HistoryDB:
- Add method to get the number of batches in a slot (used to detect when
a slot has passed the bid winner forging deadline)
- Add method to get the best bid and associated coordinator of a slot
(used to detect the forgerAddress that can forge the slot)
- General:
- Rename some instances of `currentBlock` to `lastBlock` to be more
clear.
- Node:
- Connect the API to the node and call the methods to update cached
state when the sync advances blocks.
- Call methods to update Coordinator state when the sync advances blocks
and finds reorgs.
- Synchronizer:
- Add Auction field in the Stats, which contain the current slot with
info about highest bidder and other related info required to know who
can forge in the current block.
- Better organization of cached state:
- On Sync, update the internal cached state
- On Init or Reorg, load the state from HistoryDB into the
internal cached state.
4 years ago Fix exit table, set delayed_withdrawn in exits
- In exit table, `instant_withdrawn`, `delayed_withdraw_request`, and
`delayed_withdrawn` were referencing batch_num. But these actions happen
outside a batch, so they should reference a block_num.
- Process delayed withdrawns:
- In Synchronizer, first match a Rollup delayed withdrawn request, with the
WDelayer deposit (via TxHash), and store the owner and token associated
with the delayed withdrawn.
- In HistoryDB: store the owner and token of a delayed withdrawal request
in the exit_tree, and set delayed_withdrawn when the withdraw is done in
the WDelayer.
- Update dependency of sqlx to master
- Last release of sqlx is from 2018 October, and it doesn't support
`NamedQuery` with a slice of structs, which is used in this commit.
4 years ago Fix exit table, set delayed_withdrawn in exits
- In exit table, `instant_withdrawn`, `delayed_withdraw_request`, and
`delayed_withdrawn` were referencing batch_num. But these actions happen
outside a batch, so they should reference a block_num.
- Process delayed withdrawns:
- In Synchronizer, first match a Rollup delayed withdrawn request, with the
WDelayer deposit (via TxHash), and store the owner and token associated
with the delayed withdrawn.
- In HistoryDB: store the owner and token of a delayed withdrawal request
in the exit_tree, and set delayed_withdrawn when the withdraw is done in
the WDelayer.
- Update dependency of sqlx to master
- Last release of sqlx is from 2018 October, and it doesn't support
`NamedQuery` with a slice of structs, which is used in this commit.
4 years ago Fix exit table, set delayed_withdrawn in exits
- In exit table, `instant_withdrawn`, `delayed_withdraw_request`, and
`delayed_withdrawn` were referencing batch_num. But these actions happen
outside a batch, so they should reference a block_num.
- Process delayed withdrawns:
- In Synchronizer, first match a Rollup delayed withdrawn request, with the
WDelayer deposit (via TxHash), and store the owner and token associated
with the delayed withdrawn.
- In HistoryDB: store the owner and token of a delayed withdrawal request
in the exit_tree, and set delayed_withdrawn when the withdraw is done in
the WDelayer.
- Update dependency of sqlx to master
- Last release of sqlx is from 2018 October, and it doesn't support
`NamedQuery` with a slice of structs, which is used in this commit.
4 years ago Fix exit table, set delayed_withdrawn in exits
- In exit table, `instant_withdrawn`, `delayed_withdraw_request`, and
`delayed_withdrawn` were referencing batch_num. But these actions happen
outside a batch, so they should reference a block_num.
- Process delayed withdrawns:
- In Synchronizer, first match a Rollup delayed withdrawn request, with the
WDelayer deposit (via TxHash), and store the owner and token associated
with the delayed withdrawn.
- In HistoryDB: store the owner and token of a delayed withdrawal request
in the exit_tree, and set delayed_withdrawn when the withdraw is done in
the WDelayer.
- Update dependency of sqlx to master
- Last release of sqlx is from 2018 October, and it doesn't support
`NamedQuery` with a slice of structs, which is used in this commit.
4 years ago Update coordinator, call all api update functions
- Common:
- Rename Block.EthBlockNum to Block.Num to avoid unneeded repetition
- API:
- Add UpdateNetworkInfoBlock to update just block information, to be
used when the node is not yet synchronized
- Node:
- Call API.UpdateMetrics and UpdateRecommendedFee in a loop, with
configurable time intervals
- Synchronizer:
- When mapping events by TxHash, use an array to support the possibility
of multiple calls of the same function happening in the same
transaction (for example, a smart contract in a single transaction
could call withdraw with delay twice, which would generate 2 withdraw
events, and 2 deposit events).
- In Stats, keep entire LastBlock instead of just the blockNum
- In Stats, add lastL1BatchBlock
- Test Stats and SCVars
- Coordinator:
- Enable writing the BatchInfo in every step of the pipeline to disk
(with JSON text files) for debugging purposes.
- Move the Pipeline functionality from the Coordinator to its own struct
(Pipeline)
- Implement shouldL1lL2Batch
- In TxManager, implement logic to perform several attempts when doing
ethereum node RPC calls before considering the error. (Both for calls
to forgeBatch and transaction receipt)
- In TxManager, reorganize the flow and note the specific points in
which actions are made when err != nil
- HistoryDB:
- Implement GetLastL1BatchBlockNum: returns the blockNum of the latest
forged l1Batch, to help the coordinator decide when to forge an
L1Batch.
- EthereumClient and test.Client:
- Update EthBlockByNumber to return the last block when the passed
number is -1.
4 years ago Fix exit table, set delayed_withdrawn in exits
- In exit table, `instant_withdrawn`, `delayed_withdraw_request`, and
`delayed_withdrawn` were referencing batch_num. But these actions happen
outside a batch, so they should reference a block_num.
- Process delayed withdrawns:
- In Synchronizer, first match a Rollup delayed withdrawn request, with the
WDelayer deposit (via TxHash), and store the owner and token associated
with the delayed withdrawn.
- In HistoryDB: store the owner and token of a delayed withdrawal request
in the exit_tree, and set delayed_withdrawn when the withdraw is done in
the WDelayer.
- Update dependency of sqlx to master
- Last release of sqlx is from 2018 October, and it doesn't support
`NamedQuery` with a slice of structs, which is used in this commit.
4 years ago Fix exit table, set delayed_withdrawn in exits
- In exit table, `instant_withdrawn`, `delayed_withdraw_request`, and
`delayed_withdrawn` were referencing batch_num. But these actions happen
outside a batch, so they should reference a block_num.
- Process delayed withdrawns:
- In Synchronizer, first match a Rollup delayed withdrawn request, with the
WDelayer deposit (via TxHash), and store the owner and token associated
with the delayed withdrawn.
- In HistoryDB: store the owner and token of a delayed withdrawal request
in the exit_tree, and set delayed_withdrawn when the withdraw is done in
the WDelayer.
- Update dependency of sqlx to master
- Last release of sqlx is from 2018 October, and it doesn't support
`NamedQuery` with a slice of structs, which is used in this commit.
4 years ago Fix exit table, set delayed_withdrawn in exits
- In exit table, `instant_withdrawn`, `delayed_withdraw_request`, and
`delayed_withdrawn` were referencing batch_num. But these actions happen
outside a batch, so they should reference a block_num.
- Process delayed withdrawns:
- In Synchronizer, first match a Rollup delayed withdrawn request, with the
WDelayer deposit (via TxHash), and store the owner and token associated
with the delayed withdrawn.
- In HistoryDB: store the owner and token of a delayed withdrawal request
in the exit_tree, and set delayed_withdrawn when the withdraw is done in
the WDelayer.
- Update dependency of sqlx to master
- Last release of sqlx is from 2018 October, and it doesn't support
`NamedQuery` with a slice of structs, which is used in this commit.
4 years ago Update coordinator, call all api update functions
- Common:
- Rename Block.EthBlockNum to Block.Num to avoid unneeded repetition
- API:
- Add UpdateNetworkInfoBlock to update just block information, to be
used when the node is not yet synchronized
- Node:
- Call API.UpdateMetrics and UpdateRecommendedFee in a loop, with
configurable time intervals
- Synchronizer:
- When mapping events by TxHash, use an array to support the possibility
of multiple calls of the same function happening in the same
transaction (for example, a smart contract in a single transaction
could call withdraw with delay twice, which would generate 2 withdraw
events, and 2 deposit events).
- In Stats, keep entire LastBlock instead of just the blockNum
- In Stats, add lastL1BatchBlock
- Test Stats and SCVars
- Coordinator:
- Enable writing the BatchInfo in every step of the pipeline to disk
(with JSON text files) for debugging purposes.
- Move the Pipeline functionality from the Coordinator to its own struct
(Pipeline)
- Implement shouldL1lL2Batch
- In TxManager, implement logic to perform several attempts when doing
ethereum node RPC calls before considering the error. (Both for calls
to forgeBatch and transaction receipt)
- In TxManager, reorganize the flow and note the specific points in
which actions are made when err != nil
- HistoryDB:
- Implement GetLastL1BatchBlockNum: returns the blockNum of the latest
forged l1Batch, to help the coordinator decide when to forge an
L1Batch.
- EthereumClient and test.Client:
- Update EthBlockByNumber to return the last block when the passed
number is -1.
4 years ago Fix exit table, set delayed_withdrawn in exits
- In exit table, `instant_withdrawn`, `delayed_withdraw_request`, and
`delayed_withdrawn` were referencing batch_num. But these actions happen
outside a batch, so they should reference a block_num.
- Process delayed withdrawns:
- In Synchronizer, first match a Rollup delayed withdrawn request, with the
WDelayer deposit (via TxHash), and store the owner and token associated
with the delayed withdrawn.
- In HistoryDB: store the owner and token of a delayed withdrawal request
in the exit_tree, and set delayed_withdrawn when the withdraw is done in
the WDelayer.
- Update dependency of sqlx to master
- Last release of sqlx is from 2018 October, and it doesn't support
`NamedQuery` with a slice of structs, which is used in this commit.
4 years ago Update coordinator, call all api update functions
- Common:
- Rename Block.EthBlockNum to Block.Num to avoid unneeded repetition
- API:
- Add UpdateNetworkInfoBlock to update just block information, to be
used when the node is not yet synchronized
- Node:
- Call API.UpdateMetrics and UpdateRecommendedFee in a loop, with
configurable time intervals
- Synchronizer:
- When mapping events by TxHash, use an array to support the possibility
of multiple calls of the same function happening in the same
transaction (for example, a smart contract in a single transaction
could call withdraw with delay twice, which would generate 2 withdraw
events, and 2 deposit events).
- In Stats, keep entire LastBlock instead of just the blockNum
- In Stats, add lastL1BatchBlock
- Test Stats and SCVars
- Coordinator:
- Enable writing the BatchInfo in every step of the pipeline to disk
(with JSON text files) for debugging purposes.
- Move the Pipeline functionality from the Coordinator to its own struct
(Pipeline)
- Implement shouldL1lL2Batch
- In TxManager, implement logic to perform several attempts when doing
ethereum node RPC calls before considering the error. (Both for calls
to forgeBatch and transaction receipt)
- In TxManager, reorganize the flow and note the specific points in
which actions are made when err != nil
- HistoryDB:
- Implement GetLastL1BatchBlockNum: returns the blockNum of the latest
forged l1Batch, to help the coordinator decide when to forge an
L1Batch.
- EthereumClient and test.Client:
- Update EthBlockByNumber to return the last block when the passed
number is -1.
4 years ago Update coordinator, call all api update functions
- Common:
- Rename Block.EthBlockNum to Block.Num to avoid unneeded repetition
- API:
- Add UpdateNetworkInfoBlock to update just block information, to be
used when the node is not yet synchronized
- Node:
- Call API.UpdateMetrics and UpdateRecommendedFee in a loop, with
configurable time intervals
- Synchronizer:
- When mapping events by TxHash, use an array to support the possibility
of multiple calls of the same function happening in the same
transaction (for example, a smart contract in a single transaction
could call withdraw with delay twice, which would generate 2 withdraw
events, and 2 deposit events).
- In Stats, keep entire LastBlock instead of just the blockNum
- In Stats, add lastL1BatchBlock
- Test Stats and SCVars
- Coordinator:
- Enable writing the BatchInfo in every step of the pipeline to disk
(with JSON text files) for debugging purposes.
- Move the Pipeline functionality from the Coordinator to its own struct
(Pipeline)
- Implement shouldL1lL2Batch
- In TxManager, implement logic to perform several attempts when doing
ethereum node RPC calls before considering the error. (Both for calls
to forgeBatch and transaction receipt)
- In TxManager, reorganize the flow and note the specific points in
which actions are made when err != nil
- HistoryDB:
- Implement GetLastL1BatchBlockNum: returns the blockNum of the latest
forged l1Batch, to help the coordinator decide when to forge an
L1Batch.
- EthereumClient and test.Client:
- Update EthBlockByNumber to return the last block when the passed
number is -1.
4 years ago Fix exit table, set delayed_withdrawn in exits
- In exit table, `instant_withdrawn`, `delayed_withdraw_request`, and
`delayed_withdrawn` were referencing batch_num. But these actions happen
outside a batch, so they should reference a block_num.
- Process delayed withdrawns:
- In Synchronizer, first match a Rollup delayed withdrawn request, with the
WDelayer deposit (via TxHash), and store the owner and token associated
with the delayed withdrawn.
- In HistoryDB: store the owner and token of a delayed withdrawal request
in the exit_tree, and set delayed_withdrawn when the withdraw is done in
the WDelayer.
- Update dependency of sqlx to master
- Last release of sqlx is from 2018 October, and it doesn't support
`NamedQuery` with a slice of structs, which is used in this commit.
4 years ago Update coordinator, call all api update functions
- Common:
- Rename Block.EthBlockNum to Block.Num to avoid unneeded repetition
- API:
- Add UpdateNetworkInfoBlock to update just block information, to be
used when the node is not yet synchronized
- Node:
- Call API.UpdateMetrics and UpdateRecommendedFee in a loop, with
configurable time intervals
- Synchronizer:
- When mapping events by TxHash, use an array to support the possibility
of multiple calls of the same function happening in the same
transaction (for example, a smart contract in a single transaction
could call withdraw with delay twice, which would generate 2 withdraw
events, and 2 deposit events).
- In Stats, keep entire LastBlock instead of just the blockNum
- In Stats, add lastL1BatchBlock
- Test Stats and SCVars
- Coordinator:
- Enable writing the BatchInfo in every step of the pipeline to disk
(with JSON text files) for debugging purposes.
- Move the Pipeline functionality from the Coordinator to its own struct
(Pipeline)
- Implement shouldL1lL2Batch
- In TxManager, implement logic to perform several attempts when doing
ethereum node RPC calls before considering the error. (Both for calls
to forgeBatch and transaction receipt)
- In TxManager, reorganize the flow and note the specific points in
which actions are made when err != nil
- HistoryDB:
- Implement GetLastL1BatchBlockNum: returns the blockNum of the latest
forged l1Batch, to help the coordinator decide when to forge an
L1Batch.
- EthereumClient and test.Client:
- Update EthBlockByNumber to return the last block when the passed
number is -1.
4 years ago Fix exit table, set delayed_withdrawn in exits
- In exit table, `instant_withdrawn`, `delayed_withdraw_request`, and
`delayed_withdrawn` were referencing batch_num. But these actions happen
outside a batch, so they should reference a block_num.
- Process delayed withdrawns:
- In Synchronizer, first match a Rollup delayed withdrawn request, with the
WDelayer deposit (via TxHash), and store the owner and token associated
with the delayed withdrawn.
- In HistoryDB: store the owner and token of a delayed withdrawal request
in the exit_tree, and set delayed_withdrawn when the withdraw is done in
the WDelayer.
- Update dependency of sqlx to master
- Last release of sqlx is from 2018 October, and it doesn't support
`NamedQuery` with a slice of structs, which is used in this commit.
4 years ago Update coordinator, call all api update functions
- Common:
- Rename Block.EthBlockNum to Block.Num to avoid unneeded repetition
- API:
- Add UpdateNetworkInfoBlock to update just block information, to be
used when the node is not yet synchronized
- Node:
- Call API.UpdateMetrics and UpdateRecommendedFee in a loop, with
configurable time intervals
- Synchronizer:
- When mapping events by TxHash, use an array to support the possibility
of multiple calls of the same function happening in the same
transaction (for example, a smart contract in a single transaction
could call withdraw with delay twice, which would generate 2 withdraw
events, and 2 deposit events).
- In Stats, keep entire LastBlock instead of just the blockNum
- In Stats, add lastL1BatchBlock
- Test Stats and SCVars
- Coordinator:
- Enable writing the BatchInfo in every step of the pipeline to disk
(with JSON text files) for debugging purposes.
- Move the Pipeline functionality from the Coordinator to its own struct
(Pipeline)
- Implement shouldL1lL2Batch
- In TxManager, implement logic to perform several attempts when doing
ethereum node RPC calls before considering the error. (Both for calls
to forgeBatch and transaction receipt)
- In TxManager, reorganize the flow and note the specific points in
which actions are made when err != nil
- HistoryDB:
- Implement GetLastL1BatchBlockNum: returns the blockNum of the latest
forged l1Batch, to help the coordinator decide when to forge an
L1Batch.
- EthereumClient and test.Client:
- Update EthBlockByNumber to return the last block when the passed
number is -1.
4 years ago Fix exit table, set delayed_withdrawn in exits
- In exit table, `instant_withdrawn`, `delayed_withdraw_request`, and
`delayed_withdrawn` were referencing batch_num. But these actions happen
outside a batch, so they should reference a block_num.
- Process delayed withdrawns:
- In Synchronizer, first match a Rollup delayed withdrawn request, with the
WDelayer deposit (via TxHash), and store the owner and token associated
with the delayed withdrawn.
- In HistoryDB: store the owner and token of a delayed withdrawal request
in the exit_tree, and set delayed_withdrawn when the withdraw is done in
the WDelayer.
- Update dependency of sqlx to master
- Last release of sqlx is from 2018 October, and it doesn't support
`NamedQuery` with a slice of structs, which is used in this commit.
4 years ago Update coordinator, call all api update functions
- Common:
- Rename Block.EthBlockNum to Block.Num to avoid unneeded repetition
- API:
- Add UpdateNetworkInfoBlock to update just block information, to be
used when the node is not yet synchronized
- Node:
- Call API.UpdateMetrics and UpdateRecommendedFee in a loop, with
configurable time intervals
- Synchronizer:
- When mapping events by TxHash, use an array to support the possibility
of multiple calls of the same function happening in the same
transaction (for example, a smart contract in a single transaction
could call withdraw with delay twice, which would generate 2 withdraw
events, and 2 deposit events).
- In Stats, keep entire LastBlock instead of just the blockNum
- In Stats, add lastL1BatchBlock
- Test Stats and SCVars
- Coordinator:
- Enable writing the BatchInfo in every step of the pipeline to disk
(with JSON text files) for debugging purposes.
- Move the Pipeline functionality from the Coordinator to its own struct
(Pipeline)
- Implement shouldL1lL2Batch
- In TxManager, implement logic to perform several attempts when doing
ethereum node RPC calls before considering the error. (Both for calls
to forgeBatch and transaction receipt)
- In TxManager, reorganize the flow and note the specific points in
which actions are made when err != nil
- HistoryDB:
- Implement GetLastL1BatchBlockNum: returns the blockNum of the latest
forged l1Batch, to help the coordinator decide when to forge an
L1Batch.
- EthereumClient and test.Client:
- Update EthBlockByNumber to return the last block when the passed
number is -1.
4 years ago Redo coordinator structure, connect API to node
- API:
- Modify the constructor so that hardcoded rollup constants don't need
to be passed (introduce a `Config` and use `configAPI` internally)
- Common:
- Update rollup constants with proper *big.Int when required
- Add BidCoordinator and Slot structs used by the HistoryDB and
Synchronizer.
- Add helper methods to AuctionConstants
- AuctionVariables: Add column `DefaultSlotSetBidSlotNum` (in the SQL
table: `default_slot_set_bid_slot_num`), which indicates at which
slotNum does the `DefaultSlotSetBid` specified starts applying.
- Config:
- Move coordinator exclusive configuration from the node config to the
coordinator config
- Coordinator:
- Reorganize the code towards having the goroutines started and stopped
from the coordinator itself instead of the node.
- Remove all stop and stopped channels, and use context.Context and
sync.WaitGroup instead.
- Remove BatchInfo setters and assing variables directly
- In ServerProof and ServerProofPool use context instead stop channel.
- Use message passing to notify the coordinator about sync updates and
reorgs
- Introduce the Pipeline, which can be started and stopped by the
Coordinator
- Introduce the TxManager, which manages ethereum transactions (the
TxManager is also in charge of making the forge call to the rollup
smart contract). The TxManager keeps ethereum transactions and:
1. Waits for the transaction to be accepted
2. Waits for the transaction to be confirmed for N blocks
- In forge logic, first prepare a batch and then wait for an available
server proof to have all work ready once the proof server is ready.
- Remove the `isForgeSequence` method which was querying the smart
contract, and instead use notifications sent by the Synchronizer to
figure out if it's forging time.
- Update test (which is a minimal test to manually see if the
coordinator starts)
- HistoryDB:
- Add method to get the number of batches in a slot (used to detect when
a slot has passed the bid winner forging deadline)
- Add method to get the best bid and associated coordinator of a slot
(used to detect the forgerAddress that can forge the slot)
- General:
- Rename some instances of `currentBlock` to `lastBlock` to be more
clear.
- Node:
- Connect the API to the node and call the methods to update cached
state when the sync advances blocks.
- Call methods to update Coordinator state when the sync advances blocks
and finds reorgs.
- Synchronizer:
- Add Auction field in the Stats, which contain the current slot with
info about highest bidder and other related info required to know who
can forge in the current block.
- Better organization of cached state:
- On Sync, update the internal cached state
- On Init or Reorg, load the state from HistoryDB into the
internal cached state.
4 years ago Redo coordinator structure, connect API to node
- API:
- Modify the constructor so that hardcoded rollup constants don't need
to be passed (introduce a `Config` and use `configAPI` internally)
- Common:
- Update rollup constants with proper *big.Int when required
- Add BidCoordinator and Slot structs used by the HistoryDB and
Synchronizer.
- Add helper methods to AuctionConstants
- AuctionVariables: Add column `DefaultSlotSetBidSlotNum` (in the SQL
table: `default_slot_set_bid_slot_num`), which indicates at which
slotNum does the `DefaultSlotSetBid` specified starts applying.
- Config:
- Move coordinator exclusive configuration from the node config to the
coordinator config
- Coordinator:
- Reorganize the code towards having the goroutines started and stopped
from the coordinator itself instead of the node.
- Remove all stop and stopped channels, and use context.Context and
sync.WaitGroup instead.
- Remove BatchInfo setters and assing variables directly
- In ServerProof and ServerProofPool use context instead stop channel.
- Use message passing to notify the coordinator about sync updates and
reorgs
- Introduce the Pipeline, which can be started and stopped by the
Coordinator
- Introduce the TxManager, which manages ethereum transactions (the
TxManager is also in charge of making the forge call to the rollup
smart contract). The TxManager keeps ethereum transactions and:
1. Waits for the transaction to be accepted
2. Waits for the transaction to be confirmed for N blocks
- In forge logic, first prepare a batch and then wait for an available
server proof to have all work ready once the proof server is ready.
- Remove the `isForgeSequence` method which was querying the smart
contract, and instead use notifications sent by the Synchronizer to
figure out if it's forging time.
- Update test (which is a minimal test to manually see if the
coordinator starts)
- HistoryDB:
- Add method to get the number of batches in a slot (used to detect when
a slot has passed the bid winner forging deadline)
- Add method to get the best bid and associated coordinator of a slot
(used to detect the forgerAddress that can forge the slot)
- General:
- Rename some instances of `currentBlock` to `lastBlock` to be more
clear.
- Node:
- Connect the API to the node and call the methods to update cached
state when the sync advances blocks.
- Call methods to update Coordinator state when the sync advances blocks
and finds reorgs.
- Synchronizer:
- Add Auction field in the Stats, which contain the current slot with
info about highest bidder and other related info required to know who
can forge in the current block.
- Better organization of cached state:
- On Sync, update the internal cached state
- On Init or Reorg, load the state from HistoryDB into the
internal cached state.
4 years ago |
|
package historydb
import ( "database/sql" "math" "math/big" "os" "testing" "time"
ethCommon "github.com/ethereum/go-ethereum/common" "github.com/hermeznetwork/hermez-node/common" dbUtils "github.com/hermeznetwork/hermez-node/db" "github.com/hermeznetwork/hermez-node/log" "github.com/hermeznetwork/hermez-node/test" "github.com/hermeznetwork/hermez-node/test/til" "github.com/hermeznetwork/tracerr" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" )
var historyDB *HistoryDB
// In order to run the test you need to run a Posgres DB with
// a database named "history" that is accessible by
// user: "hermez"
// pass: set it using the env var POSTGRES_PASS
// This can be achieved by running: POSTGRES_PASS=your_strong_pass && sudo docker run --rm --name hermez-db-test -p 5432:5432 -e POSTGRES_DB=history -e POSTGRES_USER=hermez -e POSTGRES_PASSWORD=$POSTGRES_PASS -d postgres && sleep 2s && sudo docker exec -it hermez-db-test psql -a history -U hermez -c "CREATE DATABASE l2;"
// After running the test you can stop the container by running: sudo docker kill hermez-db-test
// If you already did that for the L2DB you don't have to do it again
func TestMain(m *testing.M) { // init DB
pass := os.Getenv("POSTGRES_PASS") db, err := dbUtils.InitSQLDB(5432, "localhost", "hermez", pass, "hermez") if err != nil { panic(err) } historyDB = NewHistoryDB(db) if err != nil { panic(err) } // Run tests
result := m.Run() // Close DB
if err := db.Close(); err != nil { log.Error("Error closing the history DB:", err) } os.Exit(result) }
func TestBlocks(t *testing.T) { var fromBlock, toBlock int64 fromBlock = 0 toBlock = 7 // Reset DB
test.WipeDB(historyDB.DB()) // Generate blocks using til
set1 := ` Type: Blockchain // block 0 is stored as default in the DB
// block 1 does not exist
> block // blockNum=2
> block // blockNum=3
> block // blockNum=4
> block // blockNum=5
> block // blockNum=6
` tc := til.NewContext(1) blocks, err := tc.GenerateBlocks(set1) require.NoError(t, err) // Save timestamp of a block with UTC and change it without UTC
timestamp := time.Now().Add(time.Second * 13) blocks[fromBlock].Block.Timestamp = timestamp // Insert blocks into DB
for i := 0; i < len(blocks); i++ { err := historyDB.AddBlock(&blocks[i].Block) assert.NoError(t, err) } // Add block 0 to the generated blocks
blocks = append( []common.BlockData{{Block: test.Block0}}, //nolint:gofmt
blocks..., ) // Get all blocks from DB
fetchedBlocks, err := historyDB.GetBlocks(fromBlock, toBlock) assert.Equal(t, len(blocks), len(fetchedBlocks)) // Compare generated vs getted blocks
assert.NoError(t, err) for i := range fetchedBlocks { assertEqualBlock(t, &blocks[i].Block, &fetchedBlocks[i]) } // Compare saved timestamp vs getted
nameZoneUTC, offsetUTC := timestamp.UTC().Zone() zoneFetchedBlock, offsetFetchedBlock := fetchedBlocks[fromBlock].Timestamp.Zone() assert.Equal(t, nameZoneUTC, zoneFetchedBlock) assert.Equal(t, offsetUTC, offsetFetchedBlock) // Get blocks from the DB one by one
for i := int64(2); i < toBlock; i++ { // avoid block 0 for simplicity
fetchedBlock, err := historyDB.GetBlock(i) assert.NoError(t, err) assertEqualBlock(t, &blocks[i-1].Block, fetchedBlock) } // Get last block
lastBlock, err := historyDB.GetLastBlock() assert.NoError(t, err) assertEqualBlock(t, &blocks[len(blocks)-1].Block, lastBlock) }
func assertEqualBlock(t *testing.T, expected *common.Block, actual *common.Block) { assert.Equal(t, expected.Num, actual.Num) assert.Equal(t, expected.Hash, actual.Hash) assert.Equal(t, expected.Timestamp.Unix(), actual.Timestamp.Unix()) }
func TestBatches(t *testing.T) { // Reset DB
test.WipeDB(historyDB.DB()) // Generate batches using til (and blocks for foreign key)
set := ` Type: Blockchain AddToken(1) // Will have value in USD
AddToken(2) // Will NOT have value in USD
CreateAccountDeposit(1) A: 2000 CreateAccountDeposit(2) A: 2000 CreateAccountDeposit(1) B: 1000 CreateAccountDeposit(2) B: 1000 > batchL1 > batchL1 Transfer(1) A-B: 100 (5) Transfer(2) B-A: 100 (199) > batch // batchNum=2, L2 only batch, forges transfers (mixed case of with(out) USD value)
> block Transfer(1) A-B: 100 (5) > batch // batchNum=3, L2 only batch, forges transfer (with USD value)
Transfer(2) B-A: 100 (199) > batch // batchNum=4, L2 only batch, forges transfer (without USD value)
> block ` tc := til.NewContext(common.RollupConstMaxL1UserTx) tilCfgExtra := til.ConfigExtra{ BootCoordAddr: ethCommon.HexToAddress("0xE39fEc6224708f0772D2A74fd3f9055A90E0A9f2"), CoordUser: "A", } blocks, err := tc.GenerateBlocks(set) require.Nil(t, err) err = tc.FillBlocksExtra(blocks, &tilCfgExtra) assert.Nil(t, err) // Insert to DB
batches := []common.Batch{} tokensValue := make(map[common.TokenID]float64) lastL1TxsNum := new(int64) lastL1BatchBlockNum := int64(0) for _, block := range blocks { // Insert block
assert.NoError(t, historyDB.AddBlock(&block.Block)) // Insert tokens
for i, token := range block.Rollup.AddedTokens { assert.NoError(t, historyDB.AddToken(&token)) //nolint:gosec
if i%2 != 0 { // Set value to the token
value := (float64(i) + 5) * 5.389329 assert.NoError(t, historyDB.UpdateTokenValue(token.Symbol, value)) tokensValue[token.TokenID] = value / math.Pow(10, float64(token.Decimals)) } } // Combine all generated batches into single array
for _, batch := range block.Rollup.Batches { batches = append(batches, batch.Batch) forgeTxsNum := batch.Batch.ForgeL1TxsNum if forgeTxsNum != nil && (lastL1TxsNum == nil || *lastL1TxsNum < *forgeTxsNum) { *lastL1TxsNum = *forgeTxsNum lastL1BatchBlockNum = batch.Batch.EthBlockNum } } } // Insert batches
assert.NoError(t, historyDB.AddBatches(batches)) // Set expected total fee
for _, batch := range batches { total := .0 for tokenID, amount := range batch.CollectedFees { af := new(big.Float).SetInt(amount) amountFloat, _ := af.Float64() total += tokensValue[tokenID] * amountFloat } batch.TotalFeesUSD = &total } // Get batches from the DB
fetchedBatches, err := historyDB.GetBatches(0, common.BatchNum(len(batches)+1)) assert.NoError(t, err) assert.Equal(t, len(batches), len(fetchedBatches)) for i, fetchedBatch := range fetchedBatches { assert.Equal(t, batches[i], fetchedBatch) } // Test GetLastBatchNum
fetchedLastBatchNum, err := historyDB.GetLastBatchNum() assert.NoError(t, err) assert.Equal(t, batches[len(batches)-1].BatchNum, fetchedLastBatchNum) // Test GetLastL1TxsNum
fetchedLastL1TxsNum, err := historyDB.GetLastL1TxsNum() assert.NoError(t, err) assert.Equal(t, lastL1TxsNum, fetchedLastL1TxsNum) // Test GetLastL1BatchBlockNum
fetchedLastL1BatchBlockNum, err := historyDB.GetLastL1BatchBlockNum() assert.NoError(t, err) assert.Equal(t, lastL1BatchBlockNum, fetchedLastL1BatchBlockNum) }
func TestBids(t *testing.T) { const fromBlock int64 = 1 const toBlock int64 = 5 // Prepare blocks in the DB
blocks := setTestBlocks(fromBlock, toBlock) // Generate fake coordinators
const nCoords = 5 coords := test.GenCoordinators(nCoords, blocks) err := historyDB.AddCoordinators(coords) assert.NoError(t, err) // Generate fake bids
const nBids = 20 bids := test.GenBids(nBids, blocks, coords) err = historyDB.AddBids(bids) assert.NoError(t, err) // Fetch bids
fetchedBids, err := historyDB.GetAllBids() assert.NoError(t, err) // Compare fetched bids vs generated bids
for i, bid := range fetchedBids { assert.Equal(t, bids[i], bid) } }
func TestTokens(t *testing.T) { const fromBlock int64 = 1 const toBlock int64 = 5 // Prepare blocks in the DB
blocks := setTestBlocks(fromBlock, toBlock) // Generate fake tokens
const nTokens = 5 tokens, ethToken := test.GenTokens(nTokens, blocks) err := historyDB.AddTokens(tokens) assert.NoError(t, err) tokens = append([]common.Token{ethToken}, tokens...) limit := uint(10) // Fetch tokens
fetchedTokens, _, err := historyDB.GetTokens(nil, nil, "", nil, &limit, OrderAsc) assert.NoError(t, err) // Compare fetched tokens vs generated tokens
// All the tokens should have USDUpdate setted by the DB trigger
for i, token := range fetchedTokens { assert.Equal(t, tokens[i].TokenID, token.TokenID) assert.Equal(t, tokens[i].EthBlockNum, token.EthBlockNum) assert.Equal(t, tokens[i].EthAddr, token.EthAddr) assert.Equal(t, tokens[i].Name, token.Name) assert.Equal(t, tokens[i].Symbol, token.Symbol) assert.Nil(t, token.USD) assert.Nil(t, token.USDUpdate) }
// Update token value
for i, token := range tokens { value := 1.01 * float64(i) assert.NoError(t, historyDB.UpdateTokenValue(token.Symbol, value)) } // Fetch tokens
fetchedTokens, _, err = historyDB.GetTokens(nil, nil, "", nil, &limit, OrderAsc) assert.NoError(t, err) // Compare fetched tokens vs generated tokens
// All the tokens should have USDUpdate setted by the DB trigger
for i, token := range fetchedTokens { value := 1.01 * float64(i) assert.Equal(t, value, *token.USD) nameZone, offset := token.USDUpdate.Zone() assert.Equal(t, "UTC", nameZone) assert.Equal(t, 0, offset) } }
func TestAccounts(t *testing.T) { const fromBlock int64 = 1 const toBlock int64 = 5 // Prepare blocks in the DB
blocks := setTestBlocks(fromBlock, toBlock) // Generate fake tokens
const nTokens = 5 tokens, ethToken := test.GenTokens(nTokens, blocks) err := historyDB.AddTokens(tokens) assert.NoError(t, err) tokens = append([]common.Token{ethToken}, tokens...) // Generate fake batches
const nBatches = 10 batches := test.GenBatches(nBatches, blocks) err = historyDB.AddBatches(batches) assert.NoError(t, err) // Generate fake accounts
const nAccounts = 3 accs := test.GenAccounts(nAccounts, 0, tokens, nil, nil, batches) err = historyDB.AddAccounts(accs) assert.NoError(t, err) // Fetch accounts
fetchedAccs, err := historyDB.GetAllAccounts() assert.NoError(t, err) // Compare fetched accounts vs generated accounts
for i, acc := range fetchedAccs { accs[i].Balance = nil assert.Equal(t, accs[i], acc) } }
func TestTxs(t *testing.T) { // Reset DB
test.WipeDB(historyDB.DB())
set := ` Type: Blockchain AddToken(1) AddToken(2) CreateAccountDeposit(1) A: 10 CreateAccountDeposit(1) B: 10 > batchL1 > batchL1 > block CreateAccountDepositTransfer(1) C-A: 20, 10 CreateAccountCoordinator(1) User0 > batchL1 > batchL1 > block
Deposit(1) B: 10 Deposit(1) C: 10 Transfer(1) C-A : 10 (1) Transfer(1) B-C : 10 (1) Transfer(1) A-B : 10 (1) Exit(1) A: 10 (1) > batch > block DepositTransfer(1) A-B: 10, 10 > batchL1 > block
ForceTransfer(1) A-B: 10 ForceExit(1) A: 5 > batchL1 > batchL1 > block
CreateAccountDeposit(2) D: 10 > batchL1 > block
CreateAccountDeposit(2) E: 10 > batchL1 > batchL1 > block
` tc := til.NewContext(common.RollupConstMaxL1UserTx) tilCfgExtra := til.ConfigExtra{ BootCoordAddr: ethCommon.HexToAddress("0xE39fEc6224708f0772D2A74fd3f9055A90E0A9f2"), CoordUser: "A", } blocks, err := tc.GenerateBlocks(set) require.Nil(t, err) err = tc.FillBlocksExtra(blocks, &tilCfgExtra) assert.Nil(t, err)
// Sanity check
require.Equal(t, 7, len(blocks)) require.Equal(t, 2, len(blocks[0].Rollup.L1UserTxs)) require.Equal(t, 1, len(blocks[1].Rollup.L1UserTxs)) require.Equal(t, 2, len(blocks[2].Rollup.L1UserTxs)) require.Equal(t, 1, len(blocks[3].Rollup.L1UserTxs)) require.Equal(t, 2, len(blocks[4].Rollup.L1UserTxs)) require.Equal(t, 1, len(blocks[5].Rollup.L1UserTxs)) require.Equal(t, 1, len(blocks[6].Rollup.L1UserTxs))
var null *common.BatchNum = nil var txID common.TxID
// Insert blocks into DB
for i := range blocks { if i == len(blocks)-1 { blocks[i].Block.Timestamp = time.Now() dbL1Txs, err := historyDB.GetAllL1UserTxs() assert.NoError(t, err) // Check batch_num is nil before forging
assert.Equal(t, null, dbL1Txs[len(dbL1Txs)-1].BatchNum) // Save this TxId
txID = dbL1Txs[len(dbL1Txs)-1].TxID } err = historyDB.AddBlockSCData(&blocks[i]) assert.NoError(t, err) }
// Check blocks
dbBlocks, err := historyDB.GetAllBlocks() assert.NoError(t, err) assert.Equal(t, len(blocks)+1, len(dbBlocks))
// Check batches
batches, err := historyDB.GetAllBatches() assert.NoError(t, err) assert.Equal(t, 11, len(batches))
// Check L1 Transactions
dbL1Txs, err := historyDB.GetAllL1UserTxs() assert.NoError(t, err) assert.Equal(t, 10, len(dbL1Txs))
// Tx Type
assert.Equal(t, common.TxTypeCreateAccountDeposit, dbL1Txs[0].Type) assert.Equal(t, common.TxTypeCreateAccountDeposit, dbL1Txs[1].Type) assert.Equal(t, common.TxTypeCreateAccountDepositTransfer, dbL1Txs[2].Type) assert.Equal(t, common.TxTypeDeposit, dbL1Txs[3].Type) assert.Equal(t, common.TxTypeDeposit, dbL1Txs[4].Type) assert.Equal(t, common.TxTypeDepositTransfer, dbL1Txs[5].Type) assert.Equal(t, common.TxTypeForceTransfer, dbL1Txs[6].Type) assert.Equal(t, common.TxTypeForceExit, dbL1Txs[7].Type) assert.Equal(t, common.TxTypeCreateAccountDeposit, dbL1Txs[8].Type) assert.Equal(t, common.TxTypeCreateAccountDeposit, dbL1Txs[9].Type)
// Tx ID
assert.Equal(t, "0x000000000000000001000000", dbL1Txs[0].TxID.String()) assert.Equal(t, "0x000000000000000001000100", dbL1Txs[1].TxID.String()) assert.Equal(t, "0x000000000000000003000000", dbL1Txs[2].TxID.String()) assert.Equal(t, "0x000000000000000005000000", dbL1Txs[3].TxID.String()) assert.Equal(t, "0x000000000000000005000100", dbL1Txs[4].TxID.String()) assert.Equal(t, "0x000000000000000005000200", dbL1Txs[5].TxID.String()) assert.Equal(t, "0x000000000000000006000000", dbL1Txs[6].TxID.String()) assert.Equal(t, "0x000000000000000006000100", dbL1Txs[7].TxID.String()) assert.Equal(t, "0x000000000000000008000000", dbL1Txs[8].TxID.String()) assert.Equal(t, "0x000000000000000009000000", dbL1Txs[9].TxID.String())
// Tx From IDx
assert.Equal(t, common.Idx(0), dbL1Txs[0].FromIdx) assert.Equal(t, common.Idx(0), dbL1Txs[1].FromIdx) assert.Equal(t, common.Idx(0), dbL1Txs[2].FromIdx) assert.NotEqual(t, common.Idx(0), dbL1Txs[3].FromIdx) assert.NotEqual(t, common.Idx(0), dbL1Txs[4].FromIdx) assert.NotEqual(t, common.Idx(0), dbL1Txs[5].FromIdx) assert.NotEqual(t, common.Idx(0), dbL1Txs[6].FromIdx) assert.NotEqual(t, common.Idx(0), dbL1Txs[7].FromIdx) assert.Equal(t, common.Idx(0), dbL1Txs[8].FromIdx) assert.Equal(t, common.Idx(0), dbL1Txs[9].FromIdx) assert.Equal(t, common.Idx(0), dbL1Txs[9].FromIdx) assert.Equal(t, dbL1Txs[5].FromIdx, dbL1Txs[6].FromIdx) assert.Equal(t, dbL1Txs[5].FromIdx, dbL1Txs[7].FromIdx)
// Tx to IDx
assert.Equal(t, dbL1Txs[2].ToIdx, dbL1Txs[5].FromIdx) assert.Equal(t, dbL1Txs[5].ToIdx, dbL1Txs[3].FromIdx) assert.Equal(t, dbL1Txs[6].ToIdx, dbL1Txs[3].FromIdx)
// Token ID
assert.Equal(t, common.TokenID(1), dbL1Txs[0].TokenID) assert.Equal(t, common.TokenID(1), dbL1Txs[1].TokenID) assert.Equal(t, common.TokenID(1), dbL1Txs[2].TokenID) assert.Equal(t, common.TokenID(1), dbL1Txs[3].TokenID) assert.Equal(t, common.TokenID(1), dbL1Txs[4].TokenID) assert.Equal(t, common.TokenID(1), dbL1Txs[5].TokenID) assert.Equal(t, common.TokenID(1), dbL1Txs[6].TokenID) assert.Equal(t, common.TokenID(1), dbL1Txs[7].TokenID) assert.Equal(t, common.TokenID(2), dbL1Txs[8].TokenID) assert.Equal(t, common.TokenID(2), dbL1Txs[9].TokenID)
// Batch Number
var bn common.BatchNum = common.BatchNum(2)
assert.Equal(t, &bn, dbL1Txs[0].BatchNum) assert.Equal(t, &bn, dbL1Txs[1].BatchNum)
bn = common.BatchNum(4) assert.Equal(t, &bn, dbL1Txs[2].BatchNum)
bn = common.BatchNum(7) assert.Equal(t, &bn, dbL1Txs[3].BatchNum) assert.Equal(t, &bn, dbL1Txs[4].BatchNum) assert.Equal(t, &bn, dbL1Txs[5].BatchNum)
bn = common.BatchNum(8) assert.Equal(t, &bn, dbL1Txs[6].BatchNum) assert.Equal(t, &bn, dbL1Txs[7].BatchNum)
bn = common.BatchNum(10) assert.Equal(t, &bn, dbL1Txs[8].BatchNum)
bn = common.BatchNum(11) assert.Equal(t, &bn, dbL1Txs[9].BatchNum)
// eth_block_num
assert.Equal(t, int64(2), dbL1Txs[0].EthBlockNum) assert.Equal(t, int64(2), dbL1Txs[1].EthBlockNum) assert.Equal(t, int64(3), dbL1Txs[2].EthBlockNum) assert.Equal(t, int64(4), dbL1Txs[3].EthBlockNum) assert.Equal(t, int64(4), dbL1Txs[4].EthBlockNum) assert.Equal(t, int64(5), dbL1Txs[5].EthBlockNum) assert.Equal(t, int64(6), dbL1Txs[6].EthBlockNum) assert.Equal(t, int64(6), dbL1Txs[7].EthBlockNum) assert.Equal(t, int64(7), dbL1Txs[8].EthBlockNum) assert.Equal(t, int64(8), dbL1Txs[9].EthBlockNum)
// User Origin
assert.Equal(t, true, dbL1Txs[0].UserOrigin) assert.Equal(t, true, dbL1Txs[1].UserOrigin) assert.Equal(t, true, dbL1Txs[2].UserOrigin) assert.Equal(t, true, dbL1Txs[3].UserOrigin) assert.Equal(t, true, dbL1Txs[4].UserOrigin) assert.Equal(t, true, dbL1Txs[5].UserOrigin) assert.Equal(t, true, dbL1Txs[6].UserOrigin) assert.Equal(t, true, dbL1Txs[7].UserOrigin) assert.Equal(t, true, dbL1Txs[8].UserOrigin) assert.Equal(t, true, dbL1Txs[9].UserOrigin)
// Load Amount
assert.Equal(t, big.NewInt(10), dbL1Txs[0].LoadAmount) assert.Equal(t, big.NewInt(10), dbL1Txs[1].LoadAmount) assert.Equal(t, big.NewInt(20), dbL1Txs[2].LoadAmount) assert.Equal(t, big.NewInt(10), dbL1Txs[3].LoadAmount) assert.Equal(t, big.NewInt(10), dbL1Txs[4].LoadAmount) assert.Equal(t, big.NewInt(10), dbL1Txs[5].LoadAmount) assert.Equal(t, big.NewInt(0), dbL1Txs[6].LoadAmount) assert.Equal(t, big.NewInt(0), dbL1Txs[7].LoadAmount) assert.Equal(t, big.NewInt(10), dbL1Txs[8].LoadAmount) assert.Equal(t, big.NewInt(10), dbL1Txs[9].LoadAmount)
// Check saved txID's batch_num is not nil
assert.Equal(t, txID, dbL1Txs[len(dbL1Txs)-2].TxID) assert.NotEqual(t, null, dbL1Txs[len(dbL1Txs)-2].BatchNum)
// Check Coordinator TXs
coordTxs, err := historyDB.GetAllL1CoordinatorTxs() assert.NoError(t, err) assert.Equal(t, 1, len(coordTxs)) assert.Equal(t, common.TxTypeCreateAccountDeposit, coordTxs[0].Type) assert.Equal(t, false, coordTxs[0].UserOrigin)
// Check L2 TXs
dbL2Txs, err := historyDB.GetAllL2Txs() assert.NoError(t, err) assert.Equal(t, 4, len(dbL2Txs))
// Tx Type
assert.Equal(t, common.TxTypeTransfer, dbL2Txs[0].Type) assert.Equal(t, common.TxTypeTransfer, dbL2Txs[1].Type) assert.Equal(t, common.TxTypeTransfer, dbL2Txs[2].Type) assert.Equal(t, common.TxTypeExit, dbL2Txs[3].Type)
// Tx ID
assert.Equal(t, "0x020000000001030000000001", dbL2Txs[0].TxID.String()) assert.Equal(t, "0x020000000001010000000001", dbL2Txs[1].TxID.String()) assert.Equal(t, "0x020000000001000000000001", dbL2Txs[2].TxID.String()) assert.Equal(t, "0x020000000001000000000002", dbL2Txs[3].TxID.String())
// Tx From and To IDx
assert.Equal(t, dbL2Txs[0].ToIdx, dbL2Txs[2].FromIdx) assert.Equal(t, dbL2Txs[1].ToIdx, dbL2Txs[0].FromIdx) assert.Equal(t, dbL2Txs[2].ToIdx, dbL2Txs[1].FromIdx)
// Batch Number
assert.Equal(t, common.BatchNum(5), dbL2Txs[0].BatchNum) assert.Equal(t, common.BatchNum(5), dbL2Txs[1].BatchNum) assert.Equal(t, common.BatchNum(5), dbL2Txs[2].BatchNum) assert.Equal(t, common.BatchNum(5), dbL2Txs[3].BatchNum)
// eth_block_num
assert.Equal(t, int64(4), dbL2Txs[0].EthBlockNum) assert.Equal(t, int64(4), dbL2Txs[1].EthBlockNum) assert.Equal(t, int64(4), dbL2Txs[2].EthBlockNum)
// Amount
assert.Equal(t, big.NewInt(10), dbL2Txs[0].Amount) assert.Equal(t, big.NewInt(10), dbL2Txs[1].Amount) assert.Equal(t, big.NewInt(10), dbL2Txs[2].Amount) assert.Equal(t, big.NewInt(10), dbL2Txs[3].Amount) }
func TestExitTree(t *testing.T) { nBatches := 17 blocks := setTestBlocks(1, 10) batches := test.GenBatches(nBatches, blocks) err := historyDB.AddBatches(batches) assert.NoError(t, err) const nTokens = 50 tokens, ethToken := test.GenTokens(nTokens, blocks) err = historyDB.AddTokens(tokens) assert.NoError(t, err) tokens = append([]common.Token{ethToken}, tokens...) const nAccounts = 3 accs := test.GenAccounts(nAccounts, 0, tokens, nil, nil, batches) assert.NoError(t, historyDB.AddAccounts(accs)) exitTree := test.GenExitTree(nBatches, batches, accs, blocks) err = historyDB.AddExitTree(exitTree) assert.NoError(t, err) }
func TestGetL1UserTxs(t *testing.T) { test.WipeDB(historyDB.DB())
set := ` Type: Blockchain AddToken(1) AddToken(2) AddToken(3)
CreateAccountDeposit(1) A: 20 CreateAccountDeposit(2) A: 20 CreateAccountDeposit(1) B: 5 CreateAccountDeposit(1) C: 5 CreateAccountDeposit(1) D: 5
> block ` tc := til.NewContext(128) blocks, err := tc.GenerateBlocks(set) require.Nil(t, err) // Sanity check
require.Equal(t, 1, len(blocks)) require.Equal(t, 5, len(blocks[0].Rollup.L1UserTxs))
toForgeL1TxsNum := int64(1)
for i := range blocks { err = historyDB.AddBlockSCData(&blocks[i]) require.Nil(t, err) }
l1UserTxs, err := historyDB.GetL1UserTxs(toForgeL1TxsNum) require.Nil(t, err) assert.Equal(t, 5, len(l1UserTxs)) assert.Equal(t, blocks[0].Rollup.L1UserTxs, l1UserTxs)
// No l1UserTxs for this toForgeL1TxsNum
l1UserTxs, err = historyDB.GetL1UserTxs(2) require.Nil(t, err) assert.Equal(t, 0, len(l1UserTxs)) }
func exampleInitSCVars() (*common.RollupVariables, *common.AuctionVariables, *common.WDelayerVariables) { //nolint:govet
rollup := &common.RollupVariables{ 0, big.NewInt(10), 12, 13, [5]common.Bucket{}, } //nolint:govet
auction := &common.AuctionVariables{ 0, ethCommon.BigToAddress(big.NewInt(2)), ethCommon.BigToAddress(big.NewInt(3)), [6]*big.Int{ big.NewInt(1), big.NewInt(2), big.NewInt(3), big.NewInt(4), big.NewInt(5), big.NewInt(6), }, 0, 2, 4320, [3]uint16{10, 11, 12}, 1000, 20, } //nolint:govet
wDelayer := &common.WDelayerVariables{ 0, ethCommon.BigToAddress(big.NewInt(2)), ethCommon.BigToAddress(big.NewInt(3)), ethCommon.BigToAddress(big.NewInt(4)), 13, 14, false, } return rollup, auction, wDelayer }
func TestSetInitialSCVars(t *testing.T) { test.WipeDB(historyDB.DB()) _, _, _, err := historyDB.GetSCVars() assert.Equal(t, sql.ErrNoRows, tracerr.Unwrap(err)) rollup, auction, wDelayer := exampleInitSCVars() err = historyDB.SetInitialSCVars(rollup, auction, wDelayer) require.Nil(t, err) dbRollup, dbAuction, dbWDelayer, err := historyDB.GetSCVars() assert.Nil(t, err) require.Equal(t, rollup, dbRollup) require.Equal(t, auction, dbAuction) require.Equal(t, wDelayer, dbWDelayer) }
func TestUpdateExitTree(t *testing.T) { test.WipeDB(historyDB.DB())
set := ` Type: Blockchain
AddToken(1)
CreateAccountDeposit(1) C: 2000 // Idx=256+2=258
CreateAccountDeposit(1) D: 500 // Idx=256+3=259
CreateAccountCoordinator(1) A // Idx=256+0=256
CreateAccountCoordinator(1) B // Idx=256+1=257
> batchL1 // forge L1UserTxs{nil}, freeze defined L1UserTxs{5}
> batchL1 // forge defined L1UserTxs{5}, freeze L1UserTxs{nil}
> block // blockNum=2
ForceExit(1) A: 100 ForceExit(1) B: 80
Exit(1) C: 50 (172) Exit(1) D: 30 (172)
> batchL1 // forge L1UserTxs{nil}, freeze defined L1UserTxs{3}
> batchL1 // forge L1UserTxs{3}, freeze defined L1UserTxs{nil}
> block // blockNum=3
> block // blockNum=4 (empty block)
> block // blockNum=5 (empty block)
`
tc := til.NewContext(common.RollupConstMaxL1UserTx) tilCfgExtra := til.ConfigExtra{ BootCoordAddr: ethCommon.HexToAddress("0xE39fEc6224708f0772D2A74fd3f9055A90E0A9f2"), CoordUser: "A", } blocks, err := tc.GenerateBlocks(set) require.Nil(t, err) err = tc.FillBlocksExtra(blocks, &tilCfgExtra) assert.Nil(t, err)
// Add all blocks except for the last two
for i := range blocks[:len(blocks)-2] { err = historyDB.AddBlockSCData(&blocks[i]) require.Nil(t, err) }
// Add withdraws to the second-to-last block, and insert block into the DB
block := &blocks[len(blocks)-2] require.Equal(t, int64(4), block.Block.Num) tokenAddr := blocks[0].Rollup.AddedTokens[0].EthAddr // block.WDelayer.Deposits = append(block.WDelayer.Deposits,
// common.WDelayerTransfer{Owner: tc.UsersByIdx[257].Addr, Token: tokenAddr, Amount: big.NewInt(80)}, // 257
// common.WDelayerTransfer{Owner: tc.UsersByIdx[259].Addr, Token: tokenAddr, Amount: big.NewInt(15)}, // 259
// )
block.Rollup.Withdrawals = append(block.Rollup.Withdrawals, common.WithdrawInfo{Idx: 256, NumExitRoot: 4, InstantWithdraw: true}, common.WithdrawInfo{Idx: 257, NumExitRoot: 4, InstantWithdraw: false, Owner: tc.UsersByIdx[257].Addr, Token: tokenAddr}, common.WithdrawInfo{Idx: 258, NumExitRoot: 3, InstantWithdraw: true}, common.WithdrawInfo{Idx: 259, NumExitRoot: 3, InstantWithdraw: false, Owner: tc.UsersByIdx[259].Addr, Token: tokenAddr}, ) err = historyDB.addBlock(historyDB.db, &block.Block) require.Nil(t, err)
err = historyDB.updateExitTree(historyDB.db, block.Block.Num, block.Rollup.Withdrawals, block.WDelayer.Withdrawals) require.Nil(t, err)
// Check that exits in DB match with the expected values
dbExits, err := historyDB.GetAllExits() require.Nil(t, err) assert.Equal(t, 4, len(dbExits)) dbExitsByIdx := make(map[common.Idx]common.ExitInfo) for _, dbExit := range dbExits { dbExitsByIdx[dbExit.AccountIdx] = dbExit } for _, withdraw := range block.Rollup.Withdrawals { assert.Equal(t, withdraw.NumExitRoot, dbExitsByIdx[withdraw.Idx].BatchNum) if withdraw.InstantWithdraw { assert.Equal(t, &block.Block.Num, dbExitsByIdx[withdraw.Idx].InstantWithdrawn) } else { assert.Equal(t, &block.Block.Num, dbExitsByIdx[withdraw.Idx].DelayedWithdrawRequest) } }
// Add delayed withdraw to the last block, and insert block into the DB
block = &blocks[len(blocks)-1] require.Equal(t, int64(5), block.Block.Num) block.WDelayer.Withdrawals = append(block.WDelayer.Withdrawals, common.WDelayerTransfer{ Owner: tc.UsersByIdx[257].Addr, Token: tokenAddr, Amount: big.NewInt(80), }) err = historyDB.addBlock(historyDB.db, &block.Block) require.Nil(t, err)
err = historyDB.updateExitTree(historyDB.db, block.Block.Num, block.Rollup.Withdrawals, block.WDelayer.Withdrawals) require.Nil(t, err)
// Check that delayed withdrawn has been set
dbExits, err = historyDB.GetAllExits() require.Nil(t, err) for _, dbExit := range dbExits { dbExitsByIdx[dbExit.AccountIdx] = dbExit } require.Equal(t, &block.Block.Num, dbExitsByIdx[257].DelayedWithdrawn) }
func TestGetBestBidCoordinator(t *testing.T) { test.WipeDB(historyDB.DB())
rollup, auction, wDelayer := exampleInitSCVars() err := historyDB.SetInitialSCVars(rollup, auction, wDelayer) require.Nil(t, err)
tc := til.NewContext(common.RollupConstMaxL1UserTx) blocks, err := tc.GenerateBlocks(` Type: Blockchain > block // blockNum=2
`) require.Nil(t, err) err = historyDB.AddBlockSCData(&blocks[0]) require.Nil(t, err)
coords := []common.Coordinator{ { Bidder: ethCommon.BigToAddress(big.NewInt(1)), Forger: ethCommon.BigToAddress(big.NewInt(2)), EthBlockNum: 2, URL: "foo", }, { Bidder: ethCommon.BigToAddress(big.NewInt(3)), Forger: ethCommon.BigToAddress(big.NewInt(4)), EthBlockNum: 2, URL: "bar", }, } err = historyDB.addCoordinators(historyDB.db, coords) require.Nil(t, err) err = historyDB.addBids(historyDB.db, []common.Bid{ { SlotNum: 10, BidValue: big.NewInt(10), EthBlockNum: 2, Bidder: coords[0].Bidder, }, { SlotNum: 10, BidValue: big.NewInt(20), EthBlockNum: 2, Bidder: coords[1].Bidder, }, }) require.Nil(t, err)
forger10, err := historyDB.GetBestBidCoordinator(10) require.Nil(t, err) require.Equal(t, coords[1].Forger, forger10.Forger) require.Equal(t, coords[1].Bidder, forger10.Bidder) require.Equal(t, coords[1].URL, forger10.URL)
_, err = historyDB.GetBestBidCoordinator(11) require.Equal(t, sql.ErrNoRows, tracerr.Unwrap(err)) }
// setTestBlocks WARNING: this will delete the blocks and recreate them
func setTestBlocks(from, to int64) []common.Block { test.WipeDB(historyDB.DB()) blocks := test.GenBlocks(from, to) if err := historyDB.AddBlocks(blocks); err != nil { panic(err) } return blocks }
|