banner
zach

zach

github
twitter
medium

Flasbots Builder詳解 (1)初始化

image

初始化#

Flashbots Builder 是在 geth 基礎上進行開發的,因此大體架構與 geth 保持一致。Builder核心結構定義在builder/builder.go文件中,Builder 對外被封裝到 BuilderService 中,對外提供 http 服務。從外至內,先分析 BuilderService,再到 Builder 和其內部組成。

BuilderService

  • 封裝了 IBuilder 接口和 httpServer
  • NewService 參數:傳入監聽的地址,localRelay 配置,builder 實例
    • localRelay 不為空,則初始化路由
      • GET:/
      • GET: /eth/v1/builder/status
      • POST: /eth/v1/builder/validators
      • GET: /eth/v1/builder/header/{slot:[0-9]+}/{parent_hash:0x[a-fA-F0-9]+}/{pubkey:0x[a-fA-F0-9]+}
      • POST: /eth/v1/builder/blinded_blocks
  • Start:啟動 Http 服務,啟動 builder
  • Stop:關閉 Http 服務,關閉 builder

Builder

首先看NewBuilder的參數BuilderArgs ,對應字段的註釋已經添加

type BuilderArgs struct {
  	sk                            *bls.SecretKey // 運行builder的私鑰
  	ds                            flashbotsextra.IDatabaseService // 本地的數據庫服務
  	relay                         IRelay // relay接口
  	builderSigningDomain          phase0.Domain // 用於提交區塊時簽名的域名
  	builderBlockResubmitInterval  time.Duration // 間隔一段時間重複提交區塊
  	discardRevertibleTxOnErr      bool // 無用
  	eth                           IEthereumService // eth實例,用於構建區塊
  	dryRun                        bool // 是否需要向relay提交區塊
  	ignoreLatePayloadAttributes   bool // 用於在監聽事件時過濾
  	validator                     *blockvalidation.BlockValidationAPI // dryRun時用於提交驗證
  	beaconClient                  IBeaconClient // 信標鏈client,用於監聽事件構建payload
  	submissionOffsetFromEndOfSlot time.Duration  // 提交區塊的等待時間
  
  	limiter *rate.Limiter // 用作限流
}

可以看到 builder 的核心組成包括 ds, relay, eth 和 beaconClient,其他的參數在後面應用到時會做進一步的解釋。

Relay#

首先 Relay 出現在兩處(BuilderService 和 Builder),且有兩種類型(localRelay 和 remoteRelay)

  • 在 BuilderService 中已經有的是 localRelay,如果 localRelay 不為空,便會在 BuilderService 中的 http 服務註冊相應的路由
  • 在 Builder 中有 Relay,如果沒有配置 remoteReplayEndpoint,就用 localRelay,否則是 remoteRelay

由此可見,每個 builder 不一定要自己跑一個 relay 服務,但是一定會連接到相應的 relay 服務

Relay 的接口定義如下所示:

type IRelay interface {
	SubmitBlock(msg *bellatrixapi.SubmitBlockRequest, vd ValidatorData) error
	SubmitBlockCapella(msg *capellaapi.SubmitBlockRequest, vd ValidatorData) error
	GetValidatorForSlot(nextSlot uint64) (ValidatorData, error)
	Config() RelayConfig
	Start() error
	Stop()
}

DatabaseService#

先回到前面初始化 DatabaseService的地方,在初始化時會判斷是否配置 postgres 連接,如果沒有的話會初始化一個默認的 dbService,否則就建立 db 連接

var ds flashbotsextra.IDatabaseService
	dbDSN := os.Getenv("FLASHBOTS_POSTGRES_DSN")
	if dbDSN != "" {
		ds, err = flashbotsextra.NewDatabaseService(dbDSN)
		if err != nil {
			log.Error("could not connect to the DB", "err", err)
			ds = flashbotsextra.NilDbService{}
		}
	} else {
		log.Info("db dsn is not provided, starting nil db svc")
		ds = flashbotsextra.NilDbService{}
	}

IDatabaseService的接口定義如下:對於默認的 NilDbService,都返回的空

type IDatabaseService interface {
	ConsumeBuiltBlock(block *types.Block, blockValue *big.Int, OrdersClosedAt time.Time, sealedAt time.Time,
		commitedBundles []types.SimulatedBundle, allBundles []types.SimulatedBundle,
		usedSbundles []types.UsedSBundle,
		bidTrace *apiv1.BidTrace)
	GetPriorityBundles(ctx context.Context, blockNum int64, isHighPrio bool) ([]DbBundle, error)
	GetLatestUuidBundles(ctx context.Context, blockNum int64) ([]types.LatestUuidBundle, error)
}

在具體實現中,主要記錄的是 blocks bundles 表等信息,用於記錄本地 builder 的構建區塊和 bundle 信息,也用作查詢和替換用,在後面會介紹到

Eth#

這裡定義的是結構是EthereumService,是對 eth 實例的封裝,eth 實例也就是熟悉的 geth 中的 eth 實例,在前面被初始化,這裡抽象成IEthereumService 接口,對外提供以下四個方法

type IEthereumService interface {
	BuildBlock(attrs *types.BuilderPayloadAttributes, sealedBlockCallback miner.BlockHookFn) error
	GetBlockByHash(hash common.Hash) *types.Block
	Config() *params.ChainConfig
	Synced() bool
}

BeaconClient#

beaconClient 是用來與信標鏈節點通信的,在初始化部分,根據配置 BeaconEndpoints,選擇是NewBeaconClient or NewMultiBeaconClient

var beaconClient IBeaconClient
	if len(cfg.BeaconEndpoints) == 0 {
		beaconClient = &NilBeaconClient{}
	} else if len(cfg.BeaconEndpoints) == 1 {
		beaconClient = NewBeaconClient(cfg.BeaconEndpoints[0], cfg.SlotsInEpoch, cfg.SecondsInSlot)
	} else {
		beaconClient = NewMultiBeaconClient(cfg.BeaconEndpoints, cfg.SlotsInEpoch, cfg.SecondsInSlot)
	}

BeaconClient 包括三個核心的字段:

  • endpoint :建立 beaconClient 的連接
  • slotsInEpoch :默認 32
  • secondsInSlot: 默認 12

slot 是 eth2.0 中的配置,是一個固定的時間段,通常是 12s,所有的活躍驗證者按照一定規則輪流擔當不同 slot 時的 proposer,每個 slot 對應打包一個區塊

epoch 是更大的時間周期,由多個連續的 slot 組成,通常為 32 個 slot

對外提供以下幾種方法:

type IBeaconClient interface {
	isValidator(pubkey PubkeyHex) bool
	getProposerForNextSlot(requestedSlot uint64) (PubkeyHex, error)
	SubscribeToPayloadAttributesEvents(payloadAttrC chan types.BuilderPayloadAttributes)
	Start() error
	Stop()
}

重點的方法就是 SubscribeToPayloadAttributesEvents 用來獲取定閱的請求

載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。