Skip to content

Commit

Permalink
tresor, kitkat, berghain (#171)
Browse files Browse the repository at this point in the history
* tresor, kitkat, berghain

* resolve debas comments

* chain config

* slight refactor

* resolve lumos comments
  • Loading branch information
atvanguard committed Mar 10, 2024
1 parent 62c931a commit 35f9293
Show file tree
Hide file tree
Showing 10 changed files with 115 additions and 66 deletions.
3 changes: 1 addition & 2 deletions chain.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@
"priority-regossip-txs-per-address": 200,
"priority-regossip-addresses": ["0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", "0x70997970C51812dc3A010C7d01b50e0d17dc79C8", "0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC", "0x8db97C7cEcE249c2b98bDC0226Cc4C2A57BF52FC"],
"validator-private-key-file": "/tmp/validator.pk",
"is-validator": true,
"trading-api-enabled": true,
"node-type": "kitkat_berghain",
"testing-api-enabled": true,
"load-from-snapshot-enabled": true,
"snapshot-file-path": "/tmp/snapshot",
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ require (
github.com/fsnotify/fsnotify v1.6.0
github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08
github.com/go-cmd/cmd v1.4.1
github.com/golang/mock v1.6.0
github.com/google/uuid v1.3.0
github.com/gorilla/rpc v1.2.0
github.com/gorilla/websocket v1.4.2
Expand Down Expand Up @@ -77,7 +78,6 @@ require (
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang-jwt/jwt/v4 v4.3.0 // indirect
github.com/golang/mock v1.6.0 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect
github.com/google/btree v1.1.2 // indirect
Expand Down
2 changes: 0 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -1049,8 +1049,6 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
Expand Down
5 changes: 5 additions & 0 deletions network-configs/aylin/chain_tresor.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"state-sync-enabled": true,
"feeRecipient": "0xB3D25D47291D7F8b97FE3884A924541cDDcbB8Be",
"node-type": "tresor"
}
12 changes: 4 additions & 8 deletions plugin/evm/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,7 @@ const (
defaultStateSyncMinBlocks = 300_000
defaultStateSyncRequestSize = 1024 // the number of key/values to ask peers for per request

defaultIsValidator = false
defaultTradingAPIEnabled = false
defaultNodeType = "tresor"
defaultLoadFromSnapshotEnabled = true
defaultSnapshotFilePath = "/tmp/snapshot"
defaultMakerbookDatabasePath = "/tmp/makerbook"
Expand Down Expand Up @@ -236,11 +235,9 @@ type Config struct {

// Testing apis enabled
TestingApiEnabled bool `json:"testing-api-enabled"`
// IsValidator is true if this node is a validator
IsValidator bool `json:"is-validator"`

// TradingAPI is for the sdk
TradingAPIEnabled bool `json:"trading-api-enabled"`
// NodeType is the type of node among the following: "tresor", "kitkat", "berghain", meaning validator only, matching engine, rpc node respectively
NodeType string `json:"node-type"`

// LoadFromSnapshotEnabled = true if the node should load the memory db from a snapshot
LoadFromSnapshotEnabled bool `json:"load-from-snapshot-enabled"`
Expand Down Expand Up @@ -311,8 +308,7 @@ func (c *Config) SetDefaults() {
c.AcceptedCacheSize = defaultAcceptedCacheSize
c.ValidatorPrivateKeyFile = defaultValidatorPrivateKeyFile
c.TestingApiEnabled = defaultTestingApiEnabled
c.IsValidator = defaultIsValidator
c.TradingAPIEnabled = defaultTradingAPIEnabled
c.NodeType = defaultNodeType
c.LoadFromSnapshotEnabled = defaultLoadFromSnapshotEnabled
c.SnapshotFilePath = defaultSnapshotFilePath
c.MakerbookDatabasePath = defaultMakerbookDatabasePath
Expand Down
5 changes: 5 additions & 0 deletions plugin/evm/gossiper_orders.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,11 @@ func (n *pushGossiper) sendSignedOrders(orders []*hu.SignedOrder) error {
// #### HANDLER ####

func (h *GossipHandler) HandleSignedOrders(nodeID ids.NodeID, msg message.SignedOrdersGossip) error {
// for vanilla validators we do not care about gossiping orders
if h.vm.limitOrderProcesser.GetNodeType() == Tresor {
return nil
}

h.mu.Lock()
defer h.mu.Unlock()

Expand Down
73 changes: 68 additions & 5 deletions plugin/evm/limit_order.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"os"
"runtime"
"runtime/debug"
"strings"
"sync"
"time"

Expand All @@ -32,12 +33,23 @@ const (
snapshotInterval uint64 = 10 // save snapshot every 1000 blocks
)

type NodeType string

const (
Tresor NodeType = "tresor" // vanilla validator
Kitkat NodeType = "kitkat" // validator + matching engine
Berghain NodeType = "berghain" // rpc node
Kitkat_Berghain NodeType = "kitkat_berghain" // validator + matching engine + rpc node
)

type LimitOrderProcesser interface {
ListenAndProcessTransactions(blockBuilder *blockBuilder)
GetOrderBookAPI() *orderbook.OrderBookAPI
GetTestingAPI() *orderbook.TestingAPI
GetTradingAPI() *orderbook.TradingAPI
RunMatchingPipeline()
GetNodeType() NodeType
isMatcherNode() bool
}

type limitOrderProcesser struct {
Expand All @@ -56,19 +68,36 @@ type limitOrderProcesser struct {
hubbleDB database.Database
configService orderbook.IConfigService
blockBuilder *blockBuilder
isValidator bool
tradingAPIEnabled bool
nodeType NodeType
loadFromSnapshotEnabled bool
snapshotSavedBlockNumber uint64
snapshotFilePath string
tradingAPI *orderbook.TradingAPI
}

func NewLimitOrderProcesser(ctx *snow.Context, txPool *txpool.TxPool, shutdownChan <-chan struct{}, shutdownWg *sync.WaitGroup, backend *eth.EthAPIBackend, blockChain *core.BlockChain, hubbleDB database.Database, validatorPrivateKey string, config Config) LimitOrderProcesser {
func NewLimitOrderProcesser(ctx *snow.Context, txPool *txpool.TxPool, shutdownChan <-chan struct{}, shutdownWg *sync.WaitGroup, backend *eth.EthAPIBackend, blockChain *core.BlockChain, hubbleDB database.Database, config Config) (LimitOrderProcesser, error) {
log.Info("**** NewLimitOrderProcesser")

configService := orderbook.NewConfigService(blockChain)
memoryDb := orderbook.NewInMemoryDatabase(configService)

nodeType, err := stringToNodeType(config.NodeType)
if err != nil {
return nil, err
}
var validatorPrivateKey string
if nodeType == Kitkat || nodeType == Kitkat_Berghain {
validatorPrivateKey, err = loadPrivateKeyFromFile(config.ValidatorPrivateKeyFile)
if err != nil {
panic(fmt.Sprint("please specify correct path for validator-private-key-file in chain.json ", err))
}
if validatorPrivateKey == "" {
panic("validator private key is empty")
}
}
lotp := orderbook.NewLimitOrderTxProcessor(txPool, memoryDb, backend, validatorPrivateKey)

signedObAddy := configService.GetSignedOrderbookContract()
contractEventProcessor := orderbook.NewContractEventsProcessor(memoryDb, signedObAddy)

Expand Down Expand Up @@ -110,14 +139,40 @@ func NewLimitOrderProcesser(ctx *snow.Context, txPool *txpool.TxPool, shutdownCh
matchingPipeline: matchingPipeline,
filterAPI: filterAPI,
configService: configService,
isValidator: config.IsValidator,
tradingAPIEnabled: config.TradingAPIEnabled,
nodeType: nodeType,
loadFromSnapshotEnabled: config.LoadFromSnapshotEnabled,
snapshotFilePath: config.SnapshotFilePath,
}, nil
}

func loadPrivateKeyFromFile(keyFile string) (string, error) {
key, err := os.ReadFile(keyFile)
if err != nil {
return "", err
}
return strings.TrimSuffix(string(key), "\n"), nil
}

func stringToNodeType(nodeTypeString string) (NodeType, error) {
switch nodeTypeString {
case string(Tresor):
return Tresor, nil
case string(Kitkat):
return Kitkat, nil
case string(Berghain):
return Berghain, nil
case string(Kitkat_Berghain):
return Kitkat_Berghain, nil
default:
return "", fmt.Errorf("unknown NodeType: %s", nodeTypeString)
}
}

func (lop *limitOrderProcesser) ListenAndProcessTransactions(blockBuilder *blockBuilder) {
if lop.nodeType == Tresor {
return
}

lop.mu.Lock()

lastAccepted := lop.blockChain.LastAcceptedBlock()
Expand Down Expand Up @@ -174,7 +229,7 @@ func (lop *limitOrderProcesser) ListenAndProcessTransactions(blockBuilder *block
}

func (lop *limitOrderProcesser) RunMatchingPipeline() {
if !lop.isValidator {
if !lop.isMatcherNode() {
return
}
executeFuncAndRecoverPanic(func() {
Expand Down Expand Up @@ -206,6 +261,14 @@ func (lop *limitOrderProcesser) GetTestingAPI() *orderbook.TestingAPI {
return orderbook.NewTestingAPI(lop.memoryDb, lop.backend, lop.configService, lop.hubbleDB)
}

func (lop *limitOrderProcesser) GetNodeType() NodeType {
return lop.nodeType
}

func (lop *limitOrderProcesser) isMatcherNode() bool {
return lop.nodeType == Kitkat || lop.nodeType == Kitkat_Berghain
}

func (lop *limitOrderProcesser) listenAndStoreLimitOrderTransactions() {
logsCh := make(chan []*types.Log)
logsSubscription := lop.backend.SubscribeHubbleLogsEvent(logsCh)
Expand Down
1 change: 1 addition & 0 deletions plugin/evm/order_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ func (api *OrderAPI) PlaceSignedOrders(ctx context.Context, input string) (Place
continue
}

// we ignore the 2nd argument shouldTriggerMatching. since PlaceSignedOrders is only called in API nodes, we do not trigger matching in them
orderId, _, err := api.tradingAPI.PlaceOrder(order)
orderResponse.OrderId = orderId.String()
if err != nil {
Expand Down
4 changes: 2 additions & 2 deletions plugin/evm/orderbook_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -961,8 +961,8 @@ func TestHubbleLogs(t *testing.T) {
// Create two VMs which will agree on block A and then
// build the two distinct preferred chains above
ctx := context.Background()
issuer1, vm1, _, _ := GenesisVM(t, true, genesisJSON, "{\"pruning-enabled\":true}", "")
issuer2, vm2, _, _ := GenesisVM(t, true, genesisJSON, "{\"pruning-enabled\":true}", "")
issuer1, vm1, _, _ := GenesisVM(t, true, genesisJSON, "{\"pruning-enabled\":true,\"node-type\":\"kitkat\"}", "")
issuer2, vm2, _, _ := GenesisVM(t, true, genesisJSON, "{\"pruning-enabled\":true,\"node-type\":\"kitkat\"}", "")

defer func() {
if err := vm1.Shutdown(ctx); err != nil {
Expand Down
74 changes: 28 additions & 46 deletions plugin/evm/vm.go
Original file line number Diff line number Diff line change
Expand Up @@ -567,7 +567,19 @@ func (vm *VM) initializeChain(lastAcceptedHash common.Hash, ethConfig ethconfig.
vm.blockChain = vm.eth.BlockChain()
vm.miner = vm.eth.Miner()

vm.limitOrderProcesser = vm.NewLimitOrderProcesser()
vm.limitOrderProcesser, err = NewLimitOrderProcesser(
vm.ctx,
vm.txPool,
vm.shutdownChan,
&vm.shutdownWg,
vm.eth.APIBackend,
vm.blockChain,
vm.hubbleDB,
vm.config,
)
if err != nil {
return err
}
vm.eth.Start()
return vm.initChainState(vm.blockChain.LastAcceptedBlock())
}
Expand Down Expand Up @@ -1008,24 +1020,27 @@ func (vm *VM) CreateHandlers(context.Context) (map[string]http.Handler, error) {
}
enabledAPIs = append(enabledAPIs, "snowman")
}
if err := handler.RegisterName("order", NewOrderAPI(vm.limitOrderProcesser.GetTradingAPI(), vm)); err != nil {
return nil, err
}
orderbook.MakerbookDatabaseFile = vm.config.MakerbookDatabasePath

if err := handler.RegisterName("orderbook", vm.limitOrderProcesser.GetOrderBookAPI()); err != nil {
return nil, err
}
if vm.limitOrderProcesser.GetNodeType() != Tresor {
// orderbook and trading APIs should be enabled for kitkat too cuz it's good to have visibility on memory db in those nodes. To understand the validators' memory db.
if err := handler.RegisterName("order", NewOrderAPI(vm.limitOrderProcesser.GetTradingAPI(), vm)); err != nil {
return nil, err
}
orderbook.MakerbookDatabaseFile = vm.config.MakerbookDatabasePath

if vm.config.TradingAPIEnabled {
if err := handler.RegisterName("trading", vm.limitOrderProcesser.GetTradingAPI()); err != nil {
if err := handler.RegisterName("orderbook", vm.limitOrderProcesser.GetOrderBookAPI()); err != nil {
return nil, err
}
}
if vm.config.TestingApiEnabled {
if err := handler.RegisterName("testing", vm.limitOrderProcesser.GetTestingAPI()); err != nil {

if err := handler.RegisterName("trading", vm.limitOrderProcesser.GetTradingAPI()); err != nil {
return nil, err
}

if vm.config.TestingApiEnabled {
if err := handler.RegisterName("testing", vm.limitOrderProcesser.GetTestingAPI()); err != nil {
return nil, err
}
}
}

if vm.config.WarpAPIEnabled {
Expand Down Expand Up @@ -1165,36 +1180,3 @@ func attachEthService(handler *rpc.Server, apis []rpc.API, names []string) error

return nil
}

func (vm *VM) NewLimitOrderProcesser() LimitOrderProcesser {
var validatorPrivateKey string
var err error
if vm.config.IsValidator {
validatorPrivateKey, err = loadPrivateKeyFromFile(vm.config.ValidatorPrivateKeyFile)
if err != nil {
panic(fmt.Sprint("please specify correct path for validator-private-key-file in chain.json ", err))
}
if validatorPrivateKey == "" {
panic("validator private key is empty")
}
}
return NewLimitOrderProcesser(
vm.ctx,
vm.txPool,
vm.shutdownChan,
&vm.shutdownWg,
vm.eth.APIBackend,
vm.blockChain,
vm.hubbleDB,
validatorPrivateKey,
vm.config,
)
}

func loadPrivateKeyFromFile(keyFile string) (string, error) {
key, err := os.ReadFile(keyFile)
if err != nil {
return "", err
}
return strings.TrimSuffix(string(key), "\n"), nil
}

0 comments on commit 35f9293

Please sign in to comment.