mirror of
https://github.com/arnaucube/hermez-node.git
synced 2026-02-07 03:16:45 +01:00
TxSelector include L1CoordinatorTxs in selections
This commit is contained in:
@@ -22,7 +22,7 @@ type PoolL2Tx struct {
|
|||||||
FromIdx Idx `meddler:"from_idx"`
|
FromIdx Idx `meddler:"from_idx"`
|
||||||
ToIdx Idx `meddler:"to_idx,zeroisnull"`
|
ToIdx Idx `meddler:"to_idx,zeroisnull"`
|
||||||
AuxToIdx Idx `meddler:"-"` // AuxToIdx is only used internally at the StateDB to avoid repeated computation when processing transactions (from Synchronizer, TxSelector, BatchBuilder)
|
AuxToIdx Idx `meddler:"-"` // AuxToIdx is only used internally at the StateDB to avoid repeated computation when processing transactions (from Synchronizer, TxSelector, BatchBuilder)
|
||||||
ToEthAddr ethCommon.Address `meddler:"to_eth_addr"`
|
ToEthAddr ethCommon.Address `meddler:"to_eth_addr,zeroisnull"`
|
||||||
ToBJJ *babyjub.PublicKey `meddler:"to_bjj"`
|
ToBJJ *babyjub.PublicKey `meddler:"to_bjj"`
|
||||||
TokenID TokenID `meddler:"token_id"`
|
TokenID TokenID `meddler:"token_id"`
|
||||||
Amount *big.Int `meddler:"amount,bigint"` // TODO: change to float16
|
Amount *big.Int `meddler:"amount,bigint"` // TODO: change to float16
|
||||||
@@ -34,7 +34,7 @@ type PoolL2Tx struct {
|
|||||||
// Stored in DB: optional fileds, may be uninitialized
|
// Stored in DB: optional fileds, may be uninitialized
|
||||||
RqFromIdx Idx `meddler:"rq_from_idx,zeroisnull"` // FromIdx is used by L1Tx/Deposit to indicate the Idx receiver of the L1Tx.LoadAmount (deposit)
|
RqFromIdx Idx `meddler:"rq_from_idx,zeroisnull"` // FromIdx is used by L1Tx/Deposit to indicate the Idx receiver of the L1Tx.LoadAmount (deposit)
|
||||||
RqToIdx Idx `meddler:"rq_to_idx,zeroisnull"` // FromIdx is used by L1Tx/Deposit to indicate the Idx receiver of the L1Tx.LoadAmount (deposit)
|
RqToIdx Idx `meddler:"rq_to_idx,zeroisnull"` // FromIdx is used by L1Tx/Deposit to indicate the Idx receiver of the L1Tx.LoadAmount (deposit)
|
||||||
RqToEthAddr ethCommon.Address `meddler:"rq_to_eth_addr"`
|
RqToEthAddr ethCommon.Address `meddler:"rq_to_eth_addr,zeroisnull"`
|
||||||
RqToBJJ *babyjub.PublicKey `meddler:"rq_to_bjj"` // TODO: stop using json, use scanner/valuer
|
RqToBJJ *babyjub.PublicKey `meddler:"rq_to_bjj"` // TODO: stop using json, use scanner/valuer
|
||||||
RqTokenID TokenID `meddler:"rq_token_id,zeroisnull"`
|
RqTokenID TokenID `meddler:"rq_token_id,zeroisnull"`
|
||||||
RqAmount *big.Int `meddler:"rq_amount,bigintnull"` // TODO: change to float16
|
RqAmount *big.Int `meddler:"rq_amount,bigintnull"` // TODO: change to float16
|
||||||
|
|||||||
@@ -220,7 +220,7 @@ func (c *Coordinator) forge(serverProof ServerProofInterface) (*BatchInfo, error
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// 2b: only L2 txs
|
// 2b: only L2 txs
|
||||||
poolL2Txs, err = c.txsel.GetL2TxSelection([]common.Idx{}, c.batchNum) // TODO once feesInfo is added to method return, add the var
|
_, poolL2Txs, err = c.txsel.GetL2TxSelection([]common.Idx{}, c.batchNum) // TODO once feesInfo is added to method return, add the var
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ func (l2db *L2DB) AddTxTest(tx *common.PoolL2Tx) error {
|
|||||||
Amount: tx.Amount,
|
Amount: tx.Amount,
|
||||||
Fee: tx.Fee,
|
Fee: tx.Fee,
|
||||||
Nonce: tx.Nonce,
|
Nonce: tx.Nonce,
|
||||||
State: tx.State,
|
State: common.PoolL2TxStatePending,
|
||||||
Signature: tx.Signature,
|
Signature: tx.Signature,
|
||||||
RqToBJJ: tx.RqToBJJ,
|
RqToBJJ: tx.RqToBJJ,
|
||||||
RqAmount: tx.RqAmount,
|
RqAmount: tx.RqAmount,
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ type Context struct {
|
|||||||
Instructions []instruction
|
Instructions []instruction
|
||||||
userNames []string
|
userNames []string
|
||||||
Users map[string]*User
|
Users map[string]*User
|
||||||
lastRegisteredTokenID common.TokenID
|
LastRegisteredTokenID common.TokenID
|
||||||
l1CreatedAccounts map[string]*Account
|
l1CreatedAccounts map[string]*Account
|
||||||
|
|
||||||
// rollupConstMaxL1UserTx Maximum L1-user transactions allowed to be queued in a batch
|
// rollupConstMaxL1UserTx Maximum L1-user transactions allowed to be queued in a batch
|
||||||
@@ -56,7 +56,7 @@ func NewContext(rollupConstMaxL1UserTx int) *Context {
|
|||||||
return &Context{
|
return &Context{
|
||||||
Users: make(map[string]*User),
|
Users: make(map[string]*User),
|
||||||
l1CreatedAccounts: make(map[string]*Account),
|
l1CreatedAccounts: make(map[string]*Account),
|
||||||
lastRegisteredTokenID: 0,
|
LastRegisteredTokenID: 0,
|
||||||
|
|
||||||
rollupConstMaxL1UserTx: rollupConstMaxL1UserTx,
|
rollupConstMaxL1UserTx: rollupConstMaxL1UserTx,
|
||||||
idx: common.UserThreshold,
|
idx: common.UserThreshold,
|
||||||
@@ -323,10 +323,10 @@ func (tc *Context) GenerateBlocks(set string) ([]common.BlockData, error) {
|
|||||||
TokenID: inst.tokenID,
|
TokenID: inst.tokenID,
|
||||||
EthBlockNum: tc.blockNum,
|
EthBlockNum: tc.blockNum,
|
||||||
}
|
}
|
||||||
if inst.tokenID != tc.lastRegisteredTokenID+1 {
|
if inst.tokenID != tc.LastRegisteredTokenID+1 {
|
||||||
return nil, fmt.Errorf("Line %d: AddToken TokenID should be sequential, expected TokenID: %d, defined TokenID: %d", inst.lineNum, tc.lastRegisteredTokenID+1, inst.tokenID)
|
return nil, fmt.Errorf("Line %d: AddToken TokenID should be sequential, expected TokenID: %d, defined TokenID: %d", inst.lineNum, tc.LastRegisteredTokenID+1, inst.tokenID)
|
||||||
}
|
}
|
||||||
tc.lastRegisteredTokenID++
|
tc.LastRegisteredTokenID++
|
||||||
tc.currBlock.AddedTokens = append(tc.currBlock.AddedTokens, newToken)
|
tc.currBlock.AddedTokens = append(tc.currBlock.AddedTokens, newToken)
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("Line %d: Unexpected type: %s", inst.lineNum, inst.typ)
|
return nil, fmt.Errorf("Line %d: Unexpected type: %s", inst.lineNum, inst.typ)
|
||||||
@@ -457,8 +457,8 @@ func (tc *Context) checkIfAccountExists(tf string, inst instruction) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
func (tc *Context) checkIfTokenIsRegistered(inst instruction) error {
|
func (tc *Context) checkIfTokenIsRegistered(inst instruction) error {
|
||||||
if inst.tokenID > tc.lastRegisteredTokenID {
|
if inst.tokenID > tc.LastRegisteredTokenID {
|
||||||
return fmt.Errorf("Can not process %s: TokenID %d not registered, last registered TokenID: %d", inst.typ, inst.tokenID, tc.lastRegisteredTokenID)
|
return fmt.Errorf("Can not process %s: TokenID %d not registered, last registered TokenID: %d", inst.typ, inst.tokenID, tc.LastRegisteredTokenID)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,34 +67,11 @@ func (txsel *TxSelector) Reset(batchNum common.BatchNum) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetL2TxSelection returns a selection of the L2Txs for the next batch, from the L2DB pool
|
// GetL2TxSelection returns the L1CoordinatorTxs and a selection of the L2Txs
|
||||||
func (txsel *TxSelector) GetL2TxSelection(coordIdxs []common.Idx, batchNum common.BatchNum) ([]common.PoolL2Tx, error) {
|
// for the next batch, from the L2DB pool
|
||||||
// get pending l2-tx from tx-pool
|
func (txsel *TxSelector) GetL2TxSelection(coordIdxs []common.Idx, batchNum common.BatchNum) ([]common.L1Tx, []common.PoolL2Tx, error) {
|
||||||
l2TxsRaw, err := txsel.l2db.GetPendingTxs() // once l2db ready, maybe use parameter 'batchNum'
|
_, l1CoordinatorTxs, l2Txs, err := txsel.GetL1L2TxSelection(coordIdxs, batchNum, []common.L1Tx{})
|
||||||
if err != nil {
|
return l1CoordinatorTxs, l2Txs, err
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// discard the txs that don't have an Account in the AccountDB
|
|
||||||
var validTxs txs
|
|
||||||
for _, tx := range l2TxsRaw {
|
|
||||||
_, err = txsel.localAccountsDB.GetAccount(tx.FromIdx)
|
|
||||||
if err == nil {
|
|
||||||
// if FromIdx has an account into the AccountsDB
|
|
||||||
validTxs = append(validTxs, tx)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// get most profitable L2-tx
|
|
||||||
txs := txsel.getL2Profitable(validTxs, txsel.MaxTxs)
|
|
||||||
|
|
||||||
// process the txs in the local AccountsDB
|
|
||||||
_, err = txsel.localAccountsDB.ProcessTxs(coordIdxs, nil, nil, txs)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
err = txsel.localAccountsDB.MakeCheckpoint()
|
|
||||||
return txs, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetL1L2TxSelection returns the selection of L1 + L2 txs
|
// GetL1L2TxSelection returns the selection of L1 + L2 txs
|
||||||
@@ -138,7 +115,7 @@ func (txsel *TxSelector) GetL1L2TxSelection(coordIdxs []common.Idx, batchNum com
|
|||||||
if l2TxsRaw[i].ToBJJ != nil {
|
if l2TxsRaw[i].ToBJJ != nil {
|
||||||
// case: ToBJJ!=0:
|
// case: ToBJJ!=0:
|
||||||
// if idx exist for EthAddr&BJJ use it
|
// if idx exist for EthAddr&BJJ use it
|
||||||
_, err := txsel.localAccountsDB.GetIdxByEthAddrBJJ(l2TxsRaw[i].ToEthAddr, l2TxsRaw[i].ToBJJ)
|
_, err := txsel.localAccountsDB.GetIdxByEthAddrBJJ(l2TxsRaw[i].ToEthAddr, l2TxsRaw[i].ToBJJ, l2TxsRaw[i].TokenID)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
// account for ToEthAddr&ToBJJ already exist,
|
// account for ToEthAddr&ToBJJ already exist,
|
||||||
// there is no need to create a new one.
|
// there is no need to create a new one.
|
||||||
@@ -163,7 +140,7 @@ func (txsel *TxSelector) GetL1L2TxSelection(coordIdxs []common.Idx, batchNum com
|
|||||||
} else {
|
} else {
|
||||||
// case: ToBJJ==0:
|
// case: ToBJJ==0:
|
||||||
// if idx exist for EthAddr use it
|
// if idx exist for EthAddr use it
|
||||||
_, err := txsel.localAccountsDB.GetIdxByEthAddr(l2TxsRaw[i].ToEthAddr)
|
_, err := txsel.localAccountsDB.GetIdxByEthAddr(l2TxsRaw[i].ToEthAddr, l2TxsRaw[i].TokenID)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
// account for ToEthAddr already exist,
|
// account for ToEthAddr already exist,
|
||||||
// there is no need to create a new one.
|
// there is no need to create a new one.
|
||||||
@@ -194,7 +171,7 @@ func (txsel *TxSelector) GetL1L2TxSelection(coordIdxs []common.Idx, batchNum com
|
|||||||
l1CoordinatorTxs = append(l1CoordinatorTxs, l1CoordinatorTx)
|
l1CoordinatorTxs = append(l1CoordinatorTxs, l1CoordinatorTx)
|
||||||
} else if bytes.Equal(l2TxsRaw[i].ToEthAddr.Bytes(), common.FFAddr.Bytes()) && l2TxsRaw[i].ToBJJ != nil {
|
} else if bytes.Equal(l2TxsRaw[i].ToEthAddr.Bytes(), common.FFAddr.Bytes()) && l2TxsRaw[i].ToBJJ != nil {
|
||||||
// if idx exist for EthAddr&BJJ use it
|
// if idx exist for EthAddr&BJJ use it
|
||||||
_, err := txsel.localAccountsDB.GetIdxByEthAddrBJJ(l2TxsRaw[i].ToEthAddr, l2TxsRaw[i].ToBJJ)
|
_, err := txsel.localAccountsDB.GetIdxByEthAddrBJJ(l2TxsRaw[i].ToEthAddr, l2TxsRaw[i].ToBJJ, l2TxsRaw[i].TokenID)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
// account for ToEthAddr&ToBJJ already exist, (where ToEthAddr==0xff)
|
// account for ToEthAddr&ToBJJ already exist, (where ToEthAddr==0xff)
|
||||||
// there is no need to create a new one.
|
// there is no need to create a new one.
|
||||||
|
|||||||
@@ -1,7 +1,26 @@
|
|||||||
package txselector
|
package txselector
|
||||||
|
|
||||||
/*
|
import (
|
||||||
TODO update transactions generation
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"strconv"
|
||||||
|
"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/db/historydb"
|
||||||
|
"github.com/hermeznetwork/hermez-node/db/l2db"
|
||||||
|
"github.com/hermeznetwork/hermez-node/db/statedb"
|
||||||
|
"github.com/hermeznetwork/hermez-node/eth"
|
||||||
|
"github.com/hermeznetwork/hermez-node/test"
|
||||||
|
"github.com/hermeznetwork/hermez-node/test/til"
|
||||||
|
"github.com/jmoiron/sqlx"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
func initTest(t *testing.T, testSet string, maxL1UserTxs, maxL1OperatorTxs, maxTxs uint64) *TxSelector {
|
func initTest(t *testing.T, testSet string, maxL1UserTxs, maxL1OperatorTxs, maxTxs uint64) *TxSelector {
|
||||||
pass := os.Getenv("POSTGRES_PASS")
|
pass := os.Getenv("POSTGRES_PASS")
|
||||||
db, err := dbUtils.InitSQLDB(5432, "localhost", "hermez", pass, "hermez")
|
db, err := dbUtils.InitSQLDB(5432, "localhost", "hermez", pass, "hermez")
|
||||||
@@ -42,34 +61,67 @@ func TestGetL2TxSelection(t *testing.T) {
|
|||||||
txsel := initTest(t, til.SetPool0, 5, 5, 10)
|
txsel := initTest(t, til.SetPool0, 5, 5, 10)
|
||||||
test.CleanL2DB(txsel.l2db.DB())
|
test.CleanL2DB(txsel.l2db.DB())
|
||||||
|
|
||||||
// generate test transactions
|
tc := til.NewContext(eth.RollupConstMaxL1UserTx)
|
||||||
l1Txs, _, poolL2Txs, tokens := test.GenerateTestTxsFromSet(t, test.SetTest0)
|
// generate test transactions
|
||||||
|
blocks, err := tc.GenerateBlocks(til.SetBlockchain0)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
// poolL2Txs, err := tc.GeneratePoolL2Txs(til.SetPool0)
|
||||||
|
// assert.Nil(t, err)
|
||||||
|
|
||||||
// add tokens to HistoryDB to avoid breaking FK constrains
|
coordIdxs := []common.Idx{256, 257, 258, 259}
|
||||||
addTokens(t, tokens, txsel.l2db.DB())
|
|
||||||
// add the first batch of transactions to the TxSelector
|
|
||||||
addL2Txs(t, txsel, poolL2Txs[0])
|
|
||||||
|
|
||||||
_, err := txsel.GetL2TxSelection(0)
|
// add tokens to HistoryDB to avoid breaking FK constrains
|
||||||
assert.Nil(t, err)
|
var tokens []common.Token
|
||||||
|
for i := 0; i < int(tc.LastRegisteredTokenID); i++ {
|
||||||
|
tokens = append(tokens, common.Token{
|
||||||
|
TokenID: common.TokenID(i),
|
||||||
|
EthBlockNum: 1,
|
||||||
|
EthAddr: ethCommon.BytesToAddress([]byte{byte(i)}),
|
||||||
|
Name: strconv.Itoa(i),
|
||||||
|
Symbol: strconv.Itoa(i),
|
||||||
|
Decimals: 18,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
addTokens(t, tokens, txsel.l2db.DB())
|
||||||
|
|
||||||
_, _, _, err = txsel.GetL1L2TxSelection(0, l1Txs[0])
|
// Process the 1st batch, which contains the L1CoordinatorTxs necessary
|
||||||
assert.Nil(t, err)
|
// to create the Coordinator accounts to receive the fees
|
||||||
|
_, err = txsel.localAccountsDB.ProcessTxs(nil, nil, blocks[0].Batches[0].L1CoordinatorTxs, nil)
|
||||||
|
require.Nil(t, err)
|
||||||
|
|
||||||
// TODO once L2DB is updated to return error in case that AddTxTest
|
// add the 1st batch of transactions to the TxSelector
|
||||||
// fails, and the Til is updated, update this test, checking that the
|
addL2Txs(t, txsel, common.L2TxsToPoolL2Txs(blocks[0].Batches[0].L2Txs))
|
||||||
// selected PoolL2Tx are correctly sorted by Nonce
|
|
||||||
|
|
||||||
|
l1CoordTxs, l2Txs, err := txsel.GetL2TxSelection(coordIdxs, 0)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.Equal(t, 0, len(l2Txs))
|
||||||
|
assert.Equal(t, 0, len(l1CoordTxs))
|
||||||
|
|
||||||
|
_, _, _, err = txsel.GetL1L2TxSelection(coordIdxs, 0, blocks[0].L1UserTxs)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
|
||||||
// txs, err := txsel.GetL2TxSelection(0)
|
// TODO once L2DB is updated to return error in case that AddTxTest
|
||||||
// assert.Nil(t, err)
|
// fails, and the Til is updated, update this test, checking that the
|
||||||
// for _, tx := range txs {
|
// selected PoolL2Tx are correctly sorted by Nonce
|
||||||
// fmt.Println(tx.FromIdx, tx.ToIdx, tx.AbsoluteFee)
|
|
||||||
// }
|
// TODO once L2DB is updated to store the parameter AbsoluteFee (which
|
||||||
// assert.Equal(t, 3, len(txs))
|
// is used by TxSelector to sort L2Txs), uncomment this next lines of
|
||||||
// assert.Equal(t, uint64(6), txs[0].AbsoluteFee)
|
// test, and put the expected value for
|
||||||
// assert.Equal(t, uint64(5), txs[1].AbsoluteFee)
|
// l2Txs[len(l2Txs)-1].AbsoluteFee, which is the Tx which has the
|
||||||
// assert.Equal(t, uint64(4), txs[2].AbsoluteFee)
|
// Fee==192.
|
||||||
|
/*
|
||||||
|
// add the 3rd batch of transactions to the TxSelector
|
||||||
|
addL2Txs(t, txsel, common.L2TxsToPoolL2Txs(blocks[0].Batches[2].L2Txs))
|
||||||
|
|
||||||
|
_, l2Txs, err = txsel.GetL2TxSelection(coordIdxs, 0)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
for _, tx := range l2Txs {
|
||||||
|
fmt.Println(tx.FromIdx, tx.ToIdx, tx.AbsoluteFee)
|
||||||
|
}
|
||||||
|
require.Equal(t, 10, len(l2Txs))
|
||||||
|
assert.Equal(t, float64(0), l2Txs[0].AbsoluteFee)
|
||||||
|
|
||||||
|
fmt.Println(l2Txs[len(l2Txs)-1].Amount)
|
||||||
|
assert.Equal(t, float64(4), l2Txs[len(l2Txs)-1].AbsoluteFee)
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|||||||
Reference in New Issue
Block a user