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.
This commit is contained in:
Eduard S
2020-11-13 18:11:58 +01:00
parent bf88eb60b8
commit 3b99953007
31 changed files with 1195 additions and 716 deletions

View File

@@ -633,11 +633,7 @@ func TestGetL1UserTxs(t *testing.T) {
assert.Equal(t, 0, len(l1UserTxs))
}
func TestSetInitialSCVars(t *testing.T) {
test.WipeDB(historyDB.DB())
_, _, _, err := historyDB.GetSCVars()
assert.Equal(t, sql.ErrNoRows, err)
func exampleInitSCVars() (*common.RollupVariables, *common.AuctionVariables, *common.WDelayerVariables) {
//nolint:govet
rollup := &common.RollupVariables{
0,
@@ -655,6 +651,7 @@ func TestSetInitialSCVars(t *testing.T) {
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},
@@ -671,6 +668,14 @@ func TestSetInitialSCVars(t *testing.T) {
14,
false,
}
return rollup, auction, wDelayer
}
func TestSetInitialSCVars(t *testing.T) {
test.WipeDB(historyDB.DB())
_, _, _, err := historyDB.GetSCVars()
assert.Equal(t, sql.ErrNoRows, err)
rollup, auction, wDelayer := exampleInitSCVars()
err = historyDB.SetInitialSCVars(rollup, auction, wDelayer)
require.Nil(t, err)
dbRollup, dbAuction, dbWDelayer, err := historyDB.GetSCVars()
@@ -793,6 +798,64 @@ func TestUpdateExitTree(t *testing.T) {
require.Equal(t, &block.Block.EthBlockNum, 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, err)
}
// setTestBlocks WARNING: this will delete the blocks and recreate them
func setTestBlocks(from, to int64) []common.Block {
test.WipeDB(historyDB.DB())