Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tresor, kitkat, berghain #171

Merged
merged 5 commits into from
Mar 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 {
atvanguard marked this conversation as resolved.
Show resolved Hide resolved
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
}
Loading