From a1c339c9180a05af914f456ef14ff38a67ed2013 Mon Sep 17 00:00:00 2001 From: arnaucube Date: Thu, 13 Aug 2020 18:25:50 +0200 Subject: [PATCH] Add BatchQueue implementation & minor updates --- batchbuilder/batchbuilder.go | 6 ++-- coordinator/batch.go | 64 ++++++++++++++++++++++++++++++++++++ coordinator/batch_test.go | 26 +++++++++++++++ coordinator/proofpool.go | 21 ++++++++++++ db/statedb/statedb.go | 8 ++--- txselector/txselector.go | 10 +++--- 6 files changed, 123 insertions(+), 12 deletions(-) create mode 100644 coordinator/batch.go create mode 100644 coordinator/batch_test.go create mode 100644 coordinator/proofpool.go diff --git a/batchbuilder/batchbuilder.go b/batchbuilder/batchbuilder.go index f11f5e7..da61964 100644 --- a/batchbuilder/batchbuilder.go +++ b/batchbuilder/batchbuilder.go @@ -31,7 +31,7 @@ type ConfigBatch struct { // NewBatchBuilder constructs a new BatchBuilder, and executes the bb.Reset // method -func NewBatchBuilder(synchronizerStateDB *statedb.StateDB, configCircuits []ConfigCircuit, batchNum int, idx, nLevels uint64) (*BatchBuilder, error) { +func NewBatchBuilder(synchronizerStateDB *statedb.StateDB, configCircuits []ConfigCircuit, batchNum uint64, idx, nLevels uint64) (*BatchBuilder, error) { localStateDB, err := statedb.NewLocalStateDB(synchronizerStateDB, true, int(nLevels)) if err != nil { return nil, err @@ -51,7 +51,7 @@ func NewBatchBuilder(synchronizerStateDB *statedb.StateDB, configCircuits []Conf // `batchNum`. If `fromSynchronizer` is true, the BatchBuilder must take a // copy of the rollup state from the Synchronizer at that `batchNum`, otherwise // it can just roll back the internal copy. -func (bb *BatchBuilder) Reset(batchNum int, fromSynchronizer bool) error { +func (bb *BatchBuilder) Reset(batchNum uint64, fromSynchronizer bool) error { err := bb.localStateDB.Reset(batchNum, fromSynchronizer) if err != nil { return err @@ -61,7 +61,7 @@ func (bb *BatchBuilder) Reset(batchNum int, fromSynchronizer bool) error { } // BuildBatch takes the transactions and returns the common.ZKInputs of the next batch -func (bb *BatchBuilder) BuildBatch(configBatch ConfigBatch, l1usertxs, l1coordinatortxs []common.L1Tx, l2txs []common.L2Tx, tokenIDs []common.TokenID) (*common.ZKInputs, error) { +func (bb *BatchBuilder) BuildBatch(configBatch ConfigBatch, l1usertxs, l1coordinatortxs []common.L1Tx, l2txs []common.PoolL2Tx, tokenIDs []common.TokenID) (*common.ZKInputs, error) { for _, tx := range l1usertxs { err := bb.processL1Tx(tx) if err != nil { diff --git a/coordinator/batch.go b/coordinator/batch.go new file mode 100644 index 0000000..f43d930 --- /dev/null +++ b/coordinator/batch.go @@ -0,0 +1,64 @@ +package coordinator + +import ( + "github.com/hermeznetwork/hermez-node/common" +) + +// BatchInfo contans the Batch information +type BatchInfo struct { + batchNum uint64 + serverProof *ServerProofInfo + zkInputs *common.ZKInputs + L1UserTxsExtra []common.L1Tx + L1OperatorTxs []common.L1Tx + L2Txs []common.PoolL2Tx + // FeesInfo +} + +// NewBatchInfo creates a new BatchInfo with the given batchNum & +// ServerProofInfo +func NewBatchInfo(batchNum uint64, serverProof *ServerProofInfo) BatchInfo { + return BatchInfo{ + batchNum: batchNum, + serverProof: serverProof, + } +} + +// AddTxsInfo adds the l1UserTxs, l1OperatorTxs and l2Txs to the BatchInfo data +// structure +func (bi *BatchInfo) AddTxsInfo(l1UserTxsExtra, l1OperatorTxs []common.L1Tx, l2Txs []common.PoolL2Tx) { + // TBD parameter: feesInfo + bi.L1UserTxsExtra = l1UserTxsExtra + bi.L1OperatorTxs = l1OperatorTxs + bi.L2Txs = l2Txs +} + +// AddTxsInfo adds the ZKInputs to the BatchInfo data structure +func (bi *BatchInfo) AddZKInputs(zkInputs *common.ZKInputs) { + bi.zkInputs = zkInputs +} + +// AddTxsInfo adds the ServerProofInfo to the BatchInfo data structure +func (bi *BatchInfo) AddServerProof(serverProof *ServerProofInfo) { + bi.serverProof = serverProof +} + +// BatchQueue implements a FIFO queue of BatchInfo +type BatchQueue struct { + queue []*BatchInfo +} + +// Push adds the given BatchInfo to the BatchQueue +func (bq *BatchQueue) Push(b *BatchInfo) { + bq.queue = append(bq.queue, b) +} + +// Pop pops the first BatchInfo from the BatchQueue +func (bq *BatchQueue) Pop() *BatchInfo { + if len(bq.queue) == 0 { + return nil + } + b := bq.queue[0] + bq.queue = bq.queue[1:] + return b +} diff --git a/coordinator/batch_test.go b/coordinator/batch_test.go new file mode 100644 index 0000000..da1c819 --- /dev/null +++ b/coordinator/batch_test.go @@ -0,0 +1,26 @@ +package coordinator + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestBatchQueue(t *testing.T) { + bq := BatchQueue{} + + bq.Push(&BatchInfo{ + batchNum: 0, + }) + bq.Push(&BatchInfo{ + batchNum: 2, + }) + bq.Push(&BatchInfo{ + batchNum: 1, + }) + + assert.Equal(t, uint64(0), bq.Pop().batchNum) + assert.Equal(t, uint64(2), bq.Pop().batchNum) + assert.Equal(t, uint64(1), bq.Pop().batchNum) + assert.Nil(t, bq.Pop()) +} diff --git a/coordinator/proofpool.go b/coordinator/proofpool.go new file mode 100644 index 0000000..87a05f3 --- /dev/null +++ b/coordinator/proofpool.go @@ -0,0 +1,21 @@ +package coordinator + +import "github.com/hermeznetwork/hermez-node/common" + +type ServerProofInfo struct { + // TODO + Available bool +} + +func (p *ServerProofInfo) CalculateProof(zkInputs *common.ZKInputs) error { + return nil +} + +type ServerProofPool struct { + pool []ServerProofInfo +} + +func (p *ServerProofPool) GetNextAvailable() (*ServerProofInfo, error) { + + return nil, nil +} diff --git a/db/statedb/statedb.go b/db/statedb/statedb.go index 3525b53..b66e96f 100644 --- a/db/statedb/statedb.go +++ b/db/statedb/statedb.go @@ -50,21 +50,21 @@ func NewStateDB(path string, inDisk bool, withMT bool, nLevels int) (*StateDB, e } // CheckPointAt does a checkpoint at the given batchNum in the defined path -func (s *StateDB) CheckPointAt(batchNum int, path string) error { +func (s *StateDB) CheckPointAt(batchNum uint64, path string) error { // TODO return nil } // Reset resets the StateDB to the checkpoint at the given batchNum -func (s *StateDB) Reset(batchNum int) error { +func (s *StateDB) Reset(batchNum uint64) error { // TODO return nil } // Checkpoints returns a list of the checkpoints (batchNums) -func (s *StateDB) Checkpoints() ([]int, error) { +func (s *StateDB) Checkpoints() ([]uint64, error) { // TODO //batchnums, err @@ -208,7 +208,7 @@ func NewLocalStateDB(synchronizerDB *StateDB, withMT bool, nLevels int) (*LocalS // Reset performs a reset, getting the state from // LocalStateDB.synchronizerStateDB for the given batchNum -func (l *LocalStateDB) Reset(batchNum int, fromSynchronizer bool) error { +func (l *LocalStateDB) Reset(batchNum uint64, fromSynchronizer bool) error { // TODO // if fromSynchronizer==true: // make copy from l.synchronizerStateDB at the batchNum to the localStateDB diff --git a/txselector/txselector.go b/txselector/txselector.go index fed9ad8..3bb65c9 100644 --- a/txselector/txselector.go +++ b/txselector/txselector.go @@ -52,7 +52,7 @@ func NewTxSelector(synchronizerStateDB *statedb.StateDB, l2 *l2db.L2DB, maxL1Use // Reset tells the TxSelector to get it's internal AccountsDB // from the required `batchNum` -func (txsel *TxSelector) Reset(batchNum int) error { +func (txsel *TxSelector) Reset(batchNum uint64) error { err := txsel.localAccountsDB.Reset(batchNum, true) if err != nil { return err @@ -61,7 +61,7 @@ func (txsel *TxSelector) Reset(batchNum int) error { } // GetL2TxSelection returns a selection of the L2Txs for the next batch, from the L2DB pool -func (txsel *TxSelector) GetL2TxSelection(batchNum int) ([]common.PoolL2Tx, error) { +func (txsel *TxSelector) GetL2TxSelection(batchNum uint64) ([]common.PoolL2Tx, error) { // get pending l2-tx from tx-pool l2TxsRaw, err := txsel.l2db.GetPendingTxs() // once l2db ready, maybe use parameter 'batchNum' if err != nil { @@ -90,7 +90,7 @@ func (txsel *TxSelector) GetL2TxSelection(batchNum int) ([]common.PoolL2Tx, erro } // GetL1L2TxSelection returns the selection of L1 + L2 txs -func (txsel *TxSelector) GetL1L2TxSelection(batchNum int, l1txs []common.Tx) ([]common.Tx, []common.PoolL2Tx, []common.Tx, error) { +func (txsel *TxSelector) GetL1L2TxSelection(batchNum uint64, l1txs []common.L1Tx) ([]common.L1Tx, []common.L1Tx, []common.PoolL2Tx, error) { // apply l1-user-tx to localAccountDB // create new leaves // update balances @@ -134,7 +134,7 @@ func (txsel *TxSelector) GetL1L2TxSelection(batchNum int, l1txs []common.Tx) ([] maxL2Txs := txsel.MaxTxs - uint64(len(l1OperatorTxs)) // - len(l1UserTxs) l2txs := txsel.getL2Profitable(validTxs, maxL2Txs) - return l1txs, l2txs, l1OperatorTxs, nil + return l1txs, l1OperatorTxs, l2txs, nil } func (txsel *TxSelector) checkIfAccountExistOrPending(idx common.Idx) bool { @@ -155,7 +155,7 @@ func (txsel *TxSelector) getL2Profitable(txs txs, max uint64) txs { sort.Sort(txs) return txs[:max] } -func (txsel *TxSelector) createL1OperatorTxForL2Tx(accounts []common.Account) []common.Tx { +func (txsel *TxSelector) createL1OperatorTxForL2Tx(accounts []common.Account) []common.L1Tx { // return nil }