mirror of
https://github.com/arnaucube/hermez-node.git
synced 2026-02-07 03:16:45 +01:00
Integrate til into api
This commit is contained in:
@@ -36,6 +36,8 @@ func (t testAccountsResponse) GetPending() (pendingItems, lastItemID uint64) {
|
|||||||
|
|
||||||
func (t *testAccountsResponse) Len() int { return len(t.Accounts) }
|
func (t *testAccountsResponse) Len() int { return len(t.Accounts) }
|
||||||
|
|
||||||
|
func (t testAccountsResponse) New() Pendinger { return &testAccountsResponse{} }
|
||||||
|
|
||||||
func genTestAccounts(accounts []common.Account, tokens []historydb.TokenWithUSD) []testAccount {
|
func genTestAccounts(accounts []common.Account, tokens []historydb.TokenWithUSD) []testAccount {
|
||||||
tAccounts := []testAccount{}
|
tAccounts := []testAccount{}
|
||||||
for x, account := range accounts {
|
for x, account := range accounts {
|
||||||
|
|||||||
494
api/api_test.go
494
api/api_test.go
@@ -10,7 +10,6 @@ import (
|
|||||||
"math/big"
|
"math/big"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"sort"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
@@ -26,7 +25,6 @@ import (
|
|||||||
"github.com/hermeznetwork/hermez-node/log"
|
"github.com/hermeznetwork/hermez-node/log"
|
||||||
"github.com/hermeznetwork/hermez-node/test"
|
"github.com/hermeznetwork/hermez-node/test"
|
||||||
"github.com/hermeznetwork/hermez-node/test/til"
|
"github.com/hermeznetwork/hermez-node/test/til"
|
||||||
"github.com/iden3/go-iden3-crypto/babyjub"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Pendinger is an interface that allows getting last returned item ID and PendingItems to be used for building fromItem
|
// Pendinger is an interface that allows getting last returned item ID and PendingItems to be used for building fromItem
|
||||||
@@ -34,6 +32,7 @@ import (
|
|||||||
type Pendinger interface {
|
type Pendinger interface {
|
||||||
GetPending() (pendingItems, lastItemID uint64)
|
GetPending() (pendingItems, lastItemID uint64)
|
||||||
Len() int
|
Len() int
|
||||||
|
New() Pendinger
|
||||||
}
|
}
|
||||||
|
|
||||||
const apiPort = ":4010"
|
const apiPort = ":4010"
|
||||||
@@ -46,6 +45,11 @@ var SetBlockchain = `
|
|||||||
AddToken(2)
|
AddToken(2)
|
||||||
AddToken(3)
|
AddToken(3)
|
||||||
AddToken(4)
|
AddToken(4)
|
||||||
|
AddToken(5)
|
||||||
|
AddToken(6)
|
||||||
|
AddToken(7)
|
||||||
|
AddToken(8)
|
||||||
|
> block
|
||||||
|
|
||||||
// Coordinator accounts, Idxs: 256, 257
|
// Coordinator accounts, Idxs: 256, 257
|
||||||
CreateAccountCoordinator(0) Coord
|
CreateAccountCoordinator(0) Coord
|
||||||
@@ -54,8 +58,8 @@ var SetBlockchain = `
|
|||||||
// close Block:0, Batch:0
|
// close Block:0, Batch:0
|
||||||
> batch
|
> batch
|
||||||
|
|
||||||
CreateAccountDeposit(0) A: 500
|
CreateAccountDeposit(0) A: 111111111
|
||||||
CreateAccountDeposit(1) C: 0
|
CreateAccountDeposit(1) C: 222222222
|
||||||
CreateAccountCoordinator(0) C
|
CreateAccountCoordinator(0) C
|
||||||
|
|
||||||
// close Block:0, Batch:1
|
// close Block:0, Batch:1
|
||||||
@@ -64,7 +68,7 @@ var SetBlockchain = `
|
|||||||
// Coord(0): 0, Coord(1): 0
|
// Coord(0): 0, Coord(1): 0
|
||||||
// C(0): 0
|
// C(0): 0
|
||||||
|
|
||||||
CreateAccountDeposit(1) A: 500
|
CreateAccountDeposit(1) A: 333333333
|
||||||
|
|
||||||
// close Block:0, Batch:2
|
// close Block:0, Batch:2
|
||||||
> batchL1
|
> batchL1
|
||||||
@@ -72,45 +76,40 @@ var SetBlockchain = `
|
|||||||
// close Block:0, Batch:3
|
// close Block:0, Batch:3
|
||||||
> batchL1
|
> batchL1
|
||||||
|
|
||||||
CreateAccountDepositTransfer(0) B-A: 500, 100
|
CreateAccountDepositTransfer(0) B-A: 444444444, 1234444444 // to_eth_addr is NULL
|
||||||
|
|
||||||
// close Block:0, Batch:4
|
// close Block:0, Batch:4
|
||||||
> batchL1
|
> batchL1
|
||||||
CreateAccountDeposit(0) D: 800
|
CreateAccountDeposit(0) D: 555555555
|
||||||
|
|
||||||
// close Block:0, Batch:5
|
// close Block:0, Batch:5
|
||||||
> batchL1
|
> batchL1
|
||||||
|
|
||||||
CreateAccountCoordinator(1) B
|
CreateAccountCoordinator(1) B
|
||||||
|
|
||||||
Transfer(1) A-B: 200 (126)
|
Transfer(1) A-B: 111111 (2) // to_eth_addr is NULL
|
||||||
Transfer(0) B-C: 100 (126)
|
Transfer(0) B-C: 222222 (3)
|
||||||
|
|
||||||
// close Block:0, Batch:6
|
// close Block:0, Batch:6
|
||||||
> batchL1 // forge L1User{1}, forge L1Coord{2}, forge L2{2}
|
> batchL1 // forge L1User{1}, forge L1Coord{2}, forge L2{2}
|
||||||
|
|
||||||
Deposit(0) C: 500
|
Deposit(0) C: 666666666
|
||||||
DepositTransfer(0) C-D: 400, 100
|
DepositTransfer(0) C-D: 777777777, 123777777 // to_eth_addr is NULL
|
||||||
|
|
||||||
Transfer(0) A-B: 100 (126)
|
Transfer(0) A-B: 333333 (111)
|
||||||
Transfer(0) C-A: 50 (126)
|
Transfer(0) C-A: 444444 (222)
|
||||||
Transfer(1) B-C: 100 (126)
|
Transfer(1) B-C: 555555 (123)
|
||||||
Exit(0) A: 100 (126)
|
Exit(0) A: 666666 (44)
|
||||||
|
|
||||||
ForceTransfer(0) D-B: 200
|
ForceTransfer(0) D-B: 777777 // to_eth_addr is NULL
|
||||||
ForceExit(0) B: 100
|
ForceExit(0) B: 888888
|
||||||
|
|
||||||
// close Block:0, Batch:7
|
// close Block:0, Batch:7
|
||||||
> batchL1
|
> batchL1
|
||||||
> block
|
> block
|
||||||
|
|
||||||
AddToken(5)
|
Transfer(0) D-A: 999999 (77)
|
||||||
AddToken(6)
|
Transfer(0) B-D: 123123 (55)
|
||||||
AddToken(7)
|
|
||||||
AddToken(8)
|
|
||||||
|
|
||||||
Transfer(0) D-A: 300 (126)
|
|
||||||
Transfer(0) B-D: 100 (126)
|
|
||||||
|
|
||||||
// close Block:1, Batch:0
|
// close Block:1, Batch:0
|
||||||
> batchL1
|
> batchL1
|
||||||
@@ -166,13 +165,8 @@ type testCommon struct {
|
|||||||
fullBatches []testFullBatch
|
fullBatches []testFullBatch
|
||||||
coordinators []historydb.CoordinatorAPI
|
coordinators []historydb.CoordinatorAPI
|
||||||
accounts []testAccount
|
accounts []testAccount
|
||||||
usrAddr string
|
txs []testTx
|
||||||
usrBjj string
|
|
||||||
accs []common.Account
|
|
||||||
usrTxs []testTx
|
|
||||||
allTxs []testTx
|
|
||||||
exits []testExit
|
exits []testExit
|
||||||
usrExits []testExit
|
|
||||||
poolTxsToSend []testPoolTxSend
|
poolTxsToSend []testPoolTxSend
|
||||||
poolTxsToReceive []testPoolTxReceive
|
poolTxsToReceive []testPoolTxReceive
|
||||||
auths []testAuth
|
auths []testAuth
|
||||||
@@ -192,16 +186,6 @@ var api *API
|
|||||||
// emulating the task of the synchronizer in order to have data to be returned
|
// emulating the task of the synchronizer in order to have data to be returned
|
||||||
// by the API endpoints that will be tested
|
// by the API endpoints that will be tested
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
/*
|
|
||||||
til update considerations:
|
|
||||||
1. Two instructions sets should be enough (one for L2 another for historydb)
|
|
||||||
2. FillBlocksExtra function must be used, there is a coment on top of the function that explains which data is setted
|
|
||||||
3. Some data will not be generated by til nor FillBlocksExtra, test.GenXXX will still be required to cover this cases
|
|
||||||
4. Most of the historydb inserts should be replaced with nBlocks calls to AddBlockSCData
|
|
||||||
5. When defining til instructions, there is no need to have 100s of entries for each table, but it's interesting to
|
|
||||||
cover all different cases (for instance all tx types)
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Initializations
|
// Initializations
|
||||||
// Swagger
|
// Swagger
|
||||||
router := swagger.NewRouter().WithSwaggerFromFile("./swagger.yml")
|
router := swagger.NewRouter().WithSwaggerFromFile("./swagger.yml")
|
||||||
@@ -260,171 +244,117 @@ func TestMain(m *testing.M) {
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
// Fill HistoryDB and StateDB with fake data
|
// Reset DB
|
||||||
// Gen blocks and add them to DB
|
test.WipeDB(api.h.DB())
|
||||||
const nBlocks = 5
|
|
||||||
// TODO: UPDATE with til
|
|
||||||
blocks := test.GenBlocks(1, nBlocks+1)
|
|
||||||
err = api.h.AddBlocks(blocks)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
lastBlockNum := blocks[nBlocks-1].EthBlockNum
|
|
||||||
|
|
||||||
// Gen tokens and add them to DB
|
// Genratre blockchain data with til
|
||||||
const nTokens = 10
|
tcc := til.NewContext(common.RollupConstMaxL1UserTx)
|
||||||
// TODO: UPDATE with til
|
tilCfgExtra := til.ConfigExtra{
|
||||||
tokens, ethToken := test.GenTokens(nTokens, blocks)
|
BootCoordAddr: ethCommon.HexToAddress("0xE39fEc6224708f0772D2A74fd3f9055A90E0A9f2"),
|
||||||
err = api.h.AddTokens(tokens)
|
CoordUser: "Coord",
|
||||||
|
}
|
||||||
|
blocksData, err := tcc.GenerateBlocks(SetBlockchain)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
tokens = append([]common.Token{ethToken}, tokens...)
|
err = tcc.FillBlocksExtra(blocksData, &tilCfgExtra)
|
||||||
// Set token value
|
if err != nil {
|
||||||
tokensUSD := []historydb.TokenWithUSD{}
|
panic(err)
|
||||||
for i, tkn := range tokens {
|
}
|
||||||
token := historydb.TokenWithUSD{
|
AddAditionalInformation(blocksData)
|
||||||
TokenID: tkn.TokenID,
|
// Generate L2 Txs with til
|
||||||
EthBlockNum: tkn.EthBlockNum,
|
commonPoolTxs, err := tcc.GeneratePoolL2Txs(til.SetPoolL2MinimumFlow0)
|
||||||
EthAddr: tkn.EthAddr,
|
if err != nil {
|
||||||
Name: tkn.Name,
|
panic(err)
|
||||||
Symbol: tkn.Symbol,
|
}
|
||||||
Decimals: tkn.Decimals,
|
|
||||||
|
// Extract til generated data, and add it to HistoryDB
|
||||||
|
var commonBlocks []common.Block
|
||||||
|
var commonBatches []common.Batch
|
||||||
|
var commonAccounts []common.Account
|
||||||
|
var commonExitTree []common.ExitInfo
|
||||||
|
var commonL1Txs []common.L1Tx
|
||||||
|
var commonL2Txs []common.L2Tx
|
||||||
|
// Add ETH token at the beginning of the array
|
||||||
|
testTokens := []historydb.TokenWithUSD{}
|
||||||
|
ethUSD := float64(500)
|
||||||
|
ethNow := time.Now()
|
||||||
|
testTokens = append(testTokens, historydb.TokenWithUSD{
|
||||||
|
TokenID: test.EthToken.TokenID,
|
||||||
|
EthBlockNum: test.EthToken.EthBlockNum,
|
||||||
|
EthAddr: test.EthToken.EthAddr,
|
||||||
|
Name: test.EthToken.Name,
|
||||||
|
Symbol: test.EthToken.Symbol,
|
||||||
|
Decimals: test.EthToken.Decimals,
|
||||||
|
USD: ðUSD,
|
||||||
|
USDUpdate: ðNow,
|
||||||
|
})
|
||||||
|
err = api.h.UpdateTokenValue(test.EthToken.Symbol, ethUSD)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
for _, block := range blocksData {
|
||||||
|
// Insert block into HistoryDB
|
||||||
|
if err := api.h.AddBlockSCData(&block); err != nil { //nolint:gosec block is used as read only in the function
|
||||||
|
panic(err)
|
||||||
}
|
}
|
||||||
// Set value of 50% of the tokens
|
// Extract data
|
||||||
if i%2 != 0 {
|
commonBlocks = append(commonBlocks, block.Block)
|
||||||
value := float64(i) * 1.234567
|
for i, tkn := range block.Rollup.AddedTokens {
|
||||||
|
token := historydb.TokenWithUSD{
|
||||||
|
TokenID: tkn.TokenID,
|
||||||
|
EthBlockNum: tkn.EthBlockNum,
|
||||||
|
EthAddr: tkn.EthAddr,
|
||||||
|
Name: tkn.Name,
|
||||||
|
Symbol: tkn.Symbol,
|
||||||
|
Decimals: tkn.Decimals,
|
||||||
|
}
|
||||||
|
value := float64(i + 423)
|
||||||
now := time.Now().UTC()
|
now := time.Now().UTC()
|
||||||
token.USD = &value
|
token.USD = &value
|
||||||
token.USDUpdate = &now
|
token.USDUpdate = &now
|
||||||
|
// Set value in DB
|
||||||
err = api.h.UpdateTokenValue(token.Symbol, value)
|
err = api.h.UpdateTokenValue(token.Symbol, value)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
testTokens = append(testTokens, token)
|
||||||
|
}
|
||||||
|
// Set USD value for tokens in DB
|
||||||
|
commonL1Txs = append(commonL1Txs, block.Rollup.L1UserTxs...)
|
||||||
|
for _, batch := range block.Rollup.Batches {
|
||||||
|
commonL2Txs = append(commonL2Txs, batch.L2Txs...)
|
||||||
|
commonAccounts = append(commonAccounts, batch.CreatedAccounts...)
|
||||||
|
commonBatches = append(commonBatches, batch.Batch)
|
||||||
|
commonExitTree = append(commonExitTree, batch.ExitTree...)
|
||||||
|
commonL1Txs = append(commonL1Txs, batch.L1CoordinatorTxs...)
|
||||||
}
|
}
|
||||||
tokensUSD = append(tokensUSD, token)
|
|
||||||
}
|
|
||||||
// Gen batches and add them to DB
|
|
||||||
const nBatches = 10
|
|
||||||
// TODO: UPDATE with til
|
|
||||||
batches := test.GenBatches(nBatches, blocks)
|
|
||||||
err = api.h.AddBatches(batches)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
// Gen accounts and add them to HistoryDB and StateDB
|
|
||||||
const totalAccounts = 40
|
|
||||||
const userAccounts = 4
|
|
||||||
usrAddr := ethCommon.BigToAddress(big.NewInt(4896847))
|
|
||||||
privK := babyjub.NewRandPrivKey()
|
|
||||||
usrBjj := privK.Public()
|
|
||||||
// TODO: UPDATE with til
|
|
||||||
accs := test.GenAccounts(totalAccounts, userAccounts, tokens, &usrAddr, usrBjj, batches)
|
|
||||||
err = api.h.AddAccounts(accs)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// api.s.CreateAccount called in new part with til
|
// lastBlockNum2 := blocksData[len(blocksData)-1].Block.EthBlockNum
|
||||||
/* for i := 0; i < len(accs); i++ {
|
|
||||||
if _, err := api.s.CreateAccount(accs[i].Idx, &accs[i]); err != nil {
|
// Add accounts to StateDB
|
||||||
|
for i := 0; i < len(commonAccounts); i++ {
|
||||||
|
if _, err := api.s.CreateAccount(commonAccounts[i].Idx, &commonAccounts[i]); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
} */
|
|
||||||
|
|
||||||
// helper to vinculate user related resources
|
|
||||||
usrIdxs := []string{}
|
|
||||||
for _, acc := range accs {
|
|
||||||
if acc.EthAddr == usrAddr || acc.PublicKey == usrBjj {
|
|
||||||
for _, token := range tokens {
|
|
||||||
if token.TokenID == acc.TokenID {
|
|
||||||
usrIdxs = append(usrIdxs, idxToHez(acc.Idx, token.Symbol))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Gen exits and add them to DB
|
|
||||||
const totalExits = 40
|
|
||||||
// TODO: UPDATE with til
|
|
||||||
exits := test.GenExitTree(totalExits, batches, accs, blocks)
|
|
||||||
err = api.h.AddExitTree(exits)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// L1 and L2 txs need to be sorted in a combined way
|
// Generate Coordinators and add them to HistoryDB
|
||||||
// Gen L1Txs
|
|
||||||
const totalL1Txs = 40
|
|
||||||
const userL1Txs = 4
|
|
||||||
// TODO: UPDATE with til
|
|
||||||
usrL1Txs, othrL1Txs := test.GenL1Txs(256, totalL1Txs, userL1Txs, &usrAddr, accs, tokens, blocks, batches)
|
|
||||||
// Gen L2Txs
|
|
||||||
const totalL2Txs = 20
|
|
||||||
const userL2Txs = 4
|
|
||||||
// TODO: UPDATE with til
|
|
||||||
usrL2Txs, othrL2Txs := test.GenL2Txs(256+totalL1Txs, totalL2Txs, userL2Txs, &usrAddr, accs, tokens, blocks, batches)
|
|
||||||
// Sort txs
|
|
||||||
sortedTxs := []txSortFielder{}
|
|
||||||
for i := 0; i < len(usrL1Txs); i++ {
|
|
||||||
wL1 := wrappedL1(usrL1Txs[i])
|
|
||||||
sortedTxs = append(sortedTxs, &wL1)
|
|
||||||
}
|
|
||||||
for i := 0; i < len(othrL1Txs); i++ {
|
|
||||||
wL1 := wrappedL1(othrL1Txs[i])
|
|
||||||
sortedTxs = append(sortedTxs, &wL1)
|
|
||||||
}
|
|
||||||
for i := 0; i < len(usrL2Txs); i++ {
|
|
||||||
wL2 := wrappedL2(usrL2Txs[i])
|
|
||||||
sortedTxs = append(sortedTxs, &wL2)
|
|
||||||
}
|
|
||||||
for i := 0; i < len(othrL2Txs); i++ {
|
|
||||||
wL2 := wrappedL2(othrL2Txs[i])
|
|
||||||
sortedTxs = append(sortedTxs, &wL2)
|
|
||||||
}
|
|
||||||
sort.Sort(txsSort(sortedTxs))
|
|
||||||
// Store txs to DB
|
|
||||||
for _, genericTx := range sortedTxs {
|
|
||||||
l1 := genericTx.L1()
|
|
||||||
l2 := genericTx.L2()
|
|
||||||
if l1 != nil {
|
|
||||||
err = api.h.AddL1Txs([]common.L1Tx{*l1})
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
} else if l2 != nil {
|
|
||||||
err = api.h.AddL2Txs([]common.L2Tx{*l2})
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
panic("should be l1 or l2")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Coordinators
|
|
||||||
const nCoords = 10
|
const nCoords = 10
|
||||||
coords := test.GenCoordinators(nCoords, blocks)
|
commonCoords := test.GenCoordinators(nCoords, commonBlocks)
|
||||||
err = api.h.AddCoordinators(coords)
|
if err := api.h.AddCoordinators(commonCoords); err != nil {
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
fromItem := uint(0)
|
|
||||||
limit := uint(99999)
|
|
||||||
coordinators, _, err := api.h.GetCoordinatorsAPI(&fromItem, &limit, historydb.OrderAsc)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bids
|
// Generate Bids and add them to HistoryDB
|
||||||
const nBids = 20
|
const nBids = 20
|
||||||
bids := test.GenBids(nBids, blocks, coords)
|
commonBids := test.GenBids(nBids, commonBlocks, commonCoords)
|
||||||
err = api.h.AddBids(bids)
|
if err = api.h.AddBids(commonBids); err != nil {
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
testBids := genTestBids(blocks, coordinators, bids)
|
|
||||||
|
|
||||||
// Vars
|
// Generate SC vars and add them to HistoryDB (if needed)
|
||||||
var defaultSlotSetBid [6]*big.Int = [6]*big.Int{big.NewInt(10), big.NewInt(10), big.NewInt(10), big.NewInt(10), big.NewInt(10), big.NewInt(10)}
|
var defaultSlotSetBid [6]*big.Int = [6]*big.Int{big.NewInt(10), big.NewInt(10), big.NewInt(10), big.NewInt(10), big.NewInt(10), big.NewInt(10)}
|
||||||
auctionVars := common.AuctionVariables{
|
auctionVars := common.AuctionVariables{
|
||||||
EthBlockNum: int64(2),
|
EthBlockNum: int64(2),
|
||||||
@@ -453,189 +383,37 @@ func TestMain(m *testing.M) {
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
const nSlots = 20
|
// Generate test data, as expected to be received/sended from/to the API
|
||||||
|
testCoords := genTestCoordinators(commonCoords)
|
||||||
// Set testCommon
|
testBids := genTestBids(commonBlocks, testCoords, commonBids)
|
||||||
usrTxs, allTxs := genTestTxs(sortedTxs, usrIdxs, accs, tokensUSD, blocks)
|
testExits := genTestExits(commonExitTree, testTokens, commonAccounts)
|
||||||
poolTxsToSend, poolTxsToReceive := genTestPoolTx(accs, []babyjub.PrivateKey{privK}, tokensUSD) // NOTE: pool txs are not inserted to the DB here. In the test they will be posted and getted.
|
testTxs := genTestTxs(commonL1Txs, commonL2Txs, commonAccounts, testTokens, commonBlocks)
|
||||||
testBatches, fullBatches := genTestBatches(blocks, batches, allTxs)
|
testBatches, testFullBatches := genTestBatches(commonBlocks, commonBatches, testTxs)
|
||||||
/* usrExits, allExits*/ _, _ = genTestExits(exits, tokensUSD, accs, usrIdxs)
|
poolTxsToSend, poolTxsToReceive := genTestPoolTxs(commonPoolTxs, testTokens, commonAccounts)
|
||||||
|
|
||||||
// NEW WITH TIL
|
|
||||||
// Reset DB
|
|
||||||
test.WipeDB(api.h.DB())
|
|
||||||
|
|
||||||
tcc := til.NewContext(common.RollupConstMaxL1UserTx)
|
|
||||||
tilCfgExtra := til.ConfigExtra{
|
|
||||||
BootCoordAddr: ethCommon.HexToAddress("0xE39fEc6224708f0772D2A74fd3f9055A90E0A9f2"),
|
|
||||||
CoordUser: "A",
|
|
||||||
}
|
|
||||||
blocksData, err := tcc.GenerateBlocks(SetBlockchain)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
err = tcc.FillBlocksExtra(blocksData, &tilCfgExtra)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
// poolL2Txs, err := tcc.GeneratePoolL2Txs(til.SetPoolL2MinimumFlow0)
|
|
||||||
|
|
||||||
var blocksTc []common.Block
|
|
||||||
var batchesTc []common.Batch
|
|
||||||
var tokensTc []common.Token
|
|
||||||
var accountsTc []common.Account
|
|
||||||
var exitTreeTc []common.ExitInfo
|
|
||||||
var allL1TxsTc []common.L1Tx
|
|
||||||
var allL2TxsTc []common.L2Tx
|
|
||||||
|
|
||||||
AddAditionalInformation(blocksData)
|
|
||||||
|
|
||||||
for _, block := range blocksData {
|
|
||||||
// Insert block
|
|
||||||
err := api.h.AddBlockSCData(&block)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
blocksTc = append(blocksTc, block.Block)
|
|
||||||
tokensTc = append(tokensTc, block.Rollup.AddedTokens...)
|
|
||||||
allL1TxsTc = append(allL1TxsTc, block.Rollup.L1UserTxs...)
|
|
||||||
for _, batch := range block.Rollup.Batches {
|
|
||||||
allL2TxsTc = append(allL2TxsTc, batch.L2Txs...)
|
|
||||||
accountsTc = append(accountsTc, batch.CreatedAccounts...)
|
|
||||||
batchesTc = append(batchesTc, batch.Batch)
|
|
||||||
exitTreeTc = append(exitTreeTc, batch.ExitTree...)
|
|
||||||
allL1TxsTc = append(allL1TxsTc, batch.L1CoordinatorTxs...)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// lastBlockNum2 := blocksData[len(blocksData)-1].Block.EthBlockNum
|
|
||||||
|
|
||||||
tokensTc = append([]common.Token{ethToken}, tokensTc...)
|
|
||||||
tokensUSDTc := []historydb.TokenWithUSD{}
|
|
||||||
for i, tkn := range tokensTc {
|
|
||||||
token := historydb.TokenWithUSD{
|
|
||||||
TokenID: tkn.TokenID,
|
|
||||||
EthBlockNum: tkn.EthBlockNum,
|
|
||||||
EthAddr: tkn.EthAddr,
|
|
||||||
Name: tkn.Name,
|
|
||||||
Symbol: tkn.Symbol,
|
|
||||||
Decimals: tkn.Decimals,
|
|
||||||
}
|
|
||||||
// Set value of 50% of the tokens
|
|
||||||
if i%2 != 0 {
|
|
||||||
value := float64(i) * 1.234567
|
|
||||||
now := time.Now().UTC()
|
|
||||||
token.USD = &value
|
|
||||||
token.USDUpdate = &now
|
|
||||||
err = api.h.UpdateTokenValue(token.Symbol, value)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tokensUSDTc = append(tokensUSDTc, token)
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 0; i < len(accountsTc); i++ {
|
|
||||||
if _, err := api.s.CreateAccount(accountsTc[i].Idx, &accountsTc[i]); err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
usrIdxsTc := []string{}
|
|
||||||
for _, acc := range accountsTc {
|
|
||||||
for _, token := range tokensTc {
|
|
||||||
if token.TokenID == acc.TokenID {
|
|
||||||
usrIdxsTc = append(usrIdxsTc, idxToHez(acc.Idx, token.Symbol))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sort txs
|
|
||||||
sortedTxsTc := []txSortFielder{}
|
|
||||||
for i := 0; i < len(allL1TxsTc); i++ {
|
|
||||||
wL1 := wrappedL1(allL1TxsTc[i])
|
|
||||||
sortedTxsTc = append(sortedTxsTc, &wL1)
|
|
||||||
}
|
|
||||||
for i := 0; i < len(allL2TxsTc); i++ {
|
|
||||||
wL2 := wrappedL2(allL2TxsTc[i])
|
|
||||||
sortedTxsTc = append(sortedTxsTc, &wL2)
|
|
||||||
}
|
|
||||||
sort.Sort(txsSort(sortedTxsTc))
|
|
||||||
|
|
||||||
// Coordinators
|
|
||||||
const nCoordsTc = 10
|
|
||||||
coordsTc := test.GenCoordinators(nCoordsTc, blocksTc)
|
|
||||||
err = api.h.AddCoordinators(coordsTc)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
coordinatorsTc, _, err := api.h.GetCoordinatorsAPI(&fromItem, &limit, historydb.OrderAsc)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bids
|
|
||||||
const nBidsTc = 20
|
|
||||||
bidsTc := test.GenBids(nBidsTc, blocksTc, coordsTc)
|
|
||||||
err = api.h.AddBids(bidsTc)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
testBidsTc := genTestBids(blocksTc, coordinatorsTc, bidsTc)
|
|
||||||
usrExitsTc, allExitsTc := genTestExits(exitTreeTc, tokensUSDTc, accountsTc, usrIdxsTc)
|
|
||||||
_, allTxsTc := genTestTxs(sortedTxsTc, usrIdxsTc, accountsTc, tokensUSDTc, blocksTc)
|
|
||||||
fmt.Println(allTxsTc)
|
|
||||||
// allTxsTc == allTxs
|
|
||||||
// testBatchesTc, fullBatchesTc := genTestBatches(blocksTc, batchesTc, allTxsTc)
|
|
||||||
|
|
||||||
tc = testCommon{
|
tc = testCommon{
|
||||||
blocks: blocksTc,
|
blocks: commonBlocks,
|
||||||
tokens: tokensUSDTc,
|
tokens: testTokens,
|
||||||
batches: testBatches,
|
batches: testBatches,
|
||||||
fullBatches: fullBatches,
|
fullBatches: testFullBatches,
|
||||||
coordinators: coordinatorsTc,
|
coordinators: testCoords,
|
||||||
accounts: genTestAccounts(accountsTc, tokensUSDTc),
|
accounts: genTestAccounts(commonAccounts, testTokens),
|
||||||
usrAddr: ethAddrToHez(usrAddr),
|
txs: testTxs,
|
||||||
usrBjj: bjjToString(usrBjj),
|
exits: testExits,
|
||||||
accs: accountsTc,
|
|
||||||
usrTxs: usrTxs,
|
|
||||||
allTxs: allTxs,
|
|
||||||
exits: allExitsTc,
|
|
||||||
usrExits: usrExitsTc,
|
|
||||||
poolTxsToSend: poolTxsToSend,
|
|
||||||
poolTxsToReceive: poolTxsToReceive,
|
|
||||||
auths: genTestAuths(test.GenAuths(5)),
|
|
||||||
router: router,
|
|
||||||
bids: testBidsTc,
|
|
||||||
slots: api.genTestSlots(nSlots, lastBlockNum, testBids, auctionVars),
|
|
||||||
auctionVars: auctionVars,
|
|
||||||
rollupVars: rollupVars,
|
|
||||||
wdelayerVars: wdelayerVars,
|
|
||||||
}
|
|
||||||
|
|
||||||
/* tc = testCommon{
|
|
||||||
blocks: blocks,
|
|
||||||
tokens: tokensUSD,
|
|
||||||
batches: testBatches,
|
|
||||||
fullBatches: fullBatches,
|
|
||||||
coordinators: coordinators,
|
|
||||||
accounts: genTestAccounts(accs, tokensUSD),
|
|
||||||
usrAddr: ethAddrToHez(usrAddr),
|
|
||||||
usrBjj: bjjToString(usrBjj),
|
|
||||||
accs: accs,
|
|
||||||
usrTxs: usrTxs,
|
|
||||||
allTxs: allTxs,
|
|
||||||
exits: allExits,
|
|
||||||
usrExits: usrExits,
|
|
||||||
poolTxsToSend: poolTxsToSend,
|
poolTxsToSend: poolTxsToSend,
|
||||||
poolTxsToReceive: poolTxsToReceive,
|
poolTxsToReceive: poolTxsToReceive,
|
||||||
auths: genTestAuths(test.GenAuths(5)),
|
auths: genTestAuths(test.GenAuths(5)),
|
||||||
router: router,
|
router: router,
|
||||||
bids: testBids,
|
bids: testBids,
|
||||||
slots: api.genTestSlots(nSlots, lastBlockNum, testBids, auctionVars),
|
slots: api.genTestSlots(
|
||||||
auctionVars: auctionVars,
|
20,
|
||||||
rollupVars: rollupVars,
|
commonBlocks[len(commonBlocks)-1].EthBlockNum,
|
||||||
wdelayerVars: wdelayerVars,
|
testBids,
|
||||||
} */
|
auctionVars,
|
||||||
|
),
|
||||||
|
auctionVars: auctionVars,
|
||||||
|
rollupVars: rollupVars,
|
||||||
|
wdelayerVars: wdelayerVars,
|
||||||
|
}
|
||||||
|
|
||||||
// Fake server
|
// Fake server
|
||||||
if os.Getenv("FAKE_SERVER") == "yes" {
|
if os.Getenv("FAKE_SERVER") == "yes" {
|
||||||
@@ -682,7 +460,11 @@ func doGoodReqPaginated(
|
|||||||
iterPath += strconv.Itoa(int(next))
|
iterPath += strconv.Itoa(int(next))
|
||||||
}
|
}
|
||||||
// Call API to get this iteration items
|
// Call API to get this iteration items
|
||||||
if err := doGoodReq("GET", iterPath+"&order="+order, nil, iterStruct); err != nil {
|
iterStruct = iterStruct.New()
|
||||||
|
if err := doGoodReq(
|
||||||
|
"GET", iterPath+"&order="+order, nil,
|
||||||
|
iterStruct,
|
||||||
|
); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
appendIter(iterStruct)
|
appendIter(iterStruct)
|
||||||
@@ -758,8 +540,10 @@ func doGoodReq(method, path string, reqBody io.Reader, returnStruct interface{})
|
|||||||
// Unmarshal body into return struct
|
// Unmarshal body into return struct
|
||||||
if err := json.Unmarshal(body, returnStruct); err != nil {
|
if err := json.Unmarshal(body, returnStruct); err != nil {
|
||||||
log.Error("invalid json: " + string(body))
|
log.Error("invalid json: " + string(body))
|
||||||
|
log.Error(err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
// log.Info(string(body))
|
||||||
// Validate response against swagger spec
|
// Validate response against swagger spec
|
||||||
responseValidationInput := &swagger.ResponseValidationInput{
|
responseValidationInput := &swagger.ResponseValidationInput{
|
||||||
RequestValidationInput: requestValidationInput,
|
RequestValidationInput: requestValidationInput,
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package api
|
package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"database/sql"
|
||||||
"errors"
|
"errors"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
@@ -109,7 +110,7 @@ func (a *API) getFullBatch(c *gin.Context) {
|
|||||||
txs, _, err := a.h.GetHistoryTxs(
|
txs, _, err := a.h.GetHistoryTxs(
|
||||||
nil, nil, nil, nil, batchNum, nil, nil, &maxTxsPerBatch, historydb.OrderAsc,
|
nil, nil, nil, nil, batchNum, nil, nil, &maxTxsPerBatch, historydb.OrderAsc,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil && err != sql.ErrNoRows {
|
||||||
retSQLErr(err, c)
|
retSQLErr(err, c)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,6 +43,8 @@ func (t testBatchesResponse) Len() int {
|
|||||||
return len(t.Batches)
|
return len(t.Batches)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t testBatchesResponse) New() Pendinger { return &testBatchesResponse{} }
|
||||||
|
|
||||||
type testFullBatch struct {
|
type testFullBatch struct {
|
||||||
Batch testBatch `json:"batch"`
|
Batch testBatch `json:"batch"`
|
||||||
Txs []testTx `json:"transactions"`
|
Txs []testTx `json:"transactions"`
|
||||||
@@ -54,11 +56,11 @@ func genTestBatches(
|
|||||||
txs []testTx,
|
txs []testTx,
|
||||||
) ([]testBatch, []testFullBatch) {
|
) ([]testBatch, []testFullBatch) {
|
||||||
tBatches := []testBatch{}
|
tBatches := []testBatch{}
|
||||||
for _, cBatch := range cBatches {
|
for i := 0; i < len(cBatches); i++ {
|
||||||
block := common.Block{}
|
block := common.Block{}
|
||||||
found := false
|
found := false
|
||||||
for _, b := range blocks {
|
for _, b := range blocks {
|
||||||
if b.EthBlockNum == cBatch.EthBlockNum {
|
if b.EthBlockNum == cBatches[i].EthBlockNum {
|
||||||
block = b
|
block = b
|
||||||
found = true
|
found = true
|
||||||
break
|
break
|
||||||
@@ -68,22 +70,22 @@ func genTestBatches(
|
|||||||
panic("block not found")
|
panic("block not found")
|
||||||
}
|
}
|
||||||
collectedFees := make(map[common.TokenID]string)
|
collectedFees := make(map[common.TokenID]string)
|
||||||
for k, v := range cBatch.CollectedFees {
|
for k, v := range cBatches[i].CollectedFees {
|
||||||
collectedFees[k] = v.String()
|
collectedFees[k] = v.String()
|
||||||
}
|
}
|
||||||
tBatch := testBatch{
|
tBatch := testBatch{
|
||||||
BatchNum: cBatch.BatchNum,
|
BatchNum: cBatches[i].BatchNum,
|
||||||
EthBlockNum: cBatch.EthBlockNum,
|
EthBlockNum: cBatches[i].EthBlockNum,
|
||||||
EthBlockHash: block.Hash,
|
EthBlockHash: block.Hash,
|
||||||
Timestamp: block.Timestamp,
|
Timestamp: block.Timestamp,
|
||||||
ForgerAddr: cBatch.ForgerAddr,
|
ForgerAddr: cBatches[i].ForgerAddr,
|
||||||
CollectedFees: collectedFees,
|
CollectedFees: collectedFees,
|
||||||
TotalFeesUSD: cBatch.TotalFeesUSD,
|
TotalFeesUSD: cBatches[i].TotalFeesUSD,
|
||||||
StateRoot: cBatch.StateRoot.String(),
|
StateRoot: cBatches[i].StateRoot.String(),
|
||||||
NumAccounts: cBatch.NumAccounts,
|
NumAccounts: cBatches[i].NumAccounts,
|
||||||
ExitRoot: cBatch.ExitRoot.String(),
|
ExitRoot: cBatches[i].ExitRoot.String(),
|
||||||
ForgeL1TxsNum: cBatch.ForgeL1TxsNum,
|
ForgeL1TxsNum: cBatches[i].ForgeL1TxsNum,
|
||||||
SlotNum: cBatch.SlotNum,
|
SlotNum: cBatches[i].SlotNum,
|
||||||
}
|
}
|
||||||
tBatches = append(tBatches, tBatch)
|
tBatches = append(tBatches, tBatch)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,6 +38,8 @@ func (t testBidsResponse) Len() int {
|
|||||||
return len(t.Bids)
|
return len(t.Bids)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t testBidsResponse) New() Pendinger { return &testBidsResponse{} }
|
||||||
|
|
||||||
func genTestBids(blocks []common.Block, coordinators []historydb.CoordinatorAPI, bids []common.Bid) []testBid {
|
func genTestBids(blocks []common.Block, coordinators []historydb.CoordinatorAPI, bids []common.Bid) []testBid {
|
||||||
tBids := []testBid{}
|
tBids := []testBid{}
|
||||||
for _, bid := range bids {
|
for _, bid := range bids {
|
||||||
@@ -113,7 +115,7 @@ func TestGetBids(t *testing.T) {
|
|||||||
// Mixed filters
|
// Mixed filters
|
||||||
fetchedBids = []testBid{}
|
fetchedBids = []testBid{}
|
||||||
bidderAddress = tc.bids[1].Bidder
|
bidderAddress = tc.bids[1].Bidder
|
||||||
slotNum = tc.bids[5].SlotNum
|
slotNum = tc.bids[1].SlotNum
|
||||||
path = fmt.Sprintf("%s?bidderAddr=%s&slotNum=%d&limit=%d&fromItem=", endpoint, bidderAddress.String(), slotNum, limit)
|
path = fmt.Sprintf("%s?bidderAddr=%s&slotNum=%d&limit=%d&fromItem=", endpoint, bidderAddress.String(), slotNum, limit)
|
||||||
err = doGoodReqPaginated(path, historydb.OrderAsc, &testBidsResponse{}, appendIter)
|
err = doGoodReqPaginated(path, historydb.OrderAsc, &testBidsResponse{}, appendIter)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/hermeznetwork/hermez-node/common"
|
||||||
"github.com/hermeznetwork/hermez-node/db/historydb"
|
"github.com/hermeznetwork/hermez-node/db/historydb"
|
||||||
"github.com/mitchellh/copystructure"
|
"github.com/mitchellh/copystructure"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
@@ -22,10 +23,24 @@ func (t testCoordinatorsResponse) GetPending() (pendingItems, lastItemID uint64)
|
|||||||
|
|
||||||
func (t *testCoordinatorsResponse) Len() int { return len(t.Coordinators) }
|
func (t *testCoordinatorsResponse) Len() int { return len(t.Coordinators) }
|
||||||
|
|
||||||
|
func (t testCoordinatorsResponse) New() Pendinger { return &testCoordinatorsResponse{} }
|
||||||
|
|
||||||
|
func genTestCoordinators(coordinators []common.Coordinator) []historydb.CoordinatorAPI {
|
||||||
|
testCoords := []historydb.CoordinatorAPI{}
|
||||||
|
for i := 0; i < len(coordinators); i++ {
|
||||||
|
testCoords = append(testCoords, historydb.CoordinatorAPI{
|
||||||
|
Bidder: coordinators[i].Bidder,
|
||||||
|
Forger: coordinators[i].Forger,
|
||||||
|
EthBlockNum: coordinators[i].EthBlockNum,
|
||||||
|
URL: coordinators[i].URL,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return testCoords
|
||||||
|
}
|
||||||
|
|
||||||
func TestGetCoordinators(t *testing.T) {
|
func TestGetCoordinators(t *testing.T) {
|
||||||
endpoint := apiURL + "coordinators"
|
endpoint := apiURL + "coordinators"
|
||||||
fetchedCoordinators := []historydb.CoordinatorAPI{}
|
fetchedCoordinators := []historydb.CoordinatorAPI{}
|
||||||
|
|
||||||
appendIter := func(intr interface{}) {
|
appendIter := func(intr interface{}) {
|
||||||
for i := 0; i < len(intr.(*testCoordinatorsResponse).Coordinators); i++ {
|
for i := 0; i < len(intr.(*testCoordinatorsResponse).Coordinators); i++ {
|
||||||
tmp, err := copystructure.Copy(intr.(*testCoordinatorsResponse).Coordinators[i])
|
tmp, err := copystructure.Copy(intr.(*testCoordinatorsResponse).Coordinators[i])
|
||||||
@@ -36,45 +51,30 @@ func TestGetCoordinators(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// All
|
||||||
limit := 5
|
limit := 5
|
||||||
|
|
||||||
path := fmt.Sprintf("%s?limit=%d&fromItem=", endpoint, limit)
|
path := fmt.Sprintf("%s?limit=%d&fromItem=", endpoint, limit)
|
||||||
err := doGoodReqPaginated(path, historydb.OrderAsc, &testCoordinatorsResponse{}, appendIter)
|
err := doGoodReqPaginated(path, historydb.OrderAsc, &testCoordinatorsResponse{}, appendIter)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
for i := 0; i < len(fetchedCoordinators); i++ {
|
assertCoordinators(t, tc.coordinators, fetchedCoordinators)
|
||||||
assert.Equal(t, tc.coordinators[i].ItemID, fetchedCoordinators[i].ItemID)
|
|
||||||
assert.Equal(t, tc.coordinators[i].Bidder, fetchedCoordinators[i].Bidder)
|
|
||||||
assert.Equal(t, tc.coordinators[i].Forger, fetchedCoordinators[i].Forger)
|
|
||||||
assert.Equal(t, tc.coordinators[i].EthBlockNum, fetchedCoordinators[i].EthBlockNum)
|
|
||||||
assert.Equal(t, tc.coordinators[i].URL, fetchedCoordinators[i].URL)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reverse Order
|
// All in reverse order
|
||||||
reversedCoordinators := []historydb.CoordinatorAPI{}
|
fetchedCoordinators = []historydb.CoordinatorAPI{}
|
||||||
appendIter = func(intr interface{}) {
|
|
||||||
for i := 0; i < len(intr.(*testCoordinatorsResponse).Coordinators); i++ {
|
|
||||||
tmp, err := copystructure.Copy(intr.(*testCoordinatorsResponse).Coordinators[i])
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
reversedCoordinators = append(reversedCoordinators, tmp.(historydb.CoordinatorAPI))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
err = doGoodReqPaginated(path, historydb.OrderDesc, &testCoordinatorsResponse{}, appendIter)
|
err = doGoodReqPaginated(path, historydb.OrderDesc, &testCoordinatorsResponse{}, appendIter)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
for i := 0; i < len(fetchedCoordinators); i++ {
|
reversedCoordinators := []historydb.CoordinatorAPI{}
|
||||||
assert.Equal(t, reversedCoordinators[i].ItemID, fetchedCoordinators[len(fetchedCoordinators)-1-i].ItemID)
|
for i := 0; i < len(tc.coordinators); i++ {
|
||||||
assert.Equal(t, reversedCoordinators[i].Bidder, fetchedCoordinators[len(fetchedCoordinators)-1-i].Bidder)
|
reversedCoordinators = append(reversedCoordinators, tc.coordinators[len(tc.coordinators)-1-i])
|
||||||
assert.Equal(t, reversedCoordinators[i].Forger, fetchedCoordinators[len(fetchedCoordinators)-1-i].Forger)
|
|
||||||
assert.Equal(t, reversedCoordinators[i].EthBlockNum, fetchedCoordinators[len(fetchedCoordinators)-1-i].EthBlockNum)
|
|
||||||
assert.Equal(t, reversedCoordinators[i].URL, fetchedCoordinators[len(fetchedCoordinators)-1-i].URL)
|
|
||||||
}
|
}
|
||||||
|
assertCoordinators(t, reversedCoordinators, fetchedCoordinators)
|
||||||
|
|
||||||
// Test GetCoordinator
|
// Test GetCoordinator
|
||||||
path = fmt.Sprintf("%s/%s", endpoint, fetchedCoordinators[2].Forger.String())
|
for _, coord := range tc.coordinators {
|
||||||
coordinator := historydb.CoordinatorAPI{}
|
path = fmt.Sprintf("%s/%s", endpoint, coord.Forger.String())
|
||||||
assert.NoError(t, doGoodReq("GET", path, nil, &coordinator))
|
fetchedCoordinator := historydb.CoordinatorAPI{}
|
||||||
assert.Equal(t, fetchedCoordinators[2], coordinator)
|
assert.NoError(t, doGoodReq("GET", path, nil, &fetchedCoordinator))
|
||||||
|
assertCoordinator(t, coord, fetchedCoordinator)
|
||||||
|
}
|
||||||
|
|
||||||
// 400
|
// 400
|
||||||
path = fmt.Sprintf("%s/0x001", endpoint)
|
path = fmt.Sprintf("%s/0x001", endpoint)
|
||||||
@@ -85,3 +85,15 @@ func TestGetCoordinators(t *testing.T) {
|
|||||||
err = doBadReq("GET", path, nil, 404)
|
err = doBadReq("GET", path, nil, 404)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func assertCoordinator(t *testing.T, expected, actual historydb.CoordinatorAPI) {
|
||||||
|
actual.ItemID = 0
|
||||||
|
assert.Equal(t, expected, actual)
|
||||||
|
}
|
||||||
|
|
||||||
|
func assertCoordinators(t *testing.T, expected, actual []historydb.CoordinatorAPI) {
|
||||||
|
assert.Equal(t, len(expected), len(actual))
|
||||||
|
for i := 0; i < len(expected); i++ {
|
||||||
|
assertCoordinator(t, expected[i], actual[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -45,6 +45,8 @@ func (t testExitsResponse) GetPending() (pendingItems, lastItemID uint64) {
|
|||||||
return pendingItems, lastItemID
|
return pendingItems, lastItemID
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t testExitsResponse) New() Pendinger { return &testExitsResponse{} }
|
||||||
|
|
||||||
func (t *testExitsResponse) Len() int {
|
func (t *testExitsResponse) Len() int {
|
||||||
return len(t.Exits)
|
return len(t.Exits)
|
||||||
}
|
}
|
||||||
@@ -53,9 +55,8 @@ func genTestExits(
|
|||||||
commonExits []common.ExitInfo,
|
commonExits []common.ExitInfo,
|
||||||
tokens []historydb.TokenWithUSD,
|
tokens []historydb.TokenWithUSD,
|
||||||
accs []common.Account,
|
accs []common.Account,
|
||||||
usrIdxs []string,
|
) []testExit {
|
||||||
) (usrExits, allExits []testExit) {
|
allExits := []testExit{}
|
||||||
allExits = []testExit{}
|
|
||||||
for _, exit := range commonExits {
|
for _, exit := range commonExits {
|
||||||
token := getTokenByIdx(exit.AccountIdx, tokens, accs)
|
token := getTokenByIdx(exit.AccountIdx, tokens, accs)
|
||||||
siblings := []string{}
|
siblings := []string{}
|
||||||
@@ -82,16 +83,7 @@ func genTestExits(
|
|||||||
Token: token,
|
Token: token,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
usrExits = []testExit{}
|
return allExits
|
||||||
for _, exit := range allExits {
|
|
||||||
for _, idx := range usrIdxs {
|
|
||||||
if idx == exit.AccountIdx {
|
|
||||||
usrExits = append(usrExits, exit)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return usrExits, allExits
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetExits(t *testing.T) {
|
func TestGetExits(t *testing.T) {
|
||||||
@@ -116,21 +108,38 @@ func TestGetExits(t *testing.T) {
|
|||||||
// Get by ethAddr
|
// Get by ethAddr
|
||||||
fetchedExits = []testExit{}
|
fetchedExits = []testExit{}
|
||||||
limit = 7
|
limit = 7
|
||||||
account := tc.accounts[3]
|
var account testAccount
|
||||||
|
for _, tx := range tc.txs {
|
||||||
|
found := false
|
||||||
|
if tx.Type == common.TxTypeExit {
|
||||||
|
for i := 0; i < len(tc.accounts); i++ {
|
||||||
|
if tx.FromIdx != nil && string(tc.accounts[i].Idx) == *tx.FromIdx {
|
||||||
|
account = tc.accounts[i]
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if found {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
path = fmt.Sprintf(
|
path = fmt.Sprintf(
|
||||||
"%s?hermezEthereumAddress=%s&limit=%d&fromItem=",
|
"%s?hermezEthereumAddress=%s&limit=%d&fromItem=",
|
||||||
endpoint, account.EthAddr, limit,
|
endpoint, account.EthAddr, limit,
|
||||||
)
|
)
|
||||||
err = doGoodReqPaginated(path, historydb.OrderAsc, &testExitsResponse{}, appendIter)
|
err = doGoodReqPaginated(path, historydb.OrderAsc, &testExitsResponse{}, appendIter)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
accountIdx := fetchedExits[0].AccountIdx
|
var accountExits []testExit
|
||||||
var hermezEthExits []testExit
|
for i := range tc.exits {
|
||||||
for i := range tc.usrExits {
|
for _, acc := range tc.accounts {
|
||||||
if tc.usrExits[i].AccountIdx == accountIdx {
|
if string(acc.Idx) == tc.exits[i].AccountIdx {
|
||||||
hermezEthExits = append(hermezEthExits, tc.usrExits[i])
|
if acc.EthAddr == account.EthAddr {
|
||||||
|
accountExits = append(accountExits, tc.exits[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assertExitAPIs(t, hermezEthExits, fetchedExits)
|
assertExitAPIs(t, accountExits, fetchedExits)
|
||||||
// Get by bjj
|
// Get by bjj
|
||||||
fetchedExits = []testExit{}
|
fetchedExits = []testExit{}
|
||||||
limit = 6
|
limit = 6
|
||||||
@@ -140,7 +149,7 @@ func TestGetExits(t *testing.T) {
|
|||||||
)
|
)
|
||||||
err = doGoodReqPaginated(path, historydb.OrderAsc, &testExitsResponse{}, appendIter)
|
err = doGoodReqPaginated(path, historydb.OrderAsc, &testExitsResponse{}, appendIter)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assertExitAPIs(t, hermezEthExits, fetchedExits)
|
assertExitAPIs(t, accountExits, fetchedExits)
|
||||||
// Get by tokenID
|
// Get by tokenID
|
||||||
fetchedExits = []testExit{}
|
fetchedExits = []testExit{}
|
||||||
limit = 5
|
limit = 5
|
||||||
@@ -236,7 +245,7 @@ func TestGetExits(t *testing.T) {
|
|||||||
// 400
|
// 400
|
||||||
path = fmt.Sprintf(
|
path = fmt.Sprintf(
|
||||||
"%s?accountIndex=%s&hermezEthereumAddress=%s",
|
"%s?accountIndex=%s&hermezEthereumAddress=%s",
|
||||||
endpoint, idx, tc.usrAddr,
|
endpoint, idx, account.EthAddr,
|
||||||
)
|
)
|
||||||
err = doBadReq("GET", path, nil, 400)
|
err = doBadReq("GET", path, nil, 400)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ type SlotAPI struct {
|
|||||||
FirstBlock int64 `json:"firstBlock"`
|
FirstBlock int64 `json:"firstBlock"`
|
||||||
LastBlock int64 `json:"lastBlock"`
|
LastBlock int64 `json:"lastBlock"`
|
||||||
OpenAuction bool `json:"openAuction"`
|
OpenAuction bool `json:"openAuction"`
|
||||||
WinnerBid *historydb.BidAPI `json:"winnerBid"`
|
WinnerBid *historydb.BidAPI `json:"bestBid"`
|
||||||
TotalItems uint64 `json:"-"`
|
TotalItems uint64 `json:"-"`
|
||||||
FirstItem uint64 `json:"-"`
|
FirstItem uint64 `json:"-"`
|
||||||
LastItem uint64 `json:"-"`
|
LastItem uint64 `json:"-"`
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ type testSlot struct {
|
|||||||
FirstBlock int64 `json:"firstBlock"`
|
FirstBlock int64 `json:"firstBlock"`
|
||||||
LastBlock int64 `json:"lastBlock"`
|
LastBlock int64 `json:"lastBlock"`
|
||||||
OpenAuction bool `json:"openAuction"`
|
OpenAuction bool `json:"openAuction"`
|
||||||
WinnerBid *testBid `json:"winnerBid"`
|
WinnerBid *testBid `json:"bestBid"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type testSlotsResponse struct {
|
type testSlotsResponse struct {
|
||||||
@@ -35,6 +35,8 @@ func (t testSlotsResponse) Len() int {
|
|||||||
return len(t.Slots)
|
return len(t.Slots)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t testSlotsResponse) New() Pendinger { return &testSlotsResponse{} }
|
||||||
|
|
||||||
func (a *API) genTestSlots(nSlots int, lastBlockNum int64, bids []testBid, auctionVars common.AuctionVariables) []testSlot {
|
func (a *API) genTestSlots(nSlots int, lastBlockNum int64, bids []testBid, auctionVars common.AuctionVariables) []testSlot {
|
||||||
tSlots := []testSlot{}
|
tSlots := []testSlot{}
|
||||||
bestBids := make(map[int64]testBid)
|
bestBids := make(map[int64]testBid)
|
||||||
|
|||||||
19
api/state.go
19
api/state.go
@@ -12,10 +12,11 @@ import (
|
|||||||
|
|
||||||
// Network define status of the network
|
// Network define status of the network
|
||||||
type Network struct {
|
type Network struct {
|
||||||
LastBlock int64 `json:"lastBlock"`
|
LastEthBlock int64 `json:"lastEthereumBlock"`
|
||||||
LastBatch historydb.BatchAPI `json:"lastBatch"`
|
LastSyncBlock int64 `json:"lastSynchedBlock"`
|
||||||
CurrentSlot int64 `json:"currentSlot"`
|
LastBatch historydb.BatchAPI `json:"lastBatch"`
|
||||||
NextForgers []NextForger `json:"nextForgers"`
|
CurrentSlot int64 `json:"currentSlot"`
|
||||||
|
NextForgers []NextForger `json:"nextForgers"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// NextForger is a representation of the information of a coordinator and the period will forge
|
// NextForger is a representation of the information of a coordinator and the period will forge
|
||||||
@@ -65,8 +66,12 @@ func (a *API) SetAuctionVariables(auctionVariables common.AuctionVariables) {
|
|||||||
// Network
|
// Network
|
||||||
|
|
||||||
// UpdateNetworkInfo update Status.Network information
|
// UpdateNetworkInfo update Status.Network information
|
||||||
func (a *API) UpdateNetworkInfo(lastBlock common.Block, lastBatchNum common.BatchNum, currentSlot int64) error {
|
func (a *API) UpdateNetworkInfo(
|
||||||
a.status.Network.LastBlock = lastBlock.EthBlockNum
|
lastEthBlock, lastSyncBlock common.Block,
|
||||||
|
lastBatchNum common.BatchNum, currentSlot int64,
|
||||||
|
) error {
|
||||||
|
a.status.Network.LastSyncBlock = lastSyncBlock.EthBlockNum
|
||||||
|
a.status.Network.LastEthBlock = lastEthBlock.EthBlockNum
|
||||||
lastBatch, err := a.h.GetBatchAPI(lastBatchNum)
|
lastBatch, err := a.h.GetBatchAPI(lastBatchNum)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -74,7 +79,7 @@ func (a *API) UpdateNetworkInfo(lastBlock common.Block, lastBatchNum common.Batc
|
|||||||
a.status.Network.LastBatch = *lastBatch
|
a.status.Network.LastBatch = *lastBatch
|
||||||
a.status.Network.CurrentSlot = currentSlot
|
a.status.Network.CurrentSlot = currentSlot
|
||||||
lastClosedSlot := currentSlot + int64(a.status.Auction.ClosedAuctionSlots)
|
lastClosedSlot := currentSlot + int64(a.status.Auction.ClosedAuctionSlots)
|
||||||
nextForgers, err := a.GetNextForgers(lastBlock, currentSlot, lastClosedSlot)
|
nextForgers, err := a.GetNextForgers(lastSyncBlock, currentSlot, lastClosedSlot)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,10 +21,11 @@ type testStatus struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type testNetwork struct {
|
type testNetwork struct {
|
||||||
LastBlock int64 `json:"lastBlock"`
|
LastEthBlock int64 `json:"lastEthereumBlock"`
|
||||||
LastBatch testBatch `json:"lastBatch"`
|
LastSyncBlock int64 `json:"lastSynchedBlock"`
|
||||||
CurrentSlot int64 `json:"currentSlot"`
|
LastBatch testBatch `json:"lastBatch"`
|
||||||
NextForgers []NextForger `json:"nextForgers"`
|
CurrentSlot int64 `json:"currentSlot"`
|
||||||
|
NextForgers []NextForger `json:"nextForgers"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSetRollupVariables(t *testing.T) {
|
func TestSetRollupVariables(t *testing.T) {
|
||||||
@@ -80,16 +81,16 @@ func TestNextForgers(t *testing.T) {
|
|||||||
|
|
||||||
func TestUpdateNetworkInfo(t *testing.T) {
|
func TestUpdateNetworkInfo(t *testing.T) {
|
||||||
status := &Network{}
|
status := &Network{}
|
||||||
assert.Equal(t, status.LastBlock, api.status.Network.LastBlock)
|
assert.Equal(t, status.LastSyncBlock, api.status.Network.LastSyncBlock)
|
||||||
assert.Equal(t, status.LastBatch.BatchNum, api.status.Network.LastBatch.BatchNum)
|
assert.Equal(t, status.LastBatch.BatchNum, api.status.Network.LastBatch.BatchNum)
|
||||||
assert.Equal(t, status.CurrentSlot, api.status.Network.CurrentSlot)
|
assert.Equal(t, status.CurrentSlot, api.status.Network.CurrentSlot)
|
||||||
assert.Equal(t, status.NextForgers, api.status.Network.NextForgers)
|
assert.Equal(t, status.NextForgers, api.status.Network.NextForgers)
|
||||||
lastBlock := tc.blocks[3]
|
lastBlock := tc.blocks[3]
|
||||||
lastBatchNum := common.BatchNum(3)
|
lastBatchNum := common.BatchNum(3)
|
||||||
currentSlotNum := int64(1)
|
currentSlotNum := int64(1)
|
||||||
err := api.UpdateNetworkInfo(lastBlock, lastBatchNum, currentSlotNum)
|
err := api.UpdateNetworkInfo(lastBlock, lastBlock, lastBatchNum, currentSlotNum)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, lastBlock.EthBlockNum, api.status.Network.LastBlock)
|
assert.Equal(t, lastBlock.EthBlockNum, api.status.Network.LastSyncBlock)
|
||||||
assert.Equal(t, lastBatchNum, api.status.Network.LastBatch.BatchNum)
|
assert.Equal(t, lastBatchNum, api.status.Network.LastBatch.BatchNum)
|
||||||
assert.Equal(t, currentSlotNum, api.status.Network.CurrentSlot)
|
assert.Equal(t, currentSlotNum, api.status.Network.CurrentSlot)
|
||||||
assert.Equal(t, int(api.status.Auction.ClosedAuctionSlots)+1, len(api.status.Network.NextForgers))
|
assert.Equal(t, int(api.status.Auction.ClosedAuctionSlots)+1, len(api.status.Network.NextForgers))
|
||||||
@@ -101,7 +102,7 @@ func TestUpdateMetrics(t *testing.T) {
|
|||||||
lastBlock := tc.blocks[3]
|
lastBlock := tc.blocks[3]
|
||||||
lastBatchNum := common.BatchNum(3)
|
lastBatchNum := common.BatchNum(3)
|
||||||
currentSlotNum := int64(1)
|
currentSlotNum := int64(1)
|
||||||
err := api.UpdateNetworkInfo(lastBlock, lastBatchNum, currentSlotNum)
|
err := api.UpdateNetworkInfo(lastBlock, lastBlock, lastBatchNum, currentSlotNum)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
err = api.UpdateMetrics()
|
err = api.UpdateMetrics()
|
||||||
@@ -124,14 +125,14 @@ func TestUpdateRecommendedFee(t *testing.T) {
|
|||||||
api.status.RecommendedFee.ExistingAccount*createAccountInternalExtraFeePercentage)
|
api.status.RecommendedFee.ExistingAccount*createAccountInternalExtraFeePercentage)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetStatus(t *testing.T) {
|
func TestGetState(t *testing.T) {
|
||||||
lastBlock := tc.blocks[3]
|
lastBlock := tc.blocks[3]
|
||||||
lastBatchNum := common.BatchNum(3)
|
lastBatchNum := common.BatchNum(3)
|
||||||
currentSlotNum := int64(1)
|
currentSlotNum := int64(1)
|
||||||
api.SetRollupVariables(tc.rollupVars)
|
api.SetRollupVariables(tc.rollupVars)
|
||||||
api.SetWDelayerVariables(tc.wdelayerVars)
|
api.SetWDelayerVariables(tc.wdelayerVars)
|
||||||
api.SetAuctionVariables(tc.auctionVars)
|
api.SetAuctionVariables(tc.auctionVars)
|
||||||
err := api.UpdateNetworkInfo(lastBlock, lastBatchNum, currentSlotNum)
|
err := api.UpdateNetworkInfo(lastBlock, lastBlock, lastBatchNum, currentSlotNum)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
err = api.UpdateMetrics()
|
err = api.UpdateMetrics()
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
@@ -145,7 +146,8 @@ func TestGetStatus(t *testing.T) {
|
|||||||
assert.Equal(t, tc.rollupVars, status.Rollup)
|
assert.Equal(t, tc.rollupVars, status.Rollup)
|
||||||
assert.Equal(t, tc.auctionVars, status.Auction)
|
assert.Equal(t, tc.auctionVars, status.Auction)
|
||||||
assert.Equal(t, tc.wdelayerVars, status.WithdrawalDelayer)
|
assert.Equal(t, tc.wdelayerVars, status.WithdrawalDelayer)
|
||||||
assert.Equal(t, lastBlock.EthBlockNum, status.Network.LastBlock)
|
assert.Equal(t, lastBlock.EthBlockNum, status.Network.LastEthBlock)
|
||||||
|
assert.Equal(t, lastBlock.EthBlockNum, status.Network.LastSyncBlock)
|
||||||
assert.Equal(t, lastBatchNum, status.Network.LastBatch.BatchNum)
|
assert.Equal(t, lastBatchNum, status.Network.LastBatch.BatchNum)
|
||||||
assert.Equal(t, currentSlotNum, status.Network.CurrentSlot)
|
assert.Equal(t, currentSlotNum, status.Network.CurrentSlot)
|
||||||
assert.Equal(t, int(api.status.Auction.ClosedAuctionSlots)+1, len(status.Network.NextForgers))
|
assert.Equal(t, int(api.status.Auction.ClosedAuctionSlots)+1, len(status.Network.NextForgers))
|
||||||
|
|||||||
@@ -1857,6 +1857,7 @@ components:
|
|||||||
description: List of forged transactions in the batch
|
description: List of forged transactions in the batch
|
||||||
items:
|
items:
|
||||||
$ref: '#/components/schemas/HistoryTransaction'
|
$ref: '#/components/schemas/HistoryTransaction'
|
||||||
|
nullable: true
|
||||||
additionalProperties: false
|
additionalProperties: false
|
||||||
required:
|
required:
|
||||||
- batch
|
- batch
|
||||||
@@ -2205,9 +2206,9 @@ components:
|
|||||||
openAuction:
|
openAuction:
|
||||||
type: boolean
|
type: boolean
|
||||||
description: Whether the auction of the slot is open or not.
|
description: Whether the auction of the slot is open or not.
|
||||||
winnerBid:
|
bestBid:
|
||||||
type: object
|
type: object
|
||||||
description: The winning bid of the auction. If openAuction == true, is the current winner. If the auction is closed because it has already been finalized, the bid is the final winner. If the winnerBid is null, it is because no coordinator has bid for that slot.
|
description: The best bid of the auction. If the bestBid is null, it is because no coordinator has bid for that slot.
|
||||||
nullable: true
|
nullable: true
|
||||||
properties:
|
properties:
|
||||||
itemId:
|
itemId:
|
||||||
@@ -2245,7 +2246,7 @@ components:
|
|||||||
- firstBlock
|
- firstBlock
|
||||||
- lastBlock
|
- lastBlock
|
||||||
- openAuction
|
- openAuction
|
||||||
- winnerBid
|
- bestBid
|
||||||
Slots:
|
Slots:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
@@ -2328,10 +2329,15 @@ components:
|
|||||||
type: object
|
type: object
|
||||||
description: Gobal statistics of the network
|
description: Gobal statistics of the network
|
||||||
properties:
|
properties:
|
||||||
lastBlock:
|
lastEthereumBlock:
|
||||||
allOf:
|
allOf:
|
||||||
- $ref: '#/components/schemas/EthBlockNum'
|
- $ref: '#/components/schemas/EthBlockNum'
|
||||||
- description: Last synchronized Etherum block.
|
- description: Current Etherum block. Note that this is the actual last block of Ethereum, not the last synchronized block by the node.
|
||||||
|
- example: 3457437
|
||||||
|
lastSynchedBlock:
|
||||||
|
allOf:
|
||||||
|
- $ref: '#/components/schemas/EthBlockNum'
|
||||||
|
- description: Last synchronized Etherum block. Compare with lastEthereumBlock to check the synchronization status of the node.
|
||||||
- example: 3457437
|
- example: 3457437
|
||||||
lastBatch:
|
lastBatch:
|
||||||
$ref: '#/components/schemas/Batch'
|
$ref: '#/components/schemas/Batch'
|
||||||
@@ -2344,7 +2350,8 @@ components:
|
|||||||
$ref: '#/components/schemas/NextForgers'
|
$ref: '#/components/schemas/NextForgers'
|
||||||
additionalProperties: false
|
additionalProperties: false
|
||||||
required:
|
required:
|
||||||
- lastBlock
|
- lastEthereumBlock
|
||||||
|
- lastSynchedBlock
|
||||||
- lastBatch
|
- lastBatch
|
||||||
- currentSlot
|
- currentSlot
|
||||||
- nextForgers
|
- nextForgers
|
||||||
|
|||||||
@@ -26,6 +26,8 @@ func (t *testTokensResponse) Len() int {
|
|||||||
return len(t.Tokens)
|
return len(t.Tokens)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t testTokensResponse) New() Pendinger { return &testTokensResponse{} }
|
||||||
|
|
||||||
func TestGetToken(t *testing.T) {
|
func TestGetToken(t *testing.T) {
|
||||||
// Get all txs by their ID
|
// Get all txs by their ID
|
||||||
endpoint := apiURL + "tokens/"
|
endpoint := apiURL + "tokens/"
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
"sort"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -51,43 +52,14 @@ type testTx struct {
|
|||||||
Token historydb.TokenWithUSD `json:"token"`
|
Token historydb.TokenWithUSD `json:"token"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type testTxsResponse struct {
|
type txsSort []testTx
|
||||||
Txs []testTx `json:"transactions"`
|
|
||||||
PendingItems uint64 `json:"pendingItems"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t testTxsResponse) GetPending() (pendingItems, lastItemID uint64) {
|
|
||||||
pendingItems = t.PendingItems
|
|
||||||
lastItemID = t.Txs[len(t.Txs)-1].ItemID
|
|
||||||
return pendingItems, lastItemID
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t testTxsResponse) Len() int {
|
|
||||||
return len(t.Txs)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TxSortFields represents the fields needed to sort L1 and L2 transactions
|
|
||||||
type txSortFields struct {
|
|
||||||
BatchNum *common.BatchNum
|
|
||||||
Position int
|
|
||||||
}
|
|
||||||
|
|
||||||
// TxSortFielder is a interface that allows sorting L1 and L2 transactions in a combined way
|
|
||||||
type txSortFielder interface {
|
|
||||||
SortFields() txSortFields
|
|
||||||
L1() *common.L1Tx
|
|
||||||
L2() *common.L2Tx
|
|
||||||
}
|
|
||||||
|
|
||||||
// TxsSort array of TxSortFielder
|
|
||||||
type txsSort []txSortFielder
|
|
||||||
|
|
||||||
func (t txsSort) Len() int { return len(t) }
|
func (t txsSort) Len() int { return len(t) }
|
||||||
func (t txsSort) Swap(i, j int) { t[i], t[j] = t[j], t[i] }
|
func (t txsSort) Swap(i, j int) { t[i], t[j] = t[j], t[i] }
|
||||||
func (t txsSort) Less(i, j int) bool {
|
func (t txsSort) Less(i, j int) bool {
|
||||||
// i not forged yet
|
// i not forged yet
|
||||||
isf := t[i].SortFields()
|
isf := t[i]
|
||||||
jsf := t[j].SortFields()
|
jsf := t[j]
|
||||||
if isf.BatchNum == nil {
|
if isf.BatchNum == nil {
|
||||||
if jsf.BatchNum != nil { // j is already forged
|
if jsf.BatchNum != nil { // j is already forged
|
||||||
return false
|
return false
|
||||||
@@ -108,189 +80,166 @@ func (t txsSort) Less(i, j int) bool {
|
|||||||
return *isf.BatchNum < *jsf.BatchNum
|
return *isf.BatchNum < *jsf.BatchNum
|
||||||
}
|
}
|
||||||
|
|
||||||
type wrappedL1 common.L1Tx
|
type testTxsResponse struct {
|
||||||
|
Txs []testTx `json:"transactions"`
|
||||||
// SortFields implements TxSortFielder
|
PendingItems uint64 `json:"pendingItems"`
|
||||||
func (tx *wrappedL1) SortFields() txSortFields {
|
|
||||||
return txSortFields{
|
|
||||||
BatchNum: tx.BatchNum,
|
|
||||||
Position: tx.Position,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// L1 implements TxSortFielder
|
func (t testTxsResponse) GetPending() (pendingItems, lastItemID uint64) {
|
||||||
func (tx *wrappedL1) L1() *common.L1Tx {
|
pendingItems = t.PendingItems
|
||||||
l1tx := common.L1Tx(*tx)
|
lastItemID = t.Txs[len(t.Txs)-1].ItemID
|
||||||
return &l1tx
|
return pendingItems, lastItemID
|
||||||
}
|
}
|
||||||
|
|
||||||
// L2 implements TxSortFielder
|
func (t testTxsResponse) Len() int {
|
||||||
func (tx *wrappedL1) L2() *common.L2Tx { return nil }
|
return len(t.Txs)
|
||||||
|
|
||||||
type wrappedL2 common.L2Tx
|
|
||||||
|
|
||||||
// SortFields implements TxSortFielder
|
|
||||||
func (tx *wrappedL2) SortFields() txSortFields {
|
|
||||||
return txSortFields{
|
|
||||||
BatchNum: &tx.BatchNum,
|
|
||||||
Position: tx.Position,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// L1 implements TxSortFielder
|
func (t testTxsResponse) New() Pendinger { return &testTxsResponse{} }
|
||||||
func (tx *wrappedL2) L1() *common.L1Tx { return nil }
|
|
||||||
|
|
||||||
// L2 implements TxSortFielder
|
|
||||||
func (tx *wrappedL2) L2() *common.L2Tx {
|
|
||||||
l2tx := common.L2Tx(*tx)
|
|
||||||
return &l2tx
|
|
||||||
}
|
|
||||||
|
|
||||||
func genTestTxs(
|
func genTestTxs(
|
||||||
genericTxs []txSortFielder,
|
l1s []common.L1Tx,
|
||||||
usrIdxs []string,
|
l2s []common.L2Tx,
|
||||||
accs []common.Account,
|
accs []common.Account,
|
||||||
tokens []historydb.TokenWithUSD,
|
tokens []historydb.TokenWithUSD,
|
||||||
blocks []common.Block,
|
blocks []common.Block,
|
||||||
) (usrTxs []testTx, allTxs []testTx) {
|
) []testTx {
|
||||||
usrTxs = []testTx{}
|
txs := []testTx{}
|
||||||
allTxs = []testTx{}
|
// common.L1Tx ==> testTx
|
||||||
isUsrTx := func(tx testTx) bool {
|
for _, l1 := range l1s {
|
||||||
for _, idx := range usrIdxs {
|
token := getTokenByID(l1.TokenID, tokens)
|
||||||
if tx.FromIdx != nil && *tx.FromIdx == idx {
|
// l1.FromEthAddr and l1.FromBJJ can't be nil
|
||||||
return true
|
fromEthAddr := string(apitypes.NewHezEthAddr(l1.FromEthAddr))
|
||||||
}
|
fromBJJ := string(apitypes.NewHezBJJ(l1.FromBJJ))
|
||||||
if tx.ToIdx == idx {
|
tx := testTx{
|
||||||
return true
|
IsL1: "L1",
|
||||||
}
|
TxID: l1.TxID,
|
||||||
|
Type: l1.Type,
|
||||||
|
Position: l1.Position,
|
||||||
|
FromEthAddr: &fromEthAddr,
|
||||||
|
FromBJJ: &fromBJJ,
|
||||||
|
ToIdx: idxToHez(l1.ToIdx, token.Symbol),
|
||||||
|
Amount: l1.Amount.String(),
|
||||||
|
BatchNum: l1.BatchNum,
|
||||||
|
Timestamp: getTimestamp(l1.EthBlockNum, blocks),
|
||||||
|
L1Info: &testL1Info{
|
||||||
|
ToForgeL1TxsNum: l1.ToForgeL1TxsNum,
|
||||||
|
UserOrigin: l1.UserOrigin,
|
||||||
|
LoadAmount: l1.LoadAmount.String(),
|
||||||
|
EthBlockNum: l1.EthBlockNum,
|
||||||
|
},
|
||||||
|
Token: token,
|
||||||
}
|
}
|
||||||
return false
|
// set BatchNum for user txs
|
||||||
}
|
if tx.L1Info.ToForgeL1TxsNum != nil {
|
||||||
for _, genericTx := range genericTxs {
|
// WARNING: this is an asumption, and the test input data can brake it easily
|
||||||
l1 := genericTx.L1()
|
bn := common.BatchNum(*tx.L1Info.ToForgeL1TxsNum + 2)
|
||||||
l2 := genericTx.L2()
|
tx.BatchNum = &bn
|
||||||
if l1 != nil { // L1Tx to testTx
|
}
|
||||||
token := getTokenByID(l1.TokenID, tokens)
|
// If FromIdx is not nil
|
||||||
// l1.FromEthAddr and l1.FromBJJ can't be nil
|
idxStr := idxToHez(l1.FromIdx, token.Symbol)
|
||||||
fromEthAddr := string(apitypes.NewHezEthAddr(l1.FromEthAddr))
|
tx.FromIdx = &idxStr
|
||||||
fromBJJ := string(apitypes.NewHezBJJ(l1.FromBJJ))
|
// If tx has a normal ToIdx (>255), set FromEthAddr and FromBJJ
|
||||||
tx := testTx{
|
if l1.ToIdx >= common.UserThreshold {
|
||||||
IsL1: "L1",
|
// find account
|
||||||
TxID: l1.TxID,
|
|
||||||
Type: l1.Type,
|
|
||||||
Position: l1.Position,
|
|
||||||
FromEthAddr: &fromEthAddr,
|
|
||||||
FromBJJ: &fromBJJ,
|
|
||||||
ToIdx: idxToHez(l1.ToIdx, token.Symbol),
|
|
||||||
Amount: l1.Amount.String(),
|
|
||||||
BatchNum: l1.BatchNum,
|
|
||||||
Timestamp: getTimestamp(l1.EthBlockNum, blocks),
|
|
||||||
L1Info: &testL1Info{
|
|
||||||
ToForgeL1TxsNum: l1.ToForgeL1TxsNum,
|
|
||||||
UserOrigin: l1.UserOrigin,
|
|
||||||
LoadAmount: l1.LoadAmount.String(),
|
|
||||||
EthBlockNum: l1.EthBlockNum,
|
|
||||||
},
|
|
||||||
Token: token,
|
|
||||||
}
|
|
||||||
// If FromIdx is not nil
|
|
||||||
if l1.FromIdx != 0 {
|
|
||||||
idxStr := idxToHez(l1.FromIdx, token.Symbol)
|
|
||||||
tx.FromIdx = &idxStr
|
|
||||||
}
|
|
||||||
// If tx has a normal ToIdx (>255), set FromEthAddr and FromBJJ
|
|
||||||
if l1.ToIdx >= common.UserThreshold {
|
|
||||||
// find account
|
|
||||||
for _, acc := range accs {
|
|
||||||
if l1.ToIdx == acc.Idx {
|
|
||||||
toEthAddr := string(apitypes.NewHezEthAddr(acc.EthAddr))
|
|
||||||
tx.ToEthAddr = &toEthAddr
|
|
||||||
toBJJ := string(apitypes.NewHezBJJ(acc.PublicKey))
|
|
||||||
tx.ToBJJ = &toBJJ
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// If the token has USD value setted
|
|
||||||
if token.USD != nil {
|
|
||||||
af := new(big.Float).SetInt(l1.Amount)
|
|
||||||
amountFloat, _ := af.Float64()
|
|
||||||
usd := *token.USD * amountFloat / math.Pow(10, float64(token.Decimals))
|
|
||||||
tx.HistoricUSD = &usd
|
|
||||||
laf := new(big.Float).SetInt(l1.LoadAmount)
|
|
||||||
loadAmountFloat, _ := laf.Float64()
|
|
||||||
loadUSD := *token.USD * loadAmountFloat / math.Pow(10, float64(token.Decimals))
|
|
||||||
tx.L1Info.HistoricLoadAmountUSD = &loadUSD
|
|
||||||
}
|
|
||||||
allTxs = append(allTxs, tx)
|
|
||||||
if isUsrTx(tx) {
|
|
||||||
usrTxs = append(usrTxs, tx)
|
|
||||||
}
|
|
||||||
} else { // L2Tx to testTx
|
|
||||||
token := getTokenByIdx(l2.FromIdx, tokens, accs)
|
|
||||||
// l1.FromIdx can't be nil
|
|
||||||
fromIdx := idxToHez(l2.FromIdx, token.Symbol)
|
|
||||||
tx := testTx{
|
|
||||||
IsL1: "L2",
|
|
||||||
TxID: l2.TxID,
|
|
||||||
Type: l2.Type,
|
|
||||||
Position: l2.Position,
|
|
||||||
ToIdx: idxToHez(l2.ToIdx, token.Symbol),
|
|
||||||
FromIdx: &fromIdx,
|
|
||||||
Amount: l2.Amount.String(),
|
|
||||||
BatchNum: &l2.BatchNum,
|
|
||||||
Timestamp: getTimestamp(l2.EthBlockNum, blocks),
|
|
||||||
L2Info: &testL2Info{
|
|
||||||
Nonce: l2.Nonce,
|
|
||||||
Fee: l2.Fee,
|
|
||||||
},
|
|
||||||
Token: token,
|
|
||||||
}
|
|
||||||
// If FromIdx is not nil
|
|
||||||
if l2.FromIdx != 0 {
|
|
||||||
idxStr := idxToHez(l2.FromIdx, token.Symbol)
|
|
||||||
tx.FromIdx = &idxStr
|
|
||||||
}
|
|
||||||
// Set FromEthAddr and FromBJJ (FromIdx it's always >255)
|
|
||||||
for _, acc := range accs {
|
for _, acc := range accs {
|
||||||
if l2.ToIdx == acc.Idx {
|
if l1.ToIdx == acc.Idx {
|
||||||
fromEthAddr := string(apitypes.NewHezEthAddr(acc.EthAddr))
|
toEthAddr := string(apitypes.NewHezEthAddr(acc.EthAddr))
|
||||||
tx.FromEthAddr = &fromEthAddr
|
tx.ToEthAddr = &toEthAddr
|
||||||
fromBJJ := string(apitypes.NewHezBJJ(acc.PublicKey))
|
toBJJ := string(apitypes.NewHezBJJ(acc.PublicKey))
|
||||||
tx.FromBJJ = &fromBJJ
|
tx.ToBJJ = &toBJJ
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// If tx has a normal ToIdx (>255), set FromEthAddr and FromBJJ
|
}
|
||||||
if l2.ToIdx >= common.UserThreshold {
|
// If the token has USD value setted
|
||||||
// find account
|
if token.USD != nil {
|
||||||
for _, acc := range accs {
|
af := new(big.Float).SetInt(l1.Amount)
|
||||||
if l2.ToIdx == acc.Idx {
|
amountFloat, _ := af.Float64()
|
||||||
toEthAddr := string(apitypes.NewHezEthAddr(acc.EthAddr))
|
usd := *token.USD * amountFloat / math.Pow(10, float64(token.Decimals))
|
||||||
tx.ToEthAddr = &toEthAddr
|
if usd != 0 {
|
||||||
toBJJ := string(apitypes.NewHezBJJ(acc.PublicKey))
|
|
||||||
tx.ToBJJ = &toBJJ
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// If the token has USD value setted
|
|
||||||
if token.USD != nil {
|
|
||||||
af := new(big.Float).SetInt(l2.Amount)
|
|
||||||
amountFloat, _ := af.Float64()
|
|
||||||
usd := *token.USD * amountFloat / math.Pow(10, float64(token.Decimals))
|
|
||||||
tx.HistoricUSD = &usd
|
tx.HistoricUSD = &usd
|
||||||
feeUSD := usd * l2.Fee.Percentage()
|
|
||||||
tx.HistoricUSD = &usd
|
|
||||||
tx.L2Info.HistoricFeeUSD = &feeUSD
|
|
||||||
}
|
}
|
||||||
allTxs = append(allTxs, tx)
|
laf := new(big.Float).SetInt(l1.LoadAmount)
|
||||||
if isUsrTx(tx) {
|
loadAmountFloat, _ := laf.Float64()
|
||||||
usrTxs = append(usrTxs, tx)
|
loadUSD := *token.USD * loadAmountFloat / math.Pow(10, float64(token.Decimals))
|
||||||
|
if loadAmountFloat != 0 {
|
||||||
|
tx.L1Info.HistoricLoadAmountUSD = &loadUSD
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
txs = append(txs, tx)
|
||||||
}
|
}
|
||||||
return usrTxs, allTxs
|
|
||||||
|
// common.L2Tx ==> testTx
|
||||||
|
for i := 0; i < len(l2s); i++ {
|
||||||
|
token := getTokenByIdx(l2s[i].FromIdx, tokens, accs)
|
||||||
|
// l1.FromIdx can't be nil
|
||||||
|
fromIdx := idxToHez(l2s[i].FromIdx, token.Symbol)
|
||||||
|
tx := testTx{
|
||||||
|
IsL1: "L2",
|
||||||
|
TxID: l2s[i].TxID,
|
||||||
|
Type: l2s[i].Type,
|
||||||
|
Position: l2s[i].Position,
|
||||||
|
ToIdx: idxToHez(l2s[i].ToIdx, token.Symbol),
|
||||||
|
FromIdx: &fromIdx,
|
||||||
|
Amount: l2s[i].Amount.String(),
|
||||||
|
BatchNum: &l2s[i].BatchNum,
|
||||||
|
Timestamp: getTimestamp(l2s[i].EthBlockNum, blocks),
|
||||||
|
L2Info: &testL2Info{
|
||||||
|
Nonce: l2s[i].Nonce,
|
||||||
|
Fee: l2s[i].Fee,
|
||||||
|
},
|
||||||
|
Token: token,
|
||||||
|
}
|
||||||
|
// If FromIdx is not nil
|
||||||
|
if l2s[i].FromIdx != 0 {
|
||||||
|
idxStr := idxToHez(l2s[i].FromIdx, token.Symbol)
|
||||||
|
tx.FromIdx = &idxStr
|
||||||
|
}
|
||||||
|
// Set FromEthAddr and FromBJJ (FromIdx it's always >255)
|
||||||
|
for _, acc := range accs {
|
||||||
|
if l2s[i].FromIdx == acc.Idx {
|
||||||
|
fromEthAddr := string(apitypes.NewHezEthAddr(acc.EthAddr))
|
||||||
|
tx.FromEthAddr = &fromEthAddr
|
||||||
|
fromBJJ := string(apitypes.NewHezBJJ(acc.PublicKey))
|
||||||
|
tx.FromBJJ = &fromBJJ
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// If tx has a normal ToIdx (>255), set FromEthAddr and FromBJJ
|
||||||
|
if l2s[i].ToIdx >= common.UserThreshold {
|
||||||
|
// find account
|
||||||
|
for _, acc := range accs {
|
||||||
|
if l2s[i].ToIdx == acc.Idx {
|
||||||
|
toEthAddr := string(apitypes.NewHezEthAddr(acc.EthAddr))
|
||||||
|
tx.ToEthAddr = &toEthAddr
|
||||||
|
toBJJ := string(apitypes.NewHezBJJ(acc.PublicKey))
|
||||||
|
tx.ToBJJ = &toBJJ
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// If the token has USD value setted
|
||||||
|
if token.USD != nil {
|
||||||
|
af := new(big.Float).SetInt(l2s[i].Amount)
|
||||||
|
amountFloat, _ := af.Float64()
|
||||||
|
usd := *token.USD * amountFloat / math.Pow(10, float64(token.Decimals))
|
||||||
|
if usd != 0 {
|
||||||
|
tx.HistoricUSD = &usd
|
||||||
|
feeUSD := usd * l2s[i].Fee.Percentage()
|
||||||
|
if feeUSD != 0 {
|
||||||
|
tx.L2Info.HistoricFeeUSD = &feeUSD
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
txs = append(txs, tx)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sort txs
|
||||||
|
sortedTxs := txsSort(txs)
|
||||||
|
sort.Sort(sortedTxs)
|
||||||
|
|
||||||
|
return []testTx(sortedTxs)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetHistoryTxs(t *testing.T) {
|
func TestGetHistoryTxs(t *testing.T) {
|
||||||
@@ -310,32 +259,44 @@ func TestGetHistoryTxs(t *testing.T) {
|
|||||||
path := fmt.Sprintf("%s?limit=%d&fromItem=", endpoint, limit)
|
path := fmt.Sprintf("%s?limit=%d&fromItem=", endpoint, limit)
|
||||||
err := doGoodReqPaginated(path, historydb.OrderAsc, &testTxsResponse{}, appendIter)
|
err := doGoodReqPaginated(path, historydb.OrderAsc, &testTxsResponse{}, appendIter)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assertTxs(t, tc.allTxs, fetchedTxs)
|
assertTxs(t, tc.txs, fetchedTxs)
|
||||||
// Uncomment once tx generation for tests is fixed
|
// Get by ethAddr
|
||||||
// // Get by ethAddr
|
account := tc.accounts[2]
|
||||||
// fetchedTxs = []testTx{}
|
fetchedTxs = []testTx{}
|
||||||
// limit = 7
|
limit = 7
|
||||||
// path = fmt.Sprintf(
|
path = fmt.Sprintf(
|
||||||
// "%s?hermezEthereumAddress=%s&limit=%d&fromItem=",
|
"%s?hermezEthereumAddress=%s&limit=%d&fromItem=",
|
||||||
// endpoint, tc.usrAddr, limit,
|
endpoint, account.EthAddr, limit,
|
||||||
// )
|
)
|
||||||
// err = doGoodReqPaginated(path, historydb.OrderAsc, &testTxsResponse{}, appendIter)
|
err = doGoodReqPaginated(path, historydb.OrderAsc, &testTxsResponse{}, appendIter)
|
||||||
// assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
// assertTxs(t, tc.usrTxs, fetchedTxs)
|
accountTxs := []testTx{}
|
||||||
// // Get by bjj
|
for i := 0; i < len(tc.txs); i++ {
|
||||||
// fetchedTxs = []testTx{}
|
tx := tc.txs[i]
|
||||||
// limit = 6
|
if (tx.FromIdx != nil && *tx.FromIdx == string(account.Idx)) ||
|
||||||
// path = fmt.Sprintf(
|
tx.ToIdx == string(account.Idx) ||
|
||||||
// "%s?BJJ=%s&limit=%d&fromItem=",
|
(tx.FromEthAddr != nil && *tx.FromEthAddr == string(account.EthAddr)) ||
|
||||||
// endpoint, tc.usrBjj, limit,
|
(tx.ToEthAddr != nil && *tx.ToEthAddr == string(account.EthAddr)) ||
|
||||||
// )
|
(tx.FromBJJ != nil && *tx.FromBJJ == string(account.PublicKey)) ||
|
||||||
// err = doGoodReqPaginated(path, historydb.OrderAsc, &testTxsResponse{}, appendIter)
|
(tx.ToBJJ != nil && *tx.ToBJJ == string(account.PublicKey)) {
|
||||||
// assert.NoError(t, err)
|
accountTxs = append(accountTxs, tx)
|
||||||
// assertTxs(t, tc.usrTxs, fetchedTxs)
|
}
|
||||||
|
}
|
||||||
|
assertTxs(t, accountTxs, fetchedTxs)
|
||||||
|
// Get by bjj
|
||||||
|
fetchedTxs = []testTx{}
|
||||||
|
limit = 6
|
||||||
|
path = fmt.Sprintf(
|
||||||
|
"%s?BJJ=%s&limit=%d&fromItem=",
|
||||||
|
endpoint, account.PublicKey, limit,
|
||||||
|
)
|
||||||
|
err = doGoodReqPaginated(path, historydb.OrderAsc, &testTxsResponse{}, appendIter)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assertTxs(t, accountTxs, fetchedTxs)
|
||||||
// Get by tokenID
|
// Get by tokenID
|
||||||
fetchedTxs = []testTx{}
|
fetchedTxs = []testTx{}
|
||||||
limit = 5
|
limit = 5
|
||||||
tokenID := tc.allTxs[0].Token.TokenID
|
tokenID := tc.txs[0].Token.TokenID
|
||||||
path = fmt.Sprintf(
|
path = fmt.Sprintf(
|
||||||
"%s?tokenId=%d&limit=%d&fromItem=",
|
"%s?tokenId=%d&limit=%d&fromItem=",
|
||||||
endpoint, tokenID, limit,
|
endpoint, tokenID, limit,
|
||||||
@@ -343,34 +304,46 @@ func TestGetHistoryTxs(t *testing.T) {
|
|||||||
err = doGoodReqPaginated(path, historydb.OrderAsc, &testTxsResponse{}, appendIter)
|
err = doGoodReqPaginated(path, historydb.OrderAsc, &testTxsResponse{}, appendIter)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
tokenIDTxs := []testTx{}
|
tokenIDTxs := []testTx{}
|
||||||
for i := 0; i < len(tc.allTxs); i++ {
|
for i := 0; i < len(tc.txs); i++ {
|
||||||
if tc.allTxs[i].Token.TokenID == tokenID {
|
if tc.txs[i].Token.TokenID == tokenID {
|
||||||
tokenIDTxs = append(tokenIDTxs, tc.allTxs[i])
|
tokenIDTxs = append(tokenIDTxs, tc.txs[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assertTxs(t, tokenIDTxs, fetchedTxs)
|
assertTxs(t, tokenIDTxs, fetchedTxs)
|
||||||
// // idx
|
// idx
|
||||||
// fetchedTxs = []testTx{}
|
fetchedTxs = []testTx{}
|
||||||
// limit = 4
|
limit = 4
|
||||||
idx := tc.allTxs[0].ToIdx
|
idxStr := tc.txs[0].ToIdx
|
||||||
// path = fmt.Sprintf(
|
idx, err := stringToIdx(idxStr, "")
|
||||||
// "%s?accountIndex=%s&limit=%d&fromItem=",
|
assert.NoError(t, err)
|
||||||
// endpoint, idx, limit,
|
path = fmt.Sprintf(
|
||||||
// )
|
"%s?accountIndex=%s&limit=%d&fromItem=",
|
||||||
// err = doGoodReqPaginated(path, historydb.OrderAsc, &testTxsResponse{}, appendIter)
|
endpoint, idxStr, limit,
|
||||||
// assert.NoError(t, err)
|
)
|
||||||
// idxTxs := []testTx{}
|
err = doGoodReqPaginated(path, historydb.OrderAsc, &testTxsResponse{}, appendIter)
|
||||||
// for i := 0; i < len(tc.allTxs); i++ {
|
assert.NoError(t, err)
|
||||||
// if (tc.allTxs[i].FromIdx != nil && (*tc.allTxs[i].FromIdx)[6:] == idx[6:]) ||
|
idxTxs := []testTx{}
|
||||||
// tc.allTxs[i].ToIdx[6:] == idx[6:] {
|
for i := 0; i < len(tc.txs); i++ {
|
||||||
// idxTxs = append(idxTxs, tc.allTxs[i])
|
var fromIdx *common.Idx
|
||||||
// }
|
if tc.txs[i].FromIdx != nil {
|
||||||
// }
|
fromIdx, err = stringToIdx(*tc.txs[i].FromIdx, "")
|
||||||
// assertHistoryTxAPIs(t, idxTxs, fetchedTxs)
|
assert.NoError(t, err)
|
||||||
|
if *fromIdx == *idx {
|
||||||
|
idxTxs = append(idxTxs, tc.txs[i])
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
toIdx, err := stringToIdx((tc.txs[i].ToIdx), "")
|
||||||
|
assert.NoError(t, err)
|
||||||
|
if *toIdx == *idx {
|
||||||
|
idxTxs = append(idxTxs, tc.txs[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assertTxs(t, idxTxs, fetchedTxs)
|
||||||
// batchNum
|
// batchNum
|
||||||
fetchedTxs = []testTx{}
|
fetchedTxs = []testTx{}
|
||||||
limit = 3
|
limit = 3
|
||||||
batchNum := tc.allTxs[0].BatchNum
|
batchNum := tc.txs[0].BatchNum
|
||||||
path = fmt.Sprintf(
|
path = fmt.Sprintf(
|
||||||
"%s?batchNum=%d&limit=%d&fromItem=",
|
"%s?batchNum=%d&limit=%d&fromItem=",
|
||||||
endpoint, *batchNum, limit,
|
endpoint, *batchNum, limit,
|
||||||
@@ -378,26 +351,24 @@ func TestGetHistoryTxs(t *testing.T) {
|
|||||||
err = doGoodReqPaginated(path, historydb.OrderAsc, &testTxsResponse{}, appendIter)
|
err = doGoodReqPaginated(path, historydb.OrderAsc, &testTxsResponse{}, appendIter)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
batchNumTxs := []testTx{}
|
batchNumTxs := []testTx{}
|
||||||
for i := 0; i < len(tc.allTxs); i++ {
|
for i := 0; i < len(tc.txs); i++ {
|
||||||
if tc.allTxs[i].BatchNum != nil &&
|
if tc.txs[i].BatchNum != nil &&
|
||||||
*tc.allTxs[i].BatchNum == *batchNum {
|
*tc.txs[i].BatchNum == *batchNum {
|
||||||
batchNumTxs = append(batchNumTxs, tc.allTxs[i])
|
batchNumTxs = append(batchNumTxs, tc.txs[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assertTxs(t, batchNumTxs, fetchedTxs)
|
assertTxs(t, batchNumTxs, fetchedTxs)
|
||||||
// type
|
// type
|
||||||
txTypes := []common.TxType{
|
txTypes := []common.TxType{
|
||||||
// Uncomment once test gen is fixed
|
// Uncomment once test gen is fixed
|
||||||
// common.TxTypeExit,
|
common.TxTypeExit,
|
||||||
// common.TxTypeTransfer,
|
common.TxTypeTransfer,
|
||||||
// common.TxTypeDeposit,
|
common.TxTypeDeposit,
|
||||||
common.TxTypeCreateAccountDeposit,
|
common.TxTypeCreateAccountDeposit,
|
||||||
// common.TxTypeCreateAccountDepositTransfer,
|
common.TxTypeCreateAccountDepositTransfer,
|
||||||
// common.TxTypeDepositTransfer,
|
common.TxTypeDepositTransfer,
|
||||||
common.TxTypeForceTransfer,
|
common.TxTypeForceTransfer,
|
||||||
// common.TxTypeForceExit,
|
common.TxTypeForceExit,
|
||||||
// common.TxTypeTransferToEthAddr,
|
|
||||||
// common.TxTypeTransferToBJJ,
|
|
||||||
}
|
}
|
||||||
for _, txType := range txTypes {
|
for _, txType := range txTypes {
|
||||||
fetchedTxs = []testTx{}
|
fetchedTxs = []testTx{}
|
||||||
@@ -409,9 +380,9 @@ func TestGetHistoryTxs(t *testing.T) {
|
|||||||
err = doGoodReqPaginated(path, historydb.OrderAsc, &testTxsResponse{}, appendIter)
|
err = doGoodReqPaginated(path, historydb.OrderAsc, &testTxsResponse{}, appendIter)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
txTypeTxs := []testTx{}
|
txTypeTxs := []testTx{}
|
||||||
for i := 0; i < len(tc.allTxs); i++ {
|
for i := 0; i < len(tc.txs); i++ {
|
||||||
if tc.allTxs[i].Type == txType {
|
if tc.txs[i].Type == txType {
|
||||||
txTypeTxs = append(txTypeTxs, tc.allTxs[i])
|
txTypeTxs = append(txTypeTxs, tc.txs[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assertTxs(t, txTypeTxs, fetchedTxs)
|
assertTxs(t, txTypeTxs, fetchedTxs)
|
||||||
@@ -426,10 +397,10 @@ func TestGetHistoryTxs(t *testing.T) {
|
|||||||
err = doGoodReqPaginated(path, historydb.OrderAsc, &testTxsResponse{}, appendIter)
|
err = doGoodReqPaginated(path, historydb.OrderAsc, &testTxsResponse{}, appendIter)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
mixedTxs := []testTx{}
|
mixedTxs := []testTx{}
|
||||||
for i := 0; i < len(tc.allTxs); i++ {
|
for i := 0; i < len(tc.txs); i++ {
|
||||||
if tc.allTxs[i].BatchNum != nil {
|
if tc.txs[i].BatchNum != nil {
|
||||||
if *tc.allTxs[i].BatchNum == *batchNum && tc.allTxs[i].Token.TokenID == tokenID {
|
if *tc.txs[i].BatchNum == *batchNum && tc.txs[i].Token.TokenID == tokenID {
|
||||||
mixedTxs = append(mixedTxs, tc.allTxs[i])
|
mixedTxs = append(mixedTxs, tc.txs[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -441,14 +412,14 @@ func TestGetHistoryTxs(t *testing.T) {
|
|||||||
err = doGoodReqPaginated(path, historydb.OrderDesc, &testTxsResponse{}, appendIter)
|
err = doGoodReqPaginated(path, historydb.OrderDesc, &testTxsResponse{}, appendIter)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
flipedTxs := []testTx{}
|
flipedTxs := []testTx{}
|
||||||
for i := 0; i < len(tc.allTxs); i++ {
|
for i := 0; i < len(tc.txs); i++ {
|
||||||
flipedTxs = append(flipedTxs, tc.allTxs[len(tc.allTxs)-1-i])
|
flipedTxs = append(flipedTxs, tc.txs[len(tc.txs)-1-i])
|
||||||
}
|
}
|
||||||
assertTxs(t, flipedTxs, fetchedTxs)
|
assertTxs(t, flipedTxs, fetchedTxs)
|
||||||
// 400
|
// 400
|
||||||
path = fmt.Sprintf(
|
path = fmt.Sprintf(
|
||||||
"%s?accountIndex=%s&hermezEthereumAddress=%s",
|
"%s?accountIndex=%s&hermezEthereumAddress=%s",
|
||||||
endpoint, idx, tc.usrAddr,
|
endpoint, idx, account.EthAddr,
|
||||||
)
|
)
|
||||||
err = doBadReq("GET", path, nil, 400)
|
err = doBadReq("GET", path, nil, 400)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
@@ -468,13 +439,13 @@ func TestGetHistoryTx(t *testing.T) {
|
|||||||
// Get all txs by their ID
|
// Get all txs by their ID
|
||||||
endpoint := apiURL + "transactions-history/"
|
endpoint := apiURL + "transactions-history/"
|
||||||
fetchedTxs := []testTx{}
|
fetchedTxs := []testTx{}
|
||||||
for _, tx := range tc.allTxs {
|
for _, tx := range tc.txs {
|
||||||
fetchedTx := testTx{}
|
fetchedTx := testTx{}
|
||||||
err := doGoodReq("GET", endpoint+tx.TxID.String(), nil, &fetchedTx)
|
err := doGoodReq("GET", endpoint+tx.TxID.String(), nil, &fetchedTx)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
fetchedTxs = append(fetchedTxs, fetchedTx)
|
fetchedTxs = append(fetchedTxs, fetchedTx)
|
||||||
}
|
}
|
||||||
assertTxs(t, tc.allTxs, fetchedTxs)
|
assertTxs(t, tc.txs, fetchedTxs)
|
||||||
// 400
|
// 400
|
||||||
err := doBadReq("GET", endpoint+"0x001", nil, 400)
|
err := doBadReq("GET", endpoint+"0x001", nil, 400)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
@@ -486,12 +457,15 @@ func TestGetHistoryTx(t *testing.T) {
|
|||||||
func assertTxs(t *testing.T, expected, actual []testTx) {
|
func assertTxs(t *testing.T, expected, actual []testTx) {
|
||||||
require.Equal(t, len(expected), len(actual))
|
require.Equal(t, len(expected), len(actual))
|
||||||
for i := 0; i < len(actual); i++ { //nolint len(actual) won't change within the loop
|
for i := 0; i < len(actual); i++ { //nolint len(actual) won't change within the loop
|
||||||
|
assert.Equal(t, expected[i].BatchNum, actual[i].BatchNum)
|
||||||
|
assert.Equal(t, expected[i].Position, actual[i].Position)
|
||||||
actual[i].ItemID = 0
|
actual[i].ItemID = 0
|
||||||
actual[i].Token.ItemID = 0
|
actual[i].Token.ItemID = 0
|
||||||
assert.Equal(t, expected[i].Timestamp.Unix(), actual[i].Timestamp.Unix())
|
assert.Equal(t, expected[i].Timestamp.Unix(), actual[i].Timestamp.Unix())
|
||||||
expected[i].Timestamp = actual[i].Timestamp
|
expected[i].Timestamp = actual[i].Timestamp
|
||||||
if expected[i].Token.USDUpdate == nil {
|
if expected[i].Token.USDUpdate == nil {
|
||||||
assert.Equal(t, expected[i].Token.USDUpdate, actual[i].Token.USDUpdate)
|
assert.Equal(t, expected[i].Token.USDUpdate, actual[i].Token.USDUpdate)
|
||||||
|
expected[i].Token.USDUpdate = actual[i].Token.USDUpdate
|
||||||
} else {
|
} else {
|
||||||
assert.Equal(t, expected[i].Token.USDUpdate.Unix(), actual[i].Token.USDUpdate.Unix())
|
assert.Equal(t, expected[i].Token.USDUpdate.Unix(), actual[i].Token.USDUpdate.Unix())
|
||||||
expected[i].Token.USDUpdate = actual[i].Token.USDUpdate
|
expected[i].Token.USDUpdate = actual[i].Token.USDUpdate
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package api
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"math/big"
|
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -66,32 +65,11 @@ type testPoolTxSend struct {
|
|||||||
RqNonce *common.Nonce `json:"requestNonce"`
|
RqNonce *common.Nonce `json:"requestNonce"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func genTestPoolTx(accs []common.Account, privKs []babyjub.PrivateKey, tokens []historydb.TokenWithUSD) (poolTxsToSend []testPoolTxSend, poolTxsToReceive []testPoolTxReceive) {
|
func genTestPoolTxs(
|
||||||
// Generate common.PoolL2Tx
|
poolTxs []common.PoolL2Tx,
|
||||||
// WARNING: this should be replaced once til is ready
|
tokens []historydb.TokenWithUSD,
|
||||||
poolTxs := []common.PoolL2Tx{}
|
accs []common.Account,
|
||||||
amount := new(big.Int)
|
) (poolTxsToSend []testPoolTxSend, poolTxsToReceive []testPoolTxReceive) {
|
||||||
amount, ok := amount.SetString("100000000000000", 10)
|
|
||||||
if !ok {
|
|
||||||
panic("bad amount")
|
|
||||||
}
|
|
||||||
poolTx := common.PoolL2Tx{
|
|
||||||
FromIdx: accs[0].Idx,
|
|
||||||
ToIdx: accs[1].Idx,
|
|
||||||
Amount: amount,
|
|
||||||
TokenID: accs[0].TokenID,
|
|
||||||
Nonce: 6,
|
|
||||||
}
|
|
||||||
if _, err := common.NewPoolL2Tx(&poolTx); err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
h, err := poolTx.HashToSign()
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
poolTx.Signature = privKs[0].SignPoseidon(h).Compress()
|
|
||||||
poolTxs = append(poolTxs, poolTx)
|
|
||||||
// Transform to API formats
|
|
||||||
poolTxsToSend = []testPoolTxSend{}
|
poolTxsToSend = []testPoolTxSend{}
|
||||||
poolTxsToReceive = []testPoolTxReceive{}
|
poolTxsToReceive = []testPoolTxReceive{}
|
||||||
for _, poolTx := range poolTxs {
|
for _, poolTx := range poolTxs {
|
||||||
@@ -125,7 +103,7 @@ func genTestPoolTx(accs []common.Account, privKs []babyjub.PrivateKey, tokens []
|
|||||||
RqNonce: &poolTx.RqNonce,
|
RqNonce: &poolTx.RqNonce,
|
||||||
Token: token,
|
Token: token,
|
||||||
}
|
}
|
||||||
fromAcc := getAccountByIdx(poolTx.ToIdx, accs)
|
fromAcc := getAccountByIdx(poolTx.FromIdx, accs)
|
||||||
fromAddr := ethAddrToHez(fromAcc.EthAddr)
|
fromAddr := ethAddrToHez(fromAcc.EthAddr)
|
||||||
genReceiveTx.FromEthAddr = &fromAddr
|
genReceiveTx.FromEthAddr = &fromAddr
|
||||||
fromBjj := bjjToString(fromAcc.PublicKey)
|
fromBjj := bjjToString(fromAcc.PublicKey)
|
||||||
|
|||||||
@@ -95,12 +95,12 @@ func (c *CollectedFees) UnmarshalJSON(text []byte) error {
|
|||||||
if err := json.Unmarshal(text, &bigIntMap); err != nil {
|
if err := json.Unmarshal(text, &bigIntMap); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
bStrMap := make(map[common.TokenID]BigIntStr)
|
*c = CollectedFees(make(map[common.TokenID]BigIntStr))
|
||||||
for k, v := range bigIntMap {
|
for k, v := range bigIntMap {
|
||||||
bStr := NewBigIntStr(v)
|
bStr := NewBigIntStr(v)
|
||||||
bStrMap[k] = *bStr
|
(CollectedFees(*c)[k]) = *bStr
|
||||||
}
|
}
|
||||||
*c = CollectedFees(bStrMap)
|
// *c = CollectedFees(bStrMap)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -894,17 +894,13 @@ func (hdb *HistoryDB) GetHistoryTxs(
|
|||||||
nextIsAnd := false
|
nextIsAnd := false
|
||||||
// ethAddr filter
|
// ethAddr filter
|
||||||
if ethAddr != nil {
|
if ethAddr != nil {
|
||||||
queryStr = `WITH acc AS
|
queryStr += "WHERE (tx.from_eth_addr = ? OR tx.to_eth_addr = ?) "
|
||||||
(select idx from account where eth_addr = ?) ` + queryStr
|
|
||||||
queryStr += ", acc WHERE (tx.from_idx IN(acc.idx) OR tx.to_idx IN(acc.idx)) "
|
|
||||||
nextIsAnd = true
|
nextIsAnd = true
|
||||||
args = append(args, ethAddr)
|
args = append(args, ethAddr, ethAddr)
|
||||||
} else if bjj != nil { // bjj filter
|
} else if bjj != nil { // bjj filter
|
||||||
queryStr = `WITH acc AS
|
queryStr += "WHERE (tx.from_bjj = ? OR tx.to_bjj = ?) "
|
||||||
(select idx from account where bjj = ?) ` + queryStr
|
|
||||||
queryStr += ", acc WHERE (tx.from_idx IN(acc.idx) OR tx.to_idx IN(acc.idx)) "
|
|
||||||
nextIsAnd = true
|
nextIsAnd = true
|
||||||
args = append(args, bjj)
|
args = append(args, bjj, bjj)
|
||||||
}
|
}
|
||||||
// tokenID filter
|
// tokenID filter
|
||||||
if tokenID != nil {
|
if tokenID != nil {
|
||||||
@@ -1302,10 +1298,30 @@ func (hdb *HistoryDB) AddBlockSCData(blockData *common.BlockData) (err error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add l1 Txs
|
// Prepare user L1 txs to be added.
|
||||||
if len(blockData.Rollup.L1UserTxs) > 0 {
|
// They must be added before the batch that will forge them (which can be in the same block)
|
||||||
if err := hdb.addL1Txs(txn, blockData.Rollup.L1UserTxs); err != nil {
|
// and after the account that will be sent to (also can be in the same block).
|
||||||
return err
|
// Note: insert order is not relevant since item_id will be updated by a DB trigger when
|
||||||
|
// the batch that forges those txs is inserted
|
||||||
|
userL1s := make(map[common.BatchNum][]common.L1Tx)
|
||||||
|
for i := range blockData.Rollup.L1UserTxs {
|
||||||
|
batchThatForgesIsInTheBlock := false
|
||||||
|
for _, batch := range blockData.Rollup.Batches {
|
||||||
|
if batch.Batch.ForgeL1TxsNum != nil &&
|
||||||
|
*batch.Batch.ForgeL1TxsNum == *blockData.Rollup.L1UserTxs[i].ToForgeL1TxsNum {
|
||||||
|
// Tx is forged in this block. It's guaranteed that:
|
||||||
|
// * the first batch of the block won't forge user L1 txs that have been added in this block
|
||||||
|
// * batch nums are sequential therefore it's safe to add the tx at batch.BatchNum -1
|
||||||
|
batchThatForgesIsInTheBlock = true
|
||||||
|
addAtBatchNum := batch.Batch.BatchNum - 1
|
||||||
|
userL1s[addAtBatchNum] = append(userL1s[addAtBatchNum], blockData.Rollup.L1UserTxs[i])
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !batchThatForgesIsInTheBlock {
|
||||||
|
// User artificial batchNum 0 to add txs that are not forge in this block
|
||||||
|
// after all the accounts of the block have been added
|
||||||
|
userL1s[0] = append(userL1s[0], blockData.Rollup.L1UserTxs[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1318,6 +1334,13 @@ func (hdb *HistoryDB) AddBlockSCData(blockData *common.BlockData) (err error) {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add accounts
|
||||||
|
if len(batch.CreatedAccounts) > 0 {
|
||||||
|
if err := hdb.addAccounts(txn, batch.CreatedAccounts); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Add forged l1 coordinator Txs
|
// Add forged l1 coordinator Txs
|
||||||
if len(batch.L1CoordinatorTxs) > 0 {
|
if len(batch.L1CoordinatorTxs) > 0 {
|
||||||
if err := hdb.addL1Txs(txn, batch.L1CoordinatorTxs); err != nil {
|
if err := hdb.addL1Txs(txn, batch.L1CoordinatorTxs); err != nil {
|
||||||
@@ -1332,9 +1355,9 @@ func (hdb *HistoryDB) AddBlockSCData(blockData *common.BlockData) (err error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add accounts
|
// Add user L1 txs that will be forged in next batch
|
||||||
if len(batch.CreatedAccounts) > 0 {
|
if userlL1s, ok := userL1s[batch.Batch.BatchNum]; ok {
|
||||||
if err := hdb.addAccounts(txn, batch.CreatedAccounts); err != nil {
|
if err := hdb.addL1Txs(txn, userlL1s); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1346,6 +1369,12 @@ func (hdb *HistoryDB) AddBlockSCData(blockData *common.BlockData) (err error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Add user L1 txs that won't be forged in this block
|
||||||
|
if userL1sNotForgedInThisBlock, ok := userL1s[0]; ok {
|
||||||
|
if err := hdb.addL1Txs(txn, userL1sNotForgedInThisBlock); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
if blockData.Rollup.Vars != nil {
|
if blockData.Rollup.Vars != nil {
|
||||||
if err := hdb.setRollupVars(txn, blockData.Rollup.Vars); err != nil {
|
if err := hdb.setRollupVars(txn, blockData.Rollup.Vars); err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
@@ -448,7 +448,7 @@ DECLARE
|
|||||||
_tx_timestamp TIMESTAMP;
|
_tx_timestamp TIMESTAMP;
|
||||||
BEGIN
|
BEGIN
|
||||||
IF NEW.is_l1 THEN
|
IF NEW.is_l1 THEN
|
||||||
-- Validate
|
-- Validate L1 Tx
|
||||||
IF NEW.user_origin IS NULL OR
|
IF NEW.user_origin IS NULL OR
|
||||||
NEW.from_eth_addr IS NULL OR
|
NEW.from_eth_addr IS NULL OR
|
||||||
NEW.from_bjj IS NULL OR
|
NEW.from_bjj IS NULL OR
|
||||||
@@ -458,7 +458,7 @@ BEGIN
|
|||||||
RAISE EXCEPTION 'Invalid L1 tx: %', NEW;
|
RAISE EXCEPTION 'Invalid L1 tx: %', NEW;
|
||||||
END IF;
|
END IF;
|
||||||
ELSE
|
ELSE
|
||||||
-- Validate
|
-- Validate L2 Tx
|
||||||
IF NEW.batch_num IS NULL OR NEW.nonce IS NULL THEN
|
IF NEW.batch_num IS NULL OR NEW.nonce IS NULL THEN
|
||||||
RAISE EXCEPTION 'Invalid L2 tx: %', NEW;
|
RAISE EXCEPTION 'Invalid L2 tx: %', NEW;
|
||||||
END IF;
|
END IF;
|
||||||
@@ -474,17 +474,22 @@ BEGIN
|
|||||||
-- Set USD related
|
-- Set USD related
|
||||||
SELECT INTO _value, _usd_update, _tx_timestamp
|
SELECT INTO _value, _usd_update, _tx_timestamp
|
||||||
usd / POWER(10, decimals), usd_update, timestamp FROM token INNER JOIN block on token.eth_block_num = block.eth_block_num WHERE token_id = NEW.token_id;
|
usd / POWER(10, decimals), usd_update, timestamp FROM token INNER JOIN block on token.eth_block_num = block.eth_block_num WHERE token_id = NEW.token_id;
|
||||||
IF _tx_timestamp - interval '24 hours' < _usd_update AND _tx_timestamp + interval '24 hours' > _usd_update THEN
|
IF _usd_update - interval '24 hours' < _usd_update AND _usd_update + interval '24 hours' > _usd_update THEN
|
||||||
NEW."amount_usd" = (SELECT _value * NEW.amount_f);
|
IF _value > 0.0 THEN
|
||||||
IF NOT NEW.is_l1 THEN
|
IF NEW."amount_f" > 0.0 THEN
|
||||||
NEW."fee_usd" = (SELECT NEW."amount_usd" * fee_percentage(NEW.fee::NUMERIC));
|
NEW."amount_usd" = (SELECT _value * NEW."amount_f");
|
||||||
ELSE
|
IF NOT NEW."is_l1" AND NEW."fee" > 0 THEN
|
||||||
NEW."load_amount_usd" = (SELECT _value * NEW.load_amount_f);
|
NEW."fee_usd" = (SELECT NEW."amount_usd" * fee_percentage(NEW.fee::NUMERIC));
|
||||||
|
END IF;
|
||||||
|
END IF;
|
||||||
|
IF NEW."is_l1" AND NEW."load_amount_f" > 0.0 THEN
|
||||||
|
NEW."load_amount_usd" = (SELECT _value * NEW.load_amount_f);
|
||||||
|
END IF;
|
||||||
END IF;
|
END IF;
|
||||||
END IF;
|
END IF;
|
||||||
-- Set to_{eth_addr,bjj}
|
-- Set to_{eth_addr,bjj}
|
||||||
IF NEW.to_idx > 255 THEN
|
IF NEW."to_idx" > 255 THEN
|
||||||
SELECT INTO NEW."to_eth_addr", NEW."to_bjj" eth_addr, bjj FROM account WHERE idx = NEW.to_idx;
|
SELECT INTO NEW."to_eth_addr", NEW."to_bjj" eth_addr, bjj FROM account WHERE idx = NEW."to_idx";
|
||||||
END IF;
|
END IF;
|
||||||
RETURN NEW;
|
RETURN NEW;
|
||||||
END;
|
END;
|
||||||
|
|||||||
1
go.sum
1
go.sum
@@ -174,6 +174,7 @@ github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x
|
|||||||
github.com/getkin/kin-openapi v0.22.0 h1:J5IFyKd/5yuB6AZAgwK0CMBKnabWcmkowtsl6bRkz4s=
|
github.com/getkin/kin-openapi v0.22.0 h1:J5IFyKd/5yuB6AZAgwK0CMBKnabWcmkowtsl6bRkz4s=
|
||||||
github.com/getkin/kin-openapi v0.22.0/go.mod h1:WGRs2ZMM1Q8LR1QBEwUxC6RJEfaBcD0s+pcEVXFuAjw=
|
github.com/getkin/kin-openapi v0.22.0/go.mod h1:WGRs2ZMM1Q8LR1QBEwUxC6RJEfaBcD0s+pcEVXFuAjw=
|
||||||
github.com/getkin/kin-openapi v0.23.0 h1:RKtVNKk8kxcTIWEswgZ3Olvn1RxWOJ0zz8cP3d9aHIA=
|
github.com/getkin/kin-openapi v0.23.0 h1:RKtVNKk8kxcTIWEswgZ3Olvn1RxWOJ0zz8cP3d9aHIA=
|
||||||
|
github.com/getkin/kin-openapi v0.29.0 h1:YAJ8s2UFkhAfJ/bpDcBiUPD4spfVa1ur0FqhBuubaRw=
|
||||||
github.com/getsentry/raven-go v0.2.0 h1:no+xWJRb5ZI7eE8TWgIq1jLulQiIoLG0IfYxv5JYMGs=
|
github.com/getsentry/raven-go v0.2.0 h1:no+xWJRb5ZI7eE8TWgIq1jLulQiIoLG0IfYxv5JYMGs=
|
||||||
github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ=
|
github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ=
|
||||||
github.com/ghemawat/stream v0.0.0-20171120220530-696b145b53b9/go.mod h1:106OIgooyS7OzLDOpUGgm9fA3bQENb/cFSyyBmMoJDs=
|
github.com/ghemawat/stream v0.0.0-20171120220530-696b145b53b9/go.mod h1:106OIgooyS7OzLDOpUGgm9fA3bQENb/cFSyyBmMoJDs=
|
||||||
|
|||||||
Reference in New Issue
Block a user