Skip to content

Commit

Permalink
Sorted order arrays snapshot fix (#131)
Browse files Browse the repository at this point in the history
* recompute sorted arrays when loading from snapshot

* avoid consecutive sample pi txs

* err == nil
  • Loading branch information
atvanguard authored Oct 12, 2023
1 parent 3cf0921 commit 76d59c9
Show file tree
Hide file tree
Showing 7 changed files with 46 additions and 12 deletions.
3 changes: 2 additions & 1 deletion network-configs/aylin/chain_api_node.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@
"priority-regossip-addresses": ["0x06CCAD927e6B1d36E219Cb582Af3185D0705f78F"],
"coreth-admin-api-enabled": true,
"eth-apis": ["public-eth","public-eth-filter","net","web3","internal-public-eth","internal-public-blockchain","internal-public-transaction-pool","internal-public-debug","internal-private-debug","internal-public-tx-pool","internal-public-account","debug-tracer"],
"trading-api-enabled": true
"trading-api-enabled": true,
"testing-api-enabled": true
}
3 changes: 2 additions & 1 deletion network-configs/aylin/chain_archival_node.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@
"priority-regossip-addresses": ["0x06CCAD927e6B1d36E219Cb582Af3185D0705f78F"],
"coreth-admin-api-enabled": true,
"eth-apis": ["public-eth","public-eth-filter","net","web3","internal-public-eth","internal-public-blockchain","internal-public-transaction-pool","internal-public-debug","internal-private-debug","internal-public-tx-pool","internal-public-account","debug-tracer"],
"trading-api-enabled": true
"trading-api-enabled": true,
"testing-api-enabled": true
}
3 changes: 3 additions & 0 deletions plugin/evm/limit_order.go
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,9 @@ func (lop *limitOrderProcesser) saveMemoryDBSnapshot(acceptedBlockNumber *big.In
cev.ProcessEvents(logsToRemove)
}

// these SHOULD be re-populated while loading from snapshot
memoryDBCopy.LongOrders = nil
memoryDBCopy.ShortOrders = nil
snapshot := orderbook.Snapshot{
Data: memoryDBCopy,
AcceptedBlockNumber: acceptedBlockNumber,
Expand Down
6 changes: 3 additions & 3 deletions plugin/evm/orderbook/matching_pipeline.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ func (pipeline *MatchingPipeline) Run(blockNumber *big.Int) bool {
}

// check nextSamplePITime
if isSamplePITime(pipeline.db.GetNextSamplePITime()) {
if isSamplePITime(pipeline.db.GetNextSamplePITime(), pipeline.db.GetSamplePIAttemptedTime()) {
log.Info("MatchingPipeline:isSamplePITime")
err := pipeline.lotp.ExecuteSamplePITx()
if err != nil {
Expand Down Expand Up @@ -328,13 +328,13 @@ func isFundingPaymentTime(nextFundingTime uint64) bool {
return now >= nextFundingTime
}

func isSamplePITime(nextSamplePITime uint64) bool {
func isSamplePITime(nextSamplePITime, lastAttempt uint64) bool {
if nextSamplePITime == 0 {
return false
}

now := uint64(time.Now().Unix())
return now >= nextSamplePITime
return now >= nextSamplePITime && now >= lastAttempt+5 // give 5 secs for the tx to be mined
}

func executeFundingPayment(lotp LimitOrderTxProcessor) error {
Expand Down
33 changes: 26 additions & 7 deletions plugin/evm/orderbook/memory_database.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ type InMemoryDatabase struct {
LastPrice map[Market]*big.Int `json:"last_price"`
CumulativePremiumFraction map[Market]*big.Int `json:"cumulative_last_premium_fraction"`
NextSamplePITime uint64 `json:"next_sample_pi_time"`
SamplePIAttemptedTime uint64 `json:"sample_pi_attempted_time"`
configService IConfigService
}

Expand All @@ -39,7 +40,6 @@ func NewInMemoryDatabase(configService IConfigService) *InMemoryDatabase {
LongOrders: map[Market][]*Order{},
ShortOrders: map[Market][]*Order{},
TraderMap: traderMap,
NextFundingTime: 0,
LastPrice: lastPrice,
CumulativePremiumFraction: map[Market]*big.Int{},
mu: &sync.RWMutex{},
Expand Down Expand Up @@ -230,6 +230,8 @@ type LimitOrderDatabase interface {
GetNextFundingTime() uint64
UpdateNextSamplePITime(nextSamplePITime uint64)
GetNextSamplePITime() uint64
GetSamplePIAttemptedTime() uint64
SignalSamplePIAttempted(time uint64)
UpdateLastPrice(market Market, lastPrice *big.Int)
GetLastPrices() map[Market]*big.Int
GetAllTraders() map[common.Address]Trader
Expand Down Expand Up @@ -261,14 +263,15 @@ func (db *InMemoryDatabase) LoadFromSnapshot(snapshot Snapshot) error {
}

db.Orders = snapshot.Data.Orders
db.LongOrders = snapshot.Data.LongOrders
db.ShortOrders = snapshot.Data.ShortOrders
db.TraderMap = snapshot.Data.TraderMap
db.LastPrice = snapshot.Data.LastPrice
db.NextFundingTime = snapshot.Data.NextFundingTime
db.NextSamplePITime = snapshot.Data.NextSamplePITime
db.CumulativePremiumFraction = snapshot.Data.CumulativePremiumFraction

for _, order := range db.Orders {
db.AddInSortedArray(order)
}
return nil
}

Expand Down Expand Up @@ -427,8 +430,14 @@ func (db *InMemoryDatabase) Add(order *Order) {
db.mu.Lock()
defer db.mu.Unlock()

market := order.Market
order.LifecycleList = append(order.LifecycleList, Lifecycle{order.BlockNumber.Uint64(), Placed, ""})
db.AddInSortedArray(order)
db.Orders[order.Id] = order
}

// caller is expected to acquire db.mu before calling this function
func (db *InMemoryDatabase) AddInSortedArray(order *Order) {
market := order.Market

var orders []*Order
var position int
Expand All @@ -451,7 +460,6 @@ func (db *InMemoryDatabase) Add(order *Order) {
}
return false
})

} else {
orders = db.ShortOrders[market]
position = sort.Search(len(orders), func(i int) bool {
Expand Down Expand Up @@ -483,8 +491,6 @@ func (db *InMemoryDatabase) Add(order *Order) {
} else {
db.ShortOrders[market] = orders
}

db.Orders[order.Id] = order
}

func (db *InMemoryDatabase) Delete(orderId common.Hash) {
Expand Down Expand Up @@ -576,6 +582,19 @@ func (db *InMemoryDatabase) GetNextSamplePITime() uint64 {
return db.NextSamplePITime
}

func (db *InMemoryDatabase) GetSamplePIAttemptedTime() uint64 {
db.mu.RLock()
defer db.mu.RUnlock()

return db.SamplePIAttemptedTime
}

func (db *InMemoryDatabase) SignalSamplePIAttempted(time uint64) {
db.mu.Lock()
defer db.mu.Unlock()
db.SamplePIAttemptedTime = time
}

func (db *InMemoryDatabase) UpdateNextSamplePITime(nextSamplePITime uint64) {
db.mu.Lock()
defer db.mu.Unlock()
Expand Down
6 changes: 6 additions & 0 deletions plugin/evm/orderbook/mocks.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,12 @@ func (db *MockLimitOrderDatabase) GetTraderInfo(trader common.Address) *Trader {
return &Trader{}
}

func (db *MockLimitOrderDatabase) GetSamplePIAttemptedTime() uint64 {
return 0
}

func (db *MockLimitOrderDatabase) SignalSamplePIAttempted(time uint64) {}

type MockLimitOrderTxProcessor struct {
mock.Mock
}
Expand Down
4 changes: 4 additions & 0 deletions plugin/evm/orderbook/tx_processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package orderbook
import (
"context"
"crypto/ecdsa"
"time"

// "encoding/hex"
"errors"
Expand Down Expand Up @@ -119,6 +120,9 @@ func (lotp *limitOrderTxProcessor) ExecuteFundingPaymentTx() error {
func (lotp *limitOrderTxProcessor) ExecuteSamplePITx() error {
txHash, err := lotp.executeLocalTx(lotp.clearingHouseContractAddress, lotp.clearingHouseABI, "samplePI")
log.Info("ExecuteSamplePITx", "txHash", txHash.String(), "err", err)
if err == nil {
lotp.memoryDb.SignalSamplePIAttempted(uint64(time.Now().Unix()))
}
return err
}

Expand Down

0 comments on commit 76d59c9

Please sign in to comment.