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 common
import ( "encoding/binary" "fmt" "math/big"
ethCommon "github.com/ethereum/go-ethereum/common" "github.com/hermeznetwork/tracerr" )
const batchNumBytesLen = 8
// Batch is a struct that represents Hermez network batch
type Batch struct { BatchNum BatchNum `meddler:"batch_num"` EthBlockNum int64 `meddler:"eth_block_num"` // Ethereum block in which the batch is forged
ForgerAddr ethCommon.Address `meddler:"forger_addr"` CollectedFees map[TokenID]*big.Int `meddler:"fees_collected,json"` FeeIdxsCoordinator []Idx `meddler:"fee_idxs_coordinator,json"` StateRoot *big.Int `meddler:"state_root,bigint"` NumAccounts int `meddler:"num_accounts"` LastIdx int64 `meddler:"last_idx"` ExitRoot *big.Int `meddler:"exit_root,bigint"` ForgeL1TxsNum *int64 `meddler:"forge_l1_txs_num"` // optional, Only when the batch forges L1 txs. Identifier that corresponds to the group of L1 txs forged in the current batch.
SlotNum int64 `meddler:"slot_num"` // Slot in which the batch is forged
TotalFeesUSD *float64 `meddler:"total_fees_usd"` }
// NewEmptyBatch creates a new empty batch
func NewEmptyBatch() *Batch { return &Batch{ BatchNum: 0, EthBlockNum: 0, ForgerAddr: ethCommon.Address{}, CollectedFees: make(map[TokenID]*big.Int), FeeIdxsCoordinator: make([]Idx, 0), StateRoot: big.NewInt(0), NumAccounts: 0, LastIdx: 0, ExitRoot: big.NewInt(0), ForgeL1TxsNum: nil, SlotNum: 0, TotalFeesUSD: nil, } }
// BatchNum identifies a batch
type BatchNum int64
// Bytes returns a byte array of length 4 representing the BatchNum
func (bn BatchNum) Bytes() []byte { var batchNumBytes [batchNumBytesLen]byte binary.BigEndian.PutUint64(batchNumBytes[:], uint64(bn)) return batchNumBytes[:] }
// BigInt returns a *big.Int representing the BatchNum
func (bn BatchNum) BigInt() *big.Int { return big.NewInt(int64(bn)) }
// BatchNumFromBytes returns BatchNum from a []byte
func BatchNumFromBytes(b []byte) (BatchNum, error) { if len(b) != batchNumBytesLen { return 0, tracerr.Wrap(fmt.Errorf("can not parse BatchNumFromBytes, bytes len %d, expected %d", len(b), batchNumBytesLen)) } batchNum := binary.BigEndian.Uint64(b[:batchNumBytesLen]) return BatchNum(batchNum), nil }
// BatchData contains the information of a Batch
type BatchData struct { L1Batch bool // TODO: Remove once Batch.ForgeL1TxsNum is a pointer
// L1UserTxs that were forged in the batch
L1UserTxs []L1Tx L1CoordinatorTxs []L1Tx L2Txs []L2Tx CreatedAccounts []Account ExitTree []ExitInfo Batch Batch }
// NewBatchData creates an empty BatchData with the slices initialized.
func NewBatchData() *BatchData { return &BatchData{ L1Batch: false, // L1UserTxs: make([]common.L1Tx, 0),
L1CoordinatorTxs: make([]L1Tx, 0), L2Txs: make([]L2Tx, 0), CreatedAccounts: make([]Account, 0), ExitTree: make([]ExitInfo, 0), Batch: Batch{}, } }
// BatchSync is a subset of Batch that contains fileds needed for the
// synchronizer and coordinator
// type BatchSync struct {
// BatchNum BatchNum `meddler:"batch_num"`
// EthBlockNum int64 `meddler:"eth_block_num"` // Ethereum block in which the batch is forged
// ForgerAddr ethCommon.Address `meddler:"forger_addr"`
// StateRoot *big.Int `meddler:"state_root,bigint"`
// SlotNum int64 `meddler:"slot_num"` // Slot in which the batch is forged
// }
//
// func NewBatchSync() *BatchSync {
// return &BatchSync{
// BatchNum: 0,
// EthBlockNum: 0,
// ForgerAddr: ethCommon.Address,
// StateRoot: big.NewInt(0),
// SlotNum: 0,
// }
// }
|