Feature/merge history l2 tables (#156)

* WIP rebase

* Combine both SQL DBs

* API and DB refactor
This commit is contained in:
a_bennassar
2020-09-29 18:27:07 +02:00
committed by GitHub
parent 8efbb7ab18
commit c6f70f3177
34 changed files with 1493 additions and 990 deletions

View File

@@ -2,7 +2,6 @@ package api
import (
"errors"
"fmt"
"github.com/gin-gonic/gin"
"github.com/hermeznetwork/hermez-node/db/historydb"
@@ -11,8 +10,9 @@ import (
)
var h *historydb.HistoryDB
var s *statedb.StateDB // Not 100% sure if this is needed
var l2 *l2db.L2DB
// var s *statedb.StateDB // Not 100% sure if this is needed
// var l2 *l2db.L2DB
// SetAPIEndpoints sets the endpoints and the appropriate handlers, but doesn't start the server
func SetAPIEndpoints(
@@ -32,11 +32,9 @@ func SetAPIEndpoints(
}
h = hdb
s = sdb
l2 = l2db
// s = sdb
// l2 = l2db
// tmp
fmt.Println(h, s, l2)
// Add coordinator endpoints
if coordinatorEndpoints {
// Account

View File

@@ -7,6 +7,7 @@ import (
"fmt"
"io"
"io/ioutil"
"math"
"math/big"
"net/http"
"os"
@@ -19,13 +20,14 @@ import (
swagger "github.com/getkin/kin-openapi/openapi3filter"
"github.com/gin-gonic/gin"
"github.com/hermeznetwork/hermez-node/common"
dbUtils "github.com/hermeznetwork/hermez-node/db"
"github.com/hermeznetwork/hermez-node/db/historydb"
"github.com/hermeznetwork/hermez-node/db/l2db"
"github.com/hermeznetwork/hermez-node/db/statedb"
"github.com/hermeznetwork/hermez-node/log"
"github.com/hermeznetwork/hermez-node/test"
"github.com/iden3/go-iden3-crypto/babyjub"
"github.com/jinzhu/copier"
"github.com/mitchellh/copystructure"
"github.com/stretchr/testify/assert"
)
@@ -77,16 +79,18 @@ func TestMain(m *testing.M) {
// Init swagger
router := swagger.NewRouter().WithSwaggerFromFile("./swagger.yml")
// Init DBs
// HistoryDB
pass := os.Getenv("POSTGRES_PASS")
hdb, err := historydb.NewHistoryDB(5432, "localhost", "hermez", pass, "history")
db, err := dbUtils.InitSQLDB(5432, "localhost", "hermez", pass, "hermez")
if err != nil {
panic(err)
}
// Reset DB
hdb := historydb.NewHistoryDB(db)
err = hdb.Reorg(-1)
if err != nil {
panic(err)
}
// StateDB
dir, err := ioutil.TempDir("", "tmpdb")
if err != nil {
panic(err)
@@ -95,11 +99,10 @@ func TestMain(m *testing.M) {
if err != nil {
panic(err)
}
l2db, err := l2db.NewL2DB(5432, "localhost", "hermez", pass, "l2", 10, 512, 24*time.Hour)
if err != nil {
panic(err)
}
test.CleanL2DB(l2db.DB())
// L2DB
l2DB := l2db.NewL2DB(db, 10, 100, 24*time.Hour)
test.CleanL2DB(l2DB.DB())
// Init API
api := gin.Default()
if err := SetAPIEndpoints(
@@ -108,7 +111,7 @@ func TestMain(m *testing.M) {
api,
hdb,
sdb,
l2db,
l2DB,
); err != nil {
panic(err)
}
@@ -120,6 +123,7 @@ func TestMain(m *testing.M) {
panic(err)
}
}()
// Populate DBs
// Clean DB
err = h.Reorg(0)
@@ -203,40 +207,67 @@ func TestMain(m *testing.M) {
}
}
// find token
token := common.Token{}
for i := 0; i < len(tokens); i++ {
if tokens[i].TokenID == genericTx.TokenID {
token = tokens[i]
break
var token common.Token
if genericTx.IsL1 {
tokenID := genericTx.TokenID
found := false
for i := 0; i < len(tokens); i++ {
if tokens[i].TokenID == tokenID {
token = tokens[i]
found = true
break
}
}
if !found {
panic("Token not found")
}
} else {
token = test.GetToken(genericTx.FromIdx, accs, tokens)
}
var usd, loadUSD, feeUSD *float64
if token.USD != nil {
noDecimalsUSD := *token.USD / math.Pow(10, float64(token.Decimals))
usd = new(float64)
*usd = noDecimalsUSD * genericTx.AmountFloat
if genericTx.IsL1 {
loadUSD = new(float64)
*loadUSD = noDecimalsUSD * *genericTx.LoadAmountFloat
} else {
feeUSD = new(float64)
*feeUSD = *usd * genericTx.Fee.Percentage()
}
}
historyTxs = append(historyTxs, &historydb.HistoryTx{
IsL1: genericTx.IsL1,
TxID: genericTx.TxID,
Type: genericTx.Type,
Position: genericTx.Position,
FromIdx: genericTx.FromIdx,
ToIdx: genericTx.ToIdx,
Amount: genericTx.Amount,
AmountFloat: genericTx.AmountFloat,
TokenID: genericTx.TokenID,
USD: token.USD * genericTx.AmountFloat,
BatchNum: genericTx.BatchNum,
EthBlockNum: genericTx.EthBlockNum,
ToForgeL1TxsNum: genericTx.ToForgeL1TxsNum,
UserOrigin: genericTx.UserOrigin,
FromEthAddr: genericTx.FromEthAddr,
FromBJJ: genericTx.FromBJJ,
LoadAmount: genericTx.LoadAmount,
LoadAmountFloat: genericTx.LoadAmountFloat,
LoadAmountUSD: token.USD * genericTx.LoadAmountFloat,
Fee: genericTx.Fee,
FeeUSD: genericTx.Fee.Percentage() * token.USD * genericTx.AmountFloat,
Nonce: genericTx.Nonce,
Timestamp: timestamp,
TokenSymbol: token.Symbol,
CurrentUSD: token.USD * genericTx.AmountFloat,
USDUpdate: token.USDUpdate,
IsL1: genericTx.IsL1,
TxID: genericTx.TxID,
Type: genericTx.Type,
Position: genericTx.Position,
FromIdx: genericTx.FromIdx,
ToIdx: genericTx.ToIdx,
Amount: genericTx.Amount,
AmountFloat: genericTx.AmountFloat,
HistoricUSD: usd,
BatchNum: genericTx.BatchNum,
EthBlockNum: genericTx.EthBlockNum,
ToForgeL1TxsNum: genericTx.ToForgeL1TxsNum,
UserOrigin: genericTx.UserOrigin,
FromEthAddr: genericTx.FromEthAddr,
FromBJJ: genericTx.FromBJJ,
LoadAmount: genericTx.LoadAmount,
LoadAmountFloat: genericTx.LoadAmountFloat,
HistoricLoadAmountUSD: loadUSD,
Fee: genericTx.Fee,
HistoricFeeUSD: feeUSD,
Nonce: genericTx.Nonce,
Timestamp: timestamp,
TokenID: token.TokenID,
TokenEthBlockNum: token.EthBlockNum,
TokenEthAddr: token.EthAddr,
TokenName: token.Name,
TokenSymbol: token.Symbol,
TokenDecimals: token.Decimals,
TokenUSD: token.USD,
TokenUSDUpdate: token.USDUpdate,
})
}
return historyTxAPIs(historyTxsToAPI(historyTxs))
@@ -265,10 +296,7 @@ func TestMain(m *testing.M) {
if err := server.Shutdown(context.Background()); err != nil {
panic(err)
}
if err := h.Close(); err != nil {
panic(err)
}
if err := l2.Close(); err != nil {
if err := db.Close(); err != nil {
panic(err)
}
os.Exit(result)
@@ -279,11 +307,11 @@ func TestGetHistoryTxs(t *testing.T) {
fetchedTxs := historyTxAPIs{}
appendIter := func(intr interface{}) {
for i := 0; i < len(intr.(*historyTxsAPI).Txs); i++ {
tmp := &historyTxAPI{}
if err := copier.Copy(tmp, &intr.(*historyTxsAPI).Txs[i]); err != nil {
tmp, err := copystructure.Copy(intr.(*historyTxsAPI).Txs[i])
if err != nil {
panic(err)
}
fetchedTxs = append(fetchedTxs, *tmp)
fetchedTxs = append(fetchedTxs, tmp.(historyTxAPI))
}
}
// Get all (no filters)
@@ -315,7 +343,7 @@ func TestGetHistoryTxs(t *testing.T) {
// Get by tokenID
fetchedTxs = historyTxAPIs{}
limit = 5
tokenID := tc.allTxs[0].TokenID
tokenID := tc.allTxs[0].Token.TokenID
path = fmt.Sprintf(
"%s?tokenId=%d&limit=%d&offset=",
endpoint, tokenID, limit,
@@ -324,7 +352,7 @@ func TestGetHistoryTxs(t *testing.T) {
assert.NoError(t, err)
tokenIDTxs := historyTxAPIs{}
for i := 0; i < len(tc.allTxs); i++ {
if tc.allTxs[i].TokenID == tokenID {
if tc.allTxs[i].Token.TokenID == tokenID {
tokenIDTxs = append(tokenIDTxs, tc.allTxs[i])
}
}
@@ -407,7 +435,7 @@ func TestGetHistoryTxs(t *testing.T) {
mixedTxs := historyTxAPIs{}
for i := 0; i < len(tc.allTxs); i++ {
if tc.allTxs[i].BatchNum != nil {
if *tc.allTxs[i].BatchNum == *batchNum && tc.allTxs[i].TokenID == tokenID {
if *tc.allTxs[i].BatchNum == *batchNum && tc.allTxs[i].Token.TokenID == tokenID {
mixedTxs = append(mixedTxs, tc.allTxs[i])
}
}
@@ -420,11 +448,11 @@ func TestGetHistoryTxs(t *testing.T) {
appendIterRev := func(intr interface{}) {
tmpAll := historyTxAPIs{}
for i := 0; i < len(intr.(*historyTxsAPI).Txs); i++ {
tmpItem := &historyTxAPI{}
if err := copier.Copy(tmpItem, &intr.(*historyTxsAPI).Txs[i]); err != nil {
tmp, err := copystructure.Copy(intr.(*historyTxsAPI).Txs[i])
if err != nil {
panic(err)
}
tmpAll = append(tmpAll, *tmpItem)
tmpAll = append(tmpAll, tmp.(historyTxAPI))
}
fetchedTxs = append(tmpAll, fetchedTxs...)
}
@@ -455,15 +483,17 @@ func assertHistoryTxAPIs(t *testing.T, expected, actual historyTxAPIs) {
for i := 0; i < len(actual); i++ { //nolint len(actual) won't change within the loop
assert.Equal(t, expected[i].Timestamp.Unix(), actual[i].Timestamp.Unix())
expected[i].Timestamp = actual[i].Timestamp
assert.Equal(t, expected[i].USDUpdate.Unix(), actual[i].USDUpdate.Unix())
expected[i].USDUpdate = actual[i].USDUpdate
if expected[i].Token.USDUpdate == nil {
assert.Equal(t, expected[i].Token.USDUpdate, actual[i].Token.USDUpdate)
} else {
assert.Equal(t, expected[i].Token.USDUpdate.Unix(), actual[i].Token.USDUpdate.Unix())
expected[i].Token.USDUpdate = actual[i].Token.USDUpdate
}
test.AssertUSD(t, expected[i].HistoricUSD, actual[i].HistoricUSD)
if expected[i].L2Info != nil {
if expected[i].L2Info.FeeUSD > actual[i].L2Info.FeeUSD {
assert.Less(t, 0.999, actual[i].L2Info.FeeUSD/expected[i].L2Info.FeeUSD)
} else if expected[i].L2Info.FeeUSD < actual[i].L2Info.FeeUSD {
assert.Less(t, 0.999, expected[i].L2Info.FeeUSD/actual[i].L2Info.FeeUSD)
}
expected[i].L2Info.FeeUSD = actual[i].L2Info.FeeUSD
test.AssertUSD(t, expected[i].L2Info.HistoricFeeUSD, actual[i].L2Info.HistoricFeeUSD)
} else {
test.AssertUSD(t, expected[i].L1Info.HistoricLoadAmountUSD, actual[i].L1Info.HistoricLoadAmountUSD)
}
assert.Equal(t, expected[i], actual[i])
}

View File

@@ -5,6 +5,7 @@ import (
"strconv"
"time"
ethCommon "github.com/ethereum/go-ethereum/common"
"github.com/hermeznetwork/hermez-node/common"
"github.com/hermeznetwork/hermez-node/db/historydb"
"github.com/iden3/go-iden3-crypto/babyjub"
@@ -37,19 +38,19 @@ func (htx *historyTxsAPI) GetPagination() pagination { return htx.Pagination }
func (htx *historyTxsAPI) Len() int { return len(htx.Txs) }
type l1Info struct {
ToForgeL1TxsNum int64 `json:"toForgeL1TransactionsNum"`
UserOrigin bool `json:"userOrigin"`
FromEthAddr string `json:"fromEthereumAddress"`
FromBJJ string `json:"fromBJJ"`
LoadAmount string `json:"loadAmount"`
LoadAmountUSD float64 `json:"loadAmountUSD"`
EthBlockNum int64 `json:"ethereumBlockNum"`
ToForgeL1TxsNum int64 `json:"toForgeL1TransactionsNum"`
UserOrigin bool `json:"userOrigin"`
FromEthAddr string `json:"fromHezEthereumAddress"`
FromBJJ string `json:"fromBJJ"`
LoadAmount string `json:"loadAmount"`
HistoricLoadAmountUSD *float64 `json:"historicLoadAmountUSD"`
EthBlockNum int64 `json:"ethereumBlockNum"`
}
type l2Info struct {
Fee common.FeeSelector `json:"fee"`
FeeUSD float64 `json:"feeUSD"`
Nonce common.Nonce `json:"nonce"`
Fee common.FeeSelector `json:"fee"`
HistoricFeeUSD *float64 `json:"historicFeeUSD"`
Nonce common.Nonce `json:"nonce"`
}
type historyTxAPI struct {
@@ -61,14 +62,11 @@ type historyTxAPI struct {
ToIdx string `json:"toAccountIndex"`
Amount string `json:"amount"`
BatchNum *common.BatchNum `json:"batchNum"`
TokenID common.TokenID `json:"tokenId"`
TokenSymbol string `json:"tokenSymbol"`
USD float64 `json:"historicUSD"`
HistoricUSD *float64 `json:"historicUSD"`
Timestamp time.Time `json:"timestamp"`
CurrentUSD float64 `json:"currentUSD"`
USDUpdate time.Time `json:"fiatUpdate"`
L1Info *l1Info `json:"L1Info"`
L2Info *l2Info `json:"L2Info"`
Token common.Token `json:"token"`
}
func historyTxsToAPI(dbTxs []*historydb.HistoryTx) []historyTxAPI {
@@ -78,40 +76,42 @@ func historyTxsToAPI(dbTxs []*historydb.HistoryTx) []historyTxAPI {
TxID: dbTxs[i].TxID,
Type: dbTxs[i].Type,
Position: dbTxs[i].Position,
FromIdx: "hez:" + dbTxs[i].TokenSymbol + ":" + strconv.Itoa(int(dbTxs[i].FromIdx)),
ToIdx: "hez:" + dbTxs[i].TokenSymbol + ":" + strconv.Itoa(int(dbTxs[i].ToIdx)),
FromIdx: idxToHez(dbTxs[i].FromIdx, dbTxs[i].TokenSymbol),
ToIdx: idxToHez(dbTxs[i].ToIdx, dbTxs[i].TokenSymbol),
Amount: dbTxs[i].Amount.String(),
TokenID: dbTxs[i].TokenID,
USD: dbTxs[i].USD,
BatchNum: nil,
HistoricUSD: dbTxs[i].HistoricUSD,
BatchNum: dbTxs[i].BatchNum,
Timestamp: dbTxs[i].Timestamp,
TokenSymbol: dbTxs[i].TokenSymbol,
CurrentUSD: dbTxs[i].CurrentUSD,
USDUpdate: dbTxs[i].USDUpdate,
L1Info: nil,
L2Info: nil,
}
bn := dbTxs[i].BatchNum
if dbTxs[i].BatchNum != 0 {
apiTx.BatchNum = &bn
Token: common.Token{
TokenID: dbTxs[i].TokenID,
EthBlockNum: dbTxs[i].TokenEthBlockNum,
EthAddr: dbTxs[i].TokenEthAddr,
Name: dbTxs[i].TokenName,
Symbol: dbTxs[i].TokenSymbol,
Decimals: dbTxs[i].TokenDecimals,
USD: dbTxs[i].TokenUSD,
USDUpdate: dbTxs[i].TokenUSDUpdate,
},
L1Info: nil,
L2Info: nil,
}
if dbTxs[i].IsL1 {
apiTx.IsL1 = "L1"
apiTx.L1Info = &l1Info{
ToForgeL1TxsNum: dbTxs[i].ToForgeL1TxsNum,
UserOrigin: dbTxs[i].UserOrigin,
FromEthAddr: "hez:" + dbTxs[i].FromEthAddr.String(),
FromBJJ: bjjToString(dbTxs[i].FromBJJ),
LoadAmount: dbTxs[i].LoadAmount.String(),
LoadAmountUSD: dbTxs[i].LoadAmountUSD,
EthBlockNum: dbTxs[i].EthBlockNum,
ToForgeL1TxsNum: dbTxs[i].ToForgeL1TxsNum,
UserOrigin: dbTxs[i].UserOrigin,
FromEthAddr: ethAddrToHez(dbTxs[i].FromEthAddr),
FromBJJ: bjjToString(dbTxs[i].FromBJJ),
LoadAmount: dbTxs[i].LoadAmount.String(),
HistoricLoadAmountUSD: dbTxs[i].HistoricLoadAmountUSD,
EthBlockNum: dbTxs[i].EthBlockNum,
}
} else {
apiTx.IsL1 = "L2"
apiTx.L2Info = &l2Info{
Fee: dbTxs[i].Fee,
FeeUSD: dbTxs[i].FeeUSD,
Nonce: dbTxs[i].Nonce,
Fee: *dbTxs[i].Fee,
HistoricFeeUSD: dbTxs[i].HistoricFeeUSD,
Nonce: *dbTxs[i].Nonce,
}
}
apiTxs = append(apiTxs, apiTx)
@@ -128,3 +128,11 @@ func bjjToString(bjj *babyjub.PublicKey) string {
bjjSum := append(pkComp[:], sum)
return "hez:" + base64.RawURLEncoding.EncodeToString(bjjSum)
}
func ethAddrToHez(addr ethCommon.Address) string {
return "hez:" + addr.String()
}
func idxToHez(idx common.Idx, tokenSymbol string) string {
return "hez:" + tokenSymbol + ":" + strconv.Itoa(int(idx))
}

View File

@@ -96,7 +96,7 @@ paths:
application/json:
schema:
$ref: '#/components/schemas/Error500'
'/account-creation-authorization/{hermezEthereumAddress}':
'/account-creation-authorization/{hezEthereumAddress}':
get:
tags:
- Account
@@ -105,12 +105,12 @@ paths:
True if the coordinator has the required authorization to perform an account creation with the given Ethereum address on behalf of the Ethereum address holder.
operationId: getAccountCreationAuthorization
parameters:
- name: hermezEthereumAddress
- name: hezEthereumAddress
in: path
description: Ethereum address.
required: true
schema:
$ref: '#/components/schemas/HermezEthereumAddress'
$ref: '#/components/schemas/HezEthereumAddress'
responses:
'200':
description: Successful operation.
@@ -144,15 +144,15 @@ paths:
description: Get accounts balances and other associated information.
operationId: getAccounts
parameters:
- name: hermezEthereumAddress
- name: hezEthereumAddress
in: query
description: Only get accounts associated to an Ethereum address. Incompatible with the query `BJJ`.
required: false
schema:
$ref: '#/components/schemas/HermezEthereumAddress'
$ref: '#/components/schemas/HezEthereumAddress'
- name: BJJ
in: query
description: Only get accounts associated to a BabyJubJub public key. Incompatible with the query `hermezEthereumAddress`.
description: Only get accounts associated to a BabyJubJub public key. Incompatible with the query `hezEthereumAddress`.
required: false
schema:
$ref: '#/components/schemas/BJJ'
@@ -258,21 +258,21 @@ paths:
description: Get exit information. This information is required to perform a withdraw.
operationId: getExits
parameters:
- name: hermezEthereumAddress
- name: hezEthereumAddress
in: query
description: Get exits associated to a Ethereum address. Incompatible with query `BJJ` and `accountIndex`.
required: false
schema:
$ref: '#/components/schemas/HermezEthereumAddress'
$ref: '#/components/schemas/HezEthereumAddress'
- name: BJJ
in: query
description: Get exits associated to a BabyJubJub public key. Incompatible with query `hermezEthereumAddress` and `accountIndex`.
description: Get exits associated to a BabyJubJub public key. Incompatible with query `hezEthereumAddress` and `accountIndex`.
required: false
schema:
$ref: '#/components/schemas/BJJ'
- name: accountIndex
in: query
description: Get exits associated to a specific account. Incompatible with queries `hermezEthereumAddress` and `BJJ`.
description: Get exits associated to a specific account. Incompatible with queries `hezEthereumAddress` and `BJJ`.
required: false
schema:
$ref: '#/components/schemas/AccountIndex'
@@ -388,7 +388,7 @@ paths:
content:
application/json:
schema:
$ref: '#/components/schemas/PoolL2Transaction'
$ref: '#/components/schemas/PostPoolL2Transaction'
responses:
'200':
description: Successful operation.
@@ -468,22 +468,22 @@ paths:
description: Only get transactions of specific token
schema:
$ref: '#/components/schemas/TokenId'
- name: hermezEthereumAddress
- name: hezEthereumAddress
in: query
required: false
description: Only get transactions sent from or to an account associated to an Ethereum address Incompatible with the queries `BJJ` and `accountIndex`.
schema:
$ref: '#/components/schemas/HermezEthereumAddress'
$ref: '#/components/schemas/HezEthereumAddress'
- name: BJJ
in: query
description: Only get transactions associated to a BabyJubJub public key. Incompatible with the queries `hermezEthereumAddress` and `accountIndex`.
description: Only get transactions associated to a BabyJubJub public key. Incompatible with the queries `hezEthereumAddress` and `accountIndex`.
required: false
schema:
$ref: '#/components/schemas/BJJ'
- name: accountIndex
in: query
required: false
description: Only get transactions sent from or to a specific account. Incompatible with the queries `tokenId`, `hermezEthereumAddress` and `BJJ`.
description: Only get transactions sent from or to a specific account. Incompatible with the queries `tokenId`, `hezEthereumAddress` and `BJJ`.
schema:
$ref: '#/components/schemas/AccountIndex'
- name: batchNum
@@ -1228,6 +1228,101 @@ paths:
$ref: '#/components/schemas/Error500'
components:
schemas:
PostPoolL2Transaction:
type: object
properties:
id:
$ref: '#/components/schemas/TransactionId'
type:
$ref: '#/components/schemas/TransactionType'
tokenId:
$ref: '#/components/schemas/TokenId'
fromAccountIndex:
$ref: '#/components/schemas/AccountIndex'
toAccountIndex:
allOf:
- $ref: '#/components/schemas/AccountIndex'
- example: "hez:DAI:672"
toHezEthereumAddress:
$ref: '#/components/schemas/HezEthereumAddress'
toBjj:
$ref: '#/components/schemas/BJJ'
amount:
allOf:
- $ref: '#/components/schemas/BigInt'
- description: Amount of tokens to be sent.
example: "63"
fee:
$ref: '#/components/schemas/FeeSelector'
nonce:
$ref: '#/components/schemas/Nonce'
signature:
allOf:
- $ref: '#/components/schemas/Signature'
- description: Signature of the transaction. More info [here](https://idocs.hermez.io/#/spec/zkrollup/README?id=l2a-idl2).
- example: "72024a43f546b0e1d9d5d7c4c30c259102a9726363adcc4ec7b6aea686bcb5116f485c5542d27c4092ae0ceaf38e3bb44417639bd2070a58ba1aa1aab9d92c03"
requestFromAccountIndex:
type: string
description: References the `fromAccountIndex` of the requested transaction.
example: null
nullable: true
requestToAccountIndex:
type: string
description: References the `toAccountIndex` of the requested transaction.
example: null
nullable: true
requestToHezEthereumAddress:
type: string
description: References the `toHezEthereumAddress` of the requested transaction.
pattern: "^hez:0x[a-fA-F0-9]{40}$"
example: null
nullable: true
requestToBJJ:
type: string
description: References the `toBJJ` of the requested transaction.
pattern: "^hez:[A-Za-z0-9_-]{44}$"
example: null
nullable: true
requestTokenId:
type: integer
description: References the `tokenId` of the requested transaction.
example: null
nullable: true
requestAmount:
type: string
description: References the `amount` of the requested transaction.
example: null
nullable: true
requestFee:
type: integer
description: References the `fee` of the requested transaction.
example: null
nullable: true
requestNonce:
type: integer
description: References the `nonce` of the requested transaction.
example: null
nullable: true
required:
- id
- type
- tokenId
- fromAccountIndex
- toHezAccountIndex
- toHezEthereumAddress
- toBjj
- amount
- fee
- nonce
- signature
- requestFromAccountIndex
- requestToAccountIndex
- requestToHezEthereumAddress
- requestToBJJ
- requestTokenId
- requestAmount
- requestFee
- requestNonce
PoolL2Transaction:
type: object
properties:
@@ -1241,20 +1336,10 @@ components:
allOf:
- $ref: '#/components/schemas/AccountIndex'
- example: "hez:DAI:672"
toEthereumAddress:
$ref: '#/components/schemas/HermezEthereumAddress'
toHezEthereumAddress:
$ref: '#/components/schemas/HezEthereumAddress'
toBjj:
$ref: '#/components/schemas/BJJ'
tokenId:
$ref: '#/components/schemas/TokenId'
USD:
type: number
description: Value of the token in USD.
example: 4.53
fiatUpdate:
type: string
format: date-time
description: Timestamp of the moment the `USD` value was updated.
amount:
allOf:
- $ref: '#/components/schemas/BigInt'
@@ -1262,10 +1347,6 @@ components:
example: "63"
fee:
$ref: '#/components/schemas/FeeSelector'
feeUSD:
type: number
description: Fee in USD.
example: 0.75
nonce:
$ref: '#/components/schemas/Nonce'
state:
@@ -1294,9 +1375,9 @@ components:
- $ref: '#/components/schemas/AccountIndex'
- nullable: true
- example: "hez:DAI:33"
requestToEthereumAddress:
requestToHezEthereumAddress:
allOf:
- $ref: '#/components/schemas/HermezEthereumAddress'
- $ref: '#/components/schemas/HezEthereumAddress'
- nullable: true
- example: "hez:0xbb942cfcd25ad4d90a62358b0dd84f33b3982699"
requestToBJJ:
@@ -1325,12 +1406,12 @@ components:
- $ref: '#/components/schemas/Nonce'
- nullable: true
- example: 6
tokenSymbol:
$ref: '#/components/schemas/TokenSymbol'
token:
$ref: '#/components/schemas/Token'
required:
- fromAccountIndex
- toAccountIndex
- toEthereumAddress
- toHezAccountIndex
- toHezEthereumAddress
- toBjj
- tokenId
- amount
@@ -1346,14 +1427,14 @@ components:
description: "Address of an Etherum account."
pattern: "^0x[a-fA-F0-9]{40}$"
example: "0xaa942cfcd25ad4d90a62358b0dd84f33b398262a"
HermezEthereumAddress:
HezEthereumAddress:
type: string
description: "Address of an Etherum account linked to the Hermez network."
pattern: "^hez:0x[a-fA-F0-9]{40}$"
example: "hez:0xaa942cfcd25ad4d90a62358b0dd84f33b398262a"
BJJ:
type: string
description: "BabyJubJub public key, encoded as base64, which result in 33 bytes (last byte used as checksum)."
description: "BabyJubJub public key, encoded as base64 URL (RFC 4648), which result in 33 bytes. The padding byte is replaced by a sum of the encoded bytes."
pattern: "^hez:[A-Za-z0-9_-]{44}$"
example: "hez:rR7LXKal-av7I56Y0dEBCVmwc9zpoLY5ERhy5w7G-xwe"
AccountIndex:
@@ -1429,8 +1510,8 @@ components:
timestamp:
type: string
format: date-time
ethereumAddress:
$ref: '#/components/schemas/HermezEthereumAddress'
hezEthereumAddress:
$ref: '#/components/schemas/HezEthereumAddress'
bjj:
$ref: '#/components/schemas/BJJ'
signature:
@@ -1475,26 +1556,17 @@ components:
maximum: 4294967295
example: 5432
nullable: true
tokenId:
$ref: '#/components/schemas/TokenId'
tokenSymbol:
$ref: '#/components/schemas/TokenSymbol'
historicUSD:
type: number
description: Value in USD at the moment the transaction was forged.
example: 49.7
currentUSD:
type: number
description: Value in USD at the current token/USD conversion.
example: 50.01
fiatUpdate:
type: string
format: date-time
description: Timestamp of the moment the `currentUSD` value was updated.
nullable: true
timestamp:
type: string
format: date-time
description: In the case of L1 indicates the moment where the transaction was added in the smart contract. For L2 indicates when the transaction was forged.
token:
$ref: '#/components/schemas/Token'
L1Info:
type: object
description: Additional information that only applies to L1 transactions.
@@ -1505,8 +1577,8 @@ components:
userOrigin:
type: boolean
description: True if the transaction was sent by a user. False if it was sent by a coordinator.
fromEthereumAddress:
$ref: '#/components/schemas/HermezEthereumAddress'
fromHezEthereumAddress:
$ref: '#/components/schemas/HezEthereumAddress'
fromBJJ:
$ref: '#/components/schemas/BJJ'
loadAmount:
@@ -1514,10 +1586,11 @@ components:
- $ref: '#/components/schemas/BigInt'
- description: Tokens transfered from L1 to L2.
- example: "49"
loadAmountUSD:
historicLoadAmountUSD:
type: number
description: Load amount in USD, at the moment the transaction was made.
example: 3.897
nullable: true
ethereumBlockNum:
allOf:
- $ref: '#/components/schemas/EthBlockNum'
@@ -1526,10 +1599,10 @@ components:
required:
- toForgeL1TransactionsNum
- userOrigin
- fromEthereumAddress
- fromHezEthereumAddress
- fromBJJ
- loadAmount
- loadAmountUSD
- historicLoadAmountUSD
- ethereumBlockNum
additionalProperties: false
L2Info:
@@ -1539,16 +1612,17 @@ components:
properties:
fee:
$ref: '#/components/schemas/FeeSelector'
feeUSD:
historicFeeUSD:
type: number
description: Fee in USD, at the moment the transaction was forged.
example: 263.89
nullable: true
nonce:
$ref: '#/components/schemas/Nonce'
example: null
required:
- fee
- feeUSD
- historicFeeUSD
- nonce
additionalProperties: false
required:
@@ -1560,12 +1634,9 @@ components:
- toAccountIndex
- amount
- batchNum
- tokenId
- tokenSymbol
- historicUSD
- currentUSD
- fiatUpdate
- timestamp
- token
- L1Info
- L2Info
additionalProperties: false
@@ -1618,10 +1689,8 @@ components:
items:
type: object
properties:
tokenId:
$ref: '#/components/schemas/TokenId'
tokenSymbol:
$ref: '#/components/schemas/TokenSymbol'
token:
$ref: '#/components/schemas/Token'
amount:
allOf:
- $ref: '#/components/schemas/BigInt'
@@ -1635,13 +1704,21 @@ components:
$ref: '#/components/schemas/BatchNum'
ethereumBlockNum:
$ref: '#/components/schemas/EthBlockNum'
ethereumBlockHash:
type: string
description: hash of the Ethereum block in which the batch was forged
example: "0xfe88c94d860f01a17f961bf4bdfb6e0c6cd10d3fda5cc861e805ca1240c58553"
timestamp:
type: string
format: date-time
description: Time in which the batch was forged.
forgerAddr:
$ref: '#/components/schemas/EthereumAddress'
collectedFees:
$ref: '#/components/schemas/CollectedFees'
totalCollectedFeesUSD:
historicTotalCollectedFeesUSD:
type: number
description: Sum of the all the fees collected, in USD.
description: Sum of the all the fees collected, in USD, at the moment the batch was forged.
example: 23.3
stateRoot:
allOf:
@@ -1668,35 +1745,8 @@ components:
type: object
description: Group of transactions forged in a coordinator and sent and validated in Ethereum.
properties:
batchNum:
$ref: '#/components/schemas/BatchNum'
forgerAddr:
$ref: '#/components/schemas/EthereumAddress'
collectedFees:
$ref: '#/components/schemas/CollectedFees'
ethereumBlockNum:
$ref: '#/components/schemas/EthBlockNum'
stateRoot:
allOf:
- $ref: '#/components/schemas/Hash'
- description: Root of the accounts Merkle Tree.
- example: "2734657026572a8708d883"
numAccounts:
type: integer
description: Number of registered accounts in this batch.
exitRoot:
allOf:
- $ref: '#/components/schemas/Hash'
- description: Root of the exit Merkle Tree associated to this batch.
- example: "2734657026572a8708d883"
forgeL1TransactionsNum:
allOf:
- $ref: '#/components/schemas/ToForgeL1TransactionsNum'
- description: Identifier that corresponds to the group of L1 transactions forged in the current batch.
- nullable: true
- example: 9
slotNum:
$ref: '#/components/schemas/SlotNum'
batch:
$ref: '#/components/schemas/Batch'
transactions:
type: array
description: List of forged transactions in the batch
@@ -1752,6 +1802,8 @@ components:
properties:
forgerAddr:
$ref: '#/components/schemas/EthereumAddress'
slotNum:
$ref: '#/components/schemas/SlotNum'
withdrawAddr:
$ref: '#/components/schemas/EthereumAddress'
URL:
@@ -1814,7 +1866,7 @@ components:
decimals:
type: integer
description: Number of decimals of the token.
example: 5
example: 18
ethereumBlockNum:
allOf:
- $ref: '#/components/schemas/EthBlockNum'
@@ -1823,11 +1875,23 @@ components:
USD:
type: number
description: Value of the token in USD.
example: 4.53
example: 1.01
nullable: true
fiatUpdate:
type: string
format: date-time
description: Timestamp of the moment the `USD` value was updated.
nullable: true
required:
- id
- ethereumAddress
- name
- symbol
- decimals
- ethereumBlockNum
- USD
- fiatUpdate
additionalProperties: false
Tokens:
type: object
properties:
@@ -1855,8 +1919,6 @@ components:
example: "0x347089321de8971320489793a823470918fffeab"
balance:
$ref: '#/components/schemas/BigInt'
nullifier:
$ref: '#/components/schemas/BigInt'
instantWithdrawn:
allOf:
- $ref: '#/components/schemas/EthBlockNum'
@@ -1872,6 +1934,8 @@ components:
- $ref: '#/components/schemas/EthBlockNum'
- description: Block in which the exit balance was delayed withdrawn after a delay withdraw request. Null indicates that a delay withdraw hasn't been performed.
- example: null
token:
$ref: '#/components/schemas/Token'
Exits:
type: object
properties:
@@ -1888,24 +1952,16 @@ components:
properties:
accountIndex:
$ref: '#/components/schemas/AccountIndex'
tokenId:
$ref: '#/components/schemas/TokenId'
tokenSymbol:
$ref: '#/components/schemas/TokenSymbol'
tokenName:
$ref: '#/components/schemas/TokenName'
nonce:
$ref: '#/components/schemas/Nonce'
balance:
$ref: '#/components/schemas/BigInt'
balanceUSD:
type: integer
description: Balance of the account in USD
example: 1304
bjj:
$ref: '#/components/schemas/BJJ'
ethereumAddress:
$ref: '#/components/schemas/HermezEthereumAddress'
hezEthereumAddress:
$ref: '#/components/schemas/HezEthereumAddress'
token:
$ref: '#/components/schemas/Token'
Accounts:
type: object
properties:
@@ -2053,6 +2109,7 @@ components:
allOf:
- $ref: '#/components/schemas/EthereumAddress'
- description: Ethereum address of the boot coordinator.
- example: "0x997dc4262BCDbf85190C01c996b4C06a461d2430"
slotDeadline:
type: integer
description: Number of blocks at the end of a slot in which any coordinator can forge if the winner has not forged one before.
@@ -2078,6 +2135,7 @@ components:
allOf:
- $ref: '#/components/schemas/EthereumAddress'
- description: Ethereum address where the donations will go to.
- example: "0x887dc4262BCDbf85190C01c996b4C06a461d2430"
allocationRatio:
type: array
description: Percentage in which fees will be splitted between donations, governance and burning. The sum of the tree values should be 100.
@@ -2092,22 +2150,27 @@ components:
allOf:
- $ref: '#/components/schemas/EthereumAddress'
- description: Ethereum address of the rollup smart contract.
- example: "0x777dc4262BCDbf85190C01c996b4C06a461d2430"
governanceAddress:
allOf:
- $ref: '#/components/schemas/EthereumAddress'
- description: Ethereum address of the governance mechanism.
- example: "0x667dc4262BCDbf85190C01c996b4C06a461d2430"
whitheHackerGroupAddress:
allOf:
- $ref: '#/components/schemas/EthereumAddress'
- description: Ethereum Address that can claim the funds in an emergency when the maximum emergency mode time is exceeded.
- example: "0x557dc4262BCDbf85190C01c996b4C06a461d2430"
keeperAddress:
allOf:
- $ref: '#/components/schemas/EthereumAddress'
- description: Ethereum Address that can enable emergency mode and modify the delay to make a withdrawal.
- example: "0x557dc4262BCDbf85190C01c996b4C06a461d2430"
withdrawalDelay:
allOf:
- $ref: '#/components/schemas/EthBlockNum'
- description: The time that anyone needs to wait until a withdrawal of the funds is allowed, in Ethereum blocks.
- example: 539573849
emergencyModeStartingTime:
type: integer
description: Ethereum block in which the emergency mode will be activated.
@@ -2140,6 +2203,7 @@ components:
allOf:
- $ref: '#/components/schemas/EthereumAddress'
- description: Ethereum address of the HEZ token.
- example: "0x444dc4262BCDbf85190C01c996b4C06a461d2430"
maxTxVerifiers:
type: integer
description: Maximum transactions of the verifiers.
@@ -2214,10 +2278,12 @@ components:
allOf:
- $ref: '#/components/schemas/EthereumAddress'
- description: Ethereum address of the HEZ token.
- example: "0x333dc4262BCDbf85190C01c996b4C06a461d2430"
rollupAddress:
allOf:
- $ref: '#/components/schemas/EthereumAddress'
- description: Ethereum address of the rollup smart contract.
- example: "0x222dc4262BCDbf85190C01c996b4C06a461d2430"
genesisBlockNum:
allOf:
- $ref: '#/components/schemas/EthBlockNum'