mirror of
https://github.com/arnaucube/hermez-node.git
synced 2026-02-07 03:16:45 +01:00
Merge pull request #247 from hermeznetwork/feature/til-sets
Add Til set w minimum flow, add balances tests at StateDB ProcessTxs, small fixes at StateDB
This commit is contained in:
@@ -28,6 +28,9 @@ var (
|
||||
// ErrToIdxNotFound is used when trying to get the ToIdx from ToEthAddr
|
||||
// or ToEthAddr&ToBJJ
|
||||
ErrToIdxNotFound = errors.New("ToIdx can not be found")
|
||||
// ErrGetIdxNoCase is used when trying to get the Idx from EthAddr &
|
||||
// BJJ with not compatible combination
|
||||
ErrGetIdxNoCase = errors.New("Can not get Idx due unexpected combination of ethereum Address & BabyJubJub PublicKey")
|
||||
|
||||
// KeyCurrentBatch is used as key in the db to store the current BatchNum
|
||||
KeyCurrentBatch = []byte("k:currentbatch")
|
||||
|
||||
@@ -264,7 +264,7 @@ func (s *StateDB) getTokenIDsBigInt(l1usertxs, l1coordinatortxs []common.L1Tx, l
|
||||
// AccountsDB (in the StateDB)
|
||||
acc, err := s.GetAccount(l2txs[i].FromIdx)
|
||||
if err != nil {
|
||||
log.Errorf("ToIdx %d not found: %s", l2txs[i].ToIdx, err.Error())
|
||||
log.Errorf("could not get account to determine TokenID of L2Tx: FromIdx %d not found: %s", l2txs[i].FromIdx, err.Error())
|
||||
return nil, err
|
||||
}
|
||||
tokenIDs[acc.TokenID] = true
|
||||
@@ -397,7 +397,6 @@ func (s *StateDB) processL2Tx(coordIdxsMap map[common.TokenID]common.Idx, collec
|
||||
// case when tx.Type== common.TxTypeTransferToEthAddr or common.TxTypeTransferToBJJ
|
||||
tx.AuxToIdx, err = s.GetIdxByEthAddrBJJ(tx.ToEthAddr, tx.ToBJJ, tx.TokenID)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
return nil, nil, false, err
|
||||
}
|
||||
}
|
||||
@@ -607,6 +606,7 @@ func (s *StateDB) applyTransfer(coordIdxsMap map[common.TokenID]common.Idx, coll
|
||||
fee := common.CalcFeeAmount(tx.Amount, *tx.Fee)
|
||||
feeAndAmount := new(big.Int).Add(tx.Amount, fee)
|
||||
accSender.Balance = new(big.Int).Sub(accSender.Balance, feeAndAmount)
|
||||
|
||||
// send the fee to the Idx of the Coordinator for the TokenID
|
||||
accCoord, err := s.GetAccount(coordIdxsMap[accSender.TokenID])
|
||||
if err != nil {
|
||||
@@ -623,6 +623,8 @@ func (s *StateDB) applyTransfer(coordIdxsMap map[common.TokenID]common.Idx, coll
|
||||
collected.Add(collected, fee)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
accSender.Balance = new(big.Int).Sub(accSender.Balance, tx.Amount)
|
||||
}
|
||||
|
||||
// add amount-feeAmount to the receiver
|
||||
@@ -676,7 +678,6 @@ func (s *StateDB) applyCreateAccountDepositTransfer(tx *common.L1Tx) error {
|
||||
PublicKey: tx.FromBJJ,
|
||||
EthAddr: tx.FromEthAddr,
|
||||
}
|
||||
accSender.Balance = new(big.Int).Add(accSender.Balance, tx.LoadAmount)
|
||||
accReceiver, err := s.GetAccount(tx.ToIdx)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -762,6 +763,8 @@ func (s *StateDB) applyExit(coordIdxsMap map[common.TokenID]common.Idx, collecte
|
||||
collected.Add(collected, fee)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
acc.Balance = new(big.Int).Sub(acc.Balance, tx.Amount)
|
||||
}
|
||||
|
||||
p, err := s.UpdateAccount(tx.FromIdx, acc)
|
||||
|
||||
@@ -15,6 +15,139 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func checkBalance(t *testing.T, tc *til.Context, sdb *StateDB, username string, tokenid int, expected string) {
|
||||
idx := tc.Users[username].Accounts[common.TokenID(tokenid)].Idx
|
||||
acc, err := sdb.GetAccount(idx)
|
||||
require.Nil(t, err)
|
||||
assert.Equal(t, expected, acc.Balance.String())
|
||||
}
|
||||
|
||||
func TestProcessTxsBalances(t *testing.T) {
|
||||
dir, err := ioutil.TempDir("", "tmpdb")
|
||||
require.Nil(t, err)
|
||||
defer assert.Nil(t, os.RemoveAll(dir))
|
||||
|
||||
sdb, err := NewStateDB(dir, TypeSynchronizer, 32)
|
||||
assert.Nil(t, err)
|
||||
|
||||
// generate test transactions from test.SetBlockchain0 code
|
||||
tc := til.NewContext(eth.RollupConstMaxL1UserTx)
|
||||
blocks, err := tc.GenerateBlocks(til.SetBlockchainMinimumFlow0)
|
||||
require.Nil(t, err)
|
||||
|
||||
// Coordinator Idx where to send the fees
|
||||
coordIdxs := []common.Idx{256, 257}
|
||||
|
||||
log.Debug("block:0 batch:0, only L1CoordinatorTxs")
|
||||
_, err = sdb.ProcessTxs(nil, nil, blocks[0].Batches[0].L1CoordinatorTxs, nil)
|
||||
require.Nil(t, err)
|
||||
|
||||
log.Debug("block:0 batch:1")
|
||||
l1UserTxs := []common.L1Tx{}
|
||||
l2Txs := common.L2TxsToPoolL2Txs(blocks[0].Batches[1].L2Txs)
|
||||
_, err = sdb.ProcessTxs(coordIdxs, l1UserTxs, blocks[0].Batches[1].L1CoordinatorTxs, l2Txs)
|
||||
require.Nil(t, err)
|
||||
|
||||
log.Debug("block:0 batch:2")
|
||||
l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Batches[2].Batch.ForgeL1TxsNum])
|
||||
l2Txs = common.L2TxsToPoolL2Txs(blocks[0].Batches[2].L2Txs)
|
||||
_, err = sdb.ProcessTxs(coordIdxs, l1UserTxs, blocks[0].Batches[2].L1CoordinatorTxs, l2Txs)
|
||||
require.Nil(t, err)
|
||||
checkBalance(t, tc, sdb, "A", 0, "500")
|
||||
|
||||
log.Debug("block:0 batch:3")
|
||||
l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Batches[3].Batch.ForgeL1TxsNum])
|
||||
l2Txs = common.L2TxsToPoolL2Txs(blocks[0].Batches[3].L2Txs)
|
||||
_, err = sdb.ProcessTxs(coordIdxs, l1UserTxs, blocks[0].Batches[3].L1CoordinatorTxs, l2Txs)
|
||||
require.Nil(t, err)
|
||||
checkBalance(t, tc, sdb, "A", 0, "500")
|
||||
checkBalance(t, tc, sdb, "A", 1, "500")
|
||||
|
||||
log.Debug("block:0 batch:4")
|
||||
l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Batches[4].Batch.ForgeL1TxsNum])
|
||||
l2Txs = common.L2TxsToPoolL2Txs(blocks[0].Batches[4].L2Txs)
|
||||
_, err = sdb.ProcessTxs(coordIdxs, l1UserTxs, blocks[0].Batches[4].L1CoordinatorTxs, l2Txs)
|
||||
require.Nil(t, err)
|
||||
checkBalance(t, tc, sdb, "A", 0, "500")
|
||||
checkBalance(t, tc, sdb, "A", 1, "500")
|
||||
|
||||
log.Debug("block:0 batch:5")
|
||||
l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Batches[5].Batch.ForgeL1TxsNum])
|
||||
l2Txs = common.L2TxsToPoolL2Txs(blocks[0].Batches[5].L2Txs)
|
||||
_, err = sdb.ProcessTxs(coordIdxs, l1UserTxs, blocks[0].Batches[5].L1CoordinatorTxs, l2Txs)
|
||||
require.Nil(t, err)
|
||||
checkBalance(t, tc, sdb, "A", 0, "600")
|
||||
checkBalance(t, tc, sdb, "A", 1, "500")
|
||||
checkBalance(t, tc, sdb, "B", 0, "400")
|
||||
|
||||
log.Debug("block:0 batch:6")
|
||||
l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Batches[6].Batch.ForgeL1TxsNum])
|
||||
l2Txs = common.L2TxsToPoolL2Txs(blocks[0].Batches[6].L2Txs)
|
||||
_, err = sdb.ProcessTxs(coordIdxs, l1UserTxs, blocks[0].Batches[6].L1CoordinatorTxs, l2Txs)
|
||||
require.Nil(t, err)
|
||||
checkBalance(t, tc, sdb, "Coord", 0, "10")
|
||||
checkBalance(t, tc, sdb, "Coord", 1, "20")
|
||||
checkBalance(t, tc, sdb, "A", 0, "600")
|
||||
checkBalance(t, tc, sdb, "A", 1, "280")
|
||||
checkBalance(t, tc, sdb, "B", 0, "290")
|
||||
checkBalance(t, tc, sdb, "B", 1, "200")
|
||||
checkBalance(t, tc, sdb, "C", 0, "100")
|
||||
checkBalance(t, tc, sdb, "D", 0, "800")
|
||||
|
||||
log.Debug("block:0 batch:7")
|
||||
l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Batches[7].Batch.ForgeL1TxsNum])
|
||||
l2Txs = common.L2TxsToPoolL2Txs(blocks[0].Batches[7].L2Txs)
|
||||
_, err = sdb.ProcessTxs(coordIdxs, l1UserTxs, blocks[0].Batches[7].L1CoordinatorTxs, l2Txs)
|
||||
require.Nil(t, err)
|
||||
checkBalance(t, tc, sdb, "Coord", 0, "35")
|
||||
checkBalance(t, tc, sdb, "Coord", 1, "30")
|
||||
checkBalance(t, tc, sdb, "A", 0, "430")
|
||||
checkBalance(t, tc, sdb, "A", 1, "280")
|
||||
checkBalance(t, tc, sdb, "B", 0, "390")
|
||||
checkBalance(t, tc, sdb, "B", 1, "90")
|
||||
checkBalance(t, tc, sdb, "C", 0, "45")
|
||||
checkBalance(t, tc, sdb, "C", 1, "100")
|
||||
checkBalance(t, tc, sdb, "D", 0, "800")
|
||||
|
||||
log.Debug("block:1 batch:0")
|
||||
l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[1].Batches[0].Batch.ForgeL1TxsNum])
|
||||
l2Txs = common.L2TxsToPoolL2Txs(blocks[1].Batches[0].L2Txs)
|
||||
_, err = sdb.ProcessTxs(coordIdxs, l1UserTxs, blocks[1].Batches[0].L1CoordinatorTxs, l2Txs)
|
||||
require.Nil(t, err)
|
||||
checkBalance(t, tc, sdb, "Coord", 0, "75")
|
||||
checkBalance(t, tc, sdb, "Coord", 1, "30")
|
||||
checkBalance(t, tc, sdb, "A", 0, "730")
|
||||
checkBalance(t, tc, sdb, "A", 1, "280")
|
||||
checkBalance(t, tc, sdb, "B", 0, "380")
|
||||
checkBalance(t, tc, sdb, "B", 1, "90")
|
||||
checkBalance(t, tc, sdb, "C", 0, "845")
|
||||
checkBalance(t, tc, sdb, "C", 1, "100")
|
||||
checkBalance(t, tc, sdb, "D", 0, "470")
|
||||
|
||||
log.Debug("block:1 batch:1")
|
||||
l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[1].Batches[1].Batch.ForgeL1TxsNum])
|
||||
l2Txs = common.L2TxsToPoolL2Txs(blocks[1].Batches[1].L2Txs)
|
||||
_, err = sdb.ProcessTxs(coordIdxs, l1UserTxs, blocks[1].Batches[1].L1CoordinatorTxs, l2Txs)
|
||||
require.Nil(t, err)
|
||||
|
||||
// use Set of PoolL2 txs
|
||||
poolL2Txs, err := tc.GeneratePoolL2Txs(til.SetPoolL2MinimumFlow0)
|
||||
assert.Nil(t, err)
|
||||
|
||||
_, err = sdb.ProcessTxs(coordIdxs, []common.L1Tx{}, []common.L1Tx{}, poolL2Txs)
|
||||
require.Nil(t, err)
|
||||
checkBalance(t, tc, sdb, "Coord", 0, "105")
|
||||
checkBalance(t, tc, sdb, "Coord", 1, "40")
|
||||
checkBalance(t, tc, sdb, "A", 0, "510")
|
||||
checkBalance(t, tc, sdb, "A", 1, "170")
|
||||
checkBalance(t, tc, sdb, "B", 0, "480")
|
||||
checkBalance(t, tc, sdb, "B", 1, "190")
|
||||
checkBalance(t, tc, sdb, "C", 0, "845")
|
||||
checkBalance(t, tc, sdb, "C", 1, "100")
|
||||
checkBalance(t, tc, sdb, "D", 0, "360")
|
||||
checkBalance(t, tc, sdb, "F", 0, "100")
|
||||
}
|
||||
|
||||
func TestProcessTxsSynchronizer(t *testing.T) {
|
||||
dir, err := ioutil.TempDir("", "tmpdb")
|
||||
require.Nil(t, err)
|
||||
@@ -121,7 +254,7 @@ func TestProcessTxsSynchronizer(t *testing.T) {
|
||||
assert.Equal(t, "0", ptOut.CollectedFees[common.TokenID(3)].String())
|
||||
acc, err = sdb.GetAccount(idxA1)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, "82", acc.Balance.String())
|
||||
assert.Equal(t, "77", acc.Balance.String())
|
||||
|
||||
idxB0 := tc.Users["C"].Accounts[common.TokenID(0)].Idx
|
||||
acc, err = sdb.GetAccount(idxB0)
|
||||
@@ -195,7 +328,7 @@ func TestProcessTxsBatchBuilder(t *testing.T) {
|
||||
require.Nil(t, err)
|
||||
acc, err = sdb.GetAccount(idxA1)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, "82", acc.Balance.String())
|
||||
assert.Equal(t, "77", acc.Balance.String())
|
||||
|
||||
idxB0 := tc.Users["C"].Accounts[common.TokenID(0)].Idx
|
||||
acc, err = sdb.GetAccount(idxB0)
|
||||
|
||||
@@ -63,6 +63,7 @@ func (s *StateDB) setIdxByEthAddrBJJ(idx common.Idx, addr ethCommon.Address, pk
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// store Addr-idx
|
||||
k = concatEthAddrTokenID(addr, tokenID)
|
||||
err = tx.Put(append(PrefixKeyAddr, k...), idxBytes[:])
|
||||
@@ -83,11 +84,11 @@ func (s *StateDB) GetIdxByEthAddr(addr ethCommon.Address, tokenID common.TokenID
|
||||
k := concatEthAddrTokenID(addr, tokenID)
|
||||
b, err := s.db.Get(append(PrefixKeyAddr, k...))
|
||||
if err != nil {
|
||||
return common.Idx(0), ErrToIdxNotFound
|
||||
return common.Idx(0), fmt.Errorf("GetIdxByEthAddr: %s: ToEthAddr: %s, TokenID: %d", ErrToIdxNotFound, addr.Hex(), tokenID)
|
||||
}
|
||||
idx, err := common.IdxFromBytes(b)
|
||||
if err != nil {
|
||||
return common.Idx(0), ErrToIdxNotFound
|
||||
return common.Idx(0), fmt.Errorf("GetIdxByEthAddr: %s: ToEthAddr: %s, TokenID: %d", err, addr.Hex(), tokenID)
|
||||
}
|
||||
return idx, nil
|
||||
}
|
||||
@@ -99,6 +100,7 @@ func (s *StateDB) GetIdxByEthAddr(addr ethCommon.Address, tokenID common.TokenID
|
||||
// the StateDB.
|
||||
func (s *StateDB) GetIdxByEthAddrBJJ(addr ethCommon.Address, pk *babyjub.PublicKey, tokenID common.TokenID) (common.Idx, error) {
|
||||
if !bytes.Equal(addr.Bytes(), common.EmptyAddr.Bytes()) && pk == nil {
|
||||
// ToEthAddr
|
||||
// case ToEthAddr!=0 && ToBJJ=0
|
||||
return s.GetIdxByEthAddr(addr, tokenID)
|
||||
} else if !bytes.Equal(addr.Bytes(), common.EmptyAddr.Bytes()) && pk != nil {
|
||||
@@ -106,16 +108,16 @@ func (s *StateDB) GetIdxByEthAddrBJJ(addr ethCommon.Address, pk *babyjub.PublicK
|
||||
k := concatEthAddrBJJTokenID(addr, pk, tokenID)
|
||||
b, err := s.db.Get(append(PrefixKeyAddrBJJ, k...))
|
||||
if err != nil {
|
||||
return common.Idx(0), ErrToIdxNotFound
|
||||
return common.Idx(0), fmt.Errorf("GetIdxByEthAddrBJJ: %s: ToEthAddr: %s, ToBJJ: %s, TokenID: %d", ErrToIdxNotFound, addr.Hex(), pk, tokenID)
|
||||
}
|
||||
idx, err := common.IdxFromBytes(b)
|
||||
if err != nil {
|
||||
return common.Idx(0), ErrToIdxNotFound
|
||||
return common.Idx(0), fmt.Errorf("GetIdxByEthAddrBJJ: %s: ToEthAddr: %s, ToBJJ: %s, TokenID: %d", err, addr.Hex(), pk, tokenID)
|
||||
}
|
||||
return idx, nil
|
||||
}
|
||||
// rest of cases (included case ToEthAddr==0) are not possible
|
||||
return common.Idx(0), ErrToIdxNotFound
|
||||
return common.Idx(0), fmt.Errorf("GetIdxByEthAddrBJJ: Not found, %s: ToEthAddr: %s, ToBJJ: %s, TokenID: %d", ErrGetIdxNoCase, addr.Hex(), pk, tokenID)
|
||||
}
|
||||
|
||||
func (s *StateDB) getTokenIDsFromIdxs(idxs []common.Idx) (map[common.TokenID]common.Idx, error) {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package statedb
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"math/big"
|
||||
"os"
|
||||
@@ -82,7 +83,8 @@ func TestGetIdx(t *testing.T) {
|
||||
// expect error when trying to get Idx by addr2 & pk2
|
||||
idxR, err = sdb.GetIdxByEthAddrBJJ(addr2, pk2, tokenID0)
|
||||
assert.NotNil(t, err)
|
||||
assert.Equal(t, ErrToIdxNotFound, err)
|
||||
expectedErr := fmt.Errorf("GetIdxByEthAddrBJJ: %s: ToEthAddr: %s, ToBJJ: %s, TokenID: %d", ErrToIdxNotFound, addr2.Hex(), pk2, tokenID0)
|
||||
assert.Equal(t, expectedErr, err)
|
||||
assert.Equal(t, common.Idx(0), idxR)
|
||||
// expect error when trying to get Idx by addr with not used TokenID
|
||||
_, err = sdb.GetIdxByEthAddr(addr, tokenID1)
|
||||
|
||||
Reference in New Issue
Block a user