mirror of
https://github.com/arnaucube/hermez-node.git
synced 2026-02-07 03:16:45 +01:00
Feature/null refactor (#173)
* WIP: rebase * Make nullable fields use pointers
This commit is contained in:
@@ -133,7 +133,8 @@ func (hdb *HistoryDB) addBatches(d meddler.DB, batches []common.Batch) error {
|
||||
num_accounts,
|
||||
exit_root,
|
||||
forge_l1_txs_num,
|
||||
slot_num
|
||||
slot_num,
|
||||
total_fees_usd
|
||||
) VALUES %s;`,
|
||||
batches[:],
|
||||
)
|
||||
|
||||
@@ -109,7 +109,7 @@ func TestBatches(t *testing.T) {
|
||||
// Test GetLastL1TxsNum
|
||||
fetchedLastL1TxsNum, err = historyDB.GetLastL1TxsNum()
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, batches[nBatches-1].ForgeL1TxsNum, *fetchedLastL1TxsNum)
|
||||
assert.Equal(t, *batches[nBatches-1].ForgeL1TxsNum, *fetchedLastL1TxsNum)
|
||||
}
|
||||
|
||||
func TestBids(t *testing.T) {
|
||||
|
||||
@@ -17,7 +17,7 @@ type HistoryTx struct {
|
||||
TxID common.TxID `meddler:"id"`
|
||||
Type common.TxType `meddler:"type"`
|
||||
Position int `meddler:"position"`
|
||||
FromIdx common.Idx `meddler:"from_idx"`
|
||||
FromIdx *common.Idx `meddler:"from_idx"`
|
||||
ToIdx common.Idx `meddler:"to_idx"`
|
||||
Amount *big.Int `meddler:"amount,bigint"`
|
||||
AmountFloat float64 `meddler:"amount_f"`
|
||||
@@ -25,9 +25,9 @@ type HistoryTx struct {
|
||||
BatchNum *common.BatchNum `meddler:"batch_num"` // batchNum in which this tx was forged. If the tx is L2, this must be != 0
|
||||
EthBlockNum int64 `meddler:"eth_block_num"` // Ethereum Block Number in which this L1Tx was added to the queue
|
||||
// L1
|
||||
ToForgeL1TxsNum int64 `meddler:"to_forge_l1_txs_num"` // toForgeL1TxsNum in which the tx was forged / will be forged
|
||||
UserOrigin bool `meddler:"user_origin"` // true if the tx was originated by a user, false if it was aoriginated by a coordinator. Note that this differ from the spec for implementation simplification purpposes
|
||||
FromEthAddr ethCommon.Address `meddler:"from_eth_addr"`
|
||||
ToForgeL1TxsNum *int64 `meddler:"to_forge_l1_txs_num"` // toForgeL1TxsNum in which the tx was forged / will be forged
|
||||
UserOrigin *bool `meddler:"user_origin"` // true if the tx was originated by a user, false if it was aoriginated by a coordinator. Note that this differ from the spec for implementation simplification purpposes
|
||||
FromEthAddr *ethCommon.Address `meddler:"from_eth_addr"`
|
||||
FromBJJ *babyjub.PublicKey `meddler:"from_bjj"`
|
||||
LoadAmount *big.Int `meddler:"load_amount,bigintnull"`
|
||||
LoadAmountFloat *float64 `meddler:"load_amount_f"`
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package l2db
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"math/big"
|
||||
"time"
|
||||
|
||||
@@ -49,7 +50,10 @@ func (l2db *L2DB) AddAccountCreationAuth(auth *common.AccountCreationAuth) error
|
||||
}
|
||||
|
||||
// GetAccountCreationAuth returns an account creation authorization into the DB
|
||||
func (l2db *L2DB) GetAccountCreationAuth(addr ethCommon.Address) (*common.AccountCreationAuth, error) {
|
||||
func (l2db *L2DB) GetAccountCreationAuth(addr *ethCommon.Address) (*common.AccountCreationAuth, error) {
|
||||
if addr == nil {
|
||||
return nil, errors.New("addr cannot be nil")
|
||||
}
|
||||
auth := new(common.AccountCreationAuth)
|
||||
return auth, meddler.QueryRow(
|
||||
l2db.db, auth,
|
||||
@@ -64,8 +68,8 @@ func (l2db *L2DB) AddTxTest(tx *common.PoolL2Tx) error {
|
||||
type withouUSD struct {
|
||||
TxID common.TxID `meddler:"tx_id"`
|
||||
FromIdx common.Idx `meddler:"from_idx"`
|
||||
ToIdx common.Idx `meddler:"to_idx"`
|
||||
ToEthAddr ethCommon.Address `meddler:"to_eth_addr"`
|
||||
ToIdx *common.Idx `meddler:"to_idx"`
|
||||
ToEthAddr *ethCommon.Address `meddler:"to_eth_addr"`
|
||||
ToBJJ *babyjub.PublicKey `meddler:"to_bjj"`
|
||||
TokenID common.TokenID `meddler:"token_id"`
|
||||
Amount *big.Int `meddler:"amount,bigint"`
|
||||
@@ -75,15 +79,15 @@ func (l2db *L2DB) AddTxTest(tx *common.PoolL2Tx) error {
|
||||
State common.PoolL2TxState `meddler:"state"`
|
||||
Signature *babyjub.Signature `meddler:"signature"`
|
||||
Timestamp time.Time `meddler:"timestamp,utctime"`
|
||||
BatchNum common.BatchNum `meddler:"batch_num,zeroisnull"`
|
||||
RqFromIdx common.Idx `meddler:"rq_from_idx,zeroisnull"`
|
||||
RqToIdx common.Idx `meddler:"rq_to_idx,zeroisnull"`
|
||||
RqToEthAddr ethCommon.Address `meddler:"rq_to_eth_addr"`
|
||||
BatchNum *common.BatchNum `meddler:"batch_num"`
|
||||
RqFromIdx *common.Idx `meddler:"rq_from_idx"`
|
||||
RqToIdx *common.Idx `meddler:"rq_to_idx"`
|
||||
RqToEthAddr *ethCommon.Address `meddler:"rq_to_eth_addr"`
|
||||
RqToBJJ *babyjub.PublicKey `meddler:"rq_to_bjj"`
|
||||
RqTokenID common.TokenID `meddler:"rq_token_id,zeroisnull"`
|
||||
RqTokenID *common.TokenID `meddler:"rq_token_id"`
|
||||
RqAmount *big.Int `meddler:"rq_amount,bigintnull"`
|
||||
RqFee common.FeeSelector `meddler:"rq_fee,zeroisnull"`
|
||||
RqNonce uint64 `meddler:"rq_nonce,zeroisnull"`
|
||||
RqFee *common.FeeSelector `meddler:"rq_fee"`
|
||||
RqNonce *uint64 `meddler:"rq_nonce"`
|
||||
Type common.TxType `meddler:"tx_type"`
|
||||
}
|
||||
return meddler.Insert(l2db.db, "tx_pool", &withouUSD{
|
||||
@@ -115,8 +119,8 @@ func (l2db *L2DB) AddTxTest(tx *common.PoolL2Tx) error {
|
||||
|
||||
// selectPoolTx select part of queries to get common.PoolL2Tx
|
||||
const selectPoolTx = `SELECT tx_pool.*, token.usd * tx_pool.amount_f AS value_usd,
|
||||
fee_percentage(tx_pool.fee::NUMERIC) * token.usd * tx_pool.amount_f AS fee_usd, token.usd_update,
|
||||
token.symbol AS token_symbol FROM tx_pool INNER JOIN token ON tx_pool.token_id = token.token_id `
|
||||
fee_percentage(tx_pool.fee::NUMERIC) * token.usd * tx_pool.amount_f AS fee_usd, token.usd_update
|
||||
FROM tx_pool INNER JOIN token ON tx_pool.token_id = token.token_id `
|
||||
|
||||
// GetTx return the specified Tx
|
||||
func (l2db *L2DB) GetTx(txID common.TxID) (*common.PoolL2Tx, error) {
|
||||
|
||||
@@ -141,7 +141,7 @@ func TestStartForging(t *testing.T) {
|
||||
fetchedTx, err := l2DB.GetTx(id)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, common.PoolL2TxStateForging, fetchedTx.State)
|
||||
assert.Equal(t, fakeBatchNum, fetchedTx.BatchNum)
|
||||
assert.Equal(t, fakeBatchNum, *fetchedTx.BatchNum)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -170,7 +170,7 @@ func TestDoneForging(t *testing.T) {
|
||||
fetchedTx, err := l2DB.GetTx(id)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, common.PoolL2TxStateForged, fetchedTx.State)
|
||||
assert.Equal(t, fakeBatchNum, fetchedTx.BatchNum)
|
||||
assert.Equal(t, fakeBatchNum, *fetchedTx.BatchNum)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -199,7 +199,7 @@ func TestInvalidate(t *testing.T) {
|
||||
fetchedTx, err := l2DB.GetTx(id)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, common.PoolL2TxStateInvalid, fetchedTx.State)
|
||||
assert.Equal(t, fakeBatchNum, fetchedTx.BatchNum)
|
||||
assert.Equal(t, fakeBatchNum, *fetchedTx.BatchNum)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -242,7 +242,7 @@ func TestCheckNonces(t *testing.T) {
|
||||
fetchedTx, err := l2DB.GetTx(id)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, common.PoolL2TxStateInvalid, fetchedTx.State)
|
||||
assert.Equal(t, fakeBatchNum, fetchedTx.BatchNum)
|
||||
assert.Equal(t, fakeBatchNum, *fetchedTx.BatchNum)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -257,11 +257,12 @@ func TestReorg(t *testing.T) {
|
||||
reorgedTxIDs := []common.TxID{}
|
||||
nonReorgedTxIDs := []common.TxID{}
|
||||
for i := 0; i < len(txs); i++ {
|
||||
txs[i].BatchNum = new(common.BatchNum)
|
||||
if txs[i].State == common.PoolL2TxStateForged || txs[i].State == common.PoolL2TxStateInvalid {
|
||||
txs[i].BatchNum = reorgBatch
|
||||
*txs[i].BatchNum = reorgBatch
|
||||
reorgedTxIDs = append(reorgedTxIDs, txs[i].TxID)
|
||||
} else {
|
||||
txs[i].BatchNum = lastValidBatch
|
||||
*txs[i].BatchNum = lastValidBatch
|
||||
nonReorgedTxIDs = append(nonReorgedTxIDs, txs[i].TxID)
|
||||
}
|
||||
err := l2DB.AddTxTest(txs[i])
|
||||
@@ -269,17 +270,16 @@ func TestReorg(t *testing.T) {
|
||||
}
|
||||
err := l2DB.Reorg(lastValidBatch)
|
||||
assert.NoError(t, err)
|
||||
var nullBatchNum common.BatchNum
|
||||
for _, id := range reorgedTxIDs {
|
||||
tx, err := l2DB.GetTx(id)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, nullBatchNum, tx.BatchNum)
|
||||
assert.Nil(t, tx.BatchNum)
|
||||
assert.Equal(t, common.PoolL2TxStatePending, tx.State)
|
||||
}
|
||||
for _, id := range nonReorgedTxIDs {
|
||||
tx, err := l2DB.GetTx(id)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, lastValidBatch, tx.BatchNum)
|
||||
assert.Equal(t, lastValidBatch, *tx.BatchNum)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -294,11 +294,12 @@ func TestPurge(t *testing.T) {
|
||||
safeBatchNum := toDeleteBatchNum + l2DB.safetyPeriod + 1
|
||||
// Add txs to the DB
|
||||
for i := 0; i < int(l2DB.maxTxs); i++ {
|
||||
txs[i].BatchNum = new(common.BatchNum)
|
||||
if i%1 == 0 { // keep tx
|
||||
txs[i].BatchNum = safeBatchNum
|
||||
*txs[i].BatchNum = safeBatchNum
|
||||
keepedIDs = append(keepedIDs, txs[i].TxID)
|
||||
} else if i%2 == 0 { // delete after safety period
|
||||
txs[i].BatchNum = toDeleteBatchNum
|
||||
*txs[i].BatchNum = toDeleteBatchNum
|
||||
if i%3 == 0 {
|
||||
txs[i].State = common.PoolL2TxStateForged
|
||||
} else {
|
||||
@@ -343,7 +344,7 @@ func TestAuth(t *testing.T) {
|
||||
err := l2DB.AddAccountCreationAuth(auths[i])
|
||||
assert.NoError(t, err)
|
||||
// Fetch from DB
|
||||
auth, err := l2DB.GetAccountCreationAuth(auths[i].EthAddr)
|
||||
auth, err := l2DB.GetAccountCreationAuth(&auths[i].EthAddr)
|
||||
assert.NoError(t, err)
|
||||
// Check fetched vs generated
|
||||
assert.Equal(t, auths[i].EthAddr, auth.EthAddr)
|
||||
|
||||
@@ -17,14 +17,15 @@ CREATE TABLE coordinator (
|
||||
|
||||
CREATE TABLE batch (
|
||||
batch_num BIGINT PRIMARY KEY,
|
||||
eth_block_num BIGINT REFERENCES block (eth_block_num) ON DELETE CASCADE,
|
||||
eth_block_num BIGINT NOT NULL REFERENCES block (eth_block_num) ON DELETE CASCADE,
|
||||
forger_addr BYTEA NOT NULL, -- fake foreign key for coordinator
|
||||
fees_collected BYTEA NOT NULL,
|
||||
state_root BYTEA NOT NULL,
|
||||
num_accounts BIGINT NOT NULL,
|
||||
exit_root BYTEA NOT NULL,
|
||||
forge_l1_txs_num BIGINT,
|
||||
slot_num BIGINT NOT NULL
|
||||
slot_num BIGINT NOT NULL,
|
||||
total_fees_usd NUMERIC
|
||||
);
|
||||
|
||||
CREATE TABLE exit_tree (
|
||||
@@ -80,7 +81,7 @@ CREATE TABLE tx (
|
||||
id BYTEA PRIMARY KEY,
|
||||
type VARCHAR(40) NOT NULL,
|
||||
position INT NOT NULL,
|
||||
from_idx BIGINT NOT NULL,
|
||||
from_idx BIGINT,
|
||||
to_idx BIGINT NOT NULL,
|
||||
amount BYTEA NOT NULL,
|
||||
amount_f NUMERIC NOT NULL,
|
||||
@@ -470,9 +471,9 @@ CREATE TABLE consensus_vars (
|
||||
CREATE TABLE tx_pool (
|
||||
tx_id BYTEA PRIMARY KEY,
|
||||
from_idx BIGINT NOT NULL,
|
||||
to_idx BIGINT NOT NULL,
|
||||
to_eth_addr BYTEA NOT NULL,
|
||||
to_bjj BYTEA NOT NULL,
|
||||
to_idx BIGINT,
|
||||
to_eth_addr BYTEA,
|
||||
to_bjj BYTEA,
|
||||
token_id INT NOT NULL REFERENCES token (token_id) ON DELETE CASCADE,
|
||||
amount BYTEA NOT NULL,
|
||||
amount_f NUMERIC NOT NULL,
|
||||
|
||||
@@ -247,13 +247,19 @@ func (s *StateDB) Reset(batchNum common.BatchNum) error {
|
||||
}
|
||||
|
||||
// GetAccount returns the account for the given Idx
|
||||
func (s *StateDB) GetAccount(idx common.Idx) (*common.Account, error) {
|
||||
func (s *StateDB) GetAccount(idx *common.Idx) (*common.Account, error) {
|
||||
if idx == nil {
|
||||
return nil, errors.New("idx cannot be nil")
|
||||
}
|
||||
return getAccountInTreeDB(s.db, idx)
|
||||
}
|
||||
|
||||
// getAccountInTreeDB is abstracted from StateDB to be used from StateDB and
|
||||
// from ExitTree. GetAccount returns the account for the given Idx
|
||||
func getAccountInTreeDB(sto db.Storage, idx common.Idx) (*common.Account, error) {
|
||||
func getAccountInTreeDB(sto db.Storage, idx *common.Idx) (*common.Account, error) {
|
||||
if idx == nil {
|
||||
return nil, errors.New("idx cannot be nil")
|
||||
}
|
||||
idxBytes, err := idx.Bytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -275,12 +281,12 @@ func getAccountInTreeDB(sto db.Storage, idx common.Idx) (*common.Account, error)
|
||||
// StateDB.mt==nil, MerkleTree is not affected, otherwise updates the
|
||||
// MerkleTree, returning a CircomProcessorProof.
|
||||
func (s *StateDB) CreateAccount(idx common.Idx, account *common.Account) (*merkletree.CircomProcessorProof, error) {
|
||||
cpp, err := createAccountInTreeDB(s.db, s.mt, idx, account)
|
||||
cpp, err := createAccountInTreeDB(s.db, s.mt, &idx, account)
|
||||
if err != nil {
|
||||
return cpp, err
|
||||
}
|
||||
// store idx by EthAddr & BJJ
|
||||
err = s.setIdxByEthAddrBJJ(idx, account.EthAddr, account.PublicKey)
|
||||
err = s.setIdxByEthAddrBJJ(idx, &account.EthAddr, account.PublicKey)
|
||||
return cpp, err
|
||||
}
|
||||
|
||||
@@ -288,7 +294,10 @@ func (s *StateDB) CreateAccount(idx common.Idx, account *common.Account) (*merkl
|
||||
// from ExitTree. Creates a new Account in the StateDB for the given Idx. If
|
||||
// StateDB.mt==nil, MerkleTree is not affected, otherwise updates the
|
||||
// MerkleTree, returning a CircomProcessorProof.
|
||||
func createAccountInTreeDB(sto db.Storage, mt *merkletree.MerkleTree, idx common.Idx, account *common.Account) (*merkletree.CircomProcessorProof, error) {
|
||||
func createAccountInTreeDB(sto db.Storage, mt *merkletree.MerkleTree, idx *common.Idx, account *common.Account) (*merkletree.CircomProcessorProof, error) {
|
||||
if idx == nil {
|
||||
return nil, errors.New("idx cannot be nil")
|
||||
}
|
||||
// store at the DB the key: v, and value: leaf.Bytes()
|
||||
v, err := account.HashValue()
|
||||
if err != nil {
|
||||
@@ -337,7 +346,10 @@ func createAccountInTreeDB(sto db.Storage, mt *merkletree.MerkleTree, idx common
|
||||
// UpdateAccount updates the Account in the StateDB for the given Idx. If
|
||||
// StateDB.mt==nil, MerkleTree is not affected, otherwise updates the
|
||||
// MerkleTree, returning a CircomProcessorProof.
|
||||
func (s *StateDB) UpdateAccount(idx common.Idx, account *common.Account) (*merkletree.CircomProcessorProof, error) {
|
||||
func (s *StateDB) UpdateAccount(idx *common.Idx, account *common.Account) (*merkletree.CircomProcessorProof, error) {
|
||||
if idx == nil {
|
||||
return nil, errors.New("idx cannot be nil")
|
||||
}
|
||||
return updateAccountInTreeDB(s.db, s.mt, idx, account)
|
||||
}
|
||||
|
||||
@@ -345,7 +357,10 @@ func (s *StateDB) UpdateAccount(idx common.Idx, account *common.Account) (*merkl
|
||||
// from ExitTree. Updates the Account in the StateDB for the given Idx. If
|
||||
// StateDB.mt==nil, MerkleTree is not affected, otherwise updates the
|
||||
// MerkleTree, returning a CircomProcessorProof.
|
||||
func updateAccountInTreeDB(sto db.Storage, mt *merkletree.MerkleTree, idx common.Idx, account *common.Account) (*merkletree.CircomProcessorProof, error) {
|
||||
func updateAccountInTreeDB(sto db.Storage, mt *merkletree.MerkleTree, idx *common.Idx, account *common.Account) (*merkletree.CircomProcessorProof, error) {
|
||||
if idx == nil {
|
||||
return nil, errors.New("idx cannot be nil")
|
||||
}
|
||||
// store at the DB the key: v, and value: account.Bytes()
|
||||
v, err := account.HashValue()
|
||||
if err != nil {
|
||||
|
||||
@@ -129,7 +129,8 @@ func TestStateDBWithoutMT(t *testing.T) {
|
||||
}
|
||||
|
||||
// get non-existing account, expecting an error
|
||||
_, err = sdb.GetAccount(common.Idx(1))
|
||||
unexistingAccount := common.Idx(1)
|
||||
_, err = sdb.GetAccount(&unexistingAccount)
|
||||
assert.NotNil(t, err)
|
||||
assert.Equal(t, db.ErrNotFound, err)
|
||||
|
||||
@@ -140,13 +141,15 @@ func TestStateDBWithoutMT(t *testing.T) {
|
||||
}
|
||||
|
||||
for i := 0; i < len(accounts); i++ {
|
||||
accGetted, err := sdb.GetAccount(common.Idx(i))
|
||||
existingAccount := common.Idx(i)
|
||||
accGetted, err := sdb.GetAccount(&existingAccount)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, accounts[i], accGetted)
|
||||
}
|
||||
|
||||
// try already existing idx and get error
|
||||
_, err = sdb.GetAccount(common.Idx(1)) // check that exist
|
||||
existingAccount := common.Idx(1)
|
||||
_, err = sdb.GetAccount(&existingAccount) // check that exist
|
||||
assert.Nil(t, err)
|
||||
_, err = sdb.CreateAccount(common.Idx(1), accounts[1]) // check that can not be created twice
|
||||
assert.NotNil(t, err)
|
||||
@@ -155,7 +158,8 @@ func TestStateDBWithoutMT(t *testing.T) {
|
||||
// update accounts
|
||||
for i := 0; i < len(accounts); i++ {
|
||||
accounts[i].Nonce = accounts[i].Nonce + 1
|
||||
_, err = sdb.UpdateAccount(common.Idx(i), accounts[i])
|
||||
existingAccount = common.Idx(i)
|
||||
_, err = sdb.UpdateAccount(&existingAccount, accounts[i])
|
||||
assert.Nil(t, err)
|
||||
}
|
||||
|
||||
@@ -178,7 +182,8 @@ func TestStateDBWithMT(t *testing.T) {
|
||||
}
|
||||
|
||||
// get non-existing account, expecting an error
|
||||
_, err = sdb.GetAccount(common.Idx(1))
|
||||
accountIdx := common.Idx(1)
|
||||
_, err = sdb.GetAccount(&accountIdx)
|
||||
assert.NotNil(t, err)
|
||||
assert.Equal(t, db.ErrNotFound, err)
|
||||
|
||||
@@ -189,13 +194,15 @@ func TestStateDBWithMT(t *testing.T) {
|
||||
}
|
||||
|
||||
for i := 0; i < len(accounts); i++ {
|
||||
accGetted, err := sdb.GetAccount(common.Idx(i))
|
||||
accountIdx = common.Idx(i)
|
||||
accGetted, err := sdb.GetAccount(&accountIdx)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, accounts[i], accGetted)
|
||||
}
|
||||
|
||||
// try already existing idx and get error
|
||||
_, err = sdb.GetAccount(common.Idx(1)) // check that exist
|
||||
accountIdx = 1
|
||||
_, err = sdb.GetAccount(&accountIdx) // check that exist
|
||||
assert.Nil(t, err)
|
||||
_, err = sdb.CreateAccount(common.Idx(1), accounts[1]) // check that can not be created twice
|
||||
assert.NotNil(t, err)
|
||||
@@ -207,10 +214,12 @@ func TestStateDBWithMT(t *testing.T) {
|
||||
// update accounts
|
||||
for i := 0; i < len(accounts); i++ {
|
||||
accounts[i].Nonce = accounts[i].Nonce + 1
|
||||
_, err = sdb.UpdateAccount(common.Idx(i), accounts[i])
|
||||
accountIdx = common.Idx(i)
|
||||
_, err = sdb.UpdateAccount(&accountIdx, accounts[i])
|
||||
assert.Nil(t, err)
|
||||
}
|
||||
a, err := sdb.GetAccount(common.Idx(1)) // check that account value has been updated
|
||||
accountIdx = 1
|
||||
a, err := sdb.GetAccount(&accountIdx) // check that account value has been updated
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, accounts[1].Nonce, a.Nonce)
|
||||
}
|
||||
|
||||
@@ -227,7 +227,11 @@ func (s *StateDB) processL1Tx(exitTree *merkletree.MerkleTree, tx *common.L1Tx)
|
||||
if s.zki != nil {
|
||||
// Txs
|
||||
// s.zki.TxCompressedData[s.i] = tx.TxCompressedData() // uncomment once L1Tx.TxCompressedData is ready
|
||||
s.zki.FromIdx[s.i] = tx.FromIdx.BigInt()
|
||||
if tx.FromIdx != nil {
|
||||
s.zki.FromIdx[s.i] = tx.FromIdx.BigInt()
|
||||
} else {
|
||||
s.zki.FromIdx[s.i] = big.NewInt(0)
|
||||
}
|
||||
s.zki.ToIdx[s.i] = tx.ToIdx.BigInt()
|
||||
s.zki.OnChain[s.i] = big.NewInt(1)
|
||||
|
||||
@@ -292,7 +296,7 @@ func (s *StateDB) processL1Tx(exitTree *merkletree.MerkleTree, tx *common.L1Tx)
|
||||
if err != nil {
|
||||
return nil, nil, false, err
|
||||
}
|
||||
return &tx.FromIdx, exitAccount, newExit, nil
|
||||
return tx.FromIdx, exitAccount, newExit, nil
|
||||
default:
|
||||
}
|
||||
|
||||
@@ -307,7 +311,7 @@ func (s *StateDB) processL2Tx(exitTree *merkletree.MerkleTree, tx *common.PoolL2
|
||||
var err error
|
||||
var auxToIdx common.Idx
|
||||
// if tx.ToIdx==0, get toIdx by ToEthAddr or ToBJJ
|
||||
if tx.ToIdx == common.Idx(0) {
|
||||
if tx.ToIdx == nil || *tx.ToIdx == common.Idx(0) {
|
||||
auxToIdx, err = s.GetIdxByEthAddrBJJ(tx.ToEthAddr, tx.ToBJJ)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
@@ -324,7 +328,7 @@ func (s *StateDB) processL2Tx(exitTree *merkletree.MerkleTree, tx *common.PoolL2
|
||||
s.zki.ToIdx[s.i] = tx.ToIdx.BigInt()
|
||||
|
||||
// fill AuxToIdx if needed
|
||||
if tx.ToIdx == common.Idx(0) {
|
||||
if tx.ToIdx == nil {
|
||||
// use toIdx that can have been filled by tx.ToIdx or
|
||||
// if tx.Idx==0 (this case), toIdx is filled by the Idx
|
||||
// from db by ToEthAddr&ToBJJ
|
||||
@@ -332,7 +336,12 @@ func (s *StateDB) processL2Tx(exitTree *merkletree.MerkleTree, tx *common.PoolL2
|
||||
}
|
||||
|
||||
s.zki.ToBJJAy[s.i] = tx.ToBJJ.Y
|
||||
s.zki.ToEthAddr[s.i] = common.EthAddrToBigInt(tx.ToEthAddr)
|
||||
if tx.ToEthAddr != nil {
|
||||
s.zki.ToEthAddr[s.i] = common.EthAddrToBigInt(*tx.ToEthAddr)
|
||||
} else {
|
||||
// Not sure if this should throw an error
|
||||
s.zki.ToEthAddr[s.i] = big.NewInt(0)
|
||||
}
|
||||
|
||||
s.zki.OnChain[s.i] = big.NewInt(0)
|
||||
s.zki.NewAccount[s.i] = big.NewInt(0)
|
||||
@@ -362,13 +371,21 @@ func (s *StateDB) processL2Tx(exitTree *merkletree.MerkleTree, tx *common.PoolL2
|
||||
case common.TxTypeTransfer:
|
||||
// go to the MT account of sender and receiver, and update
|
||||
// balance & nonce
|
||||
err = s.applyTransfer(tx.Tx(), auxToIdx)
|
||||
tmpTx, err := tx.Tx()
|
||||
if err != nil {
|
||||
return nil, nil, false, err
|
||||
}
|
||||
err = s.applyTransfer(tmpTx, auxToIdx)
|
||||
if err != nil {
|
||||
return nil, nil, false, err
|
||||
}
|
||||
case common.TxTypeExit:
|
||||
// execute exit flow
|
||||
exitAccount, newExit, err := s.applyExit(exitTree, tx.Tx())
|
||||
tmpTx, err := tx.Tx()
|
||||
if err != nil {
|
||||
return nil, nil, false, err
|
||||
}
|
||||
exitAccount, newExit, err := s.applyExit(exitTree, tmpTx)
|
||||
if err != nil {
|
||||
return nil, nil, false, err
|
||||
}
|
||||
@@ -428,7 +445,7 @@ func (s *StateDB) applyDeposit(tx *common.L1Tx, transfer bool) error {
|
||||
// in case that the tx is a L1Tx>DepositTransfer
|
||||
var accReceiver *common.Account
|
||||
if transfer {
|
||||
accReceiver, err = s.GetAccount(tx.ToIdx)
|
||||
accReceiver, err = s.GetAccount(&tx.ToIdx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -458,7 +475,7 @@ func (s *StateDB) applyDeposit(tx *common.L1Tx, transfer bool) error {
|
||||
// this is done after updating Sender Account (depositer)
|
||||
if transfer {
|
||||
// update receiver account in localStateDB
|
||||
p, err := s.UpdateAccount(tx.ToIdx, accReceiver)
|
||||
p, err := s.UpdateAccount(&tx.ToIdx, accReceiver)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -487,14 +504,17 @@ func (s *StateDB) applyDeposit(tx *common.L1Tx, transfer bool) error {
|
||||
// the real ToIdx is found trhrough the ToEthAddr or ToBJJ.
|
||||
func (s *StateDB) applyTransfer(tx *common.Tx, auxToIdx common.Idx) error {
|
||||
if auxToIdx == 0 {
|
||||
auxToIdx = tx.ToIdx
|
||||
if tx.ToIdx == nil {
|
||||
return errors.New("tx.ToIdx cannot be nil if auxToIdx is 0")
|
||||
}
|
||||
auxToIdx = *tx.ToIdx
|
||||
}
|
||||
// get sender and receiver accounts from localStateDB
|
||||
accSender, err := s.GetAccount(tx.FromIdx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
accReceiver, err := s.GetAccount(auxToIdx)
|
||||
accReceiver, err := s.GetAccount(&auxToIdx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -525,7 +545,7 @@ func (s *StateDB) applyTransfer(tx *common.Tx, auxToIdx common.Idx) error {
|
||||
}
|
||||
|
||||
// update receiver account in localStateDB
|
||||
pReceiver, err := s.UpdateAccount(auxToIdx, accReceiver)
|
||||
pReceiver, err := s.UpdateAccount(&auxToIdx, accReceiver)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -555,7 +575,7 @@ func (s *StateDB) applyCreateAccountDepositTransfer(tx *common.L1Tx) error {
|
||||
EthAddr: tx.FromEthAddr,
|
||||
}
|
||||
accSender.Balance = new(big.Int).Add(accSender.Balance, tx.LoadAmount)
|
||||
accReceiver, err := s.GetAccount(tx.ToIdx)
|
||||
accReceiver, err := s.GetAccount(&tx.ToIdx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -587,7 +607,7 @@ func (s *StateDB) applyCreateAccountDepositTransfer(tx *common.L1Tx) error {
|
||||
}
|
||||
|
||||
// update receiver account in localStateDB
|
||||
p, err = s.UpdateAccount(tx.ToIdx, accReceiver)
|
||||
p, err = s.UpdateAccount(&tx.ToIdx, accReceiver)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -40,7 +40,8 @@ func TestProcessTxs(t *testing.T) {
|
||||
require.Nil(t, err)
|
||||
}
|
||||
|
||||
acc, err := sdb.GetAccount(common.Idx(256))
|
||||
accountIdx := common.Idx(256)
|
||||
acc, err := sdb.GetAccount(&accountIdx)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, "23", acc.Balance.String())
|
||||
}
|
||||
@@ -79,7 +80,8 @@ func TestProcessTxsSynchronizer(t *testing.T) {
|
||||
// Nonce & TokenID =0, after ProcessTxs call has the expected value
|
||||
|
||||
assert.Equal(t, 0, len(exitInfos))
|
||||
acc, err := sdb.GetAccount(common.Idx(256))
|
||||
accountIdx := common.Idx(256)
|
||||
acc, err := sdb.GetAccount(&accountIdx)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, "28", acc.Balance.String())
|
||||
|
||||
@@ -88,7 +90,7 @@ func TestProcessTxsSynchronizer(t *testing.T) {
|
||||
_, exitInfos, err = sdb.ProcessTxs(l1Txs[1], coordinatorL1Txs[1], poolL2Txs[1])
|
||||
require.Nil(t, err)
|
||||
assert.Equal(t, 5, len(exitInfos))
|
||||
acc, err = sdb.GetAccount(common.Idx(256))
|
||||
acc, err = sdb.GetAccount(&accountIdx)
|
||||
require.Nil(t, err)
|
||||
assert.Equal(t, "48", acc.Balance.String())
|
||||
|
||||
@@ -97,7 +99,7 @@ func TestProcessTxsSynchronizer(t *testing.T) {
|
||||
_, exitInfos, err = sdb.ProcessTxs(l1Txs[2], coordinatorL1Txs[2], poolL2Txs[2])
|
||||
require.Nil(t, err)
|
||||
assert.Equal(t, 1, len(exitInfos))
|
||||
acc, err = sdb.GetAccount(common.Idx(256))
|
||||
acc, err = sdb.GetAccount(&accountIdx)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, "23", acc.Balance.String())
|
||||
}
|
||||
@@ -130,7 +132,8 @@ func TestProcessTxsBatchBuilder(t *testing.T) {
|
||||
_, exitInfos, err := sdb.ProcessTxs(l1Txs[0], coordinatorL1Txs[0], poolL2Txs[0])
|
||||
require.Nil(t, err)
|
||||
assert.Equal(t, 0, len(exitInfos))
|
||||
acc, err := sdb.GetAccount(common.Idx(256))
|
||||
accountIdx := common.Idx(256)
|
||||
acc, err := sdb.GetAccount(&accountIdx)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, "28", acc.Balance.String())
|
||||
|
||||
@@ -139,7 +142,7 @@ func TestProcessTxsBatchBuilder(t *testing.T) {
|
||||
_, exitInfos, err = sdb.ProcessTxs(l1Txs[1], coordinatorL1Txs[1], poolL2Txs[1])
|
||||
require.Nil(t, err)
|
||||
assert.Equal(t, 5, len(exitInfos))
|
||||
acc, err = sdb.GetAccount(common.Idx(256))
|
||||
acc, err = sdb.GetAccount(&accountIdx)
|
||||
require.Nil(t, err)
|
||||
assert.Equal(t, "48", acc.Balance.String())
|
||||
|
||||
@@ -148,7 +151,7 @@ func TestProcessTxsBatchBuilder(t *testing.T) {
|
||||
_, exitInfos, err = sdb.ProcessTxs(l1Txs[2], coordinatorL1Txs[2], poolL2Txs[2])
|
||||
require.Nil(t, err)
|
||||
assert.Equal(t, 1, len(exitInfos))
|
||||
acc, err = sdb.GetAccount(common.Idx(256))
|
||||
acc, err = sdb.GetAccount(&accountIdx)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, "23", acc.Balance.String())
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package statedb
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"math/big"
|
||||
|
||||
ethCommon "github.com/ethereum/go-ethereum/common"
|
||||
@@ -11,7 +12,7 @@ import (
|
||||
"github.com/iden3/go-merkletree"
|
||||
)
|
||||
|
||||
func concatEthAddrBJJ(addr ethCommon.Address, pk *babyjub.PublicKey) []byte {
|
||||
func concatEthAddrBJJ(addr *ethCommon.Address, pk *babyjub.PublicKey) []byte {
|
||||
pkComp := pk.Compress()
|
||||
var b []byte
|
||||
b = append(b, addr.Bytes()...)
|
||||
@@ -24,7 +25,7 @@ func concatEthAddrBJJ(addr ethCommon.Address, pk *babyjub.PublicKey) []byte {
|
||||
// - key: EthAddr & BabyJubJub PublicKey Compressed, value: idx
|
||||
// If Idx already exist for the given EthAddr & BJJ, the remaining Idx will be
|
||||
// always the smallest one.
|
||||
func (s *StateDB) setIdxByEthAddrBJJ(idx common.Idx, addr ethCommon.Address, pk *babyjub.PublicKey) error {
|
||||
func (s *StateDB) setIdxByEthAddrBJJ(idx common.Idx, addr *ethCommon.Address, pk *babyjub.PublicKey) error {
|
||||
oldIdx, err := s.GetIdxByEthAddrBJJ(addr, pk)
|
||||
if err == nil {
|
||||
// EthAddr & BJJ already have an Idx
|
||||
@@ -70,7 +71,10 @@ func (s *StateDB) setIdxByEthAddrBJJ(idx common.Idx, addr ethCommon.Address, pk
|
||||
// GetIdxByEthAddr returns the smallest Idx in the StateDB for the given
|
||||
// Ethereum Address. Will return common.Idx(0) and error in case that Idx is
|
||||
// not found in the StateDB.
|
||||
func (s *StateDB) GetIdxByEthAddr(addr ethCommon.Address) (common.Idx, error) {
|
||||
func (s *StateDB) GetIdxByEthAddr(addr *ethCommon.Address) (common.Idx, error) {
|
||||
if addr == nil {
|
||||
return 0, errors.New("addr cannot be nil")
|
||||
}
|
||||
b, err := s.db.Get(addr.Bytes())
|
||||
if err != nil {
|
||||
return common.Idx(0), ErrToIdxNotFound
|
||||
@@ -87,7 +91,10 @@ func (s *StateDB) GetIdxByEthAddr(addr ethCommon.Address) (common.Idx, error) {
|
||||
// address, it's ignored in the query. If `pk` is nil, it's ignored in the
|
||||
// query. Will return common.Idx(0) and error in case that Idx is not found in
|
||||
// the StateDB.
|
||||
func (s *StateDB) GetIdxByEthAddrBJJ(addr ethCommon.Address, pk *babyjub.PublicKey) (common.Idx, error) {
|
||||
func (s *StateDB) GetIdxByEthAddrBJJ(addr *ethCommon.Address, pk *babyjub.PublicKey) (common.Idx, error) {
|
||||
if addr == nil {
|
||||
return 0, errors.New("addr cannot be nil")
|
||||
}
|
||||
if !bytes.Equal(addr.Bytes(), common.EmptyAddr.Bytes()) && pk == nil {
|
||||
// case ToEthAddr!=0 && ToBJJ=0
|
||||
return s.GetIdxByEthAddr(addr)
|
||||
|
||||
@@ -32,47 +32,47 @@ func TestGetIdx(t *testing.T) {
|
||||
idx3 := common.Idx(1233)
|
||||
|
||||
// store the keys for idx by Addr & BJJ
|
||||
err = sdb.setIdxByEthAddrBJJ(idx, addr, pk)
|
||||
err = sdb.setIdxByEthAddrBJJ(idx, &addr, pk)
|
||||
require.Nil(t, err)
|
||||
|
||||
idxR, err := sdb.GetIdxByEthAddrBJJ(addr, pk)
|
||||
idxR, err := sdb.GetIdxByEthAddrBJJ(&addr, pk)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, idx, idxR)
|
||||
|
||||
// expect error when getting only by EthAddr, as value does not exist
|
||||
// in the db for only EthAddr
|
||||
_, err = sdb.GetIdxByEthAddr(addr)
|
||||
_, err = sdb.GetIdxByEthAddr(&addr)
|
||||
assert.Nil(t, err)
|
||||
_, err = sdb.GetIdxByEthAddr(addr2)
|
||||
_, err = sdb.GetIdxByEthAddr(&addr2)
|
||||
assert.NotNil(t, err)
|
||||
|
||||
// expect to fail
|
||||
idxR, err = sdb.GetIdxByEthAddrBJJ(addr2, pk)
|
||||
idxR, err = sdb.GetIdxByEthAddrBJJ(&addr2, pk)
|
||||
assert.NotNil(t, err)
|
||||
assert.Equal(t, common.Idx(0), idxR)
|
||||
idxR, err = sdb.GetIdxByEthAddrBJJ(addr, pk2)
|
||||
idxR, err = sdb.GetIdxByEthAddrBJJ(&addr, pk2)
|
||||
assert.NotNil(t, err)
|
||||
assert.Equal(t, common.Idx(0), idxR)
|
||||
|
||||
// try to store bigger idx, will not affect as already exist a smaller
|
||||
// Idx for that Addr & BJJ
|
||||
err = sdb.setIdxByEthAddrBJJ(idx2, addr, pk)
|
||||
err = sdb.setIdxByEthAddrBJJ(idx2, &addr, pk)
|
||||
assert.Nil(t, err)
|
||||
|
||||
// store smaller idx
|
||||
err = sdb.setIdxByEthAddrBJJ(idx3, addr, pk)
|
||||
err = sdb.setIdxByEthAddrBJJ(idx3, &addr, pk)
|
||||
assert.Nil(t, err)
|
||||
|
||||
idxR, err = sdb.GetIdxByEthAddrBJJ(addr, pk)
|
||||
idxR, err = sdb.GetIdxByEthAddrBJJ(&addr, pk)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, idx3, idxR)
|
||||
|
||||
// by EthAddr should work
|
||||
idxR, err = sdb.GetIdxByEthAddr(addr)
|
||||
idxR, err = sdb.GetIdxByEthAddr(&addr)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, idx3, idxR)
|
||||
// expect error when trying to get Idx by addr2 & pk2
|
||||
idxR, err = sdb.GetIdxByEthAddrBJJ(addr2, pk2)
|
||||
idxR, err = sdb.GetIdxByEthAddrBJJ(&addr2, pk2)
|
||||
assert.NotNil(t, err)
|
||||
assert.Equal(t, ErrToIdxNotFound, err)
|
||||
assert.Equal(t, common.Idx(0), idxR)
|
||||
|
||||
Reference in New Issue
Block a user