mirror of
https://github.com/arnaucube/hermez-node.git
synced 2026-02-06 19:06:42 +01:00
Merge pull request #428 from hermeznetwork/fix/api-next-forgers
Fix next forgers api response
This commit is contained in:
149
api/api_test.go
149
api/api_test.go
@@ -177,6 +177,7 @@ type testCommon struct {
|
||||
auctionVars common.AuctionVariables
|
||||
rollupVars common.RollupVariables
|
||||
wdelayerVars common.WDelayerVariables
|
||||
nextForgers []NextForger
|
||||
}
|
||||
|
||||
var tc testCommon
|
||||
@@ -218,7 +219,6 @@ func TestMain(m *testing.M) {
|
||||
// L2DB
|
||||
l2DB := l2db.NewL2DB(database, 10, 100, 24*time.Hour)
|
||||
test.WipeDB(l2DB.DB()) // this will clean HistoryDB and L2DB
|
||||
|
||||
// Config (smart contract constants)
|
||||
chainID := uint16(0)
|
||||
_config := getConfigTest(chainID)
|
||||
@@ -357,26 +357,128 @@ func TestMain(m *testing.M) {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Generate Bids and add them to HistoryDB
|
||||
const nBids = 20
|
||||
commonBids := test.GenBids(nBids, commonBlocks, commonCoords)
|
||||
if err = api.h.AddBids(commonBids); err != nil {
|
||||
// Test next forgers
|
||||
// Set auction vars
|
||||
// Slots 3 and 6 will have bids that will be invalidated because of minBid update
|
||||
// Slots 4 and 7 will have valid bids, the rest will be cordinator slots
|
||||
var slot3MinBid int64 = 3
|
||||
var slot4MinBid int64 = 4
|
||||
var slot6MinBid int64 = 6
|
||||
var slot7MinBid int64 = 7
|
||||
// First update will indicate how things behave from slot 0
|
||||
var defaultSlotSetBid [6]*big.Int = [6]*big.Int{
|
||||
big.NewInt(10), // Slot 0 min bid
|
||||
big.NewInt(10), // Slot 1 min bid
|
||||
big.NewInt(10), // Slot 2 min bid
|
||||
big.NewInt(slot3MinBid), // Slot 3 min bid
|
||||
big.NewInt(slot4MinBid), // Slot 4 min bid
|
||||
big.NewInt(10), // Slot 5 min bid
|
||||
}
|
||||
auctionVars := common.AuctionVariables{
|
||||
EthBlockNum: int64(2),
|
||||
DonationAddress: ethCommon.HexToAddress("0x1111111111111111111111111111111111111111"),
|
||||
DefaultSlotSetBid: defaultSlotSetBid,
|
||||
DefaultSlotSetBidSlotNum: 0,
|
||||
Outbidding: uint16(1),
|
||||
SlotDeadline: uint8(20),
|
||||
BootCoordinator: ethCommon.HexToAddress("0x1111111111111111111111111111111111111111"),
|
||||
BootCoordinatorURL: "https://boot.coordinator.io",
|
||||
ClosedAuctionSlots: uint16(10),
|
||||
OpenAuctionSlots: uint16(20),
|
||||
}
|
||||
if err := api.h.AddAuctionVars(&auctionVars); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
// Last update in auction vars will indicate how things will behave from slot 5
|
||||
defaultSlotSetBid = [6]*big.Int{
|
||||
big.NewInt(10), // Slot 5 min bid
|
||||
big.NewInt(slot6MinBid), // Slot 6 min bid
|
||||
big.NewInt(slot7MinBid), // Slot 7 min bid
|
||||
big.NewInt(10), // Slot 8 min bid
|
||||
big.NewInt(10), // Slot 9 min bid
|
||||
big.NewInt(10), // Slot 10 min bid
|
||||
}
|
||||
auctionVars = common.AuctionVariables{
|
||||
EthBlockNum: int64(3),
|
||||
DonationAddress: ethCommon.HexToAddress("0x1111111111111111111111111111111111111111"),
|
||||
DefaultSlotSetBid: defaultSlotSetBid,
|
||||
DefaultSlotSetBidSlotNum: 5,
|
||||
Outbidding: uint16(1),
|
||||
SlotDeadline: uint8(20),
|
||||
BootCoordinator: ethCommon.HexToAddress("0x1111111111111111111111111111111111111111"),
|
||||
BootCoordinatorURL: "https://boot.coordinator.io",
|
||||
ClosedAuctionSlots: uint16(10),
|
||||
OpenAuctionSlots: uint16(20),
|
||||
}
|
||||
if err := api.h.AddAuctionVars(&auctionVars); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Generate SC vars and add them to HistoryDB (if needed)
|
||||
var defaultSlotSetBid [6]*big.Int = [6]*big.Int{big.NewInt(10), big.NewInt(10), big.NewInt(10), big.NewInt(10), big.NewInt(10), big.NewInt(10)}
|
||||
auctionVars := common.AuctionVariables{
|
||||
EthBlockNum: int64(2),
|
||||
DonationAddress: ethCommon.HexToAddress("0x1111111111111111111111111111111111111111"),
|
||||
DefaultSlotSetBid: defaultSlotSetBid,
|
||||
Outbidding: uint16(1),
|
||||
SlotDeadline: uint8(20),
|
||||
BootCoordinator: ethCommon.HexToAddress("0x1111111111111111111111111111111111111111"),
|
||||
BootCoordinatorURL: "https://boot.coordinator.io",
|
||||
ClosedAuctionSlots: uint16(2),
|
||||
OpenAuctionSlots: uint16(5),
|
||||
// Generate Bids and add them to HistoryDB
|
||||
bids := []common.Bid{}
|
||||
// Slot 1 and 2, no bids, wins boot coordinator
|
||||
// Slot 3, below what's going to be the minimum (wins boot coordinator)
|
||||
bids = append(bids, common.Bid{
|
||||
SlotNum: 3,
|
||||
BidValue: big.NewInt(slot3MinBid - 1),
|
||||
EthBlockNum: commonBlocks[0].Num,
|
||||
Bidder: commonCoords[0].Bidder,
|
||||
})
|
||||
// Slot 4, valid bid (wins bidder)
|
||||
bids = append(bids, common.Bid{
|
||||
SlotNum: 4,
|
||||
BidValue: big.NewInt(slot4MinBid),
|
||||
EthBlockNum: commonBlocks[0].Num,
|
||||
Bidder: commonCoords[0].Bidder,
|
||||
})
|
||||
// Slot 5 no bids, wins boot coordinator
|
||||
// Slot 6, below what's going to be the minimum (wins boot coordinator)
|
||||
bids = append(bids, common.Bid{
|
||||
SlotNum: 6,
|
||||
BidValue: big.NewInt(slot6MinBid - 1),
|
||||
EthBlockNum: commonBlocks[0].Num,
|
||||
Bidder: commonCoords[0].Bidder,
|
||||
})
|
||||
// Slot 7, valid bid (wins bidder)
|
||||
bids = append(bids, common.Bid{
|
||||
SlotNum: 7,
|
||||
BidValue: big.NewInt(slot7MinBid),
|
||||
EthBlockNum: commonBlocks[0].Num,
|
||||
Bidder: commonCoords[0].Bidder,
|
||||
})
|
||||
if err = api.h.AddBids(bids); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
bootForger := NextForger{
|
||||
Coordinator: historydb.CoordinatorAPI{
|
||||
Bidder: ethCommon.HexToAddress("0x0111111111111111111111111111111111111111"),
|
||||
Forger: ethCommon.HexToAddress("0x0111111111111111111111111111111111111111"),
|
||||
URL: "https://bootCoordinator",
|
||||
},
|
||||
}
|
||||
// Set next forgers: set all as boot coordinator then replace the non boot coordinators
|
||||
nextForgers := []NextForger{}
|
||||
var initBlock int64 = 140
|
||||
var deltaBlocks int64 = 40
|
||||
for i := 1; i < int(auctionVars.ClosedAuctionSlots)+2; i++ {
|
||||
fromBlock := initBlock + deltaBlocks*int64(i-1)
|
||||
bootForger.Period = Period{
|
||||
SlotNum: int64(i),
|
||||
FromBlock: fromBlock,
|
||||
ToBlock: fromBlock + deltaBlocks - 1,
|
||||
}
|
||||
nextForgers = append(nextForgers, bootForger)
|
||||
}
|
||||
// Set next forgers that aren't the boot coordinator
|
||||
nonBootForger := historydb.CoordinatorAPI{
|
||||
Bidder: commonCoords[0].Bidder,
|
||||
Forger: commonCoords[0].Forger,
|
||||
URL: commonCoords[0].URL,
|
||||
}
|
||||
// Slot 4
|
||||
nextForgers[3].Coordinator = nonBootForger
|
||||
// Slot 7
|
||||
nextForgers[6].Coordinator = nonBootForger
|
||||
|
||||
var buckets [common.RollupConstNumBuckets]common.BucketParams
|
||||
for i := range buckets {
|
||||
@@ -386,6 +488,7 @@ func TestMain(m *testing.M) {
|
||||
buckets[i].MaxWithdrawals = big.NewInt(int64(i) * 10000)
|
||||
}
|
||||
|
||||
// Generate SC vars and add them to HistoryDB (if needed)
|
||||
rollupVars := common.RollupVariables{
|
||||
EthBlockNum: int64(3),
|
||||
FeeAddToken: big.NewInt(100),
|
||||
@@ -399,14 +502,9 @@ func TestMain(m *testing.M) {
|
||||
WithdrawalDelay: uint64(3000),
|
||||
}
|
||||
|
||||
err = api.h.AddAuctionVars(&auctionVars)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Generate test data, as expected to be received/sended from/to the API
|
||||
testCoords := genTestCoordinators(commonCoords)
|
||||
testBids := genTestBids(commonBlocks, testCoords, commonBids)
|
||||
testBids := genTestBids(commonBlocks, testCoords, bids)
|
||||
testExits := genTestExits(commonExitTree, testTokens, commonAccounts)
|
||||
testTxs := genTestTxs(commonL1Txs, commonL2Txs, commonAccounts, testTokens, commonBlocks)
|
||||
testBatches, testFullBatches := genTestBatches(commonBlocks, commonBatches, testTxs)
|
||||
@@ -434,8 +532,11 @@ func TestMain(m *testing.M) {
|
||||
auctionVars: auctionVars,
|
||||
rollupVars: rollupVars,
|
||||
wdelayerVars: wdelayerVars,
|
||||
nextForgers: nextForgers,
|
||||
}
|
||||
|
||||
// Run tests
|
||||
result := m.Run()
|
||||
// Fake server
|
||||
if os.Getenv("FAKE_SERVER") == "yes" {
|
||||
for {
|
||||
@@ -443,8 +544,6 @@ func TestMain(m *testing.M) {
|
||||
time.Sleep(30 * time.Second)
|
||||
}
|
||||
}
|
||||
// Run tests
|
||||
result := m.Run()
|
||||
// Stop server
|
||||
if err := server.Shutdown(context.Background()); err != nil {
|
||||
panic(err)
|
||||
|
||||
@@ -141,7 +141,7 @@ func TestGetBids(t *testing.T) {
|
||||
err = doBadReq("GET", path, nil, 400)
|
||||
assert.NoError(t, err)
|
||||
// 404
|
||||
path = fmt.Sprintf("%s?slotNum=%d&bidderAddr=%s", endpoint, tc.bids[0].SlotNum, tc.bids[1].Bidder.String())
|
||||
path = fmt.Sprintf("%s?slotNum=%d&bidderAddr=%s", endpoint, 5, tc.bids[1].Bidder.String())
|
||||
err = doBadReq("GET", path, nil, 404)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
@@ -62,13 +62,13 @@ func (a *API) genTestSlots(nSlots int, lastBlockNum int64, bids []testBid, aucti
|
||||
return tSlots
|
||||
}
|
||||
|
||||
func (a *API) getEmptyTestSlot(slotNum int64) testSlot {
|
||||
firstBlock, lastBlock := a.getFirstLastBlock(slotNum)
|
||||
func (a *API) getEmptyTestSlot(slotNum, lastBlock int64, auctionVars common.AuctionVariables) testSlot {
|
||||
firstSlotBlock, lastSlotBlock := a.getFirstLastBlock(slotNum)
|
||||
slot := testSlot{
|
||||
SlotNum: slotNum,
|
||||
FirstBlock: firstBlock,
|
||||
LastBlock: lastBlock,
|
||||
OpenAuction: false,
|
||||
FirstBlock: firstSlotBlock,
|
||||
LastBlock: lastSlotBlock,
|
||||
OpenAuction: a.isOpenAuction(lastBlock, slotNum, auctionVars),
|
||||
WinnerBid: nil,
|
||||
}
|
||||
return slot
|
||||
@@ -98,7 +98,7 @@ func TestGetSlot(t *testing.T) {
|
||||
nil, &fetchedSlot,
|
||||
),
|
||||
)
|
||||
emptySlot := api.getEmptyTestSlot(slotNum)
|
||||
emptySlot := api.getEmptyTestSlot(slotNum, api.status.Network.LastSyncBlock, tc.auctionVars)
|
||||
assertSlot(t, emptySlot, fetchedSlot)
|
||||
|
||||
// Invalid slotNum
|
||||
@@ -127,7 +127,7 @@ func TestGetSlots(t *testing.T) {
|
||||
assert.NoError(t, err)
|
||||
allSlots := tc.slots
|
||||
for i := tc.slots[len(tc.slots)-1].SlotNum; i < maxSlotNum; i++ {
|
||||
emptySlot := api.getEmptyTestSlot(i + 1)
|
||||
emptySlot := api.getEmptyTestSlot(i+1, api.status.Network.LastSyncBlock, tc.auctionVars)
|
||||
allSlots = append(allSlots, emptySlot)
|
||||
}
|
||||
assertSlots(t, allSlots, fetchedSlots)
|
||||
@@ -148,7 +148,7 @@ func TestGetSlots(t *testing.T) {
|
||||
// maxSlotNum & wonByEthereumAddress
|
||||
fetchedSlots = []testSlot{}
|
||||
limit = 1
|
||||
bidderAddr := tc.coordinators[2].Bidder
|
||||
bidderAddr := tc.coordinators[0].Bidder
|
||||
path = fmt.Sprintf("%s?maxSlotNum=%d&wonByEthereumAddress=%s&limit=%d", endpoint, maxSlotNum, bidderAddr.String(), limit)
|
||||
err = doGoodReqPaginated(path, historydb.OrderAsc, &testSlotsResponse{}, appendIter)
|
||||
assert.NoError(t, err)
|
||||
|
||||
48
api/state.go
48
api/state.go
@@ -2,6 +2,7 @@ package api
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"math/big"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
@@ -122,6 +123,21 @@ func (a *API) getNextForgers(lastBlock common.Block, currentSlot, lastClosedSlot
|
||||
return nil, tracerr.Wrap(err)
|
||||
}
|
||||
nextForgers := []NextForger{}
|
||||
// Get min bid info
|
||||
var minBidInfo []historydb.MinBidInfo
|
||||
if currentSlot >= a.status.Auction.DefaultSlotSetBidSlotNum {
|
||||
// All min bids can be calculated with the last update of AuctionVariables
|
||||
minBidInfo = []historydb.MinBidInfo{{
|
||||
DefaultSlotSetBid: a.status.Auction.DefaultSlotSetBid,
|
||||
DefaultSlotSetBidSlotNum: a.status.Auction.DefaultSlotSetBidSlotNum,
|
||||
}}
|
||||
} else {
|
||||
// Get all the relevant updates from the DB
|
||||
minBidInfo, err = a.h.GetAuctionVarsUntilSetSlotNum(lastClosedSlot, int(lastClosedSlot-currentSlot)+1)
|
||||
if err != nil {
|
||||
return nil, tracerr.Wrap(err)
|
||||
}
|
||||
}
|
||||
// Create nextForger for each slot
|
||||
for i := currentSlot; i <= lastClosedSlot; i++ {
|
||||
fromBlock := i*int64(a.cg.AuctionConstants.BlocksPerSlot) + a.cg.AuctionConstants.GenesisBlockNum
|
||||
@@ -135,11 +151,35 @@ func (a *API) getNextForgers(lastBlock common.Block, currentSlot, lastClosedSlot
|
||||
ToTimestamp: lastBlock.Timestamp.Add(time.Second * time.Duration(secondsPerBlock*(toBlock-lastBlock.Num))),
|
||||
},
|
||||
}
|
||||
foundBid := false
|
||||
foundForger := false
|
||||
// If there is a bid for a slot, get forger (coordinator)
|
||||
for j := range bids {
|
||||
if bids[j].SlotNum == i {
|
||||
foundBid = true
|
||||
slotNum := bids[j].SlotNum
|
||||
if slotNum == i {
|
||||
// There's a bid for the slot
|
||||
// Check if the bid is greater than the minimum required
|
||||
for i := 0; i < len(minBidInfo); i++ {
|
||||
// Find the most recent update
|
||||
if slotNum >= minBidInfo[i].DefaultSlotSetBidSlotNum {
|
||||
// Get min bid
|
||||
minBidSelector := slotNum % int64(len(a.status.Auction.DefaultSlotSetBid))
|
||||
minBid := minBidInfo[i].DefaultSlotSetBid[minBidSelector]
|
||||
// Check if the bid has beaten the minimum
|
||||
bid, ok := new(big.Int).SetString(string(bids[j].BidValue), 10)
|
||||
if !ok {
|
||||
return nil, tracerr.New("Wrong bid value, error parsing it as big.Int")
|
||||
}
|
||||
if minBid.Cmp(bid) == 1 {
|
||||
// Min bid is greater than bid, the slot will be forged by boot coordinator
|
||||
break
|
||||
}
|
||||
foundForger = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !foundForger { // There is no bid or it's smaller than the minimum
|
||||
break
|
||||
}
|
||||
coordinator, err := a.h.GetCoordinatorAPI(bids[j].Bidder)
|
||||
if err != nil {
|
||||
return nil, tracerr.Wrap(err)
|
||||
@@ -149,7 +189,7 @@ func (a *API) getNextForgers(lastBlock common.Block, currentSlot, lastClosedSlot
|
||||
}
|
||||
}
|
||||
// If there is no bid, the coordinator that will forge is boot coordinator
|
||||
if !foundBid {
|
||||
if !foundForger {
|
||||
nextForger.Coordinator = bootCoordinator
|
||||
}
|
||||
nextForgers = append(nextForgers, nextForger)
|
||||
|
||||
@@ -2,15 +2,12 @@ package api
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/hermeznetwork/hermez-node/common"
|
||||
"github.com/hermeznetwork/hermez-node/db/historydb"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
const secondsPerBlock = 15
|
||||
|
||||
type testStatus struct {
|
||||
Network testNetwork `json:"network"`
|
||||
Metrics historydb.Metrics `json:"metrics"`
|
||||
@@ -49,36 +46,6 @@ func TestSetAuctionVariables(t *testing.T) {
|
||||
assert.Equal(t, tc.auctionVars, api.status.Auction)
|
||||
}
|
||||
|
||||
func TestNextForgers(t *testing.T) {
|
||||
// It's assumed that bids for each slot will be received in increasing order
|
||||
bestBids := make(map[int64]testBid)
|
||||
for j := range tc.bids {
|
||||
bestBids[tc.bids[j].SlotNum] = tc.bids[j]
|
||||
}
|
||||
lastBlock := tc.blocks[len(tc.blocks)-1]
|
||||
for i := int64(0); i < tc.slots[len(tc.slots)-1].SlotNum; i++ {
|
||||
lastClosedSlot := i + int64(api.status.Auction.ClosedAuctionSlots)
|
||||
nextForgers, err := api.getNextForgers(tc.blocks[len(tc.blocks)-1], i, lastClosedSlot)
|
||||
assert.NoError(t, err)
|
||||
for j := i; j <= lastClosedSlot; j++ {
|
||||
for q := range nextForgers {
|
||||
if nextForgers[q].Period.SlotNum == j {
|
||||
if nextForgers[q].Coordinator.ItemID != 0 {
|
||||
assert.Equal(t, bestBids[j].Bidder, nextForgers[q].Coordinator.Bidder)
|
||||
} else {
|
||||
assert.Equal(t, bootCoordinator.Bidder, nextForgers[q].Coordinator.Bidder)
|
||||
}
|
||||
firstBlockSlot, lastBlockSlot := api.getFirstLastBlock(j)
|
||||
fromTimestamp := lastBlock.Timestamp.Add(time.Second * time.Duration(secondsPerBlock*(firstBlockSlot-lastBlock.Num)))
|
||||
toTimestamp := lastBlock.Timestamp.Add(time.Second * time.Duration(secondsPerBlock*(lastBlockSlot-lastBlock.Num)))
|
||||
assert.Equal(t, fromTimestamp.Unix(), nextForgers[q].Period.FromTimestamp.Unix())
|
||||
assert.Equal(t, toTimestamp.Unix(), nextForgers[q].Period.ToTimestamp.Unix())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestUpdateNetworkInfo(t *testing.T) {
|
||||
status := &Network{}
|
||||
assert.Equal(t, status.LastSyncBlock, api.status.Network.LastSyncBlock)
|
||||
@@ -143,23 +110,43 @@ func TestGetState(t *testing.T) {
|
||||
var status testStatus
|
||||
|
||||
assert.NoError(t, doGoodReq("GET", endpoint, nil, &status))
|
||||
|
||||
// SC vars
|
||||
assert.Equal(t, tc.rollupVars, status.Rollup)
|
||||
assert.Equal(t, tc.auctionVars, status.Auction)
|
||||
assert.Equal(t, tc.wdelayerVars, status.WithdrawalDelayer)
|
||||
// Network
|
||||
assert.Equal(t, lastBlock.Num, status.Network.LastEthBlock)
|
||||
assert.Equal(t, lastBlock.Num, status.Network.LastSyncBlock)
|
||||
// TODO: assert all the batch, not just the batch num
|
||||
assert.Equal(t, lastBatchNum, status.Network.LastBatch.BatchNum)
|
||||
assert.Equal(t, currentSlotNum, status.Network.CurrentSlot)
|
||||
assert.Equal(t, int(api.status.Auction.ClosedAuctionSlots)+1, len(status.Network.NextForgers))
|
||||
assertNextForgers(t, tc.nextForgers, status.Network.NextForgers)
|
||||
// Metrics
|
||||
// TODO: perform real asserts (not just greater than 0)
|
||||
assert.Greater(t, status.Metrics.TransactionsPerBatch, float64(0))
|
||||
assert.Greater(t, status.Metrics.BatchFrequency, float64(0))
|
||||
assert.Greater(t, status.Metrics.TransactionsPerBatch, float64(0))
|
||||
assert.Greater(t, status.Metrics.TotalAccounts, int64(0))
|
||||
assert.Greater(t, status.Metrics.TotalBJJs, int64(0))
|
||||
assert.Greater(t, status.Metrics.AvgTransactionFee, float64(0))
|
||||
// Recommended fee
|
||||
// TODO: perform real asserts (not just greater than 0)
|
||||
assert.Greater(t, status.RecommendedFee.ExistingAccount, float64(0))
|
||||
assert.Equal(t, status.RecommendedFee.CreatesAccount,
|
||||
status.RecommendedFee.ExistingAccount*createAccountExtraFeePercentage)
|
||||
assert.Equal(t, status.RecommendedFee.CreatesAccountAndRegister,
|
||||
status.RecommendedFee.ExistingAccount*createAccountInternalExtraFeePercentage)
|
||||
}
|
||||
|
||||
func assertNextForgers(t *testing.T, expected, actual []NextForger) {
|
||||
assert.Equal(t, len(expected), len(actual))
|
||||
for i := range expected {
|
||||
// ignore timestamps and other metadata
|
||||
actual[i].Period.FromTimestamp = expected[i].Period.FromTimestamp
|
||||
actual[i].Period.ToTimestamp = expected[i].Period.ToTimestamp
|
||||
actual[i].Coordinator.ItemID = expected[i].Coordinator.ItemID
|
||||
actual[i].Coordinator.EthBlockNum = expected[i].Coordinator.EthBlockNum
|
||||
assert.Equal(t, expected[i], actual[i])
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2714,6 +2714,9 @@ components:
|
||||
items:
|
||||
type: integer
|
||||
example: [32,0,68,21,55,99]
|
||||
defaultSlotSetBidSlotNum:
|
||||
type: integer
|
||||
description: Slot in which the changes will be applied for the first time.
|
||||
outbidding:
|
||||
type: number
|
||||
description: Minimum outbid over the previous one to consider it valid.
|
||||
|
||||
@@ -62,7 +62,7 @@ type AuctionVariables struct {
|
||||
// The minimum bid value in a series of 6 slots
|
||||
DefaultSlotSetBid [6]*big.Int `json:"defaultSlotSetBid" meddler:"default_slot_set_bid,json" validate:"required"`
|
||||
// SlotNum at which the new default_slot_set_bid applies
|
||||
DefaultSlotSetBidSlotNum int64 `json:"-" meddler:"default_slot_set_bid_slot_num"`
|
||||
DefaultSlotSetBidSlotNum int64 `json:"defaultSlotSetBidSlotNum" meddler:"default_slot_set_bid_slot_num"`
|
||||
// Distance (#slots) to the closest slot to which you can bid ( 2 Slots = 2 * 40 Blocks = 20 min )
|
||||
ClosedAuctionSlots uint16 `json:"closedAuctionSlots" meddler:"closed_auction_slots" validate:"required"`
|
||||
// Distance (#slots) to the farthest slot to which you can bid (30 days = 4320 slots )
|
||||
|
||||
@@ -1706,6 +1706,23 @@ func (hdb *HistoryDB) GetAuctionVars() (*common.AuctionVariables, error) {
|
||||
return auctionVars, tracerr.Wrap(err)
|
||||
}
|
||||
|
||||
// GetAuctionVarsUntilSetSlotNum returns all the updates of the auction vars
|
||||
// from the last entry in which DefaultSlotSetBidSlotNum <= slotNum
|
||||
func (hdb *HistoryDB) GetAuctionVarsUntilSetSlotNum(slotNum int64, maxItems int) ([]MinBidInfo, error) {
|
||||
auctionVars := []*MinBidInfo{}
|
||||
query := `
|
||||
SELECT DISTINCT default_slot_set_bid, default_slot_set_bid_slot_num FROM auction_vars
|
||||
WHERE default_slot_set_bid_slot_num < $1
|
||||
ORDER BY default_slot_set_bid_slot_num DESC
|
||||
LIMIT $2;
|
||||
`
|
||||
err := meddler.QueryAll(hdb.db, &auctionVars, query, slotNum, maxItems)
|
||||
if err != nil {
|
||||
return nil, tracerr.Wrap(err)
|
||||
}
|
||||
return db.SlicePtrsToSlice(auctionVars).([]MinBidInfo), nil
|
||||
}
|
||||
|
||||
// GetAccountAPI returns an account by its index
|
||||
func (hdb *HistoryDB) GetAccountAPI(idx common.Idx) (*AccountAPI, error) {
|
||||
account := &AccountAPI{}
|
||||
|
||||
@@ -331,3 +331,9 @@ type BidAPI struct {
|
||||
FirstItem uint64 `json:"-" meddler:"first_item"`
|
||||
LastItem uint64 `json:"-" meddler:"last_item"`
|
||||
}
|
||||
|
||||
// MinBidInfo gives information of the minum bid for specific slot(s)
|
||||
type MinBidInfo struct {
|
||||
DefaultSlotSetBid [6]*big.Int `json:"defaultSlotSetBid" meddler:"default_slot_set_bid,json" validate:"required"`
|
||||
DefaultSlotSetBidSlotNum int64 `json:"-" meddler:"default_slot_set_bid_slot_num"`
|
||||
}
|
||||
|
||||
@@ -345,7 +345,7 @@ func GenCoordinators(nCoords int, blocks []common.Block) []common.Coordinator {
|
||||
EthBlockNum: blocks[i%len(blocks)].Num,
|
||||
Forger: ethCommon.BigToAddress(big.NewInt(int64(i))),
|
||||
Bidder: ethCommon.BigToAddress(big.NewInt(int64(i))),
|
||||
URL: "https://foo.bar",
|
||||
URL: fmt.Sprintf("https://%d.coord", i),
|
||||
})
|
||||
}
|
||||
return coords
|
||||
|
||||
Reference in New Issue
Block a user