mirror of
https://github.com/arnaucube/hermez-node.git
synced 2026-02-07 03:16:45 +01:00
Merge pull request #142 from hermeznetwork/feature/api-boilerplate
Add GET histroy-transactions endpoint
This commit is contained in:
19
api/README.md
Normal file
19
api/README.md
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
# Hermez API
|
||||||
|
|
||||||
|
Easy to deploy and scale API for Hermez operators.
|
||||||
|
You will need to have [docker](https://docs.docker.com/engine/install/) and [docker-compose](https://docs.docker.com/compose/install/) installed on your machine in order to use this repo.
|
||||||
|
|
||||||
|
## Documentation
|
||||||
|
|
||||||
|
As of now the documentation is not hosted anywhere, but you can easily do it yourself by running `./run.sh doc` and then [opening the documentation in your browser](http://localhost:8001)
|
||||||
|
|
||||||
|
## Mock Up
|
||||||
|
|
||||||
|
To use a mock up of the endpoints in the API run `./run.sh doc` (UI + mock up server) or `./run.sh mock` (only mock up server). You can play with the mocked up endpoints using the [web UI](http://localhost:8001), importing `swagger.yml` into Postman or using your preferred language and using `http://loclahost:4010` as base URL.
|
||||||
|
|
||||||
|
## Editor
|
||||||
|
|
||||||
|
It is recomended to edit `swagger.yml` using a dedicated editor as they provide spec validation and real time visualization. Of course you can use your prefered editor. To use the editor run `./run.sh editor` and then [opening the editor in your browser](http://localhost:8002).
|
||||||
|
**Keep in mind that you will need to manually save the file otherwise you will lose the changes** you made once you close your browser seshion or stop the server.
|
||||||
|
|
||||||
|
**Note:** Your browser may cache the swagger definition, so in order to see updated changes it may be needed to refresh the page without cache (Ctrl + Shift + R).
|
||||||
77
api/api.go
Normal file
77
api/api.go
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/hermeznetwork/hermez-node/db/historydb"
|
||||||
|
"github.com/hermeznetwork/hermez-node/db/l2db"
|
||||||
|
"github.com/hermeznetwork/hermez-node/db/statedb"
|
||||||
|
)
|
||||||
|
|
||||||
|
var h *historydb.HistoryDB
|
||||||
|
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(
|
||||||
|
coordinatorEndpoints, explorerEndpoints bool,
|
||||||
|
server *gin.Engine,
|
||||||
|
hdb *historydb.HistoryDB,
|
||||||
|
sdb *statedb.StateDB,
|
||||||
|
l2db *l2db.L2DB,
|
||||||
|
) error {
|
||||||
|
// Check input
|
||||||
|
// TODO: is stateDB only needed for explorer endpoints or for both?
|
||||||
|
if coordinatorEndpoints && l2db == nil {
|
||||||
|
return errors.New("cannot serve Coordinator endpoints without L2DB")
|
||||||
|
}
|
||||||
|
if explorerEndpoints && hdb == nil {
|
||||||
|
return errors.New("cannot serve Explorer endpoints without HistoryDB")
|
||||||
|
}
|
||||||
|
|
||||||
|
h = hdb
|
||||||
|
s = sdb
|
||||||
|
l2 = l2db
|
||||||
|
|
||||||
|
// tmp
|
||||||
|
fmt.Println(h, s, l2)
|
||||||
|
// Add coordinator endpoints
|
||||||
|
if coordinatorEndpoints {
|
||||||
|
// Account
|
||||||
|
server.POST("/account-creation-authorization", postAccountCreationAuth)
|
||||||
|
server.GET("/account-creation-authorization/:hermezEthereumAddress", getAccountCreationAuth)
|
||||||
|
// Transaction
|
||||||
|
server.POST("/transactions-pool", postPoolTx)
|
||||||
|
server.POST("/transactions-pool/:id", getPoolTx)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add explorer endpoints
|
||||||
|
if explorerEndpoints {
|
||||||
|
// Account
|
||||||
|
server.GET("/accounts", getAccounts)
|
||||||
|
server.GET("/accounts/:hermezEthereumAddress/:accountIndex", getAccount)
|
||||||
|
server.GET("/exits", getExits)
|
||||||
|
server.GET("/exits/:batchNum/:accountIndex", getExit)
|
||||||
|
// Transaction
|
||||||
|
server.GET("/transactions-history", getHistoryTxs)
|
||||||
|
server.GET("/transactions-history/:id", getHistoryTx)
|
||||||
|
// Status
|
||||||
|
server.GET("/batches", getBatches)
|
||||||
|
server.GET("/batches/:batchNum", getBatch)
|
||||||
|
server.GET("/full-batches/:batchNum", getFullBatch)
|
||||||
|
server.GET("/slots", getSlots)
|
||||||
|
server.GET("/bids", getBids)
|
||||||
|
server.GET("/next-forgers", getNextForgers)
|
||||||
|
server.GET("/state", getState)
|
||||||
|
server.GET("/config", getConfig)
|
||||||
|
server.GET("/tokens", getTokens)
|
||||||
|
server.GET("/tokens/:id", getToken)
|
||||||
|
server.GET("/recommendedFee", getRecommendedFee)
|
||||||
|
server.GET("/coordinators", getCoordinators)
|
||||||
|
server.GET("/coordinators/:forgerAddr", getCoordinator)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
621
api/api_test.go
Normal file
621
api/api_test.go
Normal file
@@ -0,0 +1,621 @@
|
|||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
|
"math/big"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"sort"
|
||||||
|
"strconv"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
ethCommon "github.com/ethereum/go-ethereum/common"
|
||||||
|
swagger "github.com/getkin/kin-openapi/openapi3filter"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/hermeznetwork/hermez-node/common"
|
||||||
|
"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/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
const apiPort = ":4010"
|
||||||
|
const apiURL = "http://localhost" + apiPort + "/"
|
||||||
|
|
||||||
|
type testCommon struct {
|
||||||
|
blocks []common.Block
|
||||||
|
tokens []common.Token
|
||||||
|
batches []common.Batch
|
||||||
|
usrAddr string
|
||||||
|
usrBjj string
|
||||||
|
accs []common.Account
|
||||||
|
usrTxs historyTxAPIs
|
||||||
|
othrTxs historyTxAPIs
|
||||||
|
allTxs historyTxAPIs
|
||||||
|
router *swagger.Router
|
||||||
|
}
|
||||||
|
|
||||||
|
type historyTxAPIs []historyTxAPI
|
||||||
|
|
||||||
|
func (h historyTxAPIs) Len() int { return len(h) }
|
||||||
|
func (h historyTxAPIs) Swap(i, j int) { h[i], h[j] = h[j], h[i] }
|
||||||
|
func (h historyTxAPIs) Less(i, j int) bool {
|
||||||
|
// i not forged yet
|
||||||
|
if h[i].BatchNum == nil {
|
||||||
|
if h[j].BatchNum != nil { // j is already forged
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
// Both aren't forged, is i in a smaller position?
|
||||||
|
return h[i].Position < h[j].Position
|
||||||
|
}
|
||||||
|
// i is forged
|
||||||
|
if h[j].BatchNum == nil {
|
||||||
|
return true // j is not forged
|
||||||
|
}
|
||||||
|
// Both are forged
|
||||||
|
if *h[i].BatchNum == *h[j].BatchNum {
|
||||||
|
// At the same batch, is i in a smaller position?
|
||||||
|
return h[i].Position < h[j].Position
|
||||||
|
}
|
||||||
|
// At different batches, is i in a smaller batch?
|
||||||
|
return *h[i].BatchNum < *h[j].BatchNum
|
||||||
|
}
|
||||||
|
|
||||||
|
var tc testCommon
|
||||||
|
|
||||||
|
func TestMain(m *testing.M) {
|
||||||
|
// Init swagger
|
||||||
|
router := swagger.NewRouter().WithSwaggerFromFile("./swagger.yml")
|
||||||
|
// Init DBs
|
||||||
|
pass := os.Getenv("POSTGRES_PASS")
|
||||||
|
hdb, err := historydb.NewHistoryDB(5432, "localhost", "hermez", pass, "history")
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
dir, err := ioutil.TempDir("", "tmpdb")
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
sdb, err := statedb.NewStateDB(dir, false, 0)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
l2db, err := l2db.NewL2DB(5432, "localhost", "hermez", pass, "l2", 10, 512, 24*time.Hour)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
// Init API
|
||||||
|
api := gin.Default()
|
||||||
|
if err := SetAPIEndpoints(
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
api,
|
||||||
|
hdb,
|
||||||
|
sdb,
|
||||||
|
l2db,
|
||||||
|
); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
// Start server
|
||||||
|
server := &http.Server{Addr: apiPort, Handler: api}
|
||||||
|
go func() {
|
||||||
|
if err := server.ListenAndServe(); err != nil &&
|
||||||
|
err != http.ErrServerClosed {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
// Populate DBs
|
||||||
|
// Clean DB
|
||||||
|
err = h.Reorg(0)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
// Gen blocks and add them to DB
|
||||||
|
const nBlocks = 5
|
||||||
|
blocks := test.GenBlocks(1, nBlocks+1)
|
||||||
|
err = h.AddBlocks(blocks)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
// Gen tokens and add them to DB
|
||||||
|
const nTokens = 10
|
||||||
|
tokens := test.GenTokens(nTokens, blocks)
|
||||||
|
err = h.AddTokens(tokens)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
// Gen batches and add them to DB
|
||||||
|
const nBatches = 10
|
||||||
|
batches := test.GenBatches(nBatches, blocks)
|
||||||
|
err = h.AddBatches(batches)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
// Gen accounts and add them to DB
|
||||||
|
const totalAccounts = 40
|
||||||
|
const userAccounts = 4
|
||||||
|
usrAddr := ethCommon.BigToAddress(big.NewInt(4896847))
|
||||||
|
privK := babyjub.NewRandPrivKey()
|
||||||
|
usrBjj := privK.Public()
|
||||||
|
accs := test.GenAccounts(totalAccounts, userAccounts, tokens, &usrAddr, usrBjj, batches)
|
||||||
|
err = h.AddAccounts(accs)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
// Gen L1Txs and add them to DB
|
||||||
|
const totalL1Txs = 40
|
||||||
|
const userL1Txs = 4
|
||||||
|
usrL1Txs, othrL1Txs := test.GenL1Txs(0, totalL1Txs, userL1Txs, &usrAddr, accs, tokens, blocks, batches)
|
||||||
|
var l1Txs []common.L1Tx
|
||||||
|
l1Txs = append(l1Txs, usrL1Txs...)
|
||||||
|
l1Txs = append(l1Txs, othrL1Txs...)
|
||||||
|
err = h.AddL1Txs(l1Txs)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
// Gen L2Txs and add them to DB
|
||||||
|
const totalL2Txs = 20
|
||||||
|
const userL2Txs = 4
|
||||||
|
usrL2Txs, othrL2Txs := test.GenL2Txs(totalL1Txs, totalL2Txs, userL2Txs, &usrAddr, accs, tokens, blocks, batches)
|
||||||
|
var l2Txs []common.L2Tx
|
||||||
|
l2Txs = append(l2Txs, usrL2Txs...)
|
||||||
|
l2Txs = append(l2Txs, othrL2Txs...)
|
||||||
|
err = h.AddL2Txs(l2Txs)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set test commons
|
||||||
|
txsToAPITxs := func(l1Txs []common.L1Tx, l2Txs []common.L2Tx, blocks []common.Block, tokens []common.Token) historyTxAPIs {
|
||||||
|
// Transform L1Txs and L2Txs to generic Txs
|
||||||
|
genericTxs := []*common.Tx{}
|
||||||
|
for _, l1tx := range l1Txs {
|
||||||
|
genericTxs = append(genericTxs, l1tx.Tx())
|
||||||
|
}
|
||||||
|
for _, l2tx := range l2Txs {
|
||||||
|
genericTxs = append(genericTxs, l2tx.Tx())
|
||||||
|
}
|
||||||
|
// Transform generic Txs to HistoryTx
|
||||||
|
historyTxs := []*historydb.HistoryTx{}
|
||||||
|
for _, genericTx := range genericTxs {
|
||||||
|
// find timestamp
|
||||||
|
var timestamp time.Time
|
||||||
|
for i := 0; i < len(blocks); i++ {
|
||||||
|
if blocks[i].EthBlockNum == genericTx.EthBlockNum {
|
||||||
|
timestamp = blocks[i].Timestamp
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// find token
|
||||||
|
token := common.Token{}
|
||||||
|
for i := 0; i < len(tokens); i++ {
|
||||||
|
if tokens[i].TokenID == genericTx.TokenID {
|
||||||
|
token = tokens[i]
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return historyTxAPIs(historyTxsToAPI(historyTxs))
|
||||||
|
}
|
||||||
|
usrTxs := txsToAPITxs(usrL1Txs, usrL2Txs, blocks, tokens)
|
||||||
|
sort.Sort(usrTxs)
|
||||||
|
othrTxs := txsToAPITxs(othrL1Txs, othrL2Txs, blocks, tokens)
|
||||||
|
sort.Sort(othrTxs)
|
||||||
|
allTxs := append(usrTxs, othrTxs...)
|
||||||
|
sort.Sort(allTxs)
|
||||||
|
tc = testCommon{
|
||||||
|
blocks: blocks,
|
||||||
|
tokens: tokens,
|
||||||
|
batches: batches,
|
||||||
|
usrAddr: "hez:" + usrAddr.String(),
|
||||||
|
usrBjj: bjjToString(usrBjj),
|
||||||
|
accs: accs,
|
||||||
|
usrTxs: usrTxs,
|
||||||
|
othrTxs: othrTxs,
|
||||||
|
allTxs: allTxs,
|
||||||
|
router: router,
|
||||||
|
}
|
||||||
|
// Run tests
|
||||||
|
result := m.Run()
|
||||||
|
// Stop server
|
||||||
|
if err := server.Shutdown(context.Background()); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
if err := h.Close(); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
if err := l2.Close(); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
os.Exit(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetHistoryTxs(t *testing.T) {
|
||||||
|
endpoint := apiURL + "transactions-history"
|
||||||
|
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 {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
fetchedTxs = append(fetchedTxs, *tmp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Get all (no filters)
|
||||||
|
limit := 8
|
||||||
|
path := fmt.Sprintf("%s?limit=%d&offset=", endpoint, limit)
|
||||||
|
err := doGoodReqPaginated(path, &historyTxsAPI{}, appendIter)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assertHistoryTxAPIs(t, tc.allTxs, fetchedTxs)
|
||||||
|
// Get by ethAddr
|
||||||
|
fetchedTxs = historyTxAPIs{}
|
||||||
|
limit = 7
|
||||||
|
path = fmt.Sprintf(
|
||||||
|
"%s?hermezEthereumAddress=%s&limit=%d&offset=",
|
||||||
|
endpoint, tc.usrAddr, limit,
|
||||||
|
)
|
||||||
|
err = doGoodReqPaginated(path, &historyTxsAPI{}, appendIter)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assertHistoryTxAPIs(t, tc.usrTxs, fetchedTxs)
|
||||||
|
// Get by bjj
|
||||||
|
fetchedTxs = historyTxAPIs{}
|
||||||
|
limit = 6
|
||||||
|
path = fmt.Sprintf(
|
||||||
|
"%s?BJJ=%s&limit=%d&offset=",
|
||||||
|
endpoint, tc.usrBjj, limit,
|
||||||
|
)
|
||||||
|
err = doGoodReqPaginated(path, &historyTxsAPI{}, appendIter)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assertHistoryTxAPIs(t, tc.usrTxs, fetchedTxs)
|
||||||
|
// Get by tokenID
|
||||||
|
fetchedTxs = historyTxAPIs{}
|
||||||
|
limit = 5
|
||||||
|
tokenID := tc.allTxs[0].TokenID
|
||||||
|
path = fmt.Sprintf(
|
||||||
|
"%s?tokenId=%d&limit=%d&offset=",
|
||||||
|
endpoint, tokenID, limit,
|
||||||
|
)
|
||||||
|
err = doGoodReqPaginated(path, &historyTxsAPI{}, appendIter)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
tokenIDTxs := historyTxAPIs{}
|
||||||
|
for i := 0; i < len(tc.allTxs); i++ {
|
||||||
|
if tc.allTxs[i].TokenID == tokenID {
|
||||||
|
tokenIDTxs = append(tokenIDTxs, tc.allTxs[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assertHistoryTxAPIs(t, tokenIDTxs, fetchedTxs)
|
||||||
|
// idx
|
||||||
|
fetchedTxs = historyTxAPIs{}
|
||||||
|
limit = 4
|
||||||
|
idx := tc.allTxs[0].FromIdx
|
||||||
|
path = fmt.Sprintf(
|
||||||
|
"%s?accountIndex=%s&limit=%d&offset=",
|
||||||
|
endpoint, idx, limit,
|
||||||
|
)
|
||||||
|
err = doGoodReqPaginated(path, &historyTxsAPI{}, appendIter)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
idxTxs := historyTxAPIs{}
|
||||||
|
for i := 0; i < len(tc.allTxs); i++ {
|
||||||
|
if tc.allTxs[i].FromIdx == idx {
|
||||||
|
idxTxs = append(idxTxs, tc.allTxs[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assertHistoryTxAPIs(t, idxTxs, fetchedTxs)
|
||||||
|
// batchNum
|
||||||
|
fetchedTxs = historyTxAPIs{}
|
||||||
|
limit = 3
|
||||||
|
batchNum := tc.allTxs[0].BatchNum
|
||||||
|
path = fmt.Sprintf(
|
||||||
|
"%s?batchNum=%d&limit=%d&offset=",
|
||||||
|
endpoint, *batchNum, limit,
|
||||||
|
)
|
||||||
|
err = doGoodReqPaginated(path, &historyTxsAPI{}, appendIter)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
batchNumTxs := historyTxAPIs{}
|
||||||
|
for i := 0; i < len(tc.allTxs); i++ {
|
||||||
|
if tc.allTxs[i].BatchNum != nil &&
|
||||||
|
*tc.allTxs[i].BatchNum == *batchNum {
|
||||||
|
batchNumTxs = append(batchNumTxs, tc.allTxs[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assertHistoryTxAPIs(t, batchNumTxs, fetchedTxs)
|
||||||
|
// type
|
||||||
|
txTypes := []common.TxType{
|
||||||
|
common.TxTypeExit,
|
||||||
|
common.TxTypeWithdrawn,
|
||||||
|
common.TxTypeTransfer,
|
||||||
|
common.TxTypeDeposit,
|
||||||
|
common.TxTypeCreateAccountDeposit,
|
||||||
|
common.TxTypeCreateAccountDepositTransfer,
|
||||||
|
common.TxTypeDepositTransfer,
|
||||||
|
common.TxTypeForceTransfer,
|
||||||
|
common.TxTypeForceExit,
|
||||||
|
common.TxTypeTransferToEthAddr,
|
||||||
|
common.TxTypeTransferToBJJ,
|
||||||
|
}
|
||||||
|
for _, txType := range txTypes {
|
||||||
|
fetchedTxs = historyTxAPIs{}
|
||||||
|
limit = 2
|
||||||
|
path = fmt.Sprintf(
|
||||||
|
"%s?type=%s&limit=%d&offset=",
|
||||||
|
endpoint, txType, limit,
|
||||||
|
)
|
||||||
|
err = doGoodReqPaginated(path, &historyTxsAPI{}, appendIter)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
txTypeTxs := historyTxAPIs{}
|
||||||
|
for i := 0; i < len(tc.allTxs); i++ {
|
||||||
|
if tc.allTxs[i].Type == txType {
|
||||||
|
txTypeTxs = append(txTypeTxs, tc.allTxs[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assertHistoryTxAPIs(t, txTypeTxs, fetchedTxs)
|
||||||
|
}
|
||||||
|
// Multiple filters
|
||||||
|
fetchedTxs = historyTxAPIs{}
|
||||||
|
limit = 1
|
||||||
|
path = fmt.Sprintf(
|
||||||
|
"%s?batchNum=%d&tokeId=%d&limit=%d&offset=",
|
||||||
|
endpoint, *batchNum, tokenID, limit,
|
||||||
|
)
|
||||||
|
err = doGoodReqPaginated(path, &historyTxsAPI{}, appendIter)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
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 {
|
||||||
|
mixedTxs = append(mixedTxs, tc.allTxs[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assertHistoryTxAPIs(t, mixedTxs, fetchedTxs)
|
||||||
|
// All, in reverse order
|
||||||
|
fetchedTxs = historyTxAPIs{}
|
||||||
|
limit = 5
|
||||||
|
path = fmt.Sprintf("%s?", endpoint)
|
||||||
|
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 {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
tmpAll = append(tmpAll, *tmpItem)
|
||||||
|
}
|
||||||
|
fetchedTxs = append(tmpAll, fetchedTxs...)
|
||||||
|
}
|
||||||
|
err = doGoodReqPaginatedReverse(path, &historyTxsAPI{}, appendIterRev, limit)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assertHistoryTxAPIs(t, tc.allTxs, fetchedTxs)
|
||||||
|
// 400
|
||||||
|
path = fmt.Sprintf(
|
||||||
|
"%s?accountIndex=%s&hermezEthereumAddress=%s",
|
||||||
|
endpoint, idx, tc.usrAddr,
|
||||||
|
)
|
||||||
|
err = doBadReq("GET", path, nil, 400)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
path = fmt.Sprintf("%s?tokenId=X", endpoint)
|
||||||
|
err = doBadReq("GET", path, nil, 400)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
// 404
|
||||||
|
path = fmt.Sprintf("%s?batchNum=999999", endpoint)
|
||||||
|
err = doBadReq("GET", path, nil, 404)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
path = fmt.Sprintf("%s?limit=1000&offset=1000", endpoint)
|
||||||
|
err = doBadReq("GET", path, nil, 404)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func assertHistoryTxAPIs(t *testing.T, expected, actual historyTxAPIs) {
|
||||||
|
assert.Equal(t, len(expected), len(actual))
|
||||||
|
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].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
|
||||||
|
}
|
||||||
|
assert.Equal(t, expected[i], actual[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func doGoodReqPaginated(
|
||||||
|
path string,
|
||||||
|
iterStruct paginationer,
|
||||||
|
appendIter func(res interface{}),
|
||||||
|
) error {
|
||||||
|
next := 0
|
||||||
|
for {
|
||||||
|
// Call API to get this iteration items
|
||||||
|
if err := doGoodReq("GET", path+strconv.Itoa(next), nil, iterStruct); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
appendIter(iterStruct)
|
||||||
|
// Keep iterating?
|
||||||
|
pag := iterStruct.GetPagination()
|
||||||
|
if pag.LastReturnedItem == pag.TotalItems-1 { // No
|
||||||
|
break
|
||||||
|
} else { // Yes
|
||||||
|
next = int(pag.LastReturnedItem + 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func doGoodReqPaginatedReverse(
|
||||||
|
path string,
|
||||||
|
iterStruct paginationer,
|
||||||
|
appendIter func(res interface{}),
|
||||||
|
limit int,
|
||||||
|
) error {
|
||||||
|
next := 0
|
||||||
|
first := true
|
||||||
|
for {
|
||||||
|
// Call API to get this iteration items
|
||||||
|
if first {
|
||||||
|
first = false
|
||||||
|
pagQuery := fmt.Sprintf("last=true&limit=%d", limit)
|
||||||
|
if err := doGoodReq("GET", path+pagQuery, nil, iterStruct); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
pagQuery := fmt.Sprintf("offset=%d&limit=%d", next, limit)
|
||||||
|
if err := doGoodReq("GET", path+pagQuery, nil, iterStruct); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
appendIter(iterStruct)
|
||||||
|
// Keep iterating?
|
||||||
|
pag := iterStruct.GetPagination()
|
||||||
|
if iterStruct.Len() == pag.TotalItems || pag.LastReturnedItem-iterStruct.Len() == -1 { // No
|
||||||
|
break
|
||||||
|
} else { // Yes
|
||||||
|
prevOffset := next
|
||||||
|
next = pag.LastReturnedItem - iterStruct.Len() - limit + 1
|
||||||
|
if next < 0 {
|
||||||
|
next = 0
|
||||||
|
limit = prevOffset
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func doGoodReq(method, path string, reqBody io.Reader, returnStruct interface{}) error {
|
||||||
|
ctx := context.Background()
|
||||||
|
client := &http.Client{}
|
||||||
|
httpReq, _ := http.NewRequest(method, path, reqBody)
|
||||||
|
route, pathParams, err := tc.router.FindRoute(httpReq.Method, httpReq.URL)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// Validate request against swagger spec
|
||||||
|
requestValidationInput := &swagger.RequestValidationInput{
|
||||||
|
Request: httpReq,
|
||||||
|
PathParams: pathParams,
|
||||||
|
Route: route,
|
||||||
|
}
|
||||||
|
if err := swagger.ValidateRequest(ctx, requestValidationInput); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// Do API call
|
||||||
|
resp, err := client.Do(httpReq)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if resp.Body == nil {
|
||||||
|
return errors.New("Nil body")
|
||||||
|
}
|
||||||
|
//nolint
|
||||||
|
defer resp.Body.Close()
|
||||||
|
body, err := ioutil.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if resp.StatusCode != 200 {
|
||||||
|
return fmt.Errorf("%d response: %s", resp.StatusCode, string(body))
|
||||||
|
}
|
||||||
|
// Unmarshal body into return struct
|
||||||
|
if err := json.Unmarshal(body, returnStruct); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// Validate response against swagger spec
|
||||||
|
responseValidationInput := &swagger.ResponseValidationInput{
|
||||||
|
RequestValidationInput: requestValidationInput,
|
||||||
|
Status: resp.StatusCode,
|
||||||
|
Header: resp.Header,
|
||||||
|
}
|
||||||
|
responseValidationInput = responseValidationInput.SetBodyBytes(body)
|
||||||
|
return swagger.ValidateResponse(ctx, responseValidationInput)
|
||||||
|
}
|
||||||
|
|
||||||
|
func doBadReq(method, path string, reqBody io.Reader, expectedResponseCode int) error {
|
||||||
|
ctx := context.Background()
|
||||||
|
client := &http.Client{}
|
||||||
|
httpReq, _ := http.NewRequest(method, path, reqBody)
|
||||||
|
route, pathParams, err := tc.router.FindRoute(httpReq.Method, httpReq.URL)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// Validate request against swagger spec
|
||||||
|
requestValidationInput := &swagger.RequestValidationInput{
|
||||||
|
Request: httpReq,
|
||||||
|
PathParams: pathParams,
|
||||||
|
Route: route,
|
||||||
|
}
|
||||||
|
if err := swagger.ValidateRequest(ctx, requestValidationInput); err != nil {
|
||||||
|
if expectedResponseCode != 400 {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
log.Warn("The request does not match the API spec")
|
||||||
|
}
|
||||||
|
// Do API call
|
||||||
|
resp, err := client.Do(httpReq)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if resp.Body == nil {
|
||||||
|
return errors.New("Nil body")
|
||||||
|
}
|
||||||
|
//nolint
|
||||||
|
defer resp.Body.Close()
|
||||||
|
body, err := ioutil.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if resp.StatusCode != expectedResponseCode {
|
||||||
|
return fmt.Errorf("Unexpected response code: %d", resp.StatusCode)
|
||||||
|
}
|
||||||
|
// Validate response against swagger spec
|
||||||
|
responseValidationInput := &swagger.ResponseValidationInput{
|
||||||
|
RequestValidationInput: requestValidationInput,
|
||||||
|
Status: resp.StatusCode,
|
||||||
|
Header: resp.Header,
|
||||||
|
}
|
||||||
|
responseValidationInput = responseValidationInput.SetBodyBytes(body)
|
||||||
|
return swagger.ValidateResponse(ctx, responseValidationInput)
|
||||||
|
}
|
||||||
130
api/dbtoapistructs.go
Normal file
130
api/dbtoapistructs.go
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/base64"
|
||||||
|
"strconv"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/hermeznetwork/hermez-node/common"
|
||||||
|
"github.com/hermeznetwork/hermez-node/db/historydb"
|
||||||
|
"github.com/iden3/go-iden3-crypto/babyjub"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Commons of the API
|
||||||
|
|
||||||
|
type pagination struct {
|
||||||
|
TotalItems int `json:"totalItems"`
|
||||||
|
LastReturnedItem int `json:"lastReturnedItem"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type paginationer interface {
|
||||||
|
GetPagination() pagination
|
||||||
|
Len() int
|
||||||
|
}
|
||||||
|
|
||||||
|
type errorMsg struct {
|
||||||
|
Message string
|
||||||
|
}
|
||||||
|
|
||||||
|
// History Tx related
|
||||||
|
|
||||||
|
type historyTxsAPI struct {
|
||||||
|
Txs []historyTxAPI `json:"transactions"`
|
||||||
|
Pagination pagination `json:"pagination"`
|
||||||
|
}
|
||||||
|
|
||||||
|
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"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type l2Info struct {
|
||||||
|
Fee common.FeeSelector `json:"fee"`
|
||||||
|
FeeUSD float64 `json:"feeUSD"`
|
||||||
|
Nonce common.Nonce `json:"nonce"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type historyTxAPI struct {
|
||||||
|
IsL1 string `json:"L1orL2"`
|
||||||
|
TxID common.TxID `json:"id"`
|
||||||
|
Type common.TxType `json:"type"`
|
||||||
|
Position int `json:"position"`
|
||||||
|
FromIdx string `json:"fromAccountIndex"`
|
||||||
|
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"`
|
||||||
|
Timestamp time.Time `json:"timestamp"`
|
||||||
|
CurrentUSD float64 `json:"currentUSD"`
|
||||||
|
USDUpdate time.Time `json:"fiatUpdate"`
|
||||||
|
L1Info *l1Info `json:"L1Info"`
|
||||||
|
L2Info *l2Info `json:"L2Info"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func historyTxsToAPI(dbTxs []*historydb.HistoryTx) []historyTxAPI {
|
||||||
|
apiTxs := []historyTxAPI{}
|
||||||
|
for i := 0; i < len(dbTxs); i++ {
|
||||||
|
apiTx := 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)),
|
||||||
|
Amount: dbTxs[i].Amount.String(),
|
||||||
|
TokenID: dbTxs[i].TokenID,
|
||||||
|
USD: dbTxs[i].USD,
|
||||||
|
BatchNum: nil,
|
||||||
|
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
|
||||||
|
}
|
||||||
|
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,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
apiTx.IsL1 = "L2"
|
||||||
|
apiTx.L2Info = &l2Info{
|
||||||
|
Fee: dbTxs[i].Fee,
|
||||||
|
FeeUSD: dbTxs[i].FeeUSD,
|
||||||
|
Nonce: dbTxs[i].Nonce,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
apiTxs = append(apiTxs, apiTx)
|
||||||
|
}
|
||||||
|
return apiTxs
|
||||||
|
}
|
||||||
|
|
||||||
|
func bjjToString(bjj *babyjub.PublicKey) string {
|
||||||
|
pkComp := [32]byte(bjj.Compress())
|
||||||
|
sum := pkComp[0]
|
||||||
|
for i := 1; i < len(pkComp); i++ {
|
||||||
|
sum += pkComp[i]
|
||||||
|
}
|
||||||
|
bjjSum := append(pkComp[:], sum)
|
||||||
|
return "hez:" + base64.RawURLEncoding.EncodeToString(bjjSum)
|
||||||
|
}
|
||||||
32
api/docker-compose.yml
Normal file
32
api/docker-compose.yml
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
version: "3"
|
||||||
|
services:
|
||||||
|
hermez-api-doc:
|
||||||
|
container_name: hermez-api-doc
|
||||||
|
image: swaggerapi/swagger-ui
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- 8001:8080
|
||||||
|
volumes:
|
||||||
|
- .:/spec
|
||||||
|
environment:
|
||||||
|
- SWAGGER_JSON=/spec/swagger.yml
|
||||||
|
hermez-api-mock:
|
||||||
|
container_name: hermez-api-mock
|
||||||
|
image: stoplight/prism
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- 4010:4010
|
||||||
|
volumes:
|
||||||
|
- .:/spec
|
||||||
|
command: mock -h 0.0.0.0 "/spec/swagger.yml"
|
||||||
|
#docker run -d -p 80:8080 -e URL=/foo/swagger.json -v /bar:/usr/share/nginx/html/foo swaggerapi/swagger-editor
|
||||||
|
hermez-api-editor:
|
||||||
|
container_name: hermez-api-editor
|
||||||
|
image: swaggerapi/swagger-editor
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- 8002:8080
|
||||||
|
volumes:
|
||||||
|
- .:/spec
|
||||||
|
environment:
|
||||||
|
- SWAGGER_FILE=/spec/swagger.yml
|
||||||
204
api/handlers.go
Normal file
204
api/handlers.go
Normal file
@@ -0,0 +1,204 @@
|
|||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
"database/sql"
|
||||||
|
"errors"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
// maxLimit is the max permited items to be returned in paginated responses
|
||||||
|
const maxLimit uint = 2049
|
||||||
|
|
||||||
|
// dfltLast indicates how paginated endpoints use the query param last if not provided
|
||||||
|
const dfltLast = false
|
||||||
|
|
||||||
|
// dfltLimit indicates the limit of returned items in paginated responses if the query param limit is not provided
|
||||||
|
const dfltLimit uint = 20
|
||||||
|
|
||||||
|
// 2^32 -1
|
||||||
|
const maxUint32 = 4294967295
|
||||||
|
|
||||||
|
func postAccountCreationAuth(c *gin.Context) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func getAccountCreationAuth(c *gin.Context) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func postPoolTx(c *gin.Context) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func getPoolTx(c *gin.Context) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func getAccounts(c *gin.Context) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func getAccount(c *gin.Context) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func getExits(c *gin.Context) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func getExit(c *gin.Context) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func getHistoryTxs(c *gin.Context) {
|
||||||
|
// Get query parameters
|
||||||
|
// TokenID
|
||||||
|
tokenID, err := parseQueryUint("tokenId", nil, 0, maxUint32, c)
|
||||||
|
if err != nil {
|
||||||
|
retBadReq(err, c)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// Hez Eth addr
|
||||||
|
addr, err := parseQueryHezEthAddr(c)
|
||||||
|
if err != nil {
|
||||||
|
retBadReq(err, c)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// BJJ
|
||||||
|
bjj, err := parseQueryBJJ(c)
|
||||||
|
if err != nil {
|
||||||
|
retBadReq(err, c)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if addr != nil && bjj != nil {
|
||||||
|
retBadReq(errors.New("bjj and hermezEthereumAddress params are incompatible"), c)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// Idx
|
||||||
|
idx, err := parseIdx(c)
|
||||||
|
if err != nil {
|
||||||
|
retBadReq(err, c)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if idx != nil && (addr != nil || bjj != nil || tokenID != nil) {
|
||||||
|
retBadReq(errors.New("accountIndex is incompatible with BJJ, hermezEthereumAddress and tokenId"), c)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// BatchNum
|
||||||
|
batchNum, err := parseQueryUint("batchNum", nil, 0, maxUint32, c)
|
||||||
|
if err != nil {
|
||||||
|
retBadReq(err, c)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// TxType
|
||||||
|
txType, err := parseQueryTxType(c)
|
||||||
|
if err != nil {
|
||||||
|
retBadReq(err, c)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// Pagination
|
||||||
|
offset, last, limit, err := parsePagination(c)
|
||||||
|
if err != nil {
|
||||||
|
retBadReq(err, c)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fetch txs from historyDB
|
||||||
|
txs, totalItems, err := h.GetHistoryTxs(
|
||||||
|
addr, bjj, tokenID, idx, batchNum, txType, offset, limit, *last,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
retSQLErr(err, c)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build succesfull response
|
||||||
|
apiTxs := historyTxsToAPI(txs)
|
||||||
|
lastRet := int(*offset) + len(apiTxs) - 1
|
||||||
|
if *last {
|
||||||
|
lastRet = totalItems - 1
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusOK, &historyTxsAPI{
|
||||||
|
Txs: apiTxs,
|
||||||
|
Pagination: pagination{
|
||||||
|
TotalItems: totalItems,
|
||||||
|
LastReturnedItem: lastRet,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func getHistoryTx(c *gin.Context) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func getBatches(c *gin.Context) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func getBatch(c *gin.Context) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func getFullBatch(c *gin.Context) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func getSlots(c *gin.Context) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func getBids(c *gin.Context) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func getNextForgers(c *gin.Context) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func getState(c *gin.Context) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func getConfig(c *gin.Context) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func getTokens(c *gin.Context) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func getToken(c *gin.Context) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func getRecommendedFee(c *gin.Context) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func getCoordinators(c *gin.Context) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func getCoordinator(c *gin.Context) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func retSQLErr(err error, c *gin.Context) {
|
||||||
|
if err == sql.ErrNoRows {
|
||||||
|
c.JSON(http.StatusNotFound, errorMsg{
|
||||||
|
Message: err.Error(),
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
c.JSON(http.StatusInternalServerError, errorMsg{
|
||||||
|
Message: err.Error(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func retBadReq(err error, c *gin.Context) {
|
||||||
|
c.JSON(http.StatusBadRequest, errorMsg{
|
||||||
|
Message: err.Error(),
|
||||||
|
})
|
||||||
|
}
|
||||||
204
api/parsers.go
Normal file
204
api/parsers.go
Normal file
@@ -0,0 +1,204 @@
|
|||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/base64"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
ethCommon "github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/hermeznetwork/hermez-node/common"
|
||||||
|
"github.com/iden3/go-iden3-crypto/babyjub"
|
||||||
|
)
|
||||||
|
|
||||||
|
type querier interface {
|
||||||
|
Query(string) string
|
||||||
|
}
|
||||||
|
|
||||||
|
func parsePagination(c querier) (*uint, *bool, *uint, error) {
|
||||||
|
// Offset
|
||||||
|
offset := new(uint)
|
||||||
|
*offset = 0
|
||||||
|
offset, err := parseQueryUint("offset", offset, 0, maxUint32, c)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, nil, err
|
||||||
|
}
|
||||||
|
// Last
|
||||||
|
last := new(bool)
|
||||||
|
*last = dfltLast
|
||||||
|
last, err = parseQueryBool("last", last, c)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, nil, err
|
||||||
|
}
|
||||||
|
if *last && (offset != nil && *offset > 0) {
|
||||||
|
return nil, nil, nil, errors.New(
|
||||||
|
"last and offset are incompatible, provide only one of them",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
// Limit
|
||||||
|
limit := new(uint)
|
||||||
|
*limit = dfltLimit
|
||||||
|
limit, err = parseQueryUint("limit", limit, 1, maxLimit, c)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, nil, err
|
||||||
|
}
|
||||||
|
return offset, last, limit, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseQueryUint(name string, dflt *uint, min, max uint, c querier) (*uint, error) { //nolint:SA4009 res may be not overwriten
|
||||||
|
str := c.Query(name)
|
||||||
|
if str != "" {
|
||||||
|
resInt, err := strconv.Atoi(str)
|
||||||
|
if err != nil || resInt < 0 || resInt < int(min) || resInt > int(max) {
|
||||||
|
return nil, fmt.Errorf(
|
||||||
|
"Inavlid %s. Must be an integer within the range [%d, %d]",
|
||||||
|
name, min, max)
|
||||||
|
}
|
||||||
|
res := uint(resInt)
|
||||||
|
return &res, nil
|
||||||
|
}
|
||||||
|
return dflt, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseQueryBool(name string, dflt *bool, c querier) (*bool, error) { //nolint:SA4009 res may be not overwriten
|
||||||
|
str := c.Query(name)
|
||||||
|
if str == "" {
|
||||||
|
return dflt, nil
|
||||||
|
}
|
||||||
|
if str == "true" {
|
||||||
|
res := new(bool)
|
||||||
|
*res = true
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
if str == "false" {
|
||||||
|
res := new(bool)
|
||||||
|
*res = false
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("Inavlid %s. Must be eithe true or false", name)
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseQueryHezEthAddr(c querier) (*ethCommon.Address, error) {
|
||||||
|
const name = "hermezEthereumAddress"
|
||||||
|
addrStr := c.Query(name)
|
||||||
|
if addrStr == "" {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
splitted := strings.Split(addrStr, "hez:")
|
||||||
|
if len(splitted) != 2 || len(splitted[1]) != 42 {
|
||||||
|
return nil, fmt.Errorf(
|
||||||
|
"Invalid %s, must follow this regex: ^hez:0x[a-fA-F0-9]{40}$", name)
|
||||||
|
}
|
||||||
|
var addr ethCommon.Address
|
||||||
|
err := addr.UnmarshalText([]byte(splitted[1]))
|
||||||
|
return &addr, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseQueryBJJ(c querier) (*babyjub.PublicKey, error) {
|
||||||
|
const name = "BJJ"
|
||||||
|
const decodedLen = 33
|
||||||
|
bjjStr := c.Query(name)
|
||||||
|
if bjjStr == "" {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
splitted := strings.Split(bjjStr, "hez:")
|
||||||
|
if len(splitted) != 2 || len(splitted[1]) != 44 {
|
||||||
|
return nil, fmt.Errorf(
|
||||||
|
"Invalid %s, must follow this regex: ^hez:[A-Za-z0-9+/=]{44}$",
|
||||||
|
name)
|
||||||
|
}
|
||||||
|
decoded, err := base64.RawURLEncoding.DecodeString(splitted[1])
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf(
|
||||||
|
"Invalid %s, error decoding base64 string: %s",
|
||||||
|
name, err.Error())
|
||||||
|
}
|
||||||
|
if len(decoded) != decodedLen {
|
||||||
|
return nil, fmt.Errorf(
|
||||||
|
"invalid %s, error decoding base64 string: unexpected byte array length",
|
||||||
|
name)
|
||||||
|
}
|
||||||
|
bjjBytes := [decodedLen - 1]byte{}
|
||||||
|
copy(bjjBytes[:decodedLen-1], decoded[:decodedLen-1])
|
||||||
|
sum := bjjBytes[0]
|
||||||
|
for i := 1; i < len(bjjBytes); i++ {
|
||||||
|
sum += bjjBytes[i]
|
||||||
|
}
|
||||||
|
if decoded[decodedLen-1] != sum {
|
||||||
|
return nil, fmt.Errorf("invalid %s, checksum failed",
|
||||||
|
name)
|
||||||
|
}
|
||||||
|
bjjComp := babyjub.PublicKeyComp(bjjBytes)
|
||||||
|
bjj, err := bjjComp.Decompress()
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf(
|
||||||
|
"invalid %s, error decompressing public key: %s",
|
||||||
|
name, err.Error())
|
||||||
|
}
|
||||||
|
return bjj, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseQueryTxType(c querier) (*common.TxType, error) {
|
||||||
|
const name = "type"
|
||||||
|
typeStr := c.Query(name)
|
||||||
|
if typeStr == "" {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
switch common.TxType(typeStr) {
|
||||||
|
case common.TxTypeExit:
|
||||||
|
ret := common.TxTypeExit
|
||||||
|
return &ret, nil
|
||||||
|
case common.TxTypeWithdrawn:
|
||||||
|
ret := common.TxTypeWithdrawn
|
||||||
|
return &ret, nil
|
||||||
|
case common.TxTypeTransfer:
|
||||||
|
ret := common.TxTypeTransfer
|
||||||
|
return &ret, nil
|
||||||
|
case common.TxTypeDeposit:
|
||||||
|
ret := common.TxTypeDeposit
|
||||||
|
return &ret, nil
|
||||||
|
case common.TxTypeCreateAccountDeposit:
|
||||||
|
ret := common.TxTypeCreateAccountDeposit
|
||||||
|
return &ret, nil
|
||||||
|
case common.TxTypeCreateAccountDepositTransfer:
|
||||||
|
ret := common.TxTypeCreateAccountDepositTransfer
|
||||||
|
return &ret, nil
|
||||||
|
case common.TxTypeDepositTransfer:
|
||||||
|
ret := common.TxTypeDepositTransfer
|
||||||
|
return &ret, nil
|
||||||
|
case common.TxTypeForceTransfer:
|
||||||
|
ret := common.TxTypeForceTransfer
|
||||||
|
return &ret, nil
|
||||||
|
case common.TxTypeForceExit:
|
||||||
|
ret := common.TxTypeForceExit
|
||||||
|
return &ret, nil
|
||||||
|
case common.TxTypeTransferToEthAddr:
|
||||||
|
ret := common.TxTypeTransferToEthAddr
|
||||||
|
return &ret, nil
|
||||||
|
case common.TxTypeTransferToBJJ:
|
||||||
|
ret := common.TxTypeTransferToBJJ
|
||||||
|
return &ret, nil
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf(
|
||||||
|
"invalid %s, %s is not a valid option. Check the valid options in the docmentation",
|
||||||
|
name, typeStr,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseIdx(c querier) (*uint, error) {
|
||||||
|
const name = "accountIndex"
|
||||||
|
addrStr := c.Query(name)
|
||||||
|
if addrStr == "" {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
splitted := strings.Split(addrStr, ":")
|
||||||
|
const expectedLen = 3
|
||||||
|
if len(splitted) != expectedLen {
|
||||||
|
return nil, fmt.Errorf(
|
||||||
|
"invalid %s, must follow this: hez:<tokenSymbol>:index", name)
|
||||||
|
}
|
||||||
|
idxInt, err := strconv.Atoi(splitted[2])
|
||||||
|
idx := uint(idxInt)
|
||||||
|
return &idx, err
|
||||||
|
}
|
||||||
282
api/parsers_test.go
Normal file
282
api/parsers_test.go
Normal file
@@ -0,0 +1,282 @@
|
|||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/base64"
|
||||||
|
"math/big"
|
||||||
|
"strconv"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
ethCommon "github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/hermeznetwork/hermez-node/common"
|
||||||
|
"github.com/iden3/go-iden3-crypto/babyjub"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
type queryParser struct {
|
||||||
|
m map[string]string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (qp *queryParser) Query(query string) string {
|
||||||
|
if val, ok := qp.m[query]; ok {
|
||||||
|
return val
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestParseQueryUint(t *testing.T) {
|
||||||
|
name := "foo"
|
||||||
|
c := &queryParser{}
|
||||||
|
c.m = make(map[string]string)
|
||||||
|
var min uint = 1
|
||||||
|
var max uint = 10
|
||||||
|
var dflt *uint
|
||||||
|
// Not uint
|
||||||
|
c.m[name] = "-1"
|
||||||
|
_, err := parseQueryUint(name, dflt, min, max, c)
|
||||||
|
assert.Error(t, err)
|
||||||
|
c.m[name] = "a"
|
||||||
|
_, err = parseQueryUint(name, dflt, min, max, c)
|
||||||
|
assert.Error(t, err)
|
||||||
|
c.m[name] = "0.1"
|
||||||
|
_, err = parseQueryUint(name, dflt, min, max, c)
|
||||||
|
assert.Error(t, err)
|
||||||
|
c.m[name] = "1.0"
|
||||||
|
_, err = parseQueryUint(name, dflt, min, max, c)
|
||||||
|
assert.Error(t, err)
|
||||||
|
// Out of range
|
||||||
|
c.m[name] = strconv.Itoa(int(min) - 1)
|
||||||
|
_, err = parseQueryUint(name, dflt, min, max, c)
|
||||||
|
assert.Error(t, err)
|
||||||
|
c.m[name] = strconv.Itoa(int(max) + 1)
|
||||||
|
_, err = parseQueryUint(name, dflt, min, max, c)
|
||||||
|
assert.Error(t, err)
|
||||||
|
// Default nil
|
||||||
|
c.m[name] = ""
|
||||||
|
res, err := parseQueryUint(name, dflt, min, max, c)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Nil(t, res)
|
||||||
|
// Default not nil
|
||||||
|
dflt = new(uint)
|
||||||
|
*dflt = uint(min)
|
||||||
|
res, err = parseQueryUint(name, dflt, min, max, c)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, uint(min), *res)
|
||||||
|
// Correct
|
||||||
|
c.m[name] = strconv.Itoa(int(max))
|
||||||
|
res, err = parseQueryUint(name, res, min, max, c)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, uint(max), *res)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestParseQueryBool(t *testing.T) {
|
||||||
|
name := "foo"
|
||||||
|
c := &queryParser{}
|
||||||
|
c.m = make(map[string]string)
|
||||||
|
var dflt *bool
|
||||||
|
// Not bool
|
||||||
|
c.m[name] = "x"
|
||||||
|
_, err := parseQueryBool(name, dflt, c)
|
||||||
|
assert.Error(t, err)
|
||||||
|
c.m[name] = "False"
|
||||||
|
_, err = parseQueryBool(name, dflt, c)
|
||||||
|
assert.Error(t, err)
|
||||||
|
c.m[name] = "0"
|
||||||
|
_, err = parseQueryBool(name, dflt, c)
|
||||||
|
assert.Error(t, err)
|
||||||
|
c.m[name] = "1"
|
||||||
|
_, err = parseQueryBool(name, dflt, c)
|
||||||
|
assert.Error(t, err)
|
||||||
|
// Default nil
|
||||||
|
c.m[name] = ""
|
||||||
|
res, err := parseQueryBool(name, dflt, c)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Nil(t, res)
|
||||||
|
// Default not nil
|
||||||
|
dflt = new(bool)
|
||||||
|
*dflt = true
|
||||||
|
res, err = parseQueryBool(name, dflt, c)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.True(t, *res)
|
||||||
|
// Correct
|
||||||
|
c.m[name] = "false"
|
||||||
|
res, err = parseQueryBool(name, dflt, c)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.False(t, *res)
|
||||||
|
c.m[name] = "true"
|
||||||
|
res, err = parseQueryBool(name, dflt, c)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.True(t, *res)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestParsePagination(t *testing.T) {
|
||||||
|
c := &queryParser{}
|
||||||
|
c.m = make(map[string]string)
|
||||||
|
// Offset out of range
|
||||||
|
c.m["offset"] = "-1"
|
||||||
|
_, _, _, err := parsePagination(c)
|
||||||
|
assert.Error(t, err)
|
||||||
|
c.m["offset"] = strconv.Itoa(maxUint32 + 1)
|
||||||
|
_, _, _, err = parsePagination(c)
|
||||||
|
assert.Error(t, err)
|
||||||
|
c.m["offset"] = ""
|
||||||
|
// Limit out of range
|
||||||
|
c.m["limit"] = "0"
|
||||||
|
_, _, _, err = parsePagination(c)
|
||||||
|
assert.Error(t, err)
|
||||||
|
c.m["limit"] = strconv.Itoa(int(maxLimit) + 1)
|
||||||
|
_, _, _, err = parsePagination(c)
|
||||||
|
assert.Error(t, err)
|
||||||
|
c.m["limit"] = ""
|
||||||
|
// Last and offset
|
||||||
|
c.m["offset"] = "1"
|
||||||
|
c.m["last"] = "true"
|
||||||
|
_, _, _, err = parsePagination(c)
|
||||||
|
assert.Error(t, err)
|
||||||
|
// Default
|
||||||
|
c.m["offset"] = ""
|
||||||
|
c.m["last"] = ""
|
||||||
|
c.m["limit"] = ""
|
||||||
|
offset, last, limit, err := parsePagination(c)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, 0, int(*offset))
|
||||||
|
assert.Equal(t, dfltLast, *last)
|
||||||
|
assert.Equal(t, dfltLimit, *limit)
|
||||||
|
// Correct
|
||||||
|
c.m["offset"] = ""
|
||||||
|
c.m["last"] = "true"
|
||||||
|
c.m["limit"] = "25"
|
||||||
|
offset, last, limit, err = parsePagination(c)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, 0, int(*offset))
|
||||||
|
assert.True(t, *last)
|
||||||
|
assert.Equal(t, 25, int(*limit))
|
||||||
|
c.m["offset"] = "25"
|
||||||
|
c.m["last"] = "false"
|
||||||
|
c.m["limit"] = "50"
|
||||||
|
offset, last, limit, err = parsePagination(c)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, 25, int(*offset))
|
||||||
|
assert.False(t, *last)
|
||||||
|
assert.Equal(t, 50, int(*limit))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestParseQueryHezEthAddr(t *testing.T) {
|
||||||
|
name := "hermezEthereumAddress"
|
||||||
|
c := &queryParser{}
|
||||||
|
c.m = make(map[string]string)
|
||||||
|
ethAddr := ethCommon.BigToAddress(big.NewInt(int64(347683)))
|
||||||
|
// Not HEZ Eth addr
|
||||||
|
c.m[name] = "hez:0xf"
|
||||||
|
_, err := parseQueryHezEthAddr(c)
|
||||||
|
assert.Error(t, err)
|
||||||
|
c.m[name] = ethAddr.String()
|
||||||
|
_, err = parseQueryHezEthAddr(c)
|
||||||
|
assert.Error(t, err)
|
||||||
|
c.m[name] = "hez:0xXX942cfcd25ad4d90a62358b0dd84f33b39826XX"
|
||||||
|
_, err = parseQueryHezEthAddr(c)
|
||||||
|
assert.Error(t, err)
|
||||||
|
// Default
|
||||||
|
c.m[name] = ""
|
||||||
|
res, err := parseQueryHezEthAddr(c)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Nil(t, res)
|
||||||
|
// Correct
|
||||||
|
c.m[name] = "hez:" + ethAddr.String()
|
||||||
|
res, err = parseQueryHezEthAddr(c)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, ethAddr, *res)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestParseQueryBJJ(t *testing.T) {
|
||||||
|
name := "BJJ"
|
||||||
|
c := &queryParser{}
|
||||||
|
c.m = make(map[string]string)
|
||||||
|
privK := babyjub.NewRandPrivKey()
|
||||||
|
pubK := privK.Public()
|
||||||
|
pkComp := [32]byte(pubK.Compress())
|
||||||
|
// Not HEZ Eth addr
|
||||||
|
c.m[name] = "hez:abcd"
|
||||||
|
_, err := parseQueryBJJ(c)
|
||||||
|
assert.Error(t, err)
|
||||||
|
c.m[name] = pubK.String()
|
||||||
|
_, err = parseQueryBJJ(c)
|
||||||
|
assert.Error(t, err)
|
||||||
|
// Wrong checksum
|
||||||
|
bjjSum := append(pkComp[:], byte(1))
|
||||||
|
c.m[name] = "hez:" + base64.RawStdEncoding.EncodeToString(bjjSum)
|
||||||
|
_, err = parseQueryBJJ(c)
|
||||||
|
assert.Error(t, err)
|
||||||
|
// Default
|
||||||
|
c.m[name] = ""
|
||||||
|
res, err := parseQueryBJJ(c)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Nil(t, res)
|
||||||
|
// Correct
|
||||||
|
c.m[name] = bjjToString(pubK)
|
||||||
|
res, err = parseQueryBJJ(c)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, *pubK, *res)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestParseQueryTxType(t *testing.T) {
|
||||||
|
name := "type"
|
||||||
|
c := &queryParser{}
|
||||||
|
c.m = make(map[string]string)
|
||||||
|
// Incorrect values
|
||||||
|
c.m[name] = "deposit"
|
||||||
|
_, err := parseQueryTxType(c)
|
||||||
|
assert.Error(t, err)
|
||||||
|
c.m[name] = "1"
|
||||||
|
_, err = parseQueryTxType(c)
|
||||||
|
assert.Error(t, err)
|
||||||
|
// Default
|
||||||
|
c.m[name] = ""
|
||||||
|
res, err := parseQueryTxType(c)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Nil(t, res)
|
||||||
|
// Correct values
|
||||||
|
c.m[name] = string(common.TxTypeExit)
|
||||||
|
res, err = parseQueryTxType(c)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, common.TxTypeExit, *res)
|
||||||
|
c.m[name] = string(common.TxTypeWithdrawn)
|
||||||
|
res, err = parseQueryTxType(c)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, common.TxTypeWithdrawn, *res)
|
||||||
|
c.m[name] = string(common.TxTypeTransfer)
|
||||||
|
res, err = parseQueryTxType(c)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, common.TxTypeTransfer, *res)
|
||||||
|
c.m[name] = string(common.TxTypeDeposit)
|
||||||
|
res, err = parseQueryTxType(c)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, common.TxTypeDeposit, *res)
|
||||||
|
c.m[name] = string(common.TxTypeCreateAccountDeposit)
|
||||||
|
res, err = parseQueryTxType(c)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, common.TxTypeCreateAccountDeposit, *res)
|
||||||
|
c.m[name] = string(common.TxTypeCreateAccountDepositTransfer)
|
||||||
|
res, err = parseQueryTxType(c)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, common.TxTypeCreateAccountDepositTransfer, *res)
|
||||||
|
c.m[name] = string(common.TxTypeDepositTransfer)
|
||||||
|
res, err = parseQueryTxType(c)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, common.TxTypeDepositTransfer, *res)
|
||||||
|
c.m[name] = string(common.TxTypeForceTransfer)
|
||||||
|
res, err = parseQueryTxType(c)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, common.TxTypeForceTransfer, *res)
|
||||||
|
c.m[name] = string(common.TxTypeForceExit)
|
||||||
|
res, err = parseQueryTxType(c)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, common.TxTypeForceExit, *res)
|
||||||
|
c.m[name] = string(common.TxTypeTransferToEthAddr)
|
||||||
|
res, err = parseQueryTxType(c)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, common.TxTypeTransferToEthAddr, *res)
|
||||||
|
c.m[name] = string(common.TxTypeTransferToBJJ)
|
||||||
|
res, err = parseQueryTxType(c)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, common.TxTypeTransferToBJJ, *res)
|
||||||
|
}
|
||||||
29
api/run.sh
Executable file
29
api/run.sh
Executable file
@@ -0,0 +1,29 @@
|
|||||||
|
#!/bin/sh -e
|
||||||
|
|
||||||
|
USAGE="Available options:
|
||||||
|
doc Start documentation UI at http://loclahost:8001 and the mock up server at http://loclahost:4010
|
||||||
|
mock Start the mock up server at http://loclahost:4010
|
||||||
|
editor Start the documentation editor at http://loclahost:8002
|
||||||
|
stop Stop all runing services started using this script
|
||||||
|
help display this message"
|
||||||
|
|
||||||
|
case "$1" in
|
||||||
|
doc)
|
||||||
|
sudo docker-compose up -d hermez-api-doc hermez-api-mock && echo "\n\nStarted documentation UI at http://localhost:8001 and mockup server at http://localhost:4010"
|
||||||
|
;;
|
||||||
|
mock)
|
||||||
|
sudo docker-compose up -d hermez-api-mock && echo "\n\nStarted mockup server at http://localhost:4010"
|
||||||
|
;;
|
||||||
|
editor)
|
||||||
|
sudo docker-compose up -d hermez-api-editor hermez-api-mock && echo "\n\nStarted spec editor at http://localhost:8002 and mockup server at http://localhost:4010"
|
||||||
|
;;
|
||||||
|
stop)
|
||||||
|
sudo docker-compose rm -sf && echo "\n\nStopped all the services initialized by this script"
|
||||||
|
;;
|
||||||
|
help)
|
||||||
|
echo "$USAGE"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Invalid option.\n\n$USAGE"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
2266
api/swagger.yml
Normal file
2266
api/swagger.yml
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,7 @@
|
|||||||
package common
|
package common
|
||||||
|
|
||||||
|
import "math"
|
||||||
|
|
||||||
// Fee is a type that represents the percentage of tokens that will be paid in a transaction
|
// Fee is a type that represents the percentage of tokens that will be paid in a transaction
|
||||||
// to incentivaise the materialization of it
|
// to incentivaise the materialization of it
|
||||||
type Fee float64
|
type Fee float64
|
||||||
@@ -16,6 +18,20 @@ type RecommendedFee struct {
|
|||||||
// FeeSelector is used to select a percentage from the FeePlan.
|
// FeeSelector is used to select a percentage from the FeePlan.
|
||||||
type FeeSelector uint8
|
type FeeSelector uint8
|
||||||
|
|
||||||
|
// Percentage returns the associated percentage of the FeeSelector
|
||||||
|
func (f FeeSelector) Percentage() float64 {
|
||||||
|
if f == 0 {
|
||||||
|
return 0
|
||||||
|
//nolint:gomnd
|
||||||
|
} else if f <= 32 { //nolint:gomnd
|
||||||
|
return math.Pow(10, -24+(float64(f)/2)) //nolint:gomnd
|
||||||
|
} else if f <= 223 { //nolint:gomnd
|
||||||
|
return math.Pow(10, -8+(0.041666666666667*(float64(f)-32))) //nolint:gomnd
|
||||||
|
} else {
|
||||||
|
return math.Pow(10, float64(f)-224) //nolint:gomnd
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// MaxFeePlan is the maximum value of the FeePlan
|
// MaxFeePlan is the maximum value of the FeePlan
|
||||||
const MaxFeePlan = 256
|
const MaxFeePlan = 256
|
||||||
|
|
||||||
|
|||||||
10
common/tx.go
10
common/tx.go
@@ -27,15 +27,15 @@ const (
|
|||||||
// TxTypeCreateAccountDepositTransfer represents L1->L2 transfer + L2->L2 transfer
|
// TxTypeCreateAccountDepositTransfer represents L1->L2 transfer + L2->L2 transfer
|
||||||
TxTypeCreateAccountDepositTransfer TxType = "CreateAccountDepositTransfer"
|
TxTypeCreateAccountDepositTransfer TxType = "CreateAccountDepositTransfer"
|
||||||
// TxTypeDepositTransfer TBD
|
// TxTypeDepositTransfer TBD
|
||||||
TxTypeDepositTransfer TxType = "TxTypeDepositTransfer"
|
TxTypeDepositTransfer TxType = "DepositTransfer"
|
||||||
// TxTypeForceTransfer TBD
|
// TxTypeForceTransfer TBD
|
||||||
TxTypeForceTransfer TxType = "TxTypeForceTransfer"
|
TxTypeForceTransfer TxType = "ForceTransfer"
|
||||||
// TxTypeForceExit TBD
|
// TxTypeForceExit TBD
|
||||||
TxTypeForceExit TxType = "TxTypeForceExit"
|
TxTypeForceExit TxType = "ForceExit"
|
||||||
// TxTypeTransferToEthAddr TBD
|
// TxTypeTransferToEthAddr TBD
|
||||||
TxTypeTransferToEthAddr TxType = "TxTypeTransferToEthAddr"
|
TxTypeTransferToEthAddr TxType = "TransferToEthAddr"
|
||||||
// TxTypeTransferToBJJ TBD
|
// TxTypeTransferToBJJ TBD
|
||||||
TxTypeTransferToBJJ TxType = "TxTypeTransferToBJJ"
|
TxTypeTransferToBJJ TxType = "TransferToBJJ"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Tx is a struct used by the TxSelector & BatchBuilder as a generic type generated from L1Tx & PoolL2Tx
|
// Tx is a struct used by the TxSelector & BatchBuilder as a generic type generated from L1Tx & PoolL2Tx
|
||||||
|
|||||||
@@ -1,11 +1,16 @@
|
|||||||
package historydb
|
package historydb
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"database/sql"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
ethCommon "github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/gobuffalo/packr/v2"
|
"github.com/gobuffalo/packr/v2"
|
||||||
"github.com/hermeznetwork/hermez-node/common"
|
"github.com/hermeznetwork/hermez-node/common"
|
||||||
"github.com/hermeznetwork/hermez-node/db"
|
"github.com/hermeznetwork/hermez-node/db"
|
||||||
|
"github.com/hermeznetwork/hermez-node/log"
|
||||||
|
"github.com/iden3/go-iden3-crypto/babyjub"
|
||||||
"github.com/jmoiron/sqlx"
|
"github.com/jmoiron/sqlx"
|
||||||
|
|
||||||
//nolint:errcheck // driver for postgres DB
|
//nolint:errcheck // driver for postgres DB
|
||||||
@@ -37,9 +42,11 @@ func NewHistoryDB(port int, host, user, password, dbname string) (*HistoryDB, er
|
|||||||
migrations := &migrate.PackrMigrationSource{
|
migrations := &migrate.PackrMigrationSource{
|
||||||
Box: packr.New("history-migrations", "./migrations"),
|
Box: packr.New("history-migrations", "./migrations"),
|
||||||
}
|
}
|
||||||
if _, err := migrate.Exec(hdb.DB, "postgres", migrations, migrate.Up); err != nil {
|
nMigrations, err := migrate.Exec(hdb.DB, "postgres", migrations, migrate.Up)
|
||||||
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
log.Debug("HistoryDB applied ", nMigrations, " migrations for ", dbname, " database")
|
||||||
|
|
||||||
return &HistoryDB{hdb}, nil
|
return &HistoryDB{hdb}, nil
|
||||||
}
|
}
|
||||||
@@ -320,6 +327,107 @@ func (hdb *HistoryDB) GetTxs() ([]*common.Tx, error) {
|
|||||||
return txs, err
|
return txs, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetHistoryTxs returns a list of txs from the DB using the HistoryTx struct
|
||||||
|
func (hdb *HistoryDB) GetHistoryTxs(
|
||||||
|
ethAddr *ethCommon.Address, bjj *babyjub.PublicKey,
|
||||||
|
tokenID, idx, batchNum *uint, txType *common.TxType,
|
||||||
|
offset, limit *uint, last bool,
|
||||||
|
) ([]*HistoryTx, int, error) {
|
||||||
|
if ethAddr != nil && bjj != nil {
|
||||||
|
return nil, 0, errors.New("ethAddr and bjj are incompatible")
|
||||||
|
}
|
||||||
|
var query string
|
||||||
|
var args []interface{}
|
||||||
|
queryStr := `SELECT tx.*, tx.amount_f * token.usd AS current_usd,
|
||||||
|
token.symbol, token.usd_update, block.timestamp, count(*) OVER() AS total_items FROM tx
|
||||||
|
INNER JOIN token ON tx.token_id = token.token_id
|
||||||
|
INNER JOIN block ON tx.eth_block_num = block.eth_block_num `
|
||||||
|
// Apply filters
|
||||||
|
nextIsAnd := false
|
||||||
|
// ethAddr filter
|
||||||
|
if ethAddr != nil {
|
||||||
|
queryStr = `WITH acc AS
|
||||||
|
(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
|
||||||
|
args = append(args, ethAddr)
|
||||||
|
} else if bjj != nil { // bjj filter
|
||||||
|
queryStr = `WITH acc AS
|
||||||
|
(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
|
||||||
|
args = append(args, bjj)
|
||||||
|
}
|
||||||
|
// tokenID filter
|
||||||
|
if tokenID != nil {
|
||||||
|
if nextIsAnd {
|
||||||
|
queryStr += "AND "
|
||||||
|
} else {
|
||||||
|
queryStr += "WHERE "
|
||||||
|
}
|
||||||
|
queryStr += "tx.token_id = ? "
|
||||||
|
args = append(args, tokenID)
|
||||||
|
nextIsAnd = true
|
||||||
|
}
|
||||||
|
// idx filter
|
||||||
|
if idx != nil {
|
||||||
|
if nextIsAnd {
|
||||||
|
queryStr += "AND "
|
||||||
|
} else {
|
||||||
|
queryStr += "WHERE "
|
||||||
|
}
|
||||||
|
queryStr += "(tx.from_idx = ? OR tx.to_idx = ?) "
|
||||||
|
args = append(args, idx, idx)
|
||||||
|
nextIsAnd = true
|
||||||
|
}
|
||||||
|
// batchNum filter
|
||||||
|
if batchNum != nil {
|
||||||
|
if nextIsAnd {
|
||||||
|
queryStr += "AND "
|
||||||
|
} else {
|
||||||
|
queryStr += "WHERE "
|
||||||
|
}
|
||||||
|
queryStr += "tx.batch_num = ? "
|
||||||
|
args = append(args, batchNum)
|
||||||
|
nextIsAnd = true
|
||||||
|
}
|
||||||
|
// txType filter
|
||||||
|
if txType != nil {
|
||||||
|
if nextIsAnd {
|
||||||
|
queryStr += "AND "
|
||||||
|
} else {
|
||||||
|
queryStr += "WHERE "
|
||||||
|
}
|
||||||
|
queryStr += "tx.type = ? "
|
||||||
|
args = append(args, txType)
|
||||||
|
// nextIsAnd = true
|
||||||
|
}
|
||||||
|
// pagination
|
||||||
|
if last {
|
||||||
|
queryStr += "ORDER BY (batch_num, position) DESC NULLS FIRST "
|
||||||
|
} else {
|
||||||
|
queryStr += "ORDER BY (batch_num, position) ASC NULLS LAST "
|
||||||
|
queryStr += fmt.Sprintf("OFFSET %d ", *offset)
|
||||||
|
}
|
||||||
|
queryStr += fmt.Sprintf("LIMIT %d ", *limit)
|
||||||
|
query = hdb.db.Rebind(queryStr)
|
||||||
|
// log.Debug(query)
|
||||||
|
txs := []*HistoryTx{}
|
||||||
|
if err := meddler.QueryAll(hdb.db, &txs, query, args...); err != nil {
|
||||||
|
return nil, 0, err
|
||||||
|
}
|
||||||
|
if len(txs) == 0 {
|
||||||
|
return nil, 0, sql.ErrNoRows
|
||||||
|
} else if last {
|
||||||
|
tmp := []*HistoryTx{}
|
||||||
|
for i := len(txs) - 1; i >= 0; i-- {
|
||||||
|
tmp = append(tmp, txs[i])
|
||||||
|
}
|
||||||
|
txs = tmp
|
||||||
|
}
|
||||||
|
return txs, txs[0].TotalItems, nil
|
||||||
|
}
|
||||||
|
|
||||||
// GetTx returns a tx from the DB
|
// GetTx returns a tx from the DB
|
||||||
func (hdb *HistoryDB) GetTx(txID common.TxID) (*common.Tx, error) {
|
func (hdb *HistoryDB) GetTx(txID common.TxID) (*common.Tx, error) {
|
||||||
tx := new(common.Tx)
|
tx := new(common.Tx)
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package historydb
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
|
||||||
"math/big"
|
"math/big"
|
||||||
"os"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
@@ -186,7 +185,7 @@ func TestAccounts(t *testing.T) {
|
|||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
// Generate fake accounts
|
// Generate fake accounts
|
||||||
const nAccounts = 3
|
const nAccounts = 3
|
||||||
accs := test.GenAccounts(nAccounts, 0, tokens, nil, batches)
|
accs := test.GenAccounts(nAccounts, 0, tokens, nil, nil, batches)
|
||||||
err = historyDB.AddAccounts(accs)
|
err = historyDB.AddAccounts(accs)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
// Fetch accounts
|
// Fetch accounts
|
||||||
@@ -219,7 +218,7 @@ func TestTxs(t *testing.T) {
|
|||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
// Generate fake accounts
|
// Generate fake accounts
|
||||||
const nAccounts = 3
|
const nAccounts = 3
|
||||||
accs := test.GenAccounts(nAccounts, 0, tokens, nil, batches)
|
accs := test.GenAccounts(nAccounts, 0, tokens, nil, nil, batches)
|
||||||
err = historyDB.AddAccounts(accs)
|
err = historyDB.AddAccounts(accs)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
// Generate fake L1 txs
|
// Generate fake L1 txs
|
||||||
@@ -265,15 +264,7 @@ func TestTxs(t *testing.T) {
|
|||||||
} else {
|
} else {
|
||||||
assert.Less(t, 0.999, fetchedTx.USD/tx.USD)
|
assert.Less(t, 0.999, fetchedTx.USD/tx.USD)
|
||||||
}
|
}
|
||||||
if tx.Fee == 0 {
|
tx.FeeUSD = tx.USD * tx.Fee.Percentage()
|
||||||
tx.FeeUSD = 0
|
|
||||||
} else if tx.Fee <= 32 {
|
|
||||||
tx.FeeUSD = tx.USD * math.Pow(10, -24+(float64(tx.Fee)/2))
|
|
||||||
} else if tx.Fee <= 223 {
|
|
||||||
tx.FeeUSD = tx.USD * math.Pow(10, -8+(0.041666666666667*(float64(tx.Fee)-32)))
|
|
||||||
} else {
|
|
||||||
tx.FeeUSD = tx.USD * math.Pow(10, float64(tx.Fee)-224)
|
|
||||||
}
|
|
||||||
if fetchedTx.FeeUSD > tx.FeeUSD {
|
if fetchedTx.FeeUSD > tx.FeeUSD {
|
||||||
assert.Less(t, 0.999, tx.FeeUSD/fetchedTx.FeeUSD)
|
assert.Less(t, 0.999, tx.FeeUSD/fetchedTx.FeeUSD)
|
||||||
} else if fetchedTx.FeeUSD < tx.FeeUSD {
|
} else if fetchedTx.FeeUSD < tx.FeeUSD {
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ CREATE TABLE block (
|
|||||||
hash BYTEA NOT NULL
|
hash BYTEA NOT NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE coordianator (
|
CREATE TABLE coordinator (
|
||||||
forger_addr BYTEA NOT NULL,
|
forger_addr BYTEA NOT NULL,
|
||||||
eth_block_num BIGINT NOT NULL REFERENCES block (eth_block_num) ON DELETE CASCADE,
|
eth_block_num BIGINT NOT NULL REFERENCES block (eth_block_num) ON DELETE CASCADE,
|
||||||
withdraw_addr BYTEA NOT NULL,
|
withdraw_addr BYTEA NOT NULL,
|
||||||
@@ -99,6 +99,8 @@ CREATE TABLE tx (
|
|||||||
nonce BIGINT
|
nonce BIGINT
|
||||||
);
|
);
|
||||||
|
|
||||||
|
CREATE INDEX tx_order ON tx (batch_num, position);
|
||||||
|
|
||||||
-- +migrate StatementBegin
|
-- +migrate StatementBegin
|
||||||
CREATE FUNCTION set_tx()
|
CREATE FUNCTION set_tx()
|
||||||
RETURNS TRIGGER
|
RETURNS TRIGGER
|
||||||
@@ -197,11 +199,10 @@ CREATE TABLE consensus_vars (
|
|||||||
DROP TABLE consensus_vars;
|
DROP TABLE consensus_vars;
|
||||||
DROP TABLE rollup_vars;
|
DROP TABLE rollup_vars;
|
||||||
DROP TABLE account;
|
DROP TABLE account;
|
||||||
DROP TABLE l2tx;
|
DROP TABLE tx;
|
||||||
DROP TABLE l1tx;
|
|
||||||
DROP TABLE token;
|
DROP TABLE token;
|
||||||
DROP TABLE bid;
|
DROP TABLE bid;
|
||||||
DROP TABLE exit_tree;
|
DROP TABLE exit_tree;
|
||||||
DROP TABLE batch;
|
DROP TABLE batch;
|
||||||
DROP TABLE coordianator;
|
DROP TABLE coordinator;
|
||||||
DROP TABLE block;
|
DROP TABLE block;
|
||||||
46
db/historydb/views.go
Normal file
46
db/historydb/views.go
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
package historydb
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math/big"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
ethCommon "github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/hermeznetwork/hermez-node/common"
|
||||||
|
"github.com/iden3/go-iden3-crypto/babyjub"
|
||||||
|
)
|
||||||
|
|
||||||
|
// HistoryTx is a representation of a generic Tx with additional information
|
||||||
|
// required by the API, and extracted by joining block and token tables
|
||||||
|
type HistoryTx struct {
|
||||||
|
// Generic
|
||||||
|
IsL1 bool `meddler:"is_l1"`
|
||||||
|
TxID common.TxID `meddler:"id"`
|
||||||
|
Type common.TxType `meddler:"type"`
|
||||||
|
Position int `meddler:"position"`
|
||||||
|
FromIdx common.Idx `meddler:"from_idx"`
|
||||||
|
ToIdx common.Idx `meddler:"to_idx"`
|
||||||
|
Amount *big.Int `meddler:"amount,bigint"`
|
||||||
|
AmountFloat float64 `meddler:"amount_f"`
|
||||||
|
TokenID common.TokenID `meddler:"token_id"`
|
||||||
|
USD float64 `meddler:"amount_usd,zeroisnull"`
|
||||||
|
BatchNum common.BatchNum `meddler:"batch_num,zeroisnull"` // batchNum in which this tx was forged. If the tx is L2, this must be != 0
|
||||||
|
EthBlockNum int64 `meddler:"eth_block_num"` // Ethereum Block Number in which this L1Tx was added to the queue
|
||||||
|
// L1
|
||||||
|
ToForgeL1TxsNum int64 `meddler:"to_forge_l1_txs_num"` // toForgeL1TxsNum in which the tx was forged / will be forged
|
||||||
|
UserOrigin bool `meddler:"user_origin"` // true if the tx was originated by a user, false if it was aoriginated by a coordinator. Note that this differ from the spec for implementation simplification purpposes
|
||||||
|
FromEthAddr ethCommon.Address `meddler:"from_eth_addr"`
|
||||||
|
FromBJJ *babyjub.PublicKey `meddler:"from_bjj"`
|
||||||
|
LoadAmount *big.Int `meddler:"load_amount,bigintnull"`
|
||||||
|
LoadAmountFloat float64 `meddler:"load_amount_f"`
|
||||||
|
LoadAmountUSD float64 `meddler:"load_amount_usd,zeroisnull"`
|
||||||
|
// L2
|
||||||
|
Fee common.FeeSelector `meddler:"fee,zeroisnull"`
|
||||||
|
FeeUSD float64 `meddler:"fee_usd,zeroisnull"`
|
||||||
|
Nonce common.Nonce `meddler:"nonce,zeroisnull"`
|
||||||
|
// API extras
|
||||||
|
Timestamp time.Time `meddler:"timestamp,utctime"`
|
||||||
|
TokenSymbol string `meddler:"symbol"`
|
||||||
|
CurrentUSD float64 `meddler:"current_usd"`
|
||||||
|
USDUpdate time.Time `meddler:"usd_update,utctime"`
|
||||||
|
TotalItems int `meddler:"total_items"`
|
||||||
|
}
|
||||||
@@ -8,6 +8,7 @@ import (
|
|||||||
"github.com/gobuffalo/packr/v2"
|
"github.com/gobuffalo/packr/v2"
|
||||||
"github.com/hermeznetwork/hermez-node/common"
|
"github.com/hermeznetwork/hermez-node/common"
|
||||||
"github.com/hermeznetwork/hermez-node/db"
|
"github.com/hermeznetwork/hermez-node/db"
|
||||||
|
"github.com/hermeznetwork/hermez-node/log"
|
||||||
"github.com/jmoiron/sqlx"
|
"github.com/jmoiron/sqlx"
|
||||||
|
|
||||||
//nolint:errcheck // driver for postgres DB
|
//nolint:errcheck // driver for postgres DB
|
||||||
@@ -48,11 +49,13 @@ func NewL2DB(
|
|||||||
|
|
||||||
// Run DB migrations
|
// Run DB migrations
|
||||||
migrations := &migrate.PackrMigrationSource{
|
migrations := &migrate.PackrMigrationSource{
|
||||||
Box: packr.New("history-migrations", "./migrations"),
|
Box: packr.New("l2db-migrations", "./migrations"),
|
||||||
}
|
}
|
||||||
if _, err := migrate.Exec(db.DB, "postgres", migrations, migrate.Up); err != nil {
|
nMigrations, err := migrate.Exec(db.DB, "postgres", migrations, migrate.Up)
|
||||||
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
log.Debug("L2DB applied ", nMigrations, " migrations for ", dbname, " database")
|
||||||
|
|
||||||
return &L2DB{
|
return &L2DB{
|
||||||
db: db,
|
db: db,
|
||||||
|
|||||||
@@ -21,7 +21,10 @@ func TestMain(m *testing.M) {
|
|||||||
pass := os.Getenv("POSTGRES_PASS")
|
pass := os.Getenv("POSTGRES_PASS")
|
||||||
l2DB, err = NewL2DB(5432, "localhost", "hermez", pass, "l2", 10, 100, 24*time.Hour)
|
l2DB, err = NewL2DB(5432, "localhost", "hermez", pass, "l2", 10, 100, 24*time.Hour)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Error("L2DB migration failed: " + err.Error())
|
||||||
panic(err)
|
panic(err)
|
||||||
|
} else {
|
||||||
|
log.Debug("L2DB migration succed")
|
||||||
}
|
}
|
||||||
// Run tests
|
// Run tests
|
||||||
result := m.Run()
|
result := m.Run()
|
||||||
@@ -34,7 +37,7 @@ func TestMain(m *testing.M) {
|
|||||||
|
|
||||||
func TestAddTx(t *testing.T) {
|
func TestAddTx(t *testing.T) {
|
||||||
const nInserts = 20
|
const nInserts = 20
|
||||||
cleanDB()
|
test.CleanL2DB(l2DB.DB())
|
||||||
txs := test.GenPoolTxs(nInserts)
|
txs := test.GenPoolTxs(nInserts)
|
||||||
for _, tx := range txs {
|
for _, tx := range txs {
|
||||||
err := l2DB.AddTx(tx)
|
err := l2DB.AddTx(tx)
|
||||||
@@ -52,7 +55,7 @@ func TestAddTx(t *testing.T) {
|
|||||||
|
|
||||||
func BenchmarkAddTx(b *testing.B) {
|
func BenchmarkAddTx(b *testing.B) {
|
||||||
const nInserts = 20
|
const nInserts = 20
|
||||||
cleanDB()
|
test.CleanL2DB(l2DB.DB())
|
||||||
txs := test.GenPoolTxs(nInserts)
|
txs := test.GenPoolTxs(nInserts)
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
for _, tx := range txs {
|
for _, tx := range txs {
|
||||||
@@ -64,7 +67,7 @@ func BenchmarkAddTx(b *testing.B) {
|
|||||||
|
|
||||||
func TestGetPending(t *testing.T) {
|
func TestGetPending(t *testing.T) {
|
||||||
const nInserts = 20
|
const nInserts = 20
|
||||||
cleanDB()
|
test.CleanL2DB(l2DB.DB())
|
||||||
txs := test.GenPoolTxs(nInserts)
|
txs := test.GenPoolTxs(nInserts)
|
||||||
var pendingTxs []*common.PoolL2Tx
|
var pendingTxs []*common.PoolL2Tx
|
||||||
for _, tx := range txs {
|
for _, tx := range txs {
|
||||||
@@ -90,7 +93,7 @@ func TestStartForging(t *testing.T) {
|
|||||||
// Generate txs
|
// Generate txs
|
||||||
const nInserts = 60
|
const nInserts = 60
|
||||||
const fakeBatchNum common.BatchNum = 33
|
const fakeBatchNum common.BatchNum = 33
|
||||||
cleanDB()
|
test.CleanL2DB(l2DB.DB())
|
||||||
txs := test.GenPoolTxs(nInserts)
|
txs := test.GenPoolTxs(nInserts)
|
||||||
var startForgingTxIDs []common.TxID
|
var startForgingTxIDs []common.TxID
|
||||||
randomizer := 0
|
randomizer := 0
|
||||||
@@ -119,7 +122,7 @@ func TestDoneForging(t *testing.T) {
|
|||||||
// Generate txs
|
// Generate txs
|
||||||
const nInserts = 60
|
const nInserts = 60
|
||||||
const fakeBatchNum common.BatchNum = 33
|
const fakeBatchNum common.BatchNum = 33
|
||||||
cleanDB()
|
test.CleanL2DB(l2DB.DB())
|
||||||
txs := test.GenPoolTxs(nInserts)
|
txs := test.GenPoolTxs(nInserts)
|
||||||
var doneForgingTxIDs []common.TxID
|
var doneForgingTxIDs []common.TxID
|
||||||
randomizer := 0
|
randomizer := 0
|
||||||
@@ -148,7 +151,7 @@ func TestInvalidate(t *testing.T) {
|
|||||||
// Generate txs
|
// Generate txs
|
||||||
const nInserts = 60
|
const nInserts = 60
|
||||||
const fakeBatchNum common.BatchNum = 33
|
const fakeBatchNum common.BatchNum = 33
|
||||||
cleanDB()
|
test.CleanL2DB(l2DB.DB())
|
||||||
txs := test.GenPoolTxs(nInserts)
|
txs := test.GenPoolTxs(nInserts)
|
||||||
var invalidTxIDs []common.TxID
|
var invalidTxIDs []common.TxID
|
||||||
randomizer := 0
|
randomizer := 0
|
||||||
@@ -177,7 +180,7 @@ func TestCheckNonces(t *testing.T) {
|
|||||||
// Generate txs
|
// Generate txs
|
||||||
const nInserts = 60
|
const nInserts = 60
|
||||||
const fakeBatchNum common.BatchNum = 33
|
const fakeBatchNum common.BatchNum = 33
|
||||||
cleanDB()
|
test.CleanL2DB(l2DB.DB())
|
||||||
txs := test.GenPoolTxs(nInserts)
|
txs := test.GenPoolTxs(nInserts)
|
||||||
var invalidTxIDs []common.TxID
|
var invalidTxIDs []common.TxID
|
||||||
// Generate accounts
|
// Generate accounts
|
||||||
@@ -219,7 +222,7 @@ func TestCheckNonces(t *testing.T) {
|
|||||||
func TestUpdateTxValue(t *testing.T) {
|
func TestUpdateTxValue(t *testing.T) {
|
||||||
// Generate txs
|
// Generate txs
|
||||||
const nInserts = 255 // Force all possible fee selector values
|
const nInserts = 255 // Force all possible fee selector values
|
||||||
cleanDB()
|
test.CleanL2DB(l2DB.DB())
|
||||||
txs := test.GenPoolTxs(nInserts)
|
txs := test.GenPoolTxs(nInserts)
|
||||||
// Generate tokens
|
// Generate tokens
|
||||||
const nTokens = 2
|
const nTokens = 2
|
||||||
@@ -277,7 +280,7 @@ func TestReorg(t *testing.T) {
|
|||||||
const nInserts = 20
|
const nInserts = 20
|
||||||
const lastValidBatch common.BatchNum = 20
|
const lastValidBatch common.BatchNum = 20
|
||||||
const reorgBatch common.BatchNum = lastValidBatch + 1
|
const reorgBatch common.BatchNum = lastValidBatch + 1
|
||||||
cleanDB()
|
test.CleanL2DB(l2DB.DB())
|
||||||
txs := test.GenPoolTxs(nInserts)
|
txs := test.GenPoolTxs(nInserts)
|
||||||
// Add txs to the DB
|
// Add txs to the DB
|
||||||
reorgedTxIDs := []common.TxID{}
|
reorgedTxIDs := []common.TxID{}
|
||||||
@@ -312,7 +315,7 @@ func TestReorg(t *testing.T) {
|
|||||||
func TestPurge(t *testing.T) {
|
func TestPurge(t *testing.T) {
|
||||||
// Generate txs
|
// Generate txs
|
||||||
nInserts := l2DB.maxTxs + 20
|
nInserts := l2DB.maxTxs + 20
|
||||||
cleanDB()
|
test.CleanL2DB(l2DB.DB())
|
||||||
txs := test.GenPoolTxs(int(nInserts))
|
txs := test.GenPoolTxs(int(nInserts))
|
||||||
deletedIDs := []common.TxID{}
|
deletedIDs := []common.TxID{}
|
||||||
keepedIDs := []common.TxID{}
|
keepedIDs := []common.TxID{}
|
||||||
@@ -360,7 +363,7 @@ func TestPurge(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestAuth(t *testing.T) {
|
func TestAuth(t *testing.T) {
|
||||||
cleanDB()
|
test.CleanL2DB(l2DB.DB())
|
||||||
const nAuths = 5
|
const nAuths = 5
|
||||||
// Generate authorizations
|
// Generate authorizations
|
||||||
auths := test.GenAuths(nAuths)
|
auths := test.GenAuths(nAuths)
|
||||||
@@ -378,12 +381,3 @@ func TestAuth(t *testing.T) {
|
|||||||
assert.Equal(t, auths[i].Timestamp.Unix(), auths[i].Timestamp.Unix())
|
assert.Equal(t, auths[i].Timestamp.Unix(), auths[i].Timestamp.Unix())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func cleanDB() {
|
|
||||||
if _, err := l2DB.db.Exec("DELETE FROM tx_pool"); err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
if _, err := l2DB.db.Exec("DELETE FROM account_creation_auth"); err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
7
go.mod
7
go.mod
@@ -6,19 +6,20 @@ require (
|
|||||||
github.com/BurntSushi/toml v0.3.1
|
github.com/BurntSushi/toml v0.3.1
|
||||||
github.com/dghubble/sling v1.3.0
|
github.com/dghubble/sling v1.3.0
|
||||||
github.com/ethereum/go-ethereum v1.9.17
|
github.com/ethereum/go-ethereum v1.9.17
|
||||||
|
github.com/getkin/kin-openapi v0.22.0
|
||||||
|
github.com/gin-gonic/gin v1.4.0
|
||||||
github.com/go-sql-driver/mysql v1.5.0 // indirect
|
github.com/go-sql-driver/mysql v1.5.0 // indirect
|
||||||
github.com/gobuffalo/packr/v2 v2.8.0
|
github.com/gobuffalo/packr/v2 v2.8.0
|
||||||
github.com/iden3/go-iden3-core v0.0.8
|
|
||||||
github.com/iden3/go-iden3-crypto v0.0.6-0.20200823174058-e04ca5764a15
|
github.com/iden3/go-iden3-crypto v0.0.6-0.20200823174058-e04ca5764a15
|
||||||
github.com/iden3/go-merkletree v0.0.0-20200902123354-eeb949f8c334
|
github.com/iden3/go-merkletree v0.0.0-20200902123354-eeb949f8c334
|
||||||
github.com/jinzhu/gorm v1.9.15
|
github.com/jinzhu/copier v0.0.0-20190924061706-b57f9002281a
|
||||||
github.com/jmoiron/sqlx v1.2.0
|
github.com/jmoiron/sqlx v1.2.0
|
||||||
github.com/lib/pq v1.8.0
|
github.com/lib/pq v1.8.0
|
||||||
github.com/mitchellh/copystructure v1.0.0
|
github.com/mitchellh/copystructure v1.0.0
|
||||||
github.com/rubenv/sql-migrate v0.0.0-20200616145509-8d140a17f351
|
github.com/rubenv/sql-migrate v0.0.0-20200616145509-8d140a17f351
|
||||||
github.com/russross/meddler v1.0.0
|
github.com/russross/meddler v1.0.0
|
||||||
github.com/stretchr/testify v1.6.1
|
github.com/stretchr/testify v1.6.1
|
||||||
github.com/urfave/cli v1.22.1
|
github.com/ugorji/go v1.1.8 // indirect
|
||||||
github.com/urfave/cli/v2 v2.2.0
|
github.com/urfave/cli/v2 v2.2.0
|
||||||
go.uber.org/multierr v1.6.0 // indirect
|
go.uber.org/multierr v1.6.0 // indirect
|
||||||
go.uber.org/zap v1.16.0
|
go.uber.org/zap v1.16.0
|
||||||
|
|||||||
76
go.sum
76
go.sum
@@ -20,9 +20,9 @@ github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym
|
|||||||
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
|
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
|
||||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||||
github.com/OneOfOne/xxhash v1.2.5/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q=
|
github.com/OneOfOne/xxhash v1.2.5/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q=
|
||||||
github.com/PuerkitoBio/goquery v1.5.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc=
|
|
||||||
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
|
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
|
||||||
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
|
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
|
||||||
|
github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 h1:fLjPD/aNc3UIOA6tDi6QXUemppXK3P9BI7mr2hd6gx8=
|
||||||
github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
|
github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
|
||||||
github.com/VictoriaMetrics/fastcache v1.5.3/go.mod h1:+jv9Ckb+za/P1ZRg/sulP5Ni1v49daAVERr0H3CuscE=
|
github.com/VictoriaMetrics/fastcache v1.5.3/go.mod h1:+jv9Ckb+za/P1ZRg/sulP5Ni1v49daAVERr0H3CuscE=
|
||||||
github.com/VictoriaMetrics/fastcache v1.5.7 h1:4y6y0G8PRzszQUYIQHHssv/jgPHAb5qQuuDNdCbyAgw=
|
github.com/VictoriaMetrics/fastcache v1.5.7 h1:4y6y0G8PRzszQUYIQHHssv/jgPHAb5qQuuDNdCbyAgw=
|
||||||
@@ -36,8 +36,8 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy
|
|||||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||||
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||||
github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM=
|
github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM=
|
||||||
|
github.com/allegro/bigcache v1.2.1 h1:hg1sY1raCwic3Vnsvje6TT7/pnZba83LeFck5NrFKSc=
|
||||||
github.com/allegro/bigcache v1.2.1/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM=
|
github.com/allegro/bigcache v1.2.1/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM=
|
||||||
github.com/andybalholm/cascadia v1.1.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y=
|
|
||||||
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
|
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
|
||||||
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
|
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
|
||||||
github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
|
github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
|
||||||
@@ -76,6 +76,7 @@ github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA
|
|||||||
github.com/certifi/gocertifi v0.0.0-20200211180108-c7c1fbc02894 h1:JLaf/iINcLyjwbtTsCJjc6rtlASgHeIJPrB6QmwURnA=
|
github.com/certifi/gocertifi v0.0.0-20200211180108-c7c1fbc02894 h1:JLaf/iINcLyjwbtTsCJjc6rtlASgHeIJPrB6QmwURnA=
|
||||||
github.com/certifi/gocertifi v0.0.0-20200211180108-c7c1fbc02894/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA=
|
github.com/certifi/gocertifi v0.0.0-20200211180108-c7c1fbc02894/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA=
|
||||||
github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s=
|
github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s=
|
||||||
|
github.com/cespare/cp v1.1.1 h1:nCb6ZLdB7NRaqsm91JtQTAme2SKJzXVsdPIPkyJr1MU=
|
||||||
github.com/cespare/cp v1.1.1/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s=
|
github.com/cespare/cp v1.1.1/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s=
|
||||||
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
|
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
|
||||||
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||||
@@ -119,7 +120,6 @@ github.com/deckarep/golang-set v0.0.0-20180603214616-504e848d77ea/go.mod h1:93vs
|
|||||||
github.com/deckarep/golang-set v1.7.1 h1:SCQV0S6gTtp6itiFrTqI+pfmJ4LN85S1YzhDf9rTHJQ=
|
github.com/deckarep/golang-set v1.7.1 h1:SCQV0S6gTtp6itiFrTqI+pfmJ4LN85S1YzhDf9rTHJQ=
|
||||||
github.com/deckarep/golang-set v1.7.1/go.mod h1:93vsz/8Wt4joVM7c2AVqh+YRMiUSc14yDtF28KmMOgQ=
|
github.com/deckarep/golang-set v1.7.1/go.mod h1:93vsz/8Wt4joVM7c2AVqh+YRMiUSc14yDtF28KmMOgQ=
|
||||||
github.com/denisenkom/go-mssqldb v0.0.0-20191001013358-cfbb681360f0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
|
github.com/denisenkom/go-mssqldb v0.0.0-20191001013358-cfbb681360f0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
|
||||||
github.com/denisenkom/go-mssqldb v0.0.0-20191124224453-732737034ffd/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
|
|
||||||
github.com/dghubble/sling v1.3.0 h1:pZHjCJq4zJvc6qVQ5wN1jo5oNZlNE0+8T/h0XeXBUKU=
|
github.com/dghubble/sling v1.3.0 h1:pZHjCJq4zJvc6qVQ5wN1jo5oNZlNE0+8T/h0XeXBUKU=
|
||||||
github.com/dghubble/sling v1.3.0/go.mod h1:XXShWaBWKzNLhu2OxikSNFrlsvowtz4kyRuXUG7oQKY=
|
github.com/dghubble/sling v1.3.0/go.mod h1:XXShWaBWKzNLhu2OxikSNFrlsvowtz4kyRuXUG7oQKY=
|
||||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||||
@@ -142,7 +142,6 @@ github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3
|
|||||||
github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g=
|
github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g=
|
||||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||||
github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0=
|
|
||||||
github.com/ethereum/go-ethereum v1.9.12/go.mod h1:PvsVkQmhZFx92Y+h2ylythYlheEDt/uBgFbl61Js/jo=
|
github.com/ethereum/go-ethereum v1.9.12/go.mod h1:PvsVkQmhZFx92Y+h2ylythYlheEDt/uBgFbl61Js/jo=
|
||||||
github.com/ethereum/go-ethereum v1.9.13/go.mod h1:qwN9d1GLyDh0N7Ab8bMGd0H9knaji2jOBm2RrMGjXls=
|
github.com/ethereum/go-ethereum v1.9.13/go.mod h1:qwN9d1GLyDh0N7Ab8bMGd0H9knaji2jOBm2RrMGjXls=
|
||||||
github.com/ethereum/go-ethereum v1.9.17 h1:2D02O8KcoyQHxfizvMi0vGXXzFIkQTMeKXwt0+4SYEA=
|
github.com/ethereum/go-ethereum v1.9.17 h1:2D02O8KcoyQHxfizvMi0vGXXzFIkQTMeKXwt0+4SYEA=
|
||||||
@@ -155,23 +154,32 @@ github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5/go.mod h1:VvhXpOYNQvB+
|
|||||||
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
|
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
|
||||||
github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4=
|
github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4=
|
||||||
github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20=
|
github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20=
|
||||||
|
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
|
||||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||||
github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff h1:tY80oXqGNY4FhTFhk+o9oFHGINQ/+vhlm8HFzi6znCI=
|
github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff h1:tY80oXqGNY4FhTFhk+o9oFHGINQ/+vhlm8HFzi6znCI=
|
||||||
github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww=
|
github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww=
|
||||||
|
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/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=
|
||||||
|
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
|
||||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||||
|
github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3 h1:t8FVkw33L+wilf2QiWkw0UV77qRpcH/JHPKGpKa2E8g=
|
||||||
github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s=
|
github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s=
|
||||||
|
github.com/gin-gonic/gin v1.4.0 h1:3tMoCCfM7ppqsR0ptz/wi1impNpT7/9wQtMZ8lr1mCQ=
|
||||||
github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM=
|
github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM=
|
||||||
github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
|
github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
|
||||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||||
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||||
|
github.com/go-kit/kit v0.10.0 h1:dXFJfIHVvUcpSgDOV+Ne6t7jXri8Tfv2uOLHUZ2XNuo=
|
||||||
github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o=
|
github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o=
|
||||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||||
|
github.com/go-logfmt/logfmt v0.5.0 h1:TrB8swr/68K7m9CcGut2g3UOihhbcbiMAYiuTXdEih4=
|
||||||
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
|
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
|
||||||
|
github.com/go-ole/go-ole v1.2.1 h1:2lOsA72HgjxAuMlKpFiCbHTvu44PIVkZ5hqm3RSdI/E=
|
||||||
github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8=
|
github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8=
|
||||||
github.com/go-playground/locales v0.12.1 h1:2FITxuFt/xuCNP1Acdhv62OzaCiviiE4kotfhkmOqEc=
|
github.com/go-playground/locales v0.12.1 h1:2FITxuFt/xuCNP1Acdhv62OzaCiviiE4kotfhkmOqEc=
|
||||||
github.com/go-playground/locales v0.12.1/go.mod h1:IUMDtCfWo/w/mtMfIE/IG2K+Ey3ygWanZIBtBW0W2TM=
|
github.com/go-playground/locales v0.12.1/go.mod h1:IUMDtCfWo/w/mtMfIE/IG2K+Ey3ygWanZIBtBW0W2TM=
|
||||||
@@ -274,6 +282,7 @@ github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/J
|
|||||||
github.com/holiman/uint256 v1.1.0 h1:Iye6ze0DW9s+7EMn8y6Q4ebegDzpu28JQHEVM1Bq+Wg=
|
github.com/holiman/uint256 v1.1.0 h1:Iye6ze0DW9s+7EMn8y6Q4ebegDzpu28JQHEVM1Bq+Wg=
|
||||||
github.com/holiman/uint256 v1.1.0/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw=
|
github.com/holiman/uint256 v1.1.0/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw=
|
||||||
github.com/howeyc/fsnotify v0.9.0/go.mod h1:41HzSPxBGeFRQKEEwgh49TRw/nKBsYZ2cF1OzPjSJsA=
|
github.com/howeyc/fsnotify v0.9.0/go.mod h1:41HzSPxBGeFRQKEEwgh49TRw/nKBsYZ2cF1OzPjSJsA=
|
||||||
|
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
|
||||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||||
github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg=
|
github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg=
|
||||||
github.com/huin/goupnp v0.0.0-20161224104101-679507af18f3/go.mod h1:MZ2ZmwcBpvOoJ22IJsc7va19ZwoheaBk43rKg12SKag=
|
github.com/huin/goupnp v0.0.0-20161224104101-679507af18f3/go.mod h1:MZ2ZmwcBpvOoJ22IJsc7va19ZwoheaBk43rKg12SKag=
|
||||||
@@ -287,34 +296,10 @@ github.com/iden3/go-iden3-core v0.0.8 h1:PLw7iCiX7Pw1dqBkR+JaLQWqB5RKd+vgu25UBdv
|
|||||||
github.com/iden3/go-iden3-core v0.0.8/go.mod h1:URNjIhMql6sEbWubIGrjJdw5wHCE1Pk1XghxjBOtA3s=
|
github.com/iden3/go-iden3-core v0.0.8/go.mod h1:URNjIhMql6sEbWubIGrjJdw5wHCE1Pk1XghxjBOtA3s=
|
||||||
github.com/iden3/go-iden3-crypto v0.0.5 h1:inCSm5a+ry+nbpVTL/9+m6UcIwSv6nhUm0tnIxEbcps=
|
github.com/iden3/go-iden3-crypto v0.0.5 h1:inCSm5a+ry+nbpVTL/9+m6UcIwSv6nhUm0tnIxEbcps=
|
||||||
github.com/iden3/go-iden3-crypto v0.0.5/go.mod h1:XKw1oDwYn2CIxKOtr7m/mL5jMn4mLOxAxtZBRxQBev8=
|
github.com/iden3/go-iden3-crypto v0.0.5/go.mod h1:XKw1oDwYn2CIxKOtr7m/mL5jMn4mLOxAxtZBRxQBev8=
|
||||||
github.com/iden3/go-iden3-crypto v0.0.6-0.20200723082457-29a66457f0bf h1:/7L5dEqctuzJY2g8OEQct+1Y+n2sMKyd4JoYhw2jy1s=
|
|
||||||
github.com/iden3/go-iden3-crypto v0.0.6-0.20200723082457-29a66457f0bf/go.mod h1:XKw1oDwYn2CIxKOtr7m/mL5jMn4mLOxAxtZBRxQBev8=
|
|
||||||
github.com/iden3/go-iden3-crypto v0.0.6-0.20200806115047-327a8175d6eb h1:4Vqq5ZoqQd9t3Uj7MUbak7eHmtaYs8mqQoo8T1DS7tA=
|
|
||||||
github.com/iden3/go-iden3-crypto v0.0.6-0.20200806115047-327a8175d6eb/go.mod h1:XKw1oDwYn2CIxKOtr7m/mL5jMn4mLOxAxtZBRxQBev8=
|
|
||||||
github.com/iden3/go-iden3-crypto v0.0.6-0.20200813145745-66519124ca17 h1:aqy++85MX/ylQyKkuoK7zJ8hHEW5mT4mLL6pguo+X8Y=
|
|
||||||
github.com/iden3/go-iden3-crypto v0.0.6-0.20200813145745-66519124ca17/go.mod h1:oBgthFLboAWi9feaBUFy7OxEcyn9vA1khHSL/WwWFyg=
|
|
||||||
github.com/iden3/go-iden3-crypto v0.0.6-0.20200814110325-70841d78e7d8 h1:1QeVvr/DjiBpk8tw3vBfYD+zs0JeYl3fPIUA/foDq3w=
|
|
||||||
github.com/iden3/go-iden3-crypto v0.0.6-0.20200814110325-70841d78e7d8/go.mod h1:oBgthFLboAWi9feaBUFy7OxEcyn9vA1khHSL/WwWFyg=
|
|
||||||
github.com/iden3/go-iden3-crypto v0.0.6-0.20200819064831-09d161e9f670 h1:gNBFu/WnRfNn+xywE04fgCWSHlb6wr0nIIll9i4R2fc=
|
github.com/iden3/go-iden3-crypto v0.0.6-0.20200819064831-09d161e9f670 h1:gNBFu/WnRfNn+xywE04fgCWSHlb6wr0nIIll9i4R2fc=
|
||||||
github.com/iden3/go-iden3-crypto v0.0.6-0.20200819064831-09d161e9f670/go.mod h1:oBgthFLboAWi9feaBUFy7OxEcyn9vA1khHSL/WwWFyg=
|
github.com/iden3/go-iden3-crypto v0.0.6-0.20200819064831-09d161e9f670/go.mod h1:oBgthFLboAWi9feaBUFy7OxEcyn9vA1khHSL/WwWFyg=
|
||||||
github.com/iden3/go-iden3-crypto v0.0.6-0.20200823174058-e04ca5764a15 h1:hzCf9JY0vKUB9wVq+oXzqcei20xDtBu8XEIQIjgOowE=
|
github.com/iden3/go-iden3-crypto v0.0.6-0.20200823174058-e04ca5764a15 h1:hzCf9JY0vKUB9wVq+oXzqcei20xDtBu8XEIQIjgOowE=
|
||||||
github.com/iden3/go-iden3-crypto v0.0.6-0.20200823174058-e04ca5764a15/go.mod h1:oBgthFLboAWi9feaBUFy7OxEcyn9vA1khHSL/WwWFyg=
|
github.com/iden3/go-iden3-crypto v0.0.6-0.20200823174058-e04ca5764a15/go.mod h1:oBgthFLboAWi9feaBUFy7OxEcyn9vA1khHSL/WwWFyg=
|
||||||
github.com/iden3/go-merkletree v0.0.0-20200723202738-75e24244a1e3 h1:QR6LqG1HqqPE4myiLR73QFIieAfwODG3bqo1juuaqVI=
|
|
||||||
github.com/iden3/go-merkletree v0.0.0-20200723202738-75e24244a1e3/go.mod h1:Fc49UeywIsj8nUfb5lxBzmWrMeMmqzTJ5F0OcjdiEME=
|
|
||||||
github.com/iden3/go-merkletree v0.0.0-20200806171216-dd600560e44c h1:EzVMSVkwKdfcOR1a+rZe9dfbtAj6KdJnBxOEZ5B+gCQ=
|
|
||||||
github.com/iden3/go-merkletree v0.0.0-20200806171216-dd600560e44c/go.mod h1:Fc49UeywIsj8nUfb5lxBzmWrMeMmqzTJ5F0OcjdiEME=
|
|
||||||
github.com/iden3/go-merkletree v0.0.0-20200807083900-f6f82d8375d5 h1:qvWSCt3AYxj65uTdW6lLSKlrbckcHghOAW4TwdfJ+N8=
|
|
||||||
github.com/iden3/go-merkletree v0.0.0-20200807083900-f6f82d8375d5/go.mod h1:Fc49UeywIsj8nUfb5lxBzmWrMeMmqzTJ5F0OcjdiEME=
|
|
||||||
github.com/iden3/go-merkletree v0.0.0-20200815105542-2277604e65dd h1:AkPlODLWkgQT9p1k6LnO3aRLIIeVL9ENof/YW87QL14=
|
|
||||||
github.com/iden3/go-merkletree v0.0.0-20200815105542-2277604e65dd/go.mod h1:/MsQOzDnxK8X/u7XP9ZBoZwZ4gIm9FlwfqckH5dRuTM=
|
|
||||||
github.com/iden3/go-merkletree v0.0.0-20200815144208-1f1bd54b93ae h1:CC8oKPM+38/Dkq20QymuIjyRo0UFzJZeH5DPbGWURrI=
|
|
||||||
github.com/iden3/go-merkletree v0.0.0-20200815144208-1f1bd54b93ae/go.mod h1:/MsQOzDnxK8X/u7XP9ZBoZwZ4gIm9FlwfqckH5dRuTM=
|
|
||||||
github.com/iden3/go-merkletree v0.0.0-20200819075941-77df3096f7ea h1:0MtMnN42ULNxOnJYa0FH1qjeSEBPkYVH6ZCs22rz2FU=
|
|
||||||
github.com/iden3/go-merkletree v0.0.0-20200819075941-77df3096f7ea/go.mod h1:MRe6i0mi2oDVUzgBIHsNRE6XAg8EBuqIQZMsd+do+dU=
|
|
||||||
github.com/iden3/go-merkletree v0.0.0-20200819092443-dc656fdd32fc h1:VnRP7JCp5TJHnTC+r8NrXGkRBvp62tRGqeA3FcdEq+Q=
|
|
||||||
github.com/iden3/go-merkletree v0.0.0-20200819092443-dc656fdd32fc/go.mod h1:MRe6i0mi2oDVUzgBIHsNRE6XAg8EBuqIQZMsd+do+dU=
|
|
||||||
github.com/iden3/go-merkletree v0.0.0-20200825093552-a4b68208bb41 h1:mCOMMQ/YmL9ST9kk7ifT961chESkB2GFFEp8osF0Jw8=
|
|
||||||
github.com/iden3/go-merkletree v0.0.0-20200825093552-a4b68208bb41/go.mod h1:MRe6i0mi2oDVUzgBIHsNRE6XAg8EBuqIQZMsd+do+dU=
|
|
||||||
github.com/iden3/go-merkletree v0.0.0-20200902123354-eeb949f8c334 h1:FQngDJKiwM6i4kHlVFvSpJa9sO+QvZ7C+GqoPWe+5BI=
|
github.com/iden3/go-merkletree v0.0.0-20200902123354-eeb949f8c334 h1:FQngDJKiwM6i4kHlVFvSpJa9sO+QvZ7C+GqoPWe+5BI=
|
||||||
github.com/iden3/go-merkletree v0.0.0-20200902123354-eeb949f8c334/go.mod h1:MRe6i0mi2oDVUzgBIHsNRE6XAg8EBuqIQZMsd+do+dU=
|
github.com/iden3/go-merkletree v0.0.0-20200902123354-eeb949f8c334/go.mod h1:MRe6i0mi2oDVUzgBIHsNRE6XAg8EBuqIQZMsd+do+dU=
|
||||||
github.com/iden3/go-wasm3 v0.0.1/go.mod h1:j+TcAB94Dfrjlu5kJt83h2OqAU+oyNUTwNZnQyII1sI=
|
github.com/iden3/go-wasm3 v0.0.1/go.mod h1:j+TcAB94Dfrjlu5kJt83h2OqAU+oyNUTwNZnQyII1sI=
|
||||||
@@ -328,10 +313,8 @@ github.com/jackpal/go-nat-pmp v1.0.2-0.20160603034137-1fa385a6f458/go.mod h1:QPH
|
|||||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
|
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
|
||||||
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||||
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||||
|
github.com/jinzhu/copier v0.0.0-20190924061706-b57f9002281a h1:zPPuIq2jAWWPTrGt70eK/BSch+gFAGrNzecsoENgu2o=
|
||||||
github.com/jinzhu/copier v0.0.0-20190924061706-b57f9002281a/go.mod h1:yL958EeXv8Ylng6IfnvG4oflryUi3vgA3xPs9hmII1s=
|
github.com/jinzhu/copier v0.0.0-20190924061706-b57f9002281a/go.mod h1:yL958EeXv8Ylng6IfnvG4oflryUi3vgA3xPs9hmII1s=
|
||||||
github.com/jinzhu/gorm v1.9.15/go.mod h1:G3LB3wezTOWM2ITLzPxEXgSkOXAntiLHS7UdBefADcs=
|
|
||||||
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
|
||||||
github.com/jinzhu/now v1.0.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
|
||||||
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
||||||
github.com/jmoiron/sqlx v1.2.0 h1:41Ip0zITnmWNR/vHV+S4m+VoUivnWY5E4OJfLZjCJMA=
|
github.com/jmoiron/sqlx v1.2.0 h1:41Ip0zITnmWNR/vHV+S4m+VoUivnWY5E4OJfLZjCJMA=
|
||||||
github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks=
|
github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks=
|
||||||
@@ -340,6 +323,7 @@ github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22
|
|||||||
github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ=
|
github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ=
|
||||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||||
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||||
|
github.com/json-iterator/go v1.1.8 h1:QiWkFLKq0T7mpzwOTu6BzNDbfTE8OLrYhVKYMLF46Ok=
|
||||||
github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||||
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||||
github.com/julienschmidt/httprouter v1.1.1-0.20170430222011-975b5c4c7c21/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
github.com/julienschmidt/httprouter v1.1.1-0.20170430222011-975b5c4c7c21/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||||
@@ -367,7 +351,6 @@ github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+
|
|||||||
github.com/leodido/go-urn v1.1.0 h1:Sm1gr51B1kKyfD2BlRcLSiEkffoG96g6TPv6eRoEiB8=
|
github.com/leodido/go-urn v1.1.0 h1:Sm1gr51B1kKyfD2BlRcLSiEkffoG96g6TPv6eRoEiB8=
|
||||||
github.com/leodido/go-urn v1.1.0/go.mod h1:+cyI34gQWZcE1eQU7NVgKkkzdXDQHr1dBMtdAPozLkw=
|
github.com/leodido/go-urn v1.1.0/go.mod h1:+cyI34gQWZcE1eQU7NVgKkkzdXDQHr1dBMtdAPozLkw=
|
||||||
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||||
github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
|
||||||
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||||
github.com/lib/pq v1.8.0 h1:9xohqzkUwzR4Ga4ivdTcawVS89YSDVxXMa3xJX3cGzg=
|
github.com/lib/pq v1.8.0 h1:9xohqzkUwzR4Ga4ivdTcawVS89YSDVxXMa3xJX3cGzg=
|
||||||
github.com/lib/pq v1.8.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
github.com/lib/pq v1.8.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||||
@@ -400,7 +383,6 @@ github.com/mattn/go-runewidth v0.0.4 h1:2BvfKmzob6Bmd4YsL0zygOqfdFnK7GR4QL06Do4/
|
|||||||
github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||||
github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||||
github.com/mattn/go-sqlite3 v1.12.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
github.com/mattn/go-sqlite3 v1.12.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||||
github.com/mattn/go-sqlite3 v1.14.0/go.mod h1:JIl7NbARA7phWnGvh0LKTyg7S9BA+6gx71ShQilpsus=
|
|
||||||
github.com/mattn/go-sqlite3 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJKjyR5WD3HYQSd+U=
|
github.com/mattn/go-sqlite3 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJKjyR5WD3HYQSd+U=
|
||||||
github.com/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
github.com/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||||
@@ -419,8 +401,10 @@ github.com/mitchellh/mapstructure v1.3.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RR
|
|||||||
github.com/mitchellh/reflectwalk v1.0.0 h1:9D+8oIskB4VJBN5SFlmc27fSlIBZaov1Wpk/IfikLNY=
|
github.com/mitchellh/reflectwalk v1.0.0 h1:9D+8oIskB4VJBN5SFlmc27fSlIBZaov1Wpk/IfikLNY=
|
||||||
github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
|
github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
|
||||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||||
|
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
|
||||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||||
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
|
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
|
||||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||||
@@ -442,7 +426,9 @@ github.com/olekukonko/tablewriter v0.0.2-0.20190409134802-7e037d187b0c/go.mod h1
|
|||||||
github.com/olekukonko/tablewriter v0.0.2 h1:sq53g+DWf0J6/ceFUHpQ0nAEb6WgM++fq16MZ91cS6o=
|
github.com/olekukonko/tablewriter v0.0.2 h1:sq53g+DWf0J6/ceFUHpQ0nAEb6WgM++fq16MZ91cS6o=
|
||||||
github.com/olekukonko/tablewriter v0.0.2/go.mod h1:rSAaSIOAGT9odnlyGlUfAJaoc5w2fSBUmeGDbRWPxyQ=
|
github.com/olekukonko/tablewriter v0.0.2/go.mod h1:rSAaSIOAGT9odnlyGlUfAJaoc5w2fSBUmeGDbRWPxyQ=
|
||||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||||
|
github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs=
|
||||||
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||||
|
github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU=
|
||||||
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||||
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
|
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
|
||||||
github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis=
|
github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis=
|
||||||
@@ -577,12 +563,17 @@ github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1
|
|||||||
github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs=
|
github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs=
|
||||||
github.com/tyler-smith/go-bip39 v1.0.2 h1:+t3w+KwLXO6154GNJY+qUtIxLTmFjfUmpguQT1OlOT8=
|
github.com/tyler-smith/go-bip39 v1.0.2 h1:+t3w+KwLXO6154GNJY+qUtIxLTmFjfUmpguQT1OlOT8=
|
||||||
github.com/tyler-smith/go-bip39 v1.0.2/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs=
|
github.com/tyler-smith/go-bip39 v1.0.2/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs=
|
||||||
|
github.com/ugorji/go v1.1.4 h1:j4s+tAvLfL3bZyefP2SEWmhBzmuIlH/eqNuPdFPgngw=
|
||||||
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
|
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
|
||||||
|
github.com/ugorji/go v1.1.8 h1:/D9x7IRpfMHDlizVOgxrag5Fh+/NY+LtI8bsr+AswRA=
|
||||||
|
github.com/ugorji/go v1.1.8/go.mod h1:0lNM99SwWUIRhCXnigEMClngXBk/EmpTXa7mgiewYWA=
|
||||||
|
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8 h1:3SVOIvH7Ae1KRYyQWRjXWJEA9sS/c/pjvH++55Gr648=
|
||||||
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
|
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
|
||||||
|
github.com/ugorji/go/codec v1.1.8 h1:4dryPvxMP9OtkjIbuNeK2nb27M38XMHLGlfNSNph/5s=
|
||||||
|
github.com/ugorji/go/codec v1.1.8/go.mod h1:X00B19HDtwvKbQY2DcYjvZxKQp8mzrJoQ6EgoIY/D2E=
|
||||||
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
||||||
github.com/urfave/cli v1.22.1 h1:+mkCCcOFKPnCmVYVcURKps1Xe+3zP90gSYGNfRkjoIY=
|
github.com/urfave/cli v1.22.1 h1:+mkCCcOFKPnCmVYVcURKps1Xe+3zP90gSYGNfRkjoIY=
|
||||||
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||||
github.com/urfave/cli v1.22.4 h1:u7tSpNPPswAFymm8IehJhy4uJMlUuU/GmqSkvJ1InXA=
|
|
||||||
github.com/urfave/cli/v2 v2.2.0 h1:JTTnM6wKzdA0Jqodd966MVj4vWbbquZykeX1sKbe2C4=
|
github.com/urfave/cli/v2 v2.2.0 h1:JTTnM6wKzdA0Jqodd966MVj4vWbbquZykeX1sKbe2C4=
|
||||||
github.com/urfave/cli/v2 v2.2.0/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ=
|
github.com/urfave/cli/v2 v2.2.0/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ=
|
||||||
github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208 h1:1cngl9mPEoITZG8s8cVcUy5CeIBYhEESkOB7m6Gmkrk=
|
github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208 h1:1cngl9mPEoITZG8s8cVcUy5CeIBYhEESkOB7m6Gmkrk=
|
||||||
@@ -631,7 +622,6 @@ golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4/go.mod h1:yigFU9vqHzYiE8U
|
|||||||
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20191122220453-ac88ee75c92c/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20191122220453-ac88ee75c92c/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20191205180655-e7c4368fe9dd/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
|
||||||
golang.org/x/crypto v0.0.0-20200311171314-f7b00557c8c4/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200311171314-f7b00557c8c4/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
|
||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
@@ -646,6 +636,7 @@ golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTk
|
|||||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||||
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||||
|
golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs=
|
||||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||||
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
|
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
|
||||||
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
|
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
|
||||||
@@ -655,8 +646,8 @@ golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
|
|||||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||||
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||||
golang.org/x/mod v0.1.1-0.20191209134235-331c550502dd/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.1.1-0.20191209134235-331c550502dd/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
|
golang.org/x/mod v0.2.0 h1:KU7oHjnv3XNWfa5COkzUifxZmxp1TyI7ImMXqFxLwvQ=
|
||||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
|
||||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
@@ -677,10 +668,8 @@ golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLL
|
|||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
|
||||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344 h1:vGXIOMxbNfDTk/aXCmfdLgkrSV+Z2tcbze+pEc3v5W4=
|
golang.org/x/net v0.0.0-20200625001655-4c5254603344 h1:vGXIOMxbNfDTk/aXCmfdLgkrSV+Z2tcbze+pEc3v5W4=
|
||||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
@@ -746,9 +735,11 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn
|
|||||||
golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||||
golang.org/x/tools v0.0.0-20200117012304-6edc0a871e69/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
golang.org/x/tools v0.0.0-20200117012304-6edc0a871e69/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||||
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||||
|
golang.org/x/tools v0.0.0-20200308013534-11ec41452d41 h1:9Di9iYgOt9ThCipBxChBVhgNipDoE5mxO84rQV7D0FE=
|
||||||
golang.org/x/tools v0.0.0-20200308013534-11ec41452d41/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
golang.org/x/tools v0.0.0-20200308013534-11ec41452d41/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
|
google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
|
||||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||||
@@ -775,15 +766,19 @@ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33
|
|||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
|
gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
|
||||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||||
|
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
|
||||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||||
gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o=
|
gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o=
|
||||||
|
gopkg.in/go-playground/assert.v1 v1.2.1 h1:xoYuJVE7KT85PYWrN730RguIQO0ePzVRfFMXadIrXTM=
|
||||||
gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE=
|
gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE=
|
||||||
|
gopkg.in/go-playground/validator.v8 v8.18.2 h1:lFB4DoMU6B626w8ny76MV7VX6W2VHct2GVOI3xgiMrQ=
|
||||||
gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y=
|
gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y=
|
||||||
gopkg.in/go-playground/validator.v9 v9.29.1 h1:SvGtYmN60a5CVKTOzMSyfzWDeZRxRuGvRQyEAKbw1xc=
|
gopkg.in/go-playground/validator.v9 v9.29.1 h1:SvGtYmN60a5CVKTOzMSyfzWDeZRxRuGvRQyEAKbw1xc=
|
||||||
gopkg.in/go-playground/validator.v9 v9.29.1/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ=
|
gopkg.in/go-playground/validator.v9 v9.29.1/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ=
|
||||||
gopkg.in/gorp.v1 v1.7.2 h1:j3DWlAyGVv8whO7AcIWznQ2Yj7yJkn34B8s63GViAAw=
|
gopkg.in/gorp.v1 v1.7.2 h1:j3DWlAyGVv8whO7AcIWznQ2Yj7yJkn34B8s63GViAAw=
|
||||||
gopkg.in/gorp.v1 v1.7.2/go.mod h1:Wo3h+DBQZIxATwftsglhdD/62zRFPhGhTiu5jUJmCaw=
|
gopkg.in/gorp.v1 v1.7.2/go.mod h1:Wo3h+DBQZIxATwftsglhdD/62zRFPhGhTiu5jUJmCaw=
|
||||||
gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA=
|
gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA=
|
||||||
|
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce h1:+JknDZhAj8YMt7GC73Ei8pv4MzjDUNPHgQWJdtMAaDU=
|
||||||
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c=
|
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c=
|
||||||
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20190213234257-ec84240a7772/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns=
|
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20190213234257-ec84240a7772/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns=
|
||||||
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200316214253-d7b0ff38cac9/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns=
|
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200316214253-d7b0ff38cac9/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns=
|
||||||
@@ -793,6 +788,7 @@ gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
|||||||
gopkg.in/src-d/go-billy.v4 v4.3.2/go.mod h1:nDjArDMp+XMs1aFAESLRjfGSgfvoYN0hDfzEk0GjC98=
|
gopkg.in/src-d/go-billy.v4 v4.3.2/go.mod h1:nDjArDMp+XMs1aFAESLRjfGSgfvoYN0hDfzEk0GjC98=
|
||||||
gopkg.in/src-d/go-git-fixtures.v3 v3.5.0/go.mod h1:dLBcvytrw/TYZsNTWCnkNF2DSIlzWYqTe3rJR56Ac7g=
|
gopkg.in/src-d/go-git-fixtures.v3 v3.5.0/go.mod h1:dLBcvytrw/TYZsNTWCnkNF2DSIlzWYqTe3rJR56Ac7g=
|
||||||
gopkg.in/src-d/go-git.v4 v4.13.1/go.mod h1:nx5NYcxdKxq5fpltdHnPa2Exj4Sx0EclMWZQbYDu2z8=
|
gopkg.in/src-d/go-git.v4 v4.13.1/go.mod h1:nx5NYcxdKxq5fpltdHnPa2Exj4Sx0EclMWZQbYDu2z8=
|
||||||
|
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||||
gopkg.in/urfave/cli.v1 v1.20.0 h1:NdAVW6RYxDif9DhDHaAortIu956m2c0v+09AZBPTbE0=
|
gopkg.in/urfave/cli.v1 v1.20.0 h1:NdAVW6RYxDif9DhDHaAortIu956m2c0v+09AZBPTbE0=
|
||||||
gopkg.in/urfave/cli.v1 v1.20.0/go.mod h1:vuBzUtMdQeixQj8LVd+/98pzhxNGQoyuPBlsXHOQNO0=
|
gopkg.in/urfave/cli.v1 v1.20.0/go.mod h1:vuBzUtMdQeixQj8LVd+/98pzhxNGQoyuPBlsXHOQNO0=
|
||||||
@@ -800,13 +796,17 @@ gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRN
|
|||||||
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
|
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
|
||||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
gopkg.in/yaml.v2 v2.2.5 h1:ymVxjfMaHvXD8RqPRmzHHsB3VvucivSkIAvJFDI5O3c=
|
||||||
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
|
||||||
|
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
|
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
|
||||||
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
|
honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM=
|
||||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||||
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
|
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
|
||||||
sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU=
|
sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU=
|
||||||
|
|||||||
@@ -79,19 +79,21 @@ func GenBatches(nBatches int, blocks []common.Block) []common.Batch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GenAccounts generates accounts. WARNING: This is meant for DB/API testing, and may not be fully consistent with the protocol.
|
// GenAccounts generates accounts. WARNING: This is meant for DB/API testing, and may not be fully consistent with the protocol.
|
||||||
func GenAccounts(totalAccounts, userAccounts int, tokens []common.Token, userAddr *ethCommon.Address, batches []common.Batch) []common.Account {
|
func GenAccounts(totalAccounts, userAccounts int, tokens []common.Token, userAddr *ethCommon.Address, userBjj *babyjub.PublicKey, batches []common.Batch) []common.Account {
|
||||||
if totalAccounts < userAccounts {
|
if totalAccounts < userAccounts {
|
||||||
panic("totalAccounts must be greater than userAccounts")
|
panic("totalAccounts must be greater than userAccounts")
|
||||||
}
|
}
|
||||||
privK := babyjub.NewRandPrivKey()
|
|
||||||
pubK := privK.Public()
|
|
||||||
accs := []common.Account{}
|
accs := []common.Account{}
|
||||||
for i := 0; i < totalAccounts; i++ {
|
for i := 0; i < totalAccounts; i++ {
|
||||||
var addr ethCommon.Address
|
var addr ethCommon.Address
|
||||||
|
var pubK *babyjub.PublicKey
|
||||||
if i < userAccounts {
|
if i < userAccounts {
|
||||||
addr = *userAddr
|
addr = *userAddr
|
||||||
|
pubK = userBjj
|
||||||
} else {
|
} else {
|
||||||
addr = ethCommon.BigToAddress(big.NewInt(int64(i)))
|
addr = ethCommon.BigToAddress(big.NewInt(int64(i)))
|
||||||
|
privK := babyjub.NewRandPrivKey()
|
||||||
|
pubK = privK.Public()
|
||||||
}
|
}
|
||||||
accs = append(accs, common.Account{
|
accs = append(accs, common.Account{
|
||||||
Idx: common.Idx(i),
|
Idx: common.Idx(i),
|
||||||
|
|||||||
Reference in New Issue
Block a user