mirror of
https://github.com/arnaucube/hermez-node.git
synced 2026-02-07 11:26:44 +01:00
Feature/null refactor (#173)
* WIP: rebase * Make nullable fields use pointers
This commit is contained in:
@@ -223,7 +223,7 @@ func TestMain(m *testing.M) {
|
|||||||
panic("Token not found")
|
panic("Token not found")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
token = test.GetToken(genericTx.FromIdx, accs, tokens)
|
token = test.GetToken(*genericTx.FromIdx, accs, tokens)
|
||||||
}
|
}
|
||||||
var usd, loadUSD, feeUSD *float64
|
var usd, loadUSD, feeUSD *float64
|
||||||
if token.USD != nil {
|
if token.USD != nil {
|
||||||
@@ -244,7 +244,7 @@ func TestMain(m *testing.M) {
|
|||||||
Type: genericTx.Type,
|
Type: genericTx.Type,
|
||||||
Position: genericTx.Position,
|
Position: genericTx.Position,
|
||||||
FromIdx: genericTx.FromIdx,
|
FromIdx: genericTx.FromIdx,
|
||||||
ToIdx: genericTx.ToIdx,
|
ToIdx: *genericTx.ToIdx,
|
||||||
Amount: genericTx.Amount,
|
Amount: genericTx.Amount,
|
||||||
AmountFloat: genericTx.AmountFloat,
|
AmountFloat: genericTx.AmountFloat,
|
||||||
HistoricUSD: usd,
|
HistoricUSD: usd,
|
||||||
@@ -361,7 +361,7 @@ func TestGetHistoryTxs(t *testing.T) {
|
|||||||
// idx
|
// idx
|
||||||
fetchedTxs = historyTxAPIs{}
|
fetchedTxs = historyTxAPIs{}
|
||||||
limit = 4
|
limit = 4
|
||||||
idx := tc.allTxs[0].FromIdx
|
idx := tc.allTxs[0].ToIdx
|
||||||
path = fmt.Sprintf(
|
path = fmt.Sprintf(
|
||||||
"%s?accountIndex=%s&limit=%d&offset=",
|
"%s?accountIndex=%s&limit=%d&offset=",
|
||||||
endpoint, idx, limit,
|
endpoint, idx, limit,
|
||||||
@@ -370,7 +370,8 @@ func TestGetHistoryTxs(t *testing.T) {
|
|||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
idxTxs := historyTxAPIs{}
|
idxTxs := historyTxAPIs{}
|
||||||
for i := 0; i < len(tc.allTxs); i++ {
|
for i := 0; i < len(tc.allTxs); i++ {
|
||||||
if tc.allTxs[i].FromIdx[6:] == idx[6:] {
|
if (tc.allTxs[i].FromIdx != nil && (*tc.allTxs[i].FromIdx)[6:] == idx[6:]) ||
|
||||||
|
tc.allTxs[i].ToIdx[6:] == idx[6:] {
|
||||||
idxTxs = append(idxTxs, tc.allTxs[i])
|
idxTxs = append(idxTxs, tc.allTxs[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -396,7 +397,6 @@ func TestGetHistoryTxs(t *testing.T) {
|
|||||||
// type
|
// type
|
||||||
txTypes := []common.TxType{
|
txTypes := []common.TxType{
|
||||||
common.TxTypeExit,
|
common.TxTypeExit,
|
||||||
common.TxTypeWithdrawn,
|
|
||||||
common.TxTypeTransfer,
|
common.TxTypeTransfer,
|
||||||
common.TxTypeDeposit,
|
common.TxTypeDeposit,
|
||||||
common.TxTypeCreateAccountDeposit,
|
common.TxTypeCreateAccountDeposit,
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ func (htx *historyTxsAPI) GetPagination() pagination { return htx.Pagination }
|
|||||||
func (htx *historyTxsAPI) Len() int { return len(htx.Txs) }
|
func (htx *historyTxsAPI) Len() int { return len(htx.Txs) }
|
||||||
|
|
||||||
type l1Info struct {
|
type l1Info struct {
|
||||||
ToForgeL1TxsNum int64 `json:"toForgeL1TransactionsNum"`
|
ToForgeL1TxsNum *int64 `json:"toForgeL1TransactionsNum"`
|
||||||
UserOrigin bool `json:"userOrigin"`
|
UserOrigin bool `json:"userOrigin"`
|
||||||
FromEthAddr string `json:"fromHezEthereumAddress"`
|
FromEthAddr string `json:"fromHezEthereumAddress"`
|
||||||
FromBJJ string `json:"fromBJJ"`
|
FromBJJ string `json:"fromBJJ"`
|
||||||
@@ -58,7 +58,7 @@ type historyTxAPI struct {
|
|||||||
TxID string `json:"id"`
|
TxID string `json:"id"`
|
||||||
Type common.TxType `json:"type"`
|
Type common.TxType `json:"type"`
|
||||||
Position int `json:"position"`
|
Position int `json:"position"`
|
||||||
FromIdx string `json:"fromAccountIndex"`
|
FromIdx *string `json:"fromAccountIndex"`
|
||||||
ToIdx string `json:"toAccountIndex"`
|
ToIdx string `json:"toAccountIndex"`
|
||||||
Amount string `json:"amount"`
|
Amount string `json:"amount"`
|
||||||
BatchNum *common.BatchNum `json:"batchNum"`
|
BatchNum *common.BatchNum `json:"batchNum"`
|
||||||
@@ -76,7 +76,6 @@ func historyTxsToAPI(dbTxs []*historydb.HistoryTx) []historyTxAPI {
|
|||||||
TxID: dbTxs[i].TxID.String(),
|
TxID: dbTxs[i].TxID.String(),
|
||||||
Type: dbTxs[i].Type,
|
Type: dbTxs[i].Type,
|
||||||
Position: dbTxs[i].Position,
|
Position: dbTxs[i].Position,
|
||||||
FromIdx: idxToHez(dbTxs[i].FromIdx, dbTxs[i].TokenSymbol),
|
|
||||||
ToIdx: idxToHez(dbTxs[i].ToIdx, dbTxs[i].TokenSymbol),
|
ToIdx: idxToHez(dbTxs[i].ToIdx, dbTxs[i].TokenSymbol),
|
||||||
Amount: dbTxs[i].Amount.String(),
|
Amount: dbTxs[i].Amount.String(),
|
||||||
HistoricUSD: dbTxs[i].HistoricUSD,
|
HistoricUSD: dbTxs[i].HistoricUSD,
|
||||||
@@ -95,12 +94,17 @@ func historyTxsToAPI(dbTxs []*historydb.HistoryTx) []historyTxAPI {
|
|||||||
L1Info: nil,
|
L1Info: nil,
|
||||||
L2Info: nil,
|
L2Info: nil,
|
||||||
}
|
}
|
||||||
|
if dbTxs[i].FromIdx != nil {
|
||||||
|
fromIdx := new(string)
|
||||||
|
*fromIdx = idxToHez(*dbTxs[i].FromIdx, dbTxs[i].TokenSymbol)
|
||||||
|
apiTx.FromIdx = fromIdx
|
||||||
|
}
|
||||||
if dbTxs[i].IsL1 {
|
if dbTxs[i].IsL1 {
|
||||||
apiTx.IsL1 = "L1"
|
apiTx.IsL1 = "L1"
|
||||||
apiTx.L1Info = &l1Info{
|
apiTx.L1Info = &l1Info{
|
||||||
ToForgeL1TxsNum: dbTxs[i].ToForgeL1TxsNum,
|
ToForgeL1TxsNum: dbTxs[i].ToForgeL1TxsNum,
|
||||||
UserOrigin: dbTxs[i].UserOrigin,
|
UserOrigin: *dbTxs[i].UserOrigin,
|
||||||
FromEthAddr: ethAddrToHez(dbTxs[i].FromEthAddr),
|
FromEthAddr: ethAddrToHez(*dbTxs[i].FromEthAddr),
|
||||||
FromBJJ: bjjToString(dbTxs[i].FromBJJ),
|
FromBJJ: bjjToString(dbTxs[i].FromBJJ),
|
||||||
LoadAmount: dbTxs[i].LoadAmount.String(),
|
LoadAmount: dbTxs[i].LoadAmount.String(),
|
||||||
HistoricLoadAmountUSD: dbTxs[i].HistoricLoadAmountUSD,
|
HistoricLoadAmountUSD: dbTxs[i].HistoricLoadAmountUSD,
|
||||||
|
|||||||
@@ -149,9 +149,6 @@ func parseQueryTxType(c querier) (*common.TxType, error) {
|
|||||||
case common.TxTypeExit:
|
case common.TxTypeExit:
|
||||||
ret := common.TxTypeExit
|
ret := common.TxTypeExit
|
||||||
return &ret, nil
|
return &ret, nil
|
||||||
case common.TxTypeWithdrawn:
|
|
||||||
ret := common.TxTypeWithdrawn
|
|
||||||
return &ret, nil
|
|
||||||
case common.TxTypeTransfer:
|
case common.TxTypeTransfer:
|
||||||
ret := common.TxTypeTransfer
|
ret := common.TxTypeTransfer
|
||||||
return &ret, nil
|
return &ret, nil
|
||||||
|
|||||||
@@ -239,10 +239,6 @@ func TestParseQueryTxType(t *testing.T) {
|
|||||||
res, err = parseQueryTxType(c)
|
res, err = parseQueryTxType(c)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, common.TxTypeExit, *res)
|
assert.Equal(t, common.TxTypeExit, *res)
|
||||||
c.m[name] = string(common.TxTypeWithdrawn)
|
|
||||||
res, err = parseQueryTxType(c)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.Equal(t, common.TxTypeWithdrawn, *res)
|
|
||||||
c.m[name] = string(common.TxTypeTransfer)
|
c.m[name] = string(common.TxTypeTransfer)
|
||||||
res, err = parseQueryTxType(c)
|
res, err = parseQueryTxType(c)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|||||||
@@ -1240,13 +1240,24 @@ components:
|
|||||||
fromAccountIndex:
|
fromAccountIndex:
|
||||||
$ref: '#/components/schemas/AccountIndex'
|
$ref: '#/components/schemas/AccountIndex'
|
||||||
toAccountIndex:
|
toAccountIndex:
|
||||||
allOf:
|
type: string
|
||||||
- $ref: '#/components/schemas/AccountIndex'
|
description: >-
|
||||||
- example: "hez:DAI:672"
|
Identifier of the destination account. It references the position where the account is inside the state Merkle tree.
|
||||||
|
The identifier is built using: `hez:` + `token symbol:` + `index`
|
||||||
|
example: null
|
||||||
|
nullable: true
|
||||||
toHezEthereumAddress:
|
toHezEthereumAddress:
|
||||||
$ref: '#/components/schemas/HezEthereumAddress'
|
type: string
|
||||||
|
description: "Address of an Etherum account linked to the Hermez network."
|
||||||
|
pattern: "^hez:0x[a-fA-F0-9]{40}$"
|
||||||
|
example: "hez:0xaa942cfcd25ad4d90a62358b0dd84f33b398262a"
|
||||||
|
nullable: true
|
||||||
toBjj:
|
toBjj:
|
||||||
$ref: '#/components/schemas/BJJ'
|
type: string
|
||||||
|
description: "BabyJubJub public key, encoded as base64 URL (RFC 4648), which result in 33 bytes. The padding byte is replaced by a sum of the encoded bytes."
|
||||||
|
pattern: "^hez:[A-Za-z0-9_-]{44}$"
|
||||||
|
example: null
|
||||||
|
nullable: true
|
||||||
amount:
|
amount:
|
||||||
allOf:
|
allOf:
|
||||||
- $ref: '#/components/schemas/BigInt'
|
- $ref: '#/components/schemas/BigInt'
|
||||||
@@ -1308,6 +1319,7 @@ components:
|
|||||||
- type
|
- type
|
||||||
- tokenId
|
- tokenId
|
||||||
- fromAccountIndex
|
- fromAccountIndex
|
||||||
|
- toAccountIndex
|
||||||
- toHezAccountIndex
|
- toHezAccountIndex
|
||||||
- toHezEthereumAddress
|
- toHezEthereumAddress
|
||||||
- toBjj
|
- toBjj
|
||||||
@@ -1333,13 +1345,24 @@ components:
|
|||||||
fromAccountIndex:
|
fromAccountIndex:
|
||||||
$ref: '#/components/schemas/AccountIndex'
|
$ref: '#/components/schemas/AccountIndex'
|
||||||
toAccountIndex:
|
toAccountIndex:
|
||||||
allOf:
|
type: string
|
||||||
- $ref: '#/components/schemas/AccountIndex'
|
description: >-
|
||||||
- example: "hez:DAI:672"
|
Identifier of the destination account. It references the position where the account is inside the state Merkle tree.
|
||||||
|
The identifier is built using: `hez:` + `token symbol:` + `index`
|
||||||
|
example: "hez:DAI:309"
|
||||||
|
nullable: true
|
||||||
toHezEthereumAddress:
|
toHezEthereumAddress:
|
||||||
$ref: '#/components/schemas/HezEthereumAddress'
|
type: string
|
||||||
|
description: "Address of an Etherum account linked to the Hermez network."
|
||||||
|
pattern: "^hez:0x[a-fA-F0-9]{40}$"
|
||||||
|
example: null
|
||||||
|
nullable: true
|
||||||
toBjj:
|
toBjj:
|
||||||
$ref: '#/components/schemas/BJJ'
|
type: string
|
||||||
|
description: "BabyJubJub public key, encoded as base64 URL (RFC 4648), which result in 33 bytes. The padding byte is replaced by a sum of the encoded bytes."
|
||||||
|
pattern: "^hez:[A-Za-z0-9_-]{44}$"
|
||||||
|
example: null
|
||||||
|
nullable: true
|
||||||
amount:
|
amount:
|
||||||
allOf:
|
allOf:
|
||||||
- $ref: '#/components/schemas/BigInt'
|
- $ref: '#/components/schemas/BigInt'
|
||||||
@@ -1448,7 +1471,6 @@ components:
|
|||||||
description: Type of transaction.
|
description: Type of transaction.
|
||||||
enum:
|
enum:
|
||||||
- Exit
|
- Exit
|
||||||
- Withdrawn
|
|
||||||
- Transfer
|
- Transfer
|
||||||
- Deposit
|
- Deposit
|
||||||
- CreateAccountDeposit
|
- CreateAccountDeposit
|
||||||
@@ -1539,7 +1561,12 @@ components:
|
|||||||
position:
|
position:
|
||||||
$ref: '#/components/schemas/TransactionPosition'
|
$ref: '#/components/schemas/TransactionPosition'
|
||||||
fromAccountIndex:
|
fromAccountIndex:
|
||||||
$ref: '#/components/schemas/AccountIndex'
|
type: string
|
||||||
|
description: >-
|
||||||
|
Identifier of an account. It references the position where the account is inside the state Merkle tree.
|
||||||
|
The identifier is built using: `hez:` + `token symbol:` + `index`
|
||||||
|
example: "hez:DAI:4444"
|
||||||
|
nullable: true
|
||||||
toAccountIndex:
|
toAccountIndex:
|
||||||
allOf:
|
allOf:
|
||||||
- $ref: '#/components/schemas/AccountIndex'
|
- $ref: '#/components/schemas/AccountIndex'
|
||||||
@@ -1666,6 +1693,7 @@ components:
|
|||||||
minimum: 0
|
minimum: 0
|
||||||
maximum: 4294967295
|
maximum: 4294967295
|
||||||
example: 784
|
example: 784
|
||||||
|
nullable: true
|
||||||
TransactionPosition:
|
TransactionPosition:
|
||||||
type: integer
|
type: integer
|
||||||
description: Position that a transaction occupies in a batch.
|
description: Position that a transaction occupies in a batch.
|
||||||
@@ -1689,8 +1717,8 @@ components:
|
|||||||
items:
|
items:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
token:
|
tokenId:
|
||||||
$ref: '#/components/schemas/Token'
|
$ref: '#/components/schemas/TokenId'
|
||||||
amount:
|
amount:
|
||||||
allOf:
|
allOf:
|
||||||
- $ref: '#/components/schemas/BigInt'
|
- $ref: '#/components/schemas/BigInt'
|
||||||
@@ -1716,6 +1744,9 @@ components:
|
|||||||
$ref: '#/components/schemas/EthereumAddress'
|
$ref: '#/components/schemas/EthereumAddress'
|
||||||
collectedFees:
|
collectedFees:
|
||||||
$ref: '#/components/schemas/CollectedFees'
|
$ref: '#/components/schemas/CollectedFees'
|
||||||
|
totalCollectedFeesUSD:
|
||||||
|
type: number
|
||||||
|
description: Value in USD of the collected tokens by the forger in concept of fees. This is calculated at the moment the batch is forged, with the conversion rates at that time.
|
||||||
historicTotalCollectedFeesUSD:
|
historicTotalCollectedFeesUSD:
|
||||||
type: number
|
type: number
|
||||||
description: Sum of the all the fees collected, in USD, at the moment the batch was forged.
|
description: Sum of the all the fees collected, in USD, at the moment the batch was forged.
|
||||||
@@ -1737,7 +1768,6 @@ components:
|
|||||||
allOf:
|
allOf:
|
||||||
- $ref: '#/components/schemas/ToForgeL1TransactionsNum'
|
- $ref: '#/components/schemas/ToForgeL1TransactionsNum'
|
||||||
- description: Identifier that corresponds to the group of L1 transactions forged in the current batch.
|
- description: Identifier that corresponds to the group of L1 transactions forged in the current batch.
|
||||||
- nullable: true
|
|
||||||
- example: 5
|
- example: 5
|
||||||
slotNum:
|
slotNum:
|
||||||
$ref: '#/components/schemas/SlotNum'
|
$ref: '#/components/schemas/SlotNum'
|
||||||
|
|||||||
@@ -19,8 +19,9 @@ type Batch struct {
|
|||||||
StateRoot Hash `meddler:"state_root"`
|
StateRoot Hash `meddler:"state_root"`
|
||||||
NumAccounts int `meddler:"num_accounts"`
|
NumAccounts int `meddler:"num_accounts"`
|
||||||
ExitRoot Hash `meddler:"exit_root"`
|
ExitRoot Hash `meddler:"exit_root"`
|
||||||
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.
|
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 SlotNum `meddler:"slot_num"` // Slot in which the batch is forged
|
SlotNum SlotNum `meddler:"slot_num"` // Slot in which the batch is forged
|
||||||
|
TotalFeesUSD *float64 `meddler:"total_fees_usd"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// BatchNum identifies a batch
|
// BatchNum identifies a batch
|
||||||
|
|||||||
@@ -25,10 +25,10 @@ type L1Tx struct {
|
|||||||
// - L1UserTx: 0
|
// - L1UserTx: 0
|
||||||
// - L1CoordinatorTx: 1
|
// - L1CoordinatorTx: 1
|
||||||
TxID TxID
|
TxID TxID
|
||||||
ToForgeL1TxsNum int64 // toForgeL1TxsNum in which the tx was forged / will be forged
|
ToForgeL1TxsNum *int64 // toForgeL1TxsNum in which the tx was forged / will be forged
|
||||||
Position int
|
Position int
|
||||||
UserOrigin bool // 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
|
UserOrigin bool // 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
|
||||||
FromIdx Idx // FromIdx is used by L1Tx/Deposit to indicate the Idx receiver of the L1Tx.LoadAmount (deposit)
|
FromIdx *Idx // FromIdx is used by L1Tx/Deposit to indicate the Idx receiver of the L1Tx.LoadAmount (deposit)
|
||||||
FromEthAddr ethCommon.Address
|
FromEthAddr ethCommon.Address
|
||||||
FromBJJ *babyjub.PublicKey
|
FromBJJ *babyjub.PublicKey
|
||||||
ToIdx Idx // ToIdx is ignored in L1Tx/Deposit, but used in the L1Tx/DepositAndTransfer
|
ToIdx Idx // ToIdx is ignored in L1Tx/Deposit, but used in the L1Tx/DepositAndTransfer
|
||||||
@@ -47,7 +47,7 @@ type L1Tx struct {
|
|||||||
func NewL1Tx(l1Tx *L1Tx) (*L1Tx, error) {
|
func NewL1Tx(l1Tx *L1Tx) (*L1Tx, error) {
|
||||||
// calculate TxType
|
// calculate TxType
|
||||||
var txType TxType
|
var txType TxType
|
||||||
if l1Tx.FromIdx == Idx(0) {
|
if l1Tx.FromIdx == nil {
|
||||||
if l1Tx.ToIdx == Idx(0) {
|
if l1Tx.ToIdx == Idx(0) {
|
||||||
txType = TxTypeCreateAccountDeposit
|
txType = TxTypeCreateAccountDeposit
|
||||||
} else if l1Tx.ToIdx >= IdxUserThreshold {
|
} else if l1Tx.ToIdx >= IdxUserThreshold {
|
||||||
@@ -55,7 +55,7 @@ func NewL1Tx(l1Tx *L1Tx) (*L1Tx, error) {
|
|||||||
} else {
|
} else {
|
||||||
return l1Tx, fmt.Errorf("Can not determine type of L1Tx, invalid ToIdx value: %d", l1Tx.ToIdx)
|
return l1Tx, fmt.Errorf("Can not determine type of L1Tx, invalid ToIdx value: %d", l1Tx.ToIdx)
|
||||||
}
|
}
|
||||||
} else if l1Tx.FromIdx >= IdxUserThreshold {
|
} else if *l1Tx.FromIdx >= IdxUserThreshold {
|
||||||
if l1Tx.ToIdx == Idx(0) {
|
if l1Tx.ToIdx == Idx(0) {
|
||||||
txType = TxTypeDeposit
|
txType = TxTypeDeposit
|
||||||
} else if l1Tx.ToIdx == Idx(1) {
|
} else if l1Tx.ToIdx == Idx(1) {
|
||||||
@@ -83,7 +83,11 @@ func NewL1Tx(l1Tx *L1Tx) (*L1Tx, error) {
|
|||||||
txid[0] = TxIDPrefixL1CoordTx
|
txid[0] = TxIDPrefixL1CoordTx
|
||||||
}
|
}
|
||||||
var toForgeL1TxsNumBytes [8]byte
|
var toForgeL1TxsNumBytes [8]byte
|
||||||
binary.BigEndian.PutUint64(toForgeL1TxsNumBytes[:], uint64(l1Tx.ToForgeL1TxsNum))
|
var toForge uint64 = 0
|
||||||
|
if l1Tx.ToForgeL1TxsNum != nil {
|
||||||
|
toForge = uint64(*l1Tx.ToForgeL1TxsNum)
|
||||||
|
}
|
||||||
|
binary.BigEndian.PutUint64(toForgeL1TxsNumBytes[:], toForge)
|
||||||
copy(txid[1:9], toForgeL1TxsNumBytes[:])
|
copy(txid[1:9], toForgeL1TxsNumBytes[:])
|
||||||
|
|
||||||
var positionBytes [2]byte
|
var positionBytes [2]byte
|
||||||
@@ -98,19 +102,25 @@ func NewL1Tx(l1Tx *L1Tx) (*L1Tx, error) {
|
|||||||
func (tx *L1Tx) Tx() *Tx {
|
func (tx *L1Tx) Tx() *Tx {
|
||||||
f := new(big.Float).SetInt(tx.Amount)
|
f := new(big.Float).SetInt(tx.Amount)
|
||||||
amountFloat, _ := f.Float64()
|
amountFloat, _ := f.Float64()
|
||||||
|
userOrigin := new(bool)
|
||||||
|
*userOrigin = tx.UserOrigin
|
||||||
|
fromEthAddr := new(ethCommon.Address)
|
||||||
|
*fromEthAddr = tx.FromEthAddr
|
||||||
|
toIdx := new(Idx)
|
||||||
|
*toIdx = tx.ToIdx
|
||||||
genericTx := &Tx{
|
genericTx := &Tx{
|
||||||
IsL1: true,
|
IsL1: true,
|
||||||
TxID: tx.TxID,
|
TxID: tx.TxID,
|
||||||
Type: tx.Type,
|
Type: tx.Type,
|
||||||
Position: tx.Position,
|
Position: tx.Position,
|
||||||
FromIdx: tx.FromIdx,
|
FromIdx: tx.FromIdx,
|
||||||
ToIdx: tx.ToIdx,
|
ToIdx: toIdx,
|
||||||
Amount: tx.Amount,
|
Amount: tx.Amount,
|
||||||
AmountFloat: amountFloat,
|
AmountFloat: amountFloat,
|
||||||
TokenID: tx.TokenID,
|
TokenID: tx.TokenID,
|
||||||
ToForgeL1TxsNum: tx.ToForgeL1TxsNum,
|
ToForgeL1TxsNum: tx.ToForgeL1TxsNum,
|
||||||
UserOrigin: tx.UserOrigin,
|
UserOrigin: userOrigin,
|
||||||
FromEthAddr: tx.FromEthAddr,
|
FromEthAddr: fromEthAddr,
|
||||||
FromBJJ: tx.FromBJJ,
|
FromBJJ: tx.FromBJJ,
|
||||||
LoadAmount: tx.LoadAmount,
|
LoadAmount: tx.LoadAmount,
|
||||||
EthBlockNum: tx.EthBlockNum,
|
EthBlockNum: tx.EthBlockNum,
|
||||||
@@ -171,10 +181,14 @@ func L1TxFromBytes(b []byte) (*L1Tx, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
tx.FromIdx, err = IdxFromBytes(b[52:58])
|
fromIdx, err := IdxFromBytes(b[52:58])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
if fromIdx != 0 {
|
||||||
|
tx.FromIdx = new(Idx)
|
||||||
|
*tx.FromIdx = fromIdx
|
||||||
|
}
|
||||||
tx.LoadAmount = Float16FromBytes(b[58:60]).BigInt()
|
tx.LoadAmount = Float16FromBytes(b[58:60]).BigInt()
|
||||||
tx.Amount = Float16FromBytes(b[60:62]).BigInt()
|
tx.Amount = Float16FromBytes(b[60:62]).BigInt()
|
||||||
tx.TokenID, err = TokenIDFromBytes(b[62:66])
|
tx.TokenID, err = TokenIDFromBytes(b[62:66])
|
||||||
|
|||||||
@@ -12,14 +12,18 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestNewL1Tx(t *testing.T) {
|
func TestNewL1Tx(t *testing.T) {
|
||||||
|
toForge := new(int64)
|
||||||
|
*toForge = 123456
|
||||||
|
fromIdx := new(Idx)
|
||||||
|
*fromIdx = 300
|
||||||
l1Tx := &L1Tx{
|
l1Tx := &L1Tx{
|
||||||
ToForgeL1TxsNum: int64(123456),
|
ToForgeL1TxsNum: toForge,
|
||||||
Position: 71,
|
Position: 71,
|
||||||
ToIdx: 301,
|
ToIdx: 301,
|
||||||
TokenID: 5,
|
TokenID: 5,
|
||||||
Amount: big.NewInt(1),
|
Amount: big.NewInt(1),
|
||||||
LoadAmount: big.NewInt(2),
|
LoadAmount: big.NewInt(2),
|
||||||
FromIdx: 300,
|
FromIdx: fromIdx,
|
||||||
}
|
}
|
||||||
l1Tx, err := NewL1Tx(l1Tx)
|
l1Tx, err := NewL1Tx(l1Tx)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
@@ -34,12 +38,14 @@ func TestL1TxByteParsers(t *testing.T) {
|
|||||||
pk, err := pkComp.Decompress()
|
pk, err := pkComp.Decompress()
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
|
|
||||||
|
fromIdx := new(Idx)
|
||||||
|
*fromIdx = 2
|
||||||
l1Tx := &L1Tx{
|
l1Tx := &L1Tx{
|
||||||
ToIdx: 3,
|
ToIdx: 3,
|
||||||
TokenID: 5,
|
TokenID: 5,
|
||||||
Amount: big.NewInt(1),
|
Amount: big.NewInt(1),
|
||||||
LoadAmount: big.NewInt(2),
|
LoadAmount: big.NewInt(2),
|
||||||
FromIdx: 2,
|
FromIdx: fromIdx,
|
||||||
FromBJJ: pk,
|
FromBJJ: pk,
|
||||||
FromEthAddr: ethCommon.HexToAddress("0xc58d29fA6e86E4FAe04DDcEd660d45BCf3Cb2370"),
|
FromEthAddr: ethCommon.HexToAddress("0xc58d29fA6e86E4FAe04DDcEd660d45BCf3Cb2370"),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,13 +68,17 @@ func (tx *L2Tx) Tx() *Tx {
|
|||||||
*fee = tx.Fee
|
*fee = tx.Fee
|
||||||
nonce := new(Nonce)
|
nonce := new(Nonce)
|
||||||
*nonce = tx.Nonce
|
*nonce = tx.Nonce
|
||||||
|
fromIdx := new(Idx)
|
||||||
|
*fromIdx = tx.FromIdx
|
||||||
|
toIdx := new(Idx)
|
||||||
|
*toIdx = tx.ToIdx
|
||||||
return &Tx{
|
return &Tx{
|
||||||
IsL1: false,
|
IsL1: false,
|
||||||
TxID: tx.TxID,
|
TxID: tx.TxID,
|
||||||
Type: tx.Type,
|
Type: tx.Type,
|
||||||
Position: tx.Position,
|
Position: tx.Position,
|
||||||
FromIdx: tx.FromIdx,
|
FromIdx: fromIdx,
|
||||||
ToIdx: tx.ToIdx,
|
ToIdx: toIdx,
|
||||||
Amount: tx.Amount,
|
Amount: tx.Amount,
|
||||||
USD: tx.USD,
|
USD: tx.USD,
|
||||||
AmountFloat: amountFloat,
|
AmountFloat: amountFloat,
|
||||||
@@ -89,11 +93,15 @@ func (tx *L2Tx) Tx() *Tx {
|
|||||||
// PoolL2Tx returns the data structure of PoolL2Tx with the parameters of a
|
// PoolL2Tx returns the data structure of PoolL2Tx with the parameters of a
|
||||||
// L2Tx filled
|
// L2Tx filled
|
||||||
func (tx *L2Tx) PoolL2Tx() *PoolL2Tx {
|
func (tx *L2Tx) PoolL2Tx() *PoolL2Tx {
|
||||||
|
batchNum := new(BatchNum)
|
||||||
|
*batchNum = tx.BatchNum
|
||||||
|
toIdx := new(Idx)
|
||||||
|
*toIdx = tx.ToIdx
|
||||||
return &PoolL2Tx{
|
return &PoolL2Tx{
|
||||||
TxID: tx.TxID,
|
TxID: tx.TxID,
|
||||||
BatchNum: tx.BatchNum,
|
BatchNum: batchNum,
|
||||||
FromIdx: tx.FromIdx,
|
FromIdx: tx.FromIdx,
|
||||||
ToIdx: tx.ToIdx,
|
ToIdx: toIdx,
|
||||||
Amount: tx.Amount,
|
Amount: tx.Amount,
|
||||||
Fee: tx.Fee,
|
Fee: tx.Fee,
|
||||||
Nonce: tx.Nonce,
|
Nonce: tx.Nonce,
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package common
|
package common
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
"time"
|
"time"
|
||||||
@@ -19,8 +20,8 @@ type PoolL2Tx struct {
|
|||||||
// values: | type | FromIdx | Nonce |
|
// values: | type | FromIdx | Nonce |
|
||||||
TxID TxID `meddler:"tx_id"`
|
TxID TxID `meddler:"tx_id"`
|
||||||
FromIdx Idx `meddler:"from_idx"` // FromIdx is used by L1Tx/Deposit to indicate the Idx receiver of the L1Tx.LoadAmount (deposit)
|
FromIdx Idx `meddler:"from_idx"` // FromIdx is used by L1Tx/Deposit to indicate the Idx receiver of the L1Tx.LoadAmount (deposit)
|
||||||
ToIdx Idx `meddler:"to_idx"` // ToIdx is ignored in L1Tx/Deposit, but used in the L1Tx/DepositAndTransfer
|
ToIdx *Idx `meddler:"to_idx"` // ToIdx is ignored in L1Tx/Deposit, but used in the L1Tx/DepositAndTransfer
|
||||||
ToEthAddr ethCommon.Address `meddler:"to_eth_addr"`
|
ToEthAddr *ethCommon.Address `meddler:"to_eth_addr"`
|
||||||
ToBJJ *babyjub.PublicKey `meddler:"to_bjj"` // TODO: stop using json, use scanner/valuer
|
ToBJJ *babyjub.PublicKey `meddler:"to_bjj"` // TODO: stop using json, use scanner/valuer
|
||||||
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
|
||||||
@@ -32,21 +33,20 @@ type PoolL2Tx struct {
|
|||||||
Signature *babyjub.Signature `meddler:"signature"` // tx signature
|
Signature *babyjub.Signature `meddler:"signature"` // tx signature
|
||||||
Timestamp time.Time `meddler:"timestamp,utctime"` // time when added to the tx pool
|
Timestamp time.Time `meddler:"timestamp,utctime"` // time when added to the tx pool
|
||||||
// Stored in DB: optional fileds, may be uninitialized
|
// Stored in DB: optional fileds, may be uninitialized
|
||||||
BatchNum BatchNum `meddler:"batch_num,zeroisnull"` // batchNum in which this tx was forged. Presence indicates "forged" state.
|
BatchNum *BatchNum `meddler:"batch_num"` // batchNum in which this tx was forged. Presence indicates "forged" state.
|
||||||
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"` // 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"` // 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"`
|
||||||
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"`
|
||||||
RqAmount *big.Int `meddler:"rq_amount,bigintnull"` // TODO: change to float16
|
RqAmount *big.Int `meddler:"rq_amount,bigintnull"` // TODO: change to float16
|
||||||
RqFee FeeSelector `meddler:"rq_fee,zeroisnull"`
|
RqFee *FeeSelector `meddler:"rq_fee"`
|
||||||
RqNonce uint64 `meddler:"rq_nonce,zeroisnull"` // effective 48 bits used
|
RqNonce *uint64 `meddler:"rq_nonce"` // effective 48 bits used
|
||||||
AbsoluteFee *float64 `meddler:"fee_usd"`
|
AbsoluteFee *float64 `meddler:"fee_usd"`
|
||||||
AbsoluteFeeUpdate *time.Time `meddler:"usd_update,utctime"`
|
AbsoluteFeeUpdate *time.Time `meddler:"usd_update,utctime"`
|
||||||
Type TxType `meddler:"tx_type"`
|
Type TxType `meddler:"tx_type"`
|
||||||
// Extra metadata, may be uninitialized
|
// Extra metadata, may be uninitialized
|
||||||
RqTxCompressedData []byte `meddler:"-"` // 253 bits, optional for atomic txs
|
RqTxCompressedData []byte `meddler:"-"` // 253 bits, optional for atomic txs
|
||||||
TokenSymbol string `meddler:"token_symbol"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewPoolL2Tx returns the given L2Tx with the TxId & Type parameters calculated
|
// NewPoolL2Tx returns the given L2Tx with the TxId & Type parameters calculated
|
||||||
@@ -54,11 +54,11 @@ type PoolL2Tx struct {
|
|||||||
func NewPoolL2Tx(poolL2Tx *PoolL2Tx) (*PoolL2Tx, error) {
|
func NewPoolL2Tx(poolL2Tx *PoolL2Tx) (*PoolL2Tx, error) {
|
||||||
// calculate TxType
|
// calculate TxType
|
||||||
var txType TxType
|
var txType TxType
|
||||||
if poolL2Tx.ToIdx == Idx(0) {
|
if poolL2Tx.ToIdx == nil || *poolL2Tx.ToIdx == Idx(0) {
|
||||||
txType = TxTypeTransfer
|
txType = TxTypeTransfer
|
||||||
} else if poolL2Tx.ToIdx == Idx(1) {
|
} else if *poolL2Tx.ToIdx == Idx(1) {
|
||||||
txType = TxTypeExit
|
txType = TxTypeExit
|
||||||
} else if poolL2Tx.ToIdx >= IdxUserThreshold {
|
} else if *poolL2Tx.ToIdx >= IdxUserThreshold {
|
||||||
txType = TxTypeTransfer
|
txType = TxTypeTransfer
|
||||||
} else {
|
} else {
|
||||||
return poolL2Tx, fmt.Errorf("Can not determine type of PoolL2Tx, invalid ToIdx value: %d", poolL2Tx.ToIdx)
|
return poolL2Tx, fmt.Errorf("Can not determine type of PoolL2Tx, invalid ToIdx value: %d", poolL2Tx.ToIdx)
|
||||||
@@ -189,14 +189,21 @@ func (tx *PoolL2Tx) HashToSign() (*big.Int, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
toEthAddr := EthAddrToBigInt(tx.ToEthAddr)
|
toEthAddr := big.NewInt(0)
|
||||||
|
if tx.ToEthAddr != nil {
|
||||||
|
toEthAddr = EthAddrToBigInt(*tx.ToEthAddr)
|
||||||
|
}
|
||||||
|
rqToEthAddr := big.NewInt(0)
|
||||||
|
if tx.RqToEthAddr != nil {
|
||||||
|
rqToEthAddr = EthAddrToBigInt(*tx.RqToEthAddr)
|
||||||
|
}
|
||||||
toBJJAy := tx.ToBJJ.Y
|
toBJJAy := tx.ToBJJ.Y
|
||||||
rqTxCompressedDataV2, err := tx.TxCompressedDataV2()
|
rqTxCompressedDataV2, err := tx.TxCompressedDataV2()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return poseidon.Hash([]*big.Int{toCompressedData, toEthAddr, toBJJAy, rqTxCompressedDataV2, EthAddrToBigInt(tx.RqToEthAddr), tx.RqToBJJ.Y})
|
return poseidon.Hash([]*big.Int{toCompressedData, toEthAddr, toBJJAy, rqTxCompressedDataV2, rqToEthAddr, tx.RqToBJJ.Y})
|
||||||
}
|
}
|
||||||
|
|
||||||
// VerifySignature returns true if the signature verification is correct for the given PublicKey
|
// VerifySignature returns true if the signature verification is correct for the given PublicKey
|
||||||
@@ -209,39 +216,51 @@ func (tx *PoolL2Tx) VerifySignature(pk *babyjub.PublicKey) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// L2Tx returns a *L2Tx from the PoolL2Tx
|
// L2Tx returns a *L2Tx from the PoolL2Tx
|
||||||
func (tx *PoolL2Tx) L2Tx() *L2Tx {
|
func (tx *PoolL2Tx) L2Tx() (*L2Tx, error) {
|
||||||
|
if tx.ToIdx == nil || tx.BatchNum == nil {
|
||||||
|
return nil, errors.New("PoolL2Tx must have ToIdx != nil and BatchNum != nil in order to be able to transform to Tx")
|
||||||
|
}
|
||||||
return &L2Tx{
|
return &L2Tx{
|
||||||
TxID: tx.TxID,
|
TxID: tx.TxID,
|
||||||
BatchNum: tx.BatchNum,
|
BatchNum: *tx.BatchNum,
|
||||||
FromIdx: tx.FromIdx,
|
FromIdx: tx.FromIdx,
|
||||||
ToIdx: tx.ToIdx,
|
ToIdx: *tx.ToIdx,
|
||||||
Amount: tx.Amount,
|
Amount: tx.Amount,
|
||||||
Fee: tx.Fee,
|
Fee: tx.Fee,
|
||||||
Nonce: tx.Nonce,
|
Nonce: tx.Nonce,
|
||||||
Type: tx.Type,
|
Type: tx.Type,
|
||||||
}
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tx returns a *Tx from the PoolL2Tx
|
// Tx returns a *Tx from the PoolL2Tx
|
||||||
func (tx *PoolL2Tx) Tx() *Tx {
|
func (tx *PoolL2Tx) Tx() (*Tx, error) {
|
||||||
|
if tx.ToIdx == nil {
|
||||||
|
return nil, errors.New("PoolL2Tx must have ToIdx != nil in order to be able to transform to Tx")
|
||||||
|
}
|
||||||
|
fromIdx := new(Idx)
|
||||||
|
*fromIdx = tx.FromIdx
|
||||||
return &Tx{
|
return &Tx{
|
||||||
TxID: tx.TxID,
|
TxID: tx.TxID,
|
||||||
FromIdx: tx.FromIdx,
|
FromIdx: fromIdx,
|
||||||
ToIdx: tx.ToIdx,
|
ToIdx: tx.ToIdx,
|
||||||
Amount: tx.Amount,
|
Amount: tx.Amount,
|
||||||
Nonce: &tx.Nonce,
|
Nonce: &tx.Nonce,
|
||||||
Fee: &tx.Fee,
|
Fee: &tx.Fee,
|
||||||
Type: tx.Type,
|
Type: tx.Type,
|
||||||
}
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// PoolL2TxsToL2Txs returns an array of []*L2Tx from an array of []*PoolL2Tx
|
// PoolL2TxsToL2Txs returns an array of []*L2Tx from an array of []*PoolL2Tx
|
||||||
func PoolL2TxsToL2Txs(txs []*PoolL2Tx) []*L2Tx {
|
func PoolL2TxsToL2Txs(txs []*PoolL2Tx) ([]*L2Tx, error) {
|
||||||
var r []*L2Tx
|
var r []*L2Tx
|
||||||
for _, tx := range txs {
|
for _, poolTx := range txs {
|
||||||
r = append(r, tx.L2Tx())
|
tx, err := poolTx.L2Tx()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
return r
|
r = append(r, tx)
|
||||||
|
}
|
||||||
|
return r, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// PoolL2TxState is a struct that represents the status of a L2 transaction
|
// PoolL2TxState is a struct that represents the status of a L2 transaction
|
||||||
|
|||||||
@@ -11,9 +11,11 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestNewPoolL2Tx(t *testing.T) {
|
func TestNewPoolL2Tx(t *testing.T) {
|
||||||
|
toIdx := new(Idx)
|
||||||
|
*toIdx = 300
|
||||||
poolL2Tx := &PoolL2Tx{
|
poolL2Tx := &PoolL2Tx{
|
||||||
FromIdx: 87654,
|
FromIdx: 87654,
|
||||||
ToIdx: 300,
|
ToIdx: toIdx,
|
||||||
Amount: big.NewInt(4),
|
Amount: big.NewInt(4),
|
||||||
TokenID: 5,
|
TokenID: 5,
|
||||||
Nonce: 144,
|
Nonce: 144,
|
||||||
@@ -27,10 +29,11 @@ func TestTxCompressedData(t *testing.T) {
|
|||||||
var sk babyjub.PrivateKey
|
var sk babyjub.PrivateKey
|
||||||
_, err := hex.Decode(sk[:], []byte("0001020304050607080900010203040506070809000102030405060708090001"))
|
_, err := hex.Decode(sk[:], []byte("0001020304050607080900010203040506070809000102030405060708090001"))
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
toIdx := new(Idx)
|
||||||
|
*toIdx = 3
|
||||||
tx := PoolL2Tx{
|
tx := PoolL2Tx{
|
||||||
FromIdx: 2,
|
FromIdx: 2,
|
||||||
ToIdx: 3,
|
ToIdx: toIdx,
|
||||||
Amount: big.NewInt(4),
|
Amount: big.NewInt(4),
|
||||||
TokenID: 5,
|
TokenID: 5,
|
||||||
Nonce: 6,
|
Nonce: 6,
|
||||||
@@ -45,10 +48,10 @@ func TestTxCompressedData(t *testing.T) {
|
|||||||
assert.True(t, ok)
|
assert.True(t, ok)
|
||||||
assert.Equal(t, expected.Bytes(), txCompressedData.Bytes())
|
assert.Equal(t, expected.Bytes(), txCompressedData.Bytes())
|
||||||
assert.Equal(t, "10000000000060000000500040000000000030000000000020001c60be60f", hex.EncodeToString(txCompressedData.Bytes())[1:])
|
assert.Equal(t, "10000000000060000000500040000000000030000000000020001c60be60f", hex.EncodeToString(txCompressedData.Bytes())[1:])
|
||||||
|
*toIdx = 8
|
||||||
tx = PoolL2Tx{
|
tx = PoolL2Tx{
|
||||||
FromIdx: 7,
|
FromIdx: 7,
|
||||||
ToIdx: 8,
|
ToIdx: toIdx,
|
||||||
Amount: big.NewInt(9),
|
Amount: big.NewInt(9),
|
||||||
TokenID: 10,
|
TokenID: 10,
|
||||||
Nonce: 11,
|
Nonce: 11,
|
||||||
@@ -71,15 +74,16 @@ func TestHashToSign(t *testing.T) {
|
|||||||
_, err := hex.Decode(sk[:], []byte("0001020304050607080900010203040506070809000102030405060708090001"))
|
_, err := hex.Decode(sk[:], []byte("0001020304050607080900010203040506070809000102030405060708090001"))
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
ethAddr := ethCommon.HexToAddress("0xc58d29fA6e86E4FAe04DDcEd660d45BCf3Cb2370")
|
ethAddr := ethCommon.HexToAddress("0xc58d29fA6e86E4FAe04DDcEd660d45BCf3Cb2370")
|
||||||
|
toIdx := new(Idx)
|
||||||
|
*toIdx = 3
|
||||||
tx := PoolL2Tx{
|
tx := PoolL2Tx{
|
||||||
FromIdx: 2,
|
FromIdx: 2,
|
||||||
ToIdx: 3,
|
ToIdx: toIdx,
|
||||||
Amount: big.NewInt(4),
|
Amount: big.NewInt(4),
|
||||||
TokenID: 5,
|
TokenID: 5,
|
||||||
Nonce: 6,
|
Nonce: 6,
|
||||||
ToBJJ: sk.Public(),
|
ToBJJ: sk.Public(),
|
||||||
RqToEthAddr: ethAddr,
|
RqToEthAddr: ðAddr,
|
||||||
RqToBJJ: sk.Public(),
|
RqToBJJ: sk.Public(),
|
||||||
}
|
}
|
||||||
toSign, err := tx.HashToSign()
|
toSign, err := tx.HashToSign()
|
||||||
@@ -92,15 +96,16 @@ func TestVerifyTxSignature(t *testing.T) {
|
|||||||
_, err := hex.Decode(sk[:], []byte("0001020304050607080900010203040506070809000102030405060708090001"))
|
_, err := hex.Decode(sk[:], []byte("0001020304050607080900010203040506070809000102030405060708090001"))
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
ethAddr := ethCommon.HexToAddress("0xc58d29fA6e86E4FAe04DDcEd660d45BCf3Cb2370")
|
ethAddr := ethCommon.HexToAddress("0xc58d29fA6e86E4FAe04DDcEd660d45BCf3Cb2370")
|
||||||
|
toIdx := new(Idx)
|
||||||
|
*toIdx = 3
|
||||||
tx := PoolL2Tx{
|
tx := PoolL2Tx{
|
||||||
FromIdx: 2,
|
FromIdx: 2,
|
||||||
ToIdx: 3,
|
ToIdx: toIdx,
|
||||||
Amount: big.NewInt(4),
|
Amount: big.NewInt(4),
|
||||||
TokenID: 5,
|
TokenID: 5,
|
||||||
Nonce: 6,
|
Nonce: 6,
|
||||||
ToBJJ: sk.Public(),
|
ToBJJ: sk.Public(),
|
||||||
RqToEthAddr: ethAddr,
|
RqToEthAddr: ðAddr,
|
||||||
RqToBJJ: sk.Public(),
|
RqToBJJ: sk.Public(),
|
||||||
}
|
}
|
||||||
toSign, err := tx.HashToSign()
|
toSign, err := tx.HashToSign()
|
||||||
|
|||||||
29
common/tx.go
29
common/tx.go
@@ -3,6 +3,7 @@ package common
|
|||||||
import (
|
import (
|
||||||
"database/sql/driver"
|
"database/sql/driver"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
@@ -57,8 +58,6 @@ type TxType string
|
|||||||
const (
|
const (
|
||||||
// TxTypeExit represents L2->L1 token transfer. A leaf for this account appears in the exit tree of the block
|
// TxTypeExit represents L2->L1 token transfer. A leaf for this account appears in the exit tree of the block
|
||||||
TxTypeExit TxType = "Exit"
|
TxTypeExit TxType = "Exit"
|
||||||
// TxTypeWithdrawn represents the balance that was moved from L2->L1 has been widthrawn from the smart contract
|
|
||||||
TxTypeWithdrawn TxType = "Withdrawn"
|
|
||||||
// TxTypeTransfer represents L2->L2 token transfer
|
// TxTypeTransfer represents L2->L2 token transfer
|
||||||
TxTypeTransfer TxType = "Transfer"
|
TxTypeTransfer TxType = "Transfer"
|
||||||
// TxTypeDeposit represents L1->L2 transfer
|
// TxTypeDeposit represents L1->L2 transfer
|
||||||
@@ -86,8 +85,8 @@ type Tx struct {
|
|||||||
TxID TxID `meddler:"id"`
|
TxID TxID `meddler:"id"`
|
||||||
Type TxType `meddler:"type"`
|
Type TxType `meddler:"type"`
|
||||||
Position int `meddler:"position"`
|
Position int `meddler:"position"`
|
||||||
FromIdx Idx `meddler:"from_idx"`
|
FromIdx *Idx `meddler:"from_idx"`
|
||||||
ToIdx Idx `meddler:"to_idx"`
|
ToIdx *Idx `meddler:"to_idx"`
|
||||||
Amount *big.Int `meddler:"amount,bigint"`
|
Amount *big.Int `meddler:"amount,bigint"`
|
||||||
AmountFloat float64 `meddler:"amount_f"`
|
AmountFloat float64 `meddler:"amount_f"`
|
||||||
TokenID TokenID `meddler:"token_id"`
|
TokenID TokenID `meddler:"token_id"`
|
||||||
@@ -95,9 +94,9 @@ type Tx struct {
|
|||||||
BatchNum *BatchNum `meddler:"batch_num"` // batchNum in which this tx was forged. If the tx is L2, this must be != 0
|
BatchNum *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
|
EthBlockNum int64 `meddler:"eth_block_num"` // Ethereum Block Number in which this L1Tx was added to the queue
|
||||||
// L1
|
// L1
|
||||||
ToForgeL1TxsNum int64 `meddler:"to_forge_l1_txs_num"` // toForgeL1TxsNum in which the tx was forged / will be forged
|
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
|
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"`
|
FromEthAddr *ethCommon.Address `meddler:"from_eth_addr"`
|
||||||
FromBJJ *babyjub.PublicKey `meddler:"from_bjj"`
|
FromBJJ *babyjub.PublicKey `meddler:"from_bjj"`
|
||||||
LoadAmount *big.Int `meddler:"load_amount,bigintnull"`
|
LoadAmount *big.Int `meddler:"load_amount,bigintnull"`
|
||||||
LoadAmountFloat *float64 `meddler:"load_amount_f"`
|
LoadAmountFloat *float64 `meddler:"load_amount_f"`
|
||||||
@@ -109,22 +108,24 @@ type Tx struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// L1Tx returns a *L1Tx from the Tx
|
// L1Tx returns a *L1Tx from the Tx
|
||||||
func (tx *Tx) L1Tx() *L1Tx {
|
func (tx *Tx) L1Tx() (*L1Tx, error) {
|
||||||
l1Tx := &L1Tx{
|
if tx.UserOrigin == nil || tx.FromEthAddr == nil {
|
||||||
|
return nil, errors.New("Tx must have UserOrigin != nil and FromEthAddr != nil in order to be able to transform to L1Tx")
|
||||||
|
}
|
||||||
|
return &L1Tx{
|
||||||
TxID: tx.TxID,
|
TxID: tx.TxID,
|
||||||
ToForgeL1TxsNum: tx.ToForgeL1TxsNum,
|
ToForgeL1TxsNum: tx.ToForgeL1TxsNum,
|
||||||
Position: tx.Position,
|
Position: tx.Position,
|
||||||
UserOrigin: tx.UserOrigin,
|
UserOrigin: *tx.UserOrigin,
|
||||||
FromIdx: tx.FromIdx,
|
FromIdx: tx.FromIdx,
|
||||||
FromEthAddr: tx.FromEthAddr,
|
FromEthAddr: *tx.FromEthAddr,
|
||||||
FromBJJ: tx.FromBJJ,
|
FromBJJ: tx.FromBJJ,
|
||||||
ToIdx: tx.ToIdx,
|
ToIdx: *tx.ToIdx,
|
||||||
TokenID: tx.TokenID,
|
TokenID: tx.TokenID,
|
||||||
Amount: tx.Amount,
|
Amount: tx.Amount,
|
||||||
LoadAmount: tx.LoadAmount,
|
LoadAmount: tx.LoadAmount,
|
||||||
EthBlockNum: tx.EthBlockNum,
|
EthBlockNum: tx.EthBlockNum,
|
||||||
Type: tx.Type,
|
Type: tx.Type,
|
||||||
BatchNum: tx.BatchNum,
|
BatchNum: tx.BatchNum,
|
||||||
}
|
}, nil
|
||||||
return l1Tx
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -133,7 +133,8 @@ func (hdb *HistoryDB) addBatches(d meddler.DB, batches []common.Batch) error {
|
|||||||
num_accounts,
|
num_accounts,
|
||||||
exit_root,
|
exit_root,
|
||||||
forge_l1_txs_num,
|
forge_l1_txs_num,
|
||||||
slot_num
|
slot_num,
|
||||||
|
total_fees_usd
|
||||||
) VALUES %s;`,
|
) VALUES %s;`,
|
||||||
batches[:],
|
batches[:],
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ func TestBatches(t *testing.T) {
|
|||||||
// Test GetLastL1TxsNum
|
// Test GetLastL1TxsNum
|
||||||
fetchedLastL1TxsNum, err = historyDB.GetLastL1TxsNum()
|
fetchedLastL1TxsNum, err = historyDB.GetLastL1TxsNum()
|
||||||
assert.NoError(t, err)
|
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) {
|
func TestBids(t *testing.T) {
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ type HistoryTx struct {
|
|||||||
TxID common.TxID `meddler:"id"`
|
TxID common.TxID `meddler:"id"`
|
||||||
Type common.TxType `meddler:"type"`
|
Type common.TxType `meddler:"type"`
|
||||||
Position int `meddler:"position"`
|
Position int `meddler:"position"`
|
||||||
FromIdx common.Idx `meddler:"from_idx"`
|
FromIdx *common.Idx `meddler:"from_idx"`
|
||||||
ToIdx common.Idx `meddler:"to_idx"`
|
ToIdx common.Idx `meddler:"to_idx"`
|
||||||
Amount *big.Int `meddler:"amount,bigint"`
|
Amount *big.Int `meddler:"amount,bigint"`
|
||||||
AmountFloat float64 `meddler:"amount_f"`
|
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
|
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
|
EthBlockNum int64 `meddler:"eth_block_num"` // Ethereum Block Number in which this L1Tx was added to the queue
|
||||||
// L1
|
// L1
|
||||||
ToForgeL1TxsNum int64 `meddler:"to_forge_l1_txs_num"` // toForgeL1TxsNum in which the tx was forged / will be forged
|
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
|
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"`
|
FromEthAddr *ethCommon.Address `meddler:"from_eth_addr"`
|
||||||
FromBJJ *babyjub.PublicKey `meddler:"from_bjj"`
|
FromBJJ *babyjub.PublicKey `meddler:"from_bjj"`
|
||||||
LoadAmount *big.Int `meddler:"load_amount,bigintnull"`
|
LoadAmount *big.Int `meddler:"load_amount,bigintnull"`
|
||||||
LoadAmountFloat *float64 `meddler:"load_amount_f"`
|
LoadAmountFloat *float64 `meddler:"load_amount_f"`
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package l2db
|
package l2db
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"math/big"
|
"math/big"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -49,7 +50,10 @@ func (l2db *L2DB) AddAccountCreationAuth(auth *common.AccountCreationAuth) error
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetAccountCreationAuth returns an account creation authorization into the DB
|
// 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)
|
auth := new(common.AccountCreationAuth)
|
||||||
return auth, meddler.QueryRow(
|
return auth, meddler.QueryRow(
|
||||||
l2db.db, auth,
|
l2db.db, auth,
|
||||||
@@ -64,8 +68,8 @@ func (l2db *L2DB) AddTxTest(tx *common.PoolL2Tx) error {
|
|||||||
type withouUSD struct {
|
type withouUSD struct {
|
||||||
TxID common.TxID `meddler:"tx_id"`
|
TxID common.TxID `meddler:"tx_id"`
|
||||||
FromIdx common.Idx `meddler:"from_idx"`
|
FromIdx common.Idx `meddler:"from_idx"`
|
||||||
ToIdx common.Idx `meddler:"to_idx"`
|
ToIdx *common.Idx `meddler:"to_idx"`
|
||||||
ToEthAddr ethCommon.Address `meddler:"to_eth_addr"`
|
ToEthAddr *ethCommon.Address `meddler:"to_eth_addr"`
|
||||||
ToBJJ *babyjub.PublicKey `meddler:"to_bjj"`
|
ToBJJ *babyjub.PublicKey `meddler:"to_bjj"`
|
||||||
TokenID common.TokenID `meddler:"token_id"`
|
TokenID common.TokenID `meddler:"token_id"`
|
||||||
Amount *big.Int `meddler:"amount,bigint"`
|
Amount *big.Int `meddler:"amount,bigint"`
|
||||||
@@ -75,15 +79,15 @@ func (l2db *L2DB) AddTxTest(tx *common.PoolL2Tx) error {
|
|||||||
State common.PoolL2TxState `meddler:"state"`
|
State common.PoolL2TxState `meddler:"state"`
|
||||||
Signature *babyjub.Signature `meddler:"signature"`
|
Signature *babyjub.Signature `meddler:"signature"`
|
||||||
Timestamp time.Time `meddler:"timestamp,utctime"`
|
Timestamp time.Time `meddler:"timestamp,utctime"`
|
||||||
BatchNum common.BatchNum `meddler:"batch_num,zeroisnull"`
|
BatchNum *common.BatchNum `meddler:"batch_num"`
|
||||||
RqFromIdx common.Idx `meddler:"rq_from_idx,zeroisnull"`
|
RqFromIdx *common.Idx `meddler:"rq_from_idx"`
|
||||||
RqToIdx common.Idx `meddler:"rq_to_idx,zeroisnull"`
|
RqToIdx *common.Idx `meddler:"rq_to_idx"`
|
||||||
RqToEthAddr ethCommon.Address `meddler:"rq_to_eth_addr"`
|
RqToEthAddr *ethCommon.Address `meddler:"rq_to_eth_addr"`
|
||||||
RqToBJJ *babyjub.PublicKey `meddler:"rq_to_bjj"`
|
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"`
|
RqAmount *big.Int `meddler:"rq_amount,bigintnull"`
|
||||||
RqFee common.FeeSelector `meddler:"rq_fee,zeroisnull"`
|
RqFee *common.FeeSelector `meddler:"rq_fee"`
|
||||||
RqNonce uint64 `meddler:"rq_nonce,zeroisnull"`
|
RqNonce *uint64 `meddler:"rq_nonce"`
|
||||||
Type common.TxType `meddler:"tx_type"`
|
Type common.TxType `meddler:"tx_type"`
|
||||||
}
|
}
|
||||||
return meddler.Insert(l2db.db, "tx_pool", &withouUSD{
|
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
|
// selectPoolTx select part of queries to get common.PoolL2Tx
|
||||||
const selectPoolTx = `SELECT tx_pool.*, token.usd * tx_pool.amount_f AS value_usd,
|
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,
|
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 `
|
FROM tx_pool INNER JOIN token ON tx_pool.token_id = token.token_id `
|
||||||
|
|
||||||
// GetTx return the specified Tx
|
// GetTx return the specified Tx
|
||||||
func (l2db *L2DB) GetTx(txID common.TxID) (*common.PoolL2Tx, error) {
|
func (l2db *L2DB) GetTx(txID common.TxID) (*common.PoolL2Tx, error) {
|
||||||
|
|||||||
@@ -141,7 +141,7 @@ func TestStartForging(t *testing.T) {
|
|||||||
fetchedTx, err := l2DB.GetTx(id)
|
fetchedTx, err := l2DB.GetTx(id)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, common.PoolL2TxStateForging, fetchedTx.State)
|
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)
|
fetchedTx, err := l2DB.GetTx(id)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, common.PoolL2TxStateForged, fetchedTx.State)
|
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)
|
fetchedTx, err := l2DB.GetTx(id)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, common.PoolL2TxStateInvalid, fetchedTx.State)
|
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)
|
fetchedTx, err := l2DB.GetTx(id)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, common.PoolL2TxStateInvalid, fetchedTx.State)
|
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{}
|
reorgedTxIDs := []common.TxID{}
|
||||||
nonReorgedTxIDs := []common.TxID{}
|
nonReorgedTxIDs := []common.TxID{}
|
||||||
for i := 0; i < len(txs); i++ {
|
for i := 0; i < len(txs); i++ {
|
||||||
|
txs[i].BatchNum = new(common.BatchNum)
|
||||||
if txs[i].State == common.PoolL2TxStateForged || txs[i].State == common.PoolL2TxStateInvalid {
|
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)
|
reorgedTxIDs = append(reorgedTxIDs, txs[i].TxID)
|
||||||
} else {
|
} else {
|
||||||
txs[i].BatchNum = lastValidBatch
|
*txs[i].BatchNum = lastValidBatch
|
||||||
nonReorgedTxIDs = append(nonReorgedTxIDs, txs[i].TxID)
|
nonReorgedTxIDs = append(nonReorgedTxIDs, txs[i].TxID)
|
||||||
}
|
}
|
||||||
err := l2DB.AddTxTest(txs[i])
|
err := l2DB.AddTxTest(txs[i])
|
||||||
@@ -269,17 +270,16 @@ func TestReorg(t *testing.T) {
|
|||||||
}
|
}
|
||||||
err := l2DB.Reorg(lastValidBatch)
|
err := l2DB.Reorg(lastValidBatch)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
var nullBatchNum common.BatchNum
|
|
||||||
for _, id := range reorgedTxIDs {
|
for _, id := range reorgedTxIDs {
|
||||||
tx, err := l2DB.GetTx(id)
|
tx, err := l2DB.GetTx(id)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, nullBatchNum, tx.BatchNum)
|
assert.Nil(t, tx.BatchNum)
|
||||||
assert.Equal(t, common.PoolL2TxStatePending, tx.State)
|
assert.Equal(t, common.PoolL2TxStatePending, tx.State)
|
||||||
}
|
}
|
||||||
for _, id := range nonReorgedTxIDs {
|
for _, id := range nonReorgedTxIDs {
|
||||||
tx, err := l2DB.GetTx(id)
|
tx, err := l2DB.GetTx(id)
|
||||||
assert.NoError(t, err)
|
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
|
safeBatchNum := toDeleteBatchNum + l2DB.safetyPeriod + 1
|
||||||
// Add txs to the DB
|
// Add txs to the DB
|
||||||
for i := 0; i < int(l2DB.maxTxs); i++ {
|
for i := 0; i < int(l2DB.maxTxs); i++ {
|
||||||
|
txs[i].BatchNum = new(common.BatchNum)
|
||||||
if i%1 == 0 { // keep tx
|
if i%1 == 0 { // keep tx
|
||||||
txs[i].BatchNum = safeBatchNum
|
*txs[i].BatchNum = safeBatchNum
|
||||||
keepedIDs = append(keepedIDs, txs[i].TxID)
|
keepedIDs = append(keepedIDs, txs[i].TxID)
|
||||||
} else if i%2 == 0 { // delete after safety period
|
} else if i%2 == 0 { // delete after safety period
|
||||||
txs[i].BatchNum = toDeleteBatchNum
|
*txs[i].BatchNum = toDeleteBatchNum
|
||||||
if i%3 == 0 {
|
if i%3 == 0 {
|
||||||
txs[i].State = common.PoolL2TxStateForged
|
txs[i].State = common.PoolL2TxStateForged
|
||||||
} else {
|
} else {
|
||||||
@@ -343,7 +344,7 @@ func TestAuth(t *testing.T) {
|
|||||||
err := l2DB.AddAccountCreationAuth(auths[i])
|
err := l2DB.AddAccountCreationAuth(auths[i])
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
// Fetch from DB
|
// Fetch from DB
|
||||||
auth, err := l2DB.GetAccountCreationAuth(auths[i].EthAddr)
|
auth, err := l2DB.GetAccountCreationAuth(&auths[i].EthAddr)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
// Check fetched vs generated
|
// Check fetched vs generated
|
||||||
assert.Equal(t, auths[i].EthAddr, auth.EthAddr)
|
assert.Equal(t, auths[i].EthAddr, auth.EthAddr)
|
||||||
|
|||||||
@@ -17,14 +17,15 @@ CREATE TABLE coordinator (
|
|||||||
|
|
||||||
CREATE TABLE batch (
|
CREATE TABLE batch (
|
||||||
batch_num BIGINT PRIMARY KEY,
|
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
|
forger_addr BYTEA NOT NULL, -- fake foreign key for coordinator
|
||||||
fees_collected BYTEA NOT NULL,
|
fees_collected BYTEA NOT NULL,
|
||||||
state_root BYTEA NOT NULL,
|
state_root BYTEA NOT NULL,
|
||||||
num_accounts BIGINT NOT NULL,
|
num_accounts BIGINT NOT NULL,
|
||||||
exit_root BYTEA NOT NULL,
|
exit_root BYTEA NOT NULL,
|
||||||
forge_l1_txs_num BIGINT,
|
forge_l1_txs_num BIGINT,
|
||||||
slot_num BIGINT NOT NULL
|
slot_num BIGINT NOT NULL,
|
||||||
|
total_fees_usd NUMERIC
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE exit_tree (
|
CREATE TABLE exit_tree (
|
||||||
@@ -80,7 +81,7 @@ CREATE TABLE tx (
|
|||||||
id BYTEA PRIMARY KEY,
|
id BYTEA PRIMARY KEY,
|
||||||
type VARCHAR(40) NOT NULL,
|
type VARCHAR(40) NOT NULL,
|
||||||
position INT NOT NULL,
|
position INT NOT NULL,
|
||||||
from_idx BIGINT NOT NULL,
|
from_idx BIGINT,
|
||||||
to_idx BIGINT NOT NULL,
|
to_idx BIGINT NOT NULL,
|
||||||
amount BYTEA NOT NULL,
|
amount BYTEA NOT NULL,
|
||||||
amount_f NUMERIC NOT NULL,
|
amount_f NUMERIC NOT NULL,
|
||||||
@@ -470,9 +471,9 @@ CREATE TABLE consensus_vars (
|
|||||||
CREATE TABLE tx_pool (
|
CREATE TABLE tx_pool (
|
||||||
tx_id BYTEA PRIMARY KEY,
|
tx_id BYTEA PRIMARY KEY,
|
||||||
from_idx BIGINT NOT NULL,
|
from_idx BIGINT NOT NULL,
|
||||||
to_idx BIGINT NOT NULL,
|
to_idx BIGINT,
|
||||||
to_eth_addr BYTEA NOT NULL,
|
to_eth_addr BYTEA,
|
||||||
to_bjj BYTEA NOT NULL,
|
to_bjj BYTEA,
|
||||||
token_id INT NOT NULL REFERENCES token (token_id) ON DELETE CASCADE,
|
token_id INT NOT NULL REFERENCES token (token_id) ON DELETE CASCADE,
|
||||||
amount BYTEA NOT NULL,
|
amount BYTEA NOT NULL,
|
||||||
amount_f NUMERIC 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
|
// 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)
|
return getAccountInTreeDB(s.db, idx)
|
||||||
}
|
}
|
||||||
|
|
||||||
// getAccountInTreeDB is abstracted from StateDB to be used from StateDB and
|
// getAccountInTreeDB is abstracted from StateDB to be used from StateDB and
|
||||||
// from ExitTree. GetAccount returns the account for the given Idx
|
// 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()
|
idxBytes, err := idx.Bytes()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
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
|
// StateDB.mt==nil, MerkleTree is not affected, otherwise updates the
|
||||||
// MerkleTree, returning a CircomProcessorProof.
|
// MerkleTree, returning a CircomProcessorProof.
|
||||||
func (s *StateDB) CreateAccount(idx common.Idx, account *common.Account) (*merkletree.CircomProcessorProof, error) {
|
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 {
|
if err != nil {
|
||||||
return cpp, err
|
return cpp, err
|
||||||
}
|
}
|
||||||
// store idx by EthAddr & BJJ
|
// store idx by EthAddr & BJJ
|
||||||
err = s.setIdxByEthAddrBJJ(idx, account.EthAddr, account.PublicKey)
|
err = s.setIdxByEthAddrBJJ(idx, &account.EthAddr, account.PublicKey)
|
||||||
return cpp, err
|
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
|
// from ExitTree. Creates a new Account in the StateDB for the given Idx. If
|
||||||
// StateDB.mt==nil, MerkleTree is not affected, otherwise updates the
|
// StateDB.mt==nil, MerkleTree is not affected, otherwise updates the
|
||||||
// MerkleTree, returning a CircomProcessorProof.
|
// 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()
|
// store at the DB the key: v, and value: leaf.Bytes()
|
||||||
v, err := account.HashValue()
|
v, err := account.HashValue()
|
||||||
if err != nil {
|
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
|
// UpdateAccount updates the Account in the StateDB for the given Idx. If
|
||||||
// StateDB.mt==nil, MerkleTree is not affected, otherwise updates the
|
// StateDB.mt==nil, MerkleTree is not affected, otherwise updates the
|
||||||
// MerkleTree, returning a CircomProcessorProof.
|
// 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)
|
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
|
// from ExitTree. Updates the Account in the StateDB for the given Idx. If
|
||||||
// StateDB.mt==nil, MerkleTree is not affected, otherwise updates the
|
// StateDB.mt==nil, MerkleTree is not affected, otherwise updates the
|
||||||
// MerkleTree, returning a CircomProcessorProof.
|
// 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()
|
// store at the DB the key: v, and value: account.Bytes()
|
||||||
v, err := account.HashValue()
|
v, err := account.HashValue()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -129,7 +129,8 @@ func TestStateDBWithoutMT(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// get non-existing account, expecting an error
|
// 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.NotNil(t, err)
|
||||||
assert.Equal(t, db.ErrNotFound, err)
|
assert.Equal(t, db.ErrNotFound, err)
|
||||||
|
|
||||||
@@ -140,13 +141,15 @@ func TestStateDBWithoutMT(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for i := 0; i < len(accounts); i++ {
|
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.Nil(t, err)
|
||||||
assert.Equal(t, accounts[i], accGetted)
|
assert.Equal(t, accounts[i], accGetted)
|
||||||
}
|
}
|
||||||
|
|
||||||
// try already existing idx and get error
|
// 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)
|
assert.Nil(t, err)
|
||||||
_, err = sdb.CreateAccount(common.Idx(1), accounts[1]) // check that can not be created twice
|
_, err = sdb.CreateAccount(common.Idx(1), accounts[1]) // check that can not be created twice
|
||||||
assert.NotNil(t, err)
|
assert.NotNil(t, err)
|
||||||
@@ -155,7 +158,8 @@ func TestStateDBWithoutMT(t *testing.T) {
|
|||||||
// update accounts
|
// update accounts
|
||||||
for i := 0; i < len(accounts); i++ {
|
for i := 0; i < len(accounts); i++ {
|
||||||
accounts[i].Nonce = accounts[i].Nonce + 1
|
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)
|
assert.Nil(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -178,7 +182,8 @@ func TestStateDBWithMT(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// get non-existing account, expecting an error
|
// 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.NotNil(t, err)
|
||||||
assert.Equal(t, db.ErrNotFound, err)
|
assert.Equal(t, db.ErrNotFound, err)
|
||||||
|
|
||||||
@@ -189,13 +194,15 @@ func TestStateDBWithMT(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for i := 0; i < len(accounts); i++ {
|
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.Nil(t, err)
|
||||||
assert.Equal(t, accounts[i], accGetted)
|
assert.Equal(t, accounts[i], accGetted)
|
||||||
}
|
}
|
||||||
|
|
||||||
// try already existing idx and get error
|
// 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)
|
assert.Nil(t, err)
|
||||||
_, err = sdb.CreateAccount(common.Idx(1), accounts[1]) // check that can not be created twice
|
_, err = sdb.CreateAccount(common.Idx(1), accounts[1]) // check that can not be created twice
|
||||||
assert.NotNil(t, err)
|
assert.NotNil(t, err)
|
||||||
@@ -207,10 +214,12 @@ func TestStateDBWithMT(t *testing.T) {
|
|||||||
// update accounts
|
// update accounts
|
||||||
for i := 0; i < len(accounts); i++ {
|
for i := 0; i < len(accounts); i++ {
|
||||||
accounts[i].Nonce = accounts[i].Nonce + 1
|
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)
|
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.Nil(t, err)
|
||||||
assert.Equal(t, accounts[1].Nonce, a.Nonce)
|
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 {
|
if s.zki != nil {
|
||||||
// Txs
|
// Txs
|
||||||
// s.zki.TxCompressedData[s.i] = tx.TxCompressedData() // uncomment once L1Tx.TxCompressedData is ready
|
// s.zki.TxCompressedData[s.i] = tx.TxCompressedData() // uncomment once L1Tx.TxCompressedData is ready
|
||||||
|
if tx.FromIdx != nil {
|
||||||
s.zki.FromIdx[s.i] = tx.FromIdx.BigInt()
|
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.ToIdx[s.i] = tx.ToIdx.BigInt()
|
||||||
s.zki.OnChain[s.i] = big.NewInt(1)
|
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 {
|
if err != nil {
|
||||||
return nil, nil, false, err
|
return nil, nil, false, err
|
||||||
}
|
}
|
||||||
return &tx.FromIdx, exitAccount, newExit, nil
|
return tx.FromIdx, exitAccount, newExit, nil
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -307,7 +311,7 @@ func (s *StateDB) processL2Tx(exitTree *merkletree.MerkleTree, tx *common.PoolL2
|
|||||||
var err error
|
var err error
|
||||||
var auxToIdx common.Idx
|
var auxToIdx common.Idx
|
||||||
// if tx.ToIdx==0, get toIdx by ToEthAddr or ToBJJ
|
// 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)
|
auxToIdx, err = s.GetIdxByEthAddrBJJ(tx.ToEthAddr, tx.ToBJJ)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error(err)
|
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()
|
s.zki.ToIdx[s.i] = tx.ToIdx.BigInt()
|
||||||
|
|
||||||
// fill AuxToIdx if needed
|
// 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
|
// use toIdx that can have been filled by tx.ToIdx or
|
||||||
// if tx.Idx==0 (this case), toIdx is filled by the Idx
|
// if tx.Idx==0 (this case), toIdx is filled by the Idx
|
||||||
// from db by ToEthAddr&ToBJJ
|
// 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.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.OnChain[s.i] = big.NewInt(0)
|
||||||
s.zki.NewAccount[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:
|
case common.TxTypeTransfer:
|
||||||
// go to the MT account of sender and receiver, and update
|
// go to the MT account of sender and receiver, and update
|
||||||
// balance & nonce
|
// 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 {
|
if err != nil {
|
||||||
return nil, nil, false, err
|
return nil, nil, false, err
|
||||||
}
|
}
|
||||||
case common.TxTypeExit:
|
case common.TxTypeExit:
|
||||||
// execute exit flow
|
// 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 {
|
if err != nil {
|
||||||
return nil, nil, false, err
|
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
|
// in case that the tx is a L1Tx>DepositTransfer
|
||||||
var accReceiver *common.Account
|
var accReceiver *common.Account
|
||||||
if transfer {
|
if transfer {
|
||||||
accReceiver, err = s.GetAccount(tx.ToIdx)
|
accReceiver, err = s.GetAccount(&tx.ToIdx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -458,7 +475,7 @@ func (s *StateDB) applyDeposit(tx *common.L1Tx, transfer bool) error {
|
|||||||
// this is done after updating Sender Account (depositer)
|
// this is done after updating Sender Account (depositer)
|
||||||
if transfer {
|
if transfer {
|
||||||
// update receiver account in localStateDB
|
// update receiver account in localStateDB
|
||||||
p, err := s.UpdateAccount(tx.ToIdx, accReceiver)
|
p, err := s.UpdateAccount(&tx.ToIdx, accReceiver)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
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.
|
// the real ToIdx is found trhrough the ToEthAddr or ToBJJ.
|
||||||
func (s *StateDB) applyTransfer(tx *common.Tx, auxToIdx common.Idx) error {
|
func (s *StateDB) applyTransfer(tx *common.Tx, auxToIdx common.Idx) error {
|
||||||
if auxToIdx == 0 {
|
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
|
// get sender and receiver accounts from localStateDB
|
||||||
accSender, err := s.GetAccount(tx.FromIdx)
|
accSender, err := s.GetAccount(tx.FromIdx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
accReceiver, err := s.GetAccount(auxToIdx)
|
accReceiver, err := s.GetAccount(&auxToIdx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -525,7 +545,7 @@ func (s *StateDB) applyTransfer(tx *common.Tx, auxToIdx common.Idx) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// update receiver account in localStateDB
|
// update receiver account in localStateDB
|
||||||
pReceiver, err := s.UpdateAccount(auxToIdx, accReceiver)
|
pReceiver, err := s.UpdateAccount(&auxToIdx, accReceiver)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -555,7 +575,7 @@ func (s *StateDB) applyCreateAccountDepositTransfer(tx *common.L1Tx) error {
|
|||||||
EthAddr: tx.FromEthAddr,
|
EthAddr: tx.FromEthAddr,
|
||||||
}
|
}
|
||||||
accSender.Balance = new(big.Int).Add(accSender.Balance, tx.LoadAmount)
|
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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -587,7 +607,7 @@ func (s *StateDB) applyCreateAccountDepositTransfer(tx *common.L1Tx) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// update receiver account in localStateDB
|
// update receiver account in localStateDB
|
||||||
p, err = s.UpdateAccount(tx.ToIdx, accReceiver)
|
p, err = s.UpdateAccount(&tx.ToIdx, accReceiver)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,7 +40,8 @@ func TestProcessTxs(t *testing.T) {
|
|||||||
require.Nil(t, err)
|
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.Nil(t, err)
|
||||||
assert.Equal(t, "23", acc.Balance.String())
|
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
|
// Nonce & TokenID =0, after ProcessTxs call has the expected value
|
||||||
|
|
||||||
assert.Equal(t, 0, len(exitInfos))
|
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.Nil(t, err)
|
||||||
assert.Equal(t, "28", acc.Balance.String())
|
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])
|
_, exitInfos, err = sdb.ProcessTxs(l1Txs[1], coordinatorL1Txs[1], poolL2Txs[1])
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
assert.Equal(t, 5, len(exitInfos))
|
assert.Equal(t, 5, len(exitInfos))
|
||||||
acc, err = sdb.GetAccount(common.Idx(256))
|
acc, err = sdb.GetAccount(&accountIdx)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
assert.Equal(t, "48", acc.Balance.String())
|
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])
|
_, exitInfos, err = sdb.ProcessTxs(l1Txs[2], coordinatorL1Txs[2], poolL2Txs[2])
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
assert.Equal(t, 1, len(exitInfos))
|
assert.Equal(t, 1, len(exitInfos))
|
||||||
acc, err = sdb.GetAccount(common.Idx(256))
|
acc, err = sdb.GetAccount(&accountIdx)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.Equal(t, "23", acc.Balance.String())
|
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])
|
_, exitInfos, err := sdb.ProcessTxs(l1Txs[0], coordinatorL1Txs[0], poolL2Txs[0])
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
assert.Equal(t, 0, len(exitInfos))
|
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.Nil(t, err)
|
||||||
assert.Equal(t, "28", acc.Balance.String())
|
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])
|
_, exitInfos, err = sdb.ProcessTxs(l1Txs[1], coordinatorL1Txs[1], poolL2Txs[1])
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
assert.Equal(t, 5, len(exitInfos))
|
assert.Equal(t, 5, len(exitInfos))
|
||||||
acc, err = sdb.GetAccount(common.Idx(256))
|
acc, err = sdb.GetAccount(&accountIdx)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
assert.Equal(t, "48", acc.Balance.String())
|
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])
|
_, exitInfos, err = sdb.ProcessTxs(l1Txs[2], coordinatorL1Txs[2], poolL2Txs[2])
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
assert.Equal(t, 1, len(exitInfos))
|
assert.Equal(t, 1, len(exitInfos))
|
||||||
acc, err = sdb.GetAccount(common.Idx(256))
|
acc, err = sdb.GetAccount(&accountIdx)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.Equal(t, "23", acc.Balance.String())
|
assert.Equal(t, "23", acc.Balance.String())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package statedb
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"errors"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
ethCommon "github.com/ethereum/go-ethereum/common"
|
ethCommon "github.com/ethereum/go-ethereum/common"
|
||||||
@@ -11,7 +12,7 @@ import (
|
|||||||
"github.com/iden3/go-merkletree"
|
"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()
|
pkComp := pk.Compress()
|
||||||
var b []byte
|
var b []byte
|
||||||
b = append(b, addr.Bytes()...)
|
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
|
// - key: EthAddr & BabyJubJub PublicKey Compressed, value: idx
|
||||||
// If Idx already exist for the given EthAddr & BJJ, the remaining Idx will be
|
// If Idx already exist for the given EthAddr & BJJ, the remaining Idx will be
|
||||||
// always the smallest one.
|
// 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)
|
oldIdx, err := s.GetIdxByEthAddrBJJ(addr, pk)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
// EthAddr & BJJ already have an Idx
|
// 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
|
// 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
|
// Ethereum Address. Will return common.Idx(0) and error in case that Idx is
|
||||||
// not found in the StateDB.
|
// 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())
|
b, err := s.db.Get(addr.Bytes())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.Idx(0), ErrToIdxNotFound
|
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
|
// 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
|
// query. Will return common.Idx(0) and error in case that Idx is not found in
|
||||||
// the StateDB.
|
// 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 {
|
if !bytes.Equal(addr.Bytes(), common.EmptyAddr.Bytes()) && pk == nil {
|
||||||
// case ToEthAddr!=0 && ToBJJ=0
|
// case ToEthAddr!=0 && ToBJJ=0
|
||||||
return s.GetIdxByEthAddr(addr)
|
return s.GetIdxByEthAddr(addr)
|
||||||
|
|||||||
@@ -32,47 +32,47 @@ func TestGetIdx(t *testing.T) {
|
|||||||
idx3 := common.Idx(1233)
|
idx3 := common.Idx(1233)
|
||||||
|
|
||||||
// store the keys for idx by Addr & BJJ
|
// store the keys for idx by Addr & BJJ
|
||||||
err = sdb.setIdxByEthAddrBJJ(idx, addr, pk)
|
err = sdb.setIdxByEthAddrBJJ(idx, &addr, pk)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
|
|
||||||
idxR, err := sdb.GetIdxByEthAddrBJJ(addr, pk)
|
idxR, err := sdb.GetIdxByEthAddrBJJ(&addr, pk)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.Equal(t, idx, idxR)
|
assert.Equal(t, idx, idxR)
|
||||||
|
|
||||||
// expect error when getting only by EthAddr, as value does not exist
|
// expect error when getting only by EthAddr, as value does not exist
|
||||||
// in the db for only EthAddr
|
// in the db for only EthAddr
|
||||||
_, err = sdb.GetIdxByEthAddr(addr)
|
_, err = sdb.GetIdxByEthAddr(&addr)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
_, err = sdb.GetIdxByEthAddr(addr2)
|
_, err = sdb.GetIdxByEthAddr(&addr2)
|
||||||
assert.NotNil(t, err)
|
assert.NotNil(t, err)
|
||||||
|
|
||||||
// expect to fail
|
// expect to fail
|
||||||
idxR, err = sdb.GetIdxByEthAddrBJJ(addr2, pk)
|
idxR, err = sdb.GetIdxByEthAddrBJJ(&addr2, pk)
|
||||||
assert.NotNil(t, err)
|
assert.NotNil(t, err)
|
||||||
assert.Equal(t, common.Idx(0), idxR)
|
assert.Equal(t, common.Idx(0), idxR)
|
||||||
idxR, err = sdb.GetIdxByEthAddrBJJ(addr, pk2)
|
idxR, err = sdb.GetIdxByEthAddrBJJ(&addr, pk2)
|
||||||
assert.NotNil(t, err)
|
assert.NotNil(t, err)
|
||||||
assert.Equal(t, common.Idx(0), idxR)
|
assert.Equal(t, common.Idx(0), idxR)
|
||||||
|
|
||||||
// try to store bigger idx, will not affect as already exist a smaller
|
// try to store bigger idx, will not affect as already exist a smaller
|
||||||
// Idx for that Addr & BJJ
|
// Idx for that Addr & BJJ
|
||||||
err = sdb.setIdxByEthAddrBJJ(idx2, addr, pk)
|
err = sdb.setIdxByEthAddrBJJ(idx2, &addr, pk)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
|
||||||
// store smaller idx
|
// store smaller idx
|
||||||
err = sdb.setIdxByEthAddrBJJ(idx3, addr, pk)
|
err = sdb.setIdxByEthAddrBJJ(idx3, &addr, pk)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
|
||||||
idxR, err = sdb.GetIdxByEthAddrBJJ(addr, pk)
|
idxR, err = sdb.GetIdxByEthAddrBJJ(&addr, pk)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.Equal(t, idx3, idxR)
|
assert.Equal(t, idx3, idxR)
|
||||||
|
|
||||||
// by EthAddr should work
|
// by EthAddr should work
|
||||||
idxR, err = sdb.GetIdxByEthAddr(addr)
|
idxR, err = sdb.GetIdxByEthAddr(&addr)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.Equal(t, idx3, idxR)
|
assert.Equal(t, idx3, idxR)
|
||||||
// expect error when trying to get Idx by addr2 & pk2
|
// 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.NotNil(t, err)
|
||||||
assert.Equal(t, ErrToIdxNotFound, err)
|
assert.Equal(t, ErrToIdxNotFound, err)
|
||||||
assert.Equal(t, common.Idx(0), idxR)
|
assert.Equal(t, common.Idx(0), idxR)
|
||||||
|
|||||||
@@ -340,13 +340,15 @@ func (s *Synchronizer) rollupSync(blockNum int64) (*rollupData, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Replace GetLastL1TxsNum by GetNextL1TxsNum
|
// TODO: Replace GetLastL1TxsNum by GetNextL1TxsNum
|
||||||
nextForgeL1TxsNum := int64(0)
|
var nextForgeL1TxsNum int64
|
||||||
nextForgeL1TxsNumPtr, err := s.historyDB.GetLastL1TxsNum()
|
nextForgeL1TxsNumPtr, err := s.historyDB.GetLastL1TxsNum()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if nextForgeL1TxsNumPtr != nil {
|
if nextForgeL1TxsNumPtr != nil {
|
||||||
nextForgeL1TxsNum = *nextForgeL1TxsNumPtr + 1
|
nextForgeL1TxsNum = *nextForgeL1TxsNumPtr + 1
|
||||||
|
} else {
|
||||||
|
nextForgeL1TxsNum = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get newLastIdx that will be used to complete the accounts
|
// Get newLastIdx that will be used to complete the accounts
|
||||||
@@ -371,11 +373,9 @@ func (s *Synchronizer) rollupSync(blockNum int64) (*rollupData, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
forgeL1TxsNum := int64(0)
|
forgeL1TxsNum := nextForgeL1TxsNum
|
||||||
// Check if this is a L1Batch to get L1 Tx from it
|
// Check if this is a L1Batch to get L1 Tx from it
|
||||||
if forgeBatchArgs.L1Batch {
|
if forgeBatchArgs.L1Batch {
|
||||||
forgeL1TxsNum = nextForgeL1TxsNum
|
|
||||||
|
|
||||||
// Get L1 User Txs from History DB
|
// Get L1 User Txs from History DB
|
||||||
// TODO: Get L1TX from HistoryDB filtered by toforgeL1txNum & fromidx = 0 and
|
// TODO: Get L1TX from HistoryDB filtered by toforgeL1txNum & fromidx = 0 and
|
||||||
// update batch number and add accounts to createdAccounts updating idx
|
// update batch number and add accounts to createdAccounts updating idx
|
||||||
@@ -395,7 +395,7 @@ func (s *Synchronizer) rollupSync(blockNum int64) (*rollupData, error) {
|
|||||||
// Get L1 Coordinator Txs
|
// Get L1 Coordinator Txs
|
||||||
for _, l1CoordinatorTx := range forgeBatchArgs.L1CoordinatorTxs {
|
for _, l1CoordinatorTx := range forgeBatchArgs.L1CoordinatorTxs {
|
||||||
l1CoordinatorTx.Position = position
|
l1CoordinatorTx.Position = position
|
||||||
l1CoordinatorTx.ToForgeL1TxsNum = nextForgeL1TxsNum
|
l1CoordinatorTx.ToForgeL1TxsNum = &forgeL1TxsNum
|
||||||
l1CoordinatorTx.UserOrigin = false
|
l1CoordinatorTx.UserOrigin = false
|
||||||
l1CoordinatorTx.EthBlockNum = blockNum
|
l1CoordinatorTx.EthBlockNum = blockNum
|
||||||
bn := new(common.BatchNum)
|
bn := new(common.BatchNum)
|
||||||
@@ -440,7 +440,10 @@ func (s *Synchronizer) rollupSync(blockNum int64) (*rollupData, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
l2Txs := common.PoolL2TxsToL2Txs(poolL2Txs) // TODO: This is a big uggly, find a better way
|
l2Txs, err := common.PoolL2TxsToL2Txs(poolL2Txs) // TODO: This is a big uggly, find a better way
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
batchData.l2Txs = append(batchData.l2Txs, l2Txs...)
|
batchData.l2Txs = append(batchData.l2Txs, l2Txs...)
|
||||||
|
|
||||||
batchData.exitTree = exitInfo
|
batchData.exitTree = exitInfo
|
||||||
@@ -454,7 +457,7 @@ func (s *Synchronizer) rollupSync(blockNum int64) (*rollupData, error) {
|
|||||||
StateRoot: common.Hash(forgeBatchArgs.NewStRoot.Bytes()),
|
StateRoot: common.Hash(forgeBatchArgs.NewStRoot.Bytes()),
|
||||||
NumAccounts: numAccounts,
|
NumAccounts: numAccounts,
|
||||||
ExitRoot: common.Hash(forgeBatchArgs.NewExitRoot.Bytes()),
|
ExitRoot: common.Hash(forgeBatchArgs.NewExitRoot.Bytes()),
|
||||||
ForgeL1TxsNum: forgeL1TxsNum,
|
ForgeL1TxsNum: &forgeL1TxsNum,
|
||||||
// SlotNum: TODO: Calculate once ethClient provides the info // calculate from blockNum + ethClient Constants
|
// SlotNum: TODO: Calculate once ethClient provides the info // calculate from blockNum + ethClient Constants
|
||||||
}
|
}
|
||||||
batchData.batch = batch
|
batchData.batch = batch
|
||||||
@@ -573,7 +576,9 @@ func getL1UserTx(l1UserTxEvents []eth.RollupEventL1UserTx, blockNum int64) ([]*c
|
|||||||
|
|
||||||
for _, eL1UserTx := range l1UserTxEvents {
|
for _, eL1UserTx := range l1UserTxEvents {
|
||||||
// Fill aditional Tx fields
|
// Fill aditional Tx fields
|
||||||
eL1UserTx.L1Tx.ToForgeL1TxsNum = eL1UserTx.ToForgeL1TxsNum
|
toForge := new(int64)
|
||||||
|
*toForge = eL1UserTx.ToForgeL1TxsNum
|
||||||
|
eL1UserTx.L1Tx.ToForgeL1TxsNum = toForge
|
||||||
eL1UserTx.L1Tx.Position = eL1UserTx.Position
|
eL1UserTx.L1Tx.Position = eL1UserTx.Position
|
||||||
eL1UserTx.L1Tx.UserOrigin = true
|
eL1UserTx.L1Tx.UserOrigin = true
|
||||||
eL1UserTx.L1Tx.EthBlockNum = blockNum
|
eL1UserTx.L1Tx.EthBlockNum = blockNum
|
||||||
|
|||||||
@@ -566,7 +566,7 @@ func (c *Client) CtlAddL1TxUser(l1Tx *common.L1Tx) {
|
|||||||
r.State.MapL1TxQueue[r.State.LastToForgeL1TxsNum] = eth.NewQueueStruct()
|
r.State.MapL1TxQueue[r.State.LastToForgeL1TxsNum] = eth.NewQueueStruct()
|
||||||
queue = r.State.MapL1TxQueue[r.State.LastToForgeL1TxsNum]
|
queue = r.State.MapL1TxQueue[r.State.LastToForgeL1TxsNum]
|
||||||
}
|
}
|
||||||
if int64(l1Tx.FromIdx) > r.State.CurrentIdx {
|
if l1Tx.FromIdx != nil && int64(*l1Tx.FromIdx) > r.State.CurrentIdx {
|
||||||
panic("l1Tx.FromIdx > r.State.CurrentIdx")
|
panic("l1Tx.FromIdx > r.State.CurrentIdx")
|
||||||
}
|
}
|
||||||
if int(l1Tx.TokenID)+1 > len(r.State.TokenList) {
|
if int(l1Tx.TokenID)+1 > len(r.State.TokenList) {
|
||||||
|
|||||||
@@ -140,7 +140,7 @@ func TestClientRollup(t *testing.T) {
|
|||||||
for i := 0; i < N; i++ {
|
for i := 0; i < N; i++ {
|
||||||
keys[i] = genKeys(int64(i))
|
keys[i] = genKeys(int64(i))
|
||||||
l1UserTx := common.L1Tx{
|
l1UserTx := common.L1Tx{
|
||||||
FromIdx: common.Idx(0),
|
FromIdx: nil,
|
||||||
FromEthAddr: keys[i].Addr,
|
FromEthAddr: keys[i].Addr,
|
||||||
FromBJJ: keys[i].BJJPublicKey,
|
FromBJJ: keys[i].BJJPublicKey,
|
||||||
TokenID: common.TokenID(0),
|
TokenID: common.TokenID(0),
|
||||||
|
|||||||
@@ -74,7 +74,9 @@ func GenBatches(nBatches int, blocks []common.Block) []common.Batch {
|
|||||||
SlotNum: common.SlotNum(i),
|
SlotNum: common.SlotNum(i),
|
||||||
}
|
}
|
||||||
if i%2 == 0 {
|
if i%2 == 0 {
|
||||||
batch.ForgeL1TxsNum = int64(i)
|
toForge := new(int64)
|
||||||
|
*toForge = int64(i)
|
||||||
|
batch.ForgeL1TxsNum = toForge
|
||||||
}
|
}
|
||||||
batches = append(batches, batch)
|
batches = append(batches, batch)
|
||||||
}
|
}
|
||||||
@@ -155,7 +157,7 @@ func GenL1Txs(
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
tx = *nTx
|
tx = *nTx
|
||||||
if batches[i%len(batches)].ForgeL1TxsNum != 0 {
|
if batches[i%len(batches)].ForgeL1TxsNum != nil {
|
||||||
// Add already forged txs
|
// Add already forged txs
|
||||||
tx.BatchNum = &batches[i%len(batches)].BatchNum
|
tx.BatchNum = &batches[i%len(batches)].BatchNum
|
||||||
setFromToAndAppend(fromIdx, tx, i, nUserTxs, userAddr, accounts, &userTxs, &othersTxs)
|
setFromToAndAppend(fromIdx, tx, i, nUserTxs, userAddr, accounts, &userTxs, &othersTxs)
|
||||||
@@ -170,13 +172,13 @@ func GenL1Txs(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetNextToForgeNumAndBatch returns the next BatchNum and ForgeL1TxsNum to be added
|
// GetNextToForgeNumAndBatch returns the next BatchNum and ForgeL1TxsNum to be added
|
||||||
func GetNextToForgeNumAndBatch(batches []common.Batch) (common.BatchNum, int64) {
|
func GetNextToForgeNumAndBatch(batches []common.Batch) (common.BatchNum, *int64) {
|
||||||
batchNum := batches[len(batches)-1].BatchNum + 1
|
batchNum := batches[len(batches)-1].BatchNum + 1
|
||||||
var toForgeL1TxsNum int64
|
toForgeL1TxsNum := new(int64)
|
||||||
found := false
|
found := false
|
||||||
for i := len(batches) - 1; i >= 0; i-- {
|
for i := len(batches) - 1; i >= 0; i-- {
|
||||||
if batches[i].ForgeL1TxsNum != 0 {
|
if batches[i].ForgeL1TxsNum != nil {
|
||||||
toForgeL1TxsNum = batches[i].ForgeL1TxsNum + 1
|
*toForgeL1TxsNum = *batches[i].ForgeL1TxsNum + 1
|
||||||
found = true
|
found = true
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@@ -218,7 +220,9 @@ func setFromToAndAppend(
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tx.FromIdx = from.Idx
|
fromIdx := new(common.Idx)
|
||||||
|
*fromIdx = from.Idx
|
||||||
|
tx.FromIdx = fromIdx
|
||||||
tx.FromEthAddr = from.EthAddr
|
tx.FromEthAddr = from.EthAddr
|
||||||
tx.FromBJJ = from.PublicKey
|
tx.FromBJJ = from.PublicKey
|
||||||
tx.ToIdx = to.Idx
|
tx.ToIdx = to.Idx
|
||||||
@@ -232,7 +236,9 @@ func setFromToAndAppend(
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
tx.FromIdx = from.Idx
|
fromIdx := new(common.Idx)
|
||||||
|
*fromIdx = from.Idx
|
||||||
|
tx.FromIdx = fromIdx
|
||||||
tx.FromEthAddr = from.EthAddr
|
tx.FromEthAddr = from.EthAddr
|
||||||
tx.FromBJJ = from.PublicKey
|
tx.FromBJJ = from.PublicKey
|
||||||
tx.ToIdx = to.Idx
|
tx.ToIdx = to.Idx
|
||||||
@@ -435,9 +441,6 @@ func randomTxType(seed int) common.TxType {
|
|||||||
case 0:
|
case 0:
|
||||||
return common.TxTypeExit
|
return common.TxTypeExit
|
||||||
//nolint:gomnd
|
//nolint:gomnd
|
||||||
case 1:
|
|
||||||
return common.TxTypeWithdrawn
|
|
||||||
//nolint:gomnd
|
|
||||||
case 2:
|
case 2:
|
||||||
return common.TxTypeTransfer
|
return common.TxTypeTransfer
|
||||||
//nolint:gomnd
|
//nolint:gomnd
|
||||||
|
|||||||
37
test/l2db.go
37
test/l2db.go
@@ -53,10 +53,14 @@ func GenPoolTxs(n int, tokens []common.Token) []*common.PoolL2Tx {
|
|||||||
*usd = *token.USD * amountF
|
*usd = *token.USD * amountF
|
||||||
*absFee = fee.Percentage() * *usd
|
*absFee = fee.Percentage() * *usd
|
||||||
}
|
}
|
||||||
|
toIdx := new(common.Idx)
|
||||||
|
*toIdx = common.Idx(i + 1)
|
||||||
|
toEthAddr := new(ethCommon.Address)
|
||||||
|
*toEthAddr = ethCommon.BigToAddress(big.NewInt(int64(i)))
|
||||||
tx := &common.PoolL2Tx{
|
tx := &common.PoolL2Tx{
|
||||||
FromIdx: common.Idx(i),
|
FromIdx: common.Idx(i),
|
||||||
ToIdx: common.Idx(i + 1),
|
ToIdx: toIdx,
|
||||||
ToEthAddr: ethCommon.BigToAddress(big.NewInt(int64(i))),
|
ToEthAddr: toEthAddr,
|
||||||
ToBJJ: privK.Public(),
|
ToBJJ: privK.Public(),
|
||||||
TokenID: token.TokenID,
|
TokenID: token.TokenID,
|
||||||
Amount: big.NewInt(int64(i)),
|
Amount: big.NewInt(int64(i)),
|
||||||
@@ -67,7 +71,6 @@ func GenPoolTxs(n int, tokens []common.Token) []*common.PoolL2Tx {
|
|||||||
State: state,
|
State: state,
|
||||||
Signature: privK.SignPoseidon(big.NewInt(int64(i))),
|
Signature: privK.SignPoseidon(big.NewInt(int64(i))),
|
||||||
Timestamp: time.Now().UTC(),
|
Timestamp: time.Now().UTC(),
|
||||||
TokenSymbol: token.Symbol,
|
|
||||||
AbsoluteFee: absFee,
|
AbsoluteFee: absFee,
|
||||||
AbsoluteFeeUpdate: token.USDUpdate,
|
AbsoluteFeeUpdate: token.USDUpdate,
|
||||||
}
|
}
|
||||||
@@ -77,17 +80,31 @@ func GenPoolTxs(n int, tokens []common.Token) []*common.PoolL2Tx {
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
if i%2 == 0 { // Optional parameters: rq
|
if i%2 == 0 { // Optional parameters: rq
|
||||||
tx.RqFromIdx = common.Idx(i)
|
rqFromIdx := new(common.Idx)
|
||||||
tx.RqToIdx = common.Idx(i + 1)
|
*rqFromIdx = common.Idx(i)
|
||||||
tx.RqToEthAddr = ethCommon.BigToAddress(big.NewInt(int64(i)))
|
tx.RqFromIdx = rqFromIdx
|
||||||
|
rqToIdx := new(common.Idx)
|
||||||
|
*rqToIdx = common.Idx(i + 1)
|
||||||
|
tx.RqToIdx = rqToIdx
|
||||||
|
rqToEthAddr := new(ethCommon.Address)
|
||||||
|
*rqToEthAddr = ethCommon.BigToAddress(big.NewInt(int64(i)))
|
||||||
|
tx.RqToEthAddr = rqToEthAddr
|
||||||
tx.RqToBJJ = privK.Public()
|
tx.RqToBJJ = privK.Public()
|
||||||
tx.RqTokenID = common.TokenID(i)
|
rqTokenID := new(common.TokenID)
|
||||||
|
*rqTokenID = common.TokenID(i)
|
||||||
|
tx.RqTokenID = rqTokenID
|
||||||
tx.RqAmount = big.NewInt(int64(i))
|
tx.RqAmount = big.NewInt(int64(i))
|
||||||
tx.RqFee = common.FeeSelector(i)
|
rqFee := new(common.FeeSelector)
|
||||||
tx.RqNonce = uint64(i)
|
*rqFee = common.FeeSelector(i)
|
||||||
|
tx.RqFee = rqFee
|
||||||
|
rqNonce := new(uint64)
|
||||||
|
*rqNonce = uint64(i)
|
||||||
|
tx.RqNonce = rqNonce
|
||||||
}
|
}
|
||||||
if i%3 == 0 { // Optional parameters: things that get updated "a posteriori"
|
if i%3 == 0 { // Optional parameters: things that get updated "a posteriori"
|
||||||
tx.BatchNum = 489
|
batchNum := new(common.BatchNum)
|
||||||
|
*batchNum = 489
|
||||||
|
tx.BatchNum = batchNum
|
||||||
}
|
}
|
||||||
txs = append(txs, tx)
|
txs = append(txs, tx)
|
||||||
}
|
}
|
||||||
|
|||||||
19
test/txs.go
19
test/txs.go
@@ -96,11 +96,16 @@ func GenerateTestTxs(t *testing.T, instructions Instructions) ([][]*common.L1Tx,
|
|||||||
batchCoordinatorL1Txs = append(batchCoordinatorL1Txs, &tx)
|
batchCoordinatorL1Txs = append(batchCoordinatorL1Txs, &tx)
|
||||||
idx++
|
idx++
|
||||||
}
|
}
|
||||||
|
toIdx := new(common.Idx)
|
||||||
|
*toIdx = accounts[idxTokenIDToString(inst.To, inst.TokenID)].Idx
|
||||||
|
toEthAddr := new(ethCommon.Address)
|
||||||
|
*toEthAddr = accounts[idxTokenIDToString(inst.To, inst.TokenID)].Addr
|
||||||
|
rqToEthAddr := new(ethCommon.Address)
|
||||||
|
*rqToEthAddr = accounts[idxTokenIDToString(inst.To, inst.TokenID)].Addr
|
||||||
tx := common.PoolL2Tx{
|
tx := common.PoolL2Tx{
|
||||||
FromIdx: accounts[idxTokenIDToString(inst.From, inst.TokenID)].Idx,
|
FromIdx: accounts[idxTokenIDToString(inst.From, inst.TokenID)].Idx,
|
||||||
ToIdx: accounts[idxTokenIDToString(inst.To, inst.TokenID)].Idx,
|
ToIdx: toIdx,
|
||||||
ToEthAddr: accounts[idxTokenIDToString(inst.To, inst.TokenID)].Addr,
|
ToEthAddr: toEthAddr,
|
||||||
ToBJJ: accounts[idxTokenIDToString(inst.To, inst.TokenID)].BJJ.Public(),
|
ToBJJ: accounts[idxTokenIDToString(inst.To, inst.TokenID)].BJJ.Public(),
|
||||||
TokenID: inst.TokenID,
|
TokenID: inst.TokenID,
|
||||||
Amount: big.NewInt(int64(inst.Amount)),
|
Amount: big.NewInt(int64(inst.Amount)),
|
||||||
@@ -108,8 +113,8 @@ func GenerateTestTxs(t *testing.T, instructions Instructions) ([][]*common.L1Tx,
|
|||||||
Nonce: accounts[idxTokenIDToString(inst.From, inst.TokenID)].Nonce,
|
Nonce: accounts[idxTokenIDToString(inst.From, inst.TokenID)].Nonce,
|
||||||
State: common.PoolL2TxStatePending,
|
State: common.PoolL2TxStatePending,
|
||||||
Timestamp: time.Now(),
|
Timestamp: time.Now(),
|
||||||
BatchNum: common.BatchNum(0),
|
BatchNum: nil,
|
||||||
RqToEthAddr: accounts[idxTokenIDToString(inst.To, inst.TokenID)].Addr,
|
RqToEthAddr: rqToEthAddr,
|
||||||
RqToBJJ: accounts[idxTokenIDToString(inst.To, inst.TokenID)].BJJ.Public(),
|
RqToBJJ: accounts[idxTokenIDToString(inst.To, inst.TokenID)].BJJ.Public(),
|
||||||
Type: common.TxTypeTransfer,
|
Type: common.TxTypeTransfer,
|
||||||
}
|
}
|
||||||
@@ -130,8 +135,10 @@ func GenerateTestTxs(t *testing.T, instructions Instructions) ([][]*common.L1Tx,
|
|||||||
batchPoolL2Txs = append(batchPoolL2Txs, &tx)
|
batchPoolL2Txs = append(batchPoolL2Txs, &tx)
|
||||||
|
|
||||||
case common.TxTypeExit, common.TxTypeForceExit:
|
case common.TxTypeExit, common.TxTypeForceExit:
|
||||||
|
fromIdx := new(common.Idx)
|
||||||
|
*fromIdx = accounts[idxTokenIDToString(inst.From, inst.TokenID)].Idx
|
||||||
tx := common.L1Tx{
|
tx := common.L1Tx{
|
||||||
FromIdx: accounts[idxTokenIDToString(inst.From, inst.TokenID)].Idx,
|
FromIdx: fromIdx,
|
||||||
ToIdx: common.Idx(1), // as is an Exit
|
ToIdx: common.Idx(1), // as is an Exit
|
||||||
TokenID: inst.TokenID,
|
TokenID: inst.TokenID,
|
||||||
Amount: big.NewInt(int64(inst.Amount)),
|
Amount: big.NewInt(int64(inst.Amount)),
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ func TestGenerateTestL2Txs(t *testing.T) {
|
|||||||
// l2txs
|
// l2txs
|
||||||
assert.Equal(t, common.TxTypeTransfer, l2txs[0][0].Type)
|
assert.Equal(t, common.TxTypeTransfer, l2txs[0][0].Type)
|
||||||
assert.Equal(t, common.Idx(256), l2txs[0][0].FromIdx)
|
assert.Equal(t, common.Idx(256), l2txs[0][0].FromIdx)
|
||||||
assert.Equal(t, common.Idx(258), l2txs[0][0].ToIdx)
|
assert.Equal(t, common.Idx(258), *l2txs[0][0].ToIdx)
|
||||||
assert.Equal(t, accounts["B1"].BJJ.Public().String(), l2txs[0][0].ToBJJ.String())
|
assert.Equal(t, accounts["B1"].BJJ.Public().String(), l2txs[0][0].ToBJJ.String())
|
||||||
assert.Equal(t, accounts["B1"].Addr.Hex(), l2txs[0][0].ToEthAddr.Hex())
|
assert.Equal(t, accounts["B1"].Addr.Hex(), l2txs[0][0].ToEthAddr.Hex())
|
||||||
assert.Equal(t, common.Nonce(0), l2txs[0][0].Nonce)
|
assert.Equal(t, common.Nonce(0), l2txs[0][0].Nonce)
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ func (txsel *TxSelector) GetL2TxSelection(batchNum common.BatchNum) ([]*common.P
|
|||||||
// discard the txs that don't have an Account in the AccountDB
|
// discard the txs that don't have an Account in the AccountDB
|
||||||
var validTxs txs
|
var validTxs txs
|
||||||
for _, tx := range l2TxsRaw {
|
for _, tx := range l2TxsRaw {
|
||||||
_, err = txsel.localAccountsDB.GetAccount(tx.FromIdx)
|
_, err = txsel.localAccountsDB.GetAccount(&tx.FromIdx)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
// if FromIdx has an account into the AccountsDB
|
// if FromIdx has an account into the AccountsDB
|
||||||
validTxs = append(validTxs, tx)
|
validTxs = append(validTxs, tx)
|
||||||
@@ -120,16 +120,7 @@ func (txsel *TxSelector) GetL1L2TxSelection(batchNum common.BatchNum, l1Txs []*c
|
|||||||
// in AccountCreationAuthDB, if so, tx is used and L1CoordinatorTx of
|
// in AccountCreationAuthDB, if so, tx is used and L1CoordinatorTx of
|
||||||
// CreateAccountAndDeposit is created.
|
// CreateAccountAndDeposit is created.
|
||||||
for i := 0; i < len(l2TxsRaw); i++ {
|
for i := 0; i < len(l2TxsRaw); i++ {
|
||||||
if l2TxsRaw[i].ToIdx >= common.IdxUserThreshold {
|
if l2TxsRaw[i].ToIdx == nil {
|
||||||
_, err = txsel.localAccountsDB.GetAccount(l2TxsRaw[i].ToIdx)
|
|
||||||
if err != nil {
|
|
||||||
// tx not valid
|
|
||||||
log.Debugw("invalid L2Tx: ToIdx not found in StateDB", "ToIdx", l2TxsRaw[i].ToIdx)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
// Account found in the DB, include the l2Tx in the selection
|
|
||||||
validTxs = append(validTxs, l2TxsRaw[i])
|
|
||||||
} else if l2TxsRaw[i].ToIdx == common.Idx(0) {
|
|
||||||
if checkAlreadyPendingToCreate(l1CoordinatorTxs, l2TxsRaw[i].ToEthAddr, l2TxsRaw[i].ToBJJ) {
|
if checkAlreadyPendingToCreate(l1CoordinatorTxs, l2TxsRaw[i].ToEthAddr, l2TxsRaw[i].ToBJJ) {
|
||||||
// if L2Tx needs a new L1CoordinatorTx of CreateAccount type,
|
// if L2Tx needs a new L1CoordinatorTx of CreateAccount type,
|
||||||
// and a previous L2Tx in the current process already created
|
// and a previous L2Tx in the current process already created
|
||||||
@@ -215,10 +206,14 @@ func (txsel *TxSelector) GetL1L2TxSelection(batchNum common.BatchNum, l1Txs []*c
|
|||||||
// coordinator can create a new account without
|
// coordinator can create a new account without
|
||||||
// L1Authorization, as ToEthAddr==0xff
|
// L1Authorization, as ToEthAddr==0xff
|
||||||
// create L1CoordinatorTx for the accountCreation
|
// create L1CoordinatorTx for the accountCreation
|
||||||
|
if l2TxsRaw[i].ToEthAddr == nil {
|
||||||
|
log.Warn("l2TxsRaw[i].ToEthAddr should not be nil")
|
||||||
|
continue
|
||||||
|
}
|
||||||
l1CoordinatorTx := &common.L1Tx{
|
l1CoordinatorTx := &common.L1Tx{
|
||||||
Position: positionL1,
|
Position: positionL1,
|
||||||
UserOrigin: false,
|
UserOrigin: false,
|
||||||
FromEthAddr: l2TxsRaw[i].ToEthAddr,
|
FromEthAddr: *l2TxsRaw[i].ToEthAddr,
|
||||||
FromBJJ: l2TxsRaw[i].ToBJJ,
|
FromBJJ: l2TxsRaw[i].ToBJJ,
|
||||||
TokenID: l2TxsRaw[i].TokenID,
|
TokenID: l2TxsRaw[i].TokenID,
|
||||||
LoadAmount: big.NewInt(0),
|
LoadAmount: big.NewInt(0),
|
||||||
@@ -227,7 +222,16 @@ func (txsel *TxSelector) GetL1L2TxSelection(batchNum common.BatchNum, l1Txs []*c
|
|||||||
positionL1++
|
positionL1++
|
||||||
l1CoordinatorTxs = append(l1CoordinatorTxs, l1CoordinatorTx)
|
l1CoordinatorTxs = append(l1CoordinatorTxs, l1CoordinatorTx)
|
||||||
}
|
}
|
||||||
} else if l2TxsRaw[i].ToIdx == common.Idx(1) {
|
} else if *l2TxsRaw[i].ToIdx >= common.IdxUserThreshold {
|
||||||
|
_, err = txsel.localAccountsDB.GetAccount(l2TxsRaw[i].ToIdx)
|
||||||
|
if err != nil {
|
||||||
|
// tx not valid
|
||||||
|
log.Debugw("invalid L2Tx: ToIdx not found in StateDB", "ToIdx", l2TxsRaw[i].ToIdx)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// Account found in the DB, include the l2Tx in the selection
|
||||||
|
validTxs = append(validTxs, l2TxsRaw[i])
|
||||||
|
} else if *l2TxsRaw[i].ToIdx == common.Idx(1) { // nil already checked before
|
||||||
// valid txs (of Exit type)
|
// valid txs (of Exit type)
|
||||||
validTxs = append(validTxs, l2TxsRaw[i])
|
validTxs = append(validTxs, l2TxsRaw[i])
|
||||||
}
|
}
|
||||||
@@ -250,7 +254,11 @@ func (txsel *TxSelector) GetL1L2TxSelection(batchNum common.BatchNum, l1Txs []*c
|
|||||||
return l1Txs, l1CoordinatorTxs, l2Txs, nil
|
return l1Txs, l1CoordinatorTxs, l2Txs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkAlreadyPendingToCreate(l1CoordinatorTxs []*common.L1Tx, addr ethCommon.Address, bjj *babyjub.PublicKey) bool {
|
func checkAlreadyPendingToCreate(l1CoordinatorTxs []*common.L1Tx, addr *ethCommon.Address, bjj *babyjub.PublicKey) bool {
|
||||||
|
if addr == nil {
|
||||||
|
log.Warn("The provided addr is nil")
|
||||||
|
return false
|
||||||
|
}
|
||||||
for i := 0; i < len(l1CoordinatorTxs); i++ {
|
for i := 0; i < len(l1CoordinatorTxs); i++ {
|
||||||
if bytes.Equal(l1CoordinatorTxs[i].FromEthAddr.Bytes(), addr.Bytes()) {
|
if bytes.Equal(l1CoordinatorTxs[i].FromEthAddr.Bytes(), addr.Bytes()) {
|
||||||
if bjj == nil {
|
if bjj == nil {
|
||||||
|
|||||||
Reference in New Issue
Block a user