diff --git a/pkg/mev/broadcaster.go b/pkg/mev/broadcaster.go index afebe24..7e1ecca 100644 --- a/pkg/mev/broadcaster.go +++ b/pkg/mev/broadcaster.go @@ -25,6 +25,10 @@ const ( Endpoint48Club = "https://puissant-builder.48.club" EndpointBlockRazor = "https://bsc.blockrazor.xyz" EndpointBloxRouteBundleSubmissions = "https://api.blxrbdn.com" + EndpointEthGasUS = "https://us.builder.ethgas.com" + EndpointEthGasEU = "https://eu.builder.ethgas.com" + EndpointEthGasAP = "https://ap.builder.ethgas.com" + EndpointEthGasAP2 = "https://ap-2.builder.ethgas.com" ) const ( @@ -48,4 +52,5 @@ const ( BuilderBobTheBuilder string = "builder-bobthebuilder" Builder48Club string = "builder-48club" BuilderBlockRazor string = "builder-blockrazor" + BuilderEthGasID string = "builder-ethgas" ) diff --git a/pkg/mev/bsc_builder_test.go b/pkg/mev/bsc_builder_test.go index 8fb4d38..10c5602 100644 --- a/pkg/mev/bsc_builder_test.go +++ b/pkg/mev/bsc_builder_test.go @@ -138,3 +138,22 @@ func TestSendBundleV2_48ClubFieldsStayOffOtherBuilders(t *testing.T) { require.NotContains(t, got.params, "noMerge") } + +// TestSendBundleV2_EthGasGetsBomboraFields: EthGas accepts the same optional fields as Bombora, +// including replacementSeqNumber, which Ultrasound does not. +func TestSendBundleV2_EthGasGetsBomboraFields(t *testing.T) { + t.Parallel() + blockNumber, seq, refund := uint64(1), uint64(2), uint64(90) + dropping := []string{"0x01"} + got := sendOne(t, mev.BundleSenderTypeEthGas, mev.SendBundleV2Request{ + BlockNumber: &blockNumber, + DroppingTxs: &dropping, + ReplacementSeqNumber: &seq, + RefundPercent: &refund, + }) + + require.Equal(t, mev.ETHSendBundleMethod, got.method) + require.Equal(t, []any{"0x01"}, got.params["droppingTxHashes"]) + require.InDelta(t, float64(seq), got.params["replacementSeqNumber"], 0) + require.InDelta(t, float64(refund), got.params["refundPercent"], 0) +} diff --git a/pkg/mev/bundle_sender.go b/pkg/mev/bundle_sender.go index 15dabc8..c4b6501 100644 --- a/pkg/mev/bundle_sender.go +++ b/pkg/mev/bundle_sender.go @@ -526,8 +526,8 @@ type SendBundleParams struct { // (Optional) String, UUID that can be used to cancel/replace this bundle (For beaverbuild) UUID string `json:"uuid,omitempty"` StateBlockNumber string `json:"stateBlockNumber,omitempty"` - // Bundle fields that only Bombora and Ultrasound accept. - // ReplacementSeqNumber is Bombora only. + // Bundle fields that only Bombora, EthGas and Ultrasound accept. + // ReplacementSeqNumber is Bombora and EthGas only. DroppingTxHashes *[]string `json:"droppingTxHashes,omitempty"` ReplacementSeqNumber *uint64 `json:"replacementSeqNumber,omitempty"` RefundPercent *uint64 `json:"refundPercent,omitempty"` @@ -571,7 +571,7 @@ func (p *SendBundleParams) setSenderSpecificFields( senderType BundleSenderType, req SendBundleV2Request, ) *SendBundleParams { switch senderType { - case BundleSenderTypeBombora: + case BundleSenderTypeBombora, BundleSenderTypeEthGas: return p.SetBomboraFields(req) case BundleSenderTypeUltrasound: return p.SetUltrasoundFields(req) @@ -674,6 +674,8 @@ func (p *SendBundleParams) SetBuilderNetRefundAddress(addr string) *SendBundlePa } // SetBomboraFields copies Bombora-only bundle options onto p. +// EthGas accepts the same fields with the same limits, so it shares this method. +// ref: https://docs.ethgas.com/get-started/searchers/builder-endpoint func (p *SendBundleParams) SetBomboraFields(req SendBundleV2Request) *SendBundleParams { if req.DroppingTxs != nil { p.DroppingTxHashes = req.DroppingTxs diff --git a/pkg/mev/bundlesendertype_enumer.go b/pkg/mev/bundlesendertype_enumer.go index b79774e..7bfc3fd 100644 --- a/pkg/mev/bundlesendertype_enumer.go +++ b/pkg/mev/bundlesendertype_enumer.go @@ -7,11 +7,11 @@ import ( "strings" ) -const _BundleSenderTypeName = "BundleSenderTypeFlashbotBundleSenderTypeBeaverBundleSenderTypeRsyncBundleSenderTypeTitanBundleSenderTypeBloxrouteBundleSenderTypeAllBundleSenderTypeMevShareBundleSenderTypeBackrunPublicBundleSenderTypeMevBlockerBundleSenderTypeBlinkBundleSenderTypeMerkleBundleSenderTypeJetbldrBundleSenderTypePenguinBundleSenderTypeLokiBundleSenderTypeQuasarBundleSenderTypeBuilderNetBundleSenderTypeBTCSBundleSenderTypeEurekaBundleSenderTypeL2BundleSenderTypeBloxrouteBackrunmeBundleSenderTypePublicMempoolBundleSenderTypeBobTheBuilderBundleSenderTypeInternalMempoolBundleSenderTypeQuickNodeBundleSenderType48ClubBundleSenderTypeBlockRazorBundleSenderTypeNodeRealBundleSenderTypeBomboraBundleSenderTypeUltrasoundBundleSenderTypeServo" +const _BundleSenderTypeName = "BundleSenderTypeFlashbotBundleSenderTypeBeaverBundleSenderTypeRsyncBundleSenderTypeTitanBundleSenderTypeBloxrouteBundleSenderTypeAllBundleSenderTypeMevShareBundleSenderTypeBackrunPublicBundleSenderTypeMevBlockerBundleSenderTypeBlinkBundleSenderTypeMerkleBundleSenderTypeJetbldrBundleSenderTypePenguinBundleSenderTypeLokiBundleSenderTypeQuasarBundleSenderTypeBuilderNetBundleSenderTypeBTCSBundleSenderTypeEurekaBundleSenderTypeL2BundleSenderTypeBloxrouteBackrunmeBundleSenderTypePublicMempoolBundleSenderTypeBobTheBuilderBundleSenderTypeInternalMempoolBundleSenderTypeQuickNodeBundleSenderType48ClubBundleSenderTypeBlockRazorBundleSenderTypeNodeRealBundleSenderTypeBomboraBundleSenderTypeUltrasoundBundleSenderTypeServoBundleSenderTypeEthGas" -var _BundleSenderTypeIndex = [...]uint16{0, 24, 46, 67, 88, 113, 132, 156, 185, 211, 232, 254, 277, 300, 320, 342, 368, 388, 410, 428, 462, 491, 520, 551, 576, 598, 624, 648, 671, 697, 718} +var _BundleSenderTypeIndex = [...]uint16{0, 24, 46, 67, 88, 113, 132, 156, 185, 211, 232, 254, 277, 300, 320, 342, 368, 388, 410, 428, 462, 491, 520, 551, 576, 598, 624, 648, 671, 697, 718, 740} -const _BundleSenderTypeLowerName = "bundlesendertypeflashbotbundlesendertypebeaverbundlesendertypersyncbundlesendertypetitanbundlesendertypebloxroutebundlesendertypeallbundlesendertypemevsharebundlesendertypebackrunpublicbundlesendertypemevblockerbundlesendertypeblinkbundlesendertypemerklebundlesendertypejetbldrbundlesendertypepenguinbundlesendertypelokibundlesendertypequasarbundlesendertypebuildernetbundlesendertypebtcsbundlesendertypeeurekabundlesendertypel2bundlesendertypebloxroutebackrunmebundlesendertypepublicmempoolbundlesendertypebobthebuilderbundlesendertypeinternalmempoolbundlesendertypequicknodebundlesendertype48clubbundlesendertypeblockrazorbundlesendertypenoderealbundlesendertypebomborabundlesendertypeultrasoundbundlesendertypeservo" +const _BundleSenderTypeLowerName = "bundlesendertypeflashbotbundlesendertypebeaverbundlesendertypersyncbundlesendertypetitanbundlesendertypebloxroutebundlesendertypeallbundlesendertypemevsharebundlesendertypebackrunpublicbundlesendertypemevblockerbundlesendertypeblinkbundlesendertypemerklebundlesendertypejetbldrbundlesendertypepenguinbundlesendertypelokibundlesendertypequasarbundlesendertypebuildernetbundlesendertypebtcsbundlesendertypeeurekabundlesendertypel2bundlesendertypebloxroutebackrunmebundlesendertypepublicmempoolbundlesendertypebobthebuilderbundlesendertypeinternalmempoolbundlesendertypequicknodebundlesendertype48clubbundlesendertypeblockrazorbundlesendertypenoderealbundlesendertypebomborabundlesendertypeultrasoundbundlesendertypeservobundlesendertypeethgas" func (i BundleSenderType) String() string { i -= 1 @@ -55,71 +55,77 @@ func _BundleSenderTypeNoOp() { _ = x[BundleSenderTypeBombora-(28)] _ = x[BundleSenderTypeUltrasound-(29)] _ = x[BundleSenderTypeServo-(30)] + _ = x[BundleSenderTypeEthGas-(31)] } -var _BundleSenderTypeValues = []BundleSenderType{BundleSenderTypeFlashbot, BundleSenderTypeBeaver, BundleSenderTypeRsync, BundleSenderTypeTitan, BundleSenderTypeBloxroute, BundleSenderTypeAll, BundleSenderTypeMevShare, BundleSenderTypeBackrunPublic, BundleSenderTypeMevBlocker, BundleSenderTypeBlink, BundleSenderTypeMerkle, BundleSenderTypeJetbldr, BundleSenderTypePenguin, BundleSenderTypeLoki, BundleSenderTypeQuasar, BundleSenderTypeBuilderNet, BundleSenderTypeBTCS, BundleSenderTypeEureka, BundleSenderTypeL2, BundleSenderTypeBloxrouteBackrunme, BundleSenderTypePublicMempool, BundleSenderTypeBobTheBuilder, BundleSenderTypeInternalMempool, BundleSenderTypeQuickNode, BundleSenderType48Club, BundleSenderTypeBlockRazor, BundleSenderTypeNodeReal, BundleSenderTypeBombora, BundleSenderTypeUltrasound, BundleSenderTypeServo} +var _BundleSenderTypeValues = []BundleSenderType{BundleSenderTypeFlashbot, BundleSenderTypeBeaver, BundleSenderTypeRsync, BundleSenderTypeTitan, BundleSenderTypeBloxroute, BundleSenderTypeAll, BundleSenderTypeMevShare, BundleSenderTypeBackrunPublic, BundleSenderTypeMevBlocker, BundleSenderTypeBlink, BundleSenderTypeMerkle, BundleSenderTypeJetbldr, BundleSenderTypePenguin, BundleSenderTypeLoki, BundleSenderTypeQuasar, BundleSenderTypeBuilderNet, BundleSenderTypeBTCS, BundleSenderTypeEureka, BundleSenderTypeL2, BundleSenderTypeBloxrouteBackrunme, BundleSenderTypePublicMempool, BundleSenderTypeBobTheBuilder, BundleSenderTypeInternalMempool, BundleSenderTypeQuickNode, BundleSenderType48Club, BundleSenderTypeBlockRazor, BundleSenderTypeNodeReal, BundleSenderTypeBombora, BundleSenderTypeUltrasound, BundleSenderTypeServo, BundleSenderTypeEthGas} var _BundleSenderTypeNameToValueMap = map[string]BundleSenderType{ - _BundleSenderTypeName[0:24]: BundleSenderTypeFlashbot, + _BundleSenderTypeName[0:24]: BundleSenderTypeFlashbot, + _BundleSenderTypeName[24:46]: BundleSenderTypeBeaver, + _BundleSenderTypeName[46:67]: BundleSenderTypeRsync, + _BundleSenderTypeName[67:88]: BundleSenderTypeTitan, + _BundleSenderTypeName[88:113]: BundleSenderTypeBloxroute, + _BundleSenderTypeName[113:132]: BundleSenderTypeAll, + _BundleSenderTypeName[132:156]: BundleSenderTypeMevShare, + _BundleSenderTypeName[156:185]: BundleSenderTypeBackrunPublic, + _BundleSenderTypeName[185:211]: BundleSenderTypeMevBlocker, + _BundleSenderTypeName[211:232]: BundleSenderTypeBlink, + _BundleSenderTypeName[232:254]: BundleSenderTypeMerkle, + _BundleSenderTypeName[254:277]: BundleSenderTypeJetbldr, + _BundleSenderTypeName[277:300]: BundleSenderTypePenguin, + _BundleSenderTypeName[300:320]: BundleSenderTypeLoki, + _BundleSenderTypeName[320:342]: BundleSenderTypeQuasar, + _BundleSenderTypeName[342:368]: BundleSenderTypeBuilderNet, + _BundleSenderTypeName[368:388]: BundleSenderTypeBTCS, + _BundleSenderTypeName[388:410]: BundleSenderTypeEureka, + _BundleSenderTypeName[410:428]: BundleSenderTypeL2, + _BundleSenderTypeName[428:462]: BundleSenderTypeBloxrouteBackrunme, + _BundleSenderTypeName[462:491]: BundleSenderTypePublicMempool, + _BundleSenderTypeName[491:520]: BundleSenderTypeBobTheBuilder, + _BundleSenderTypeName[520:551]: BundleSenderTypeInternalMempool, + _BundleSenderTypeName[551:576]: BundleSenderTypeQuickNode, + _BundleSenderTypeName[576:598]: BundleSenderType48Club, + _BundleSenderTypeName[598:624]: BundleSenderTypeBlockRazor, + _BundleSenderTypeName[624:648]: BundleSenderTypeNodeReal, + _BundleSenderTypeName[648:671]: BundleSenderTypeBombora, + _BundleSenderTypeName[671:697]: BundleSenderTypeUltrasound, + _BundleSenderTypeName[697:718]: BundleSenderTypeServo, + _BundleSenderTypeName[718:740]: BundleSenderTypeEthGas, +} + +var _BundleSenderTypeLowerNameToValueMap = map[string]BundleSenderType{ _BundleSenderTypeLowerName[0:24]: BundleSenderTypeFlashbot, - _BundleSenderTypeName[24:46]: BundleSenderTypeBeaver, _BundleSenderTypeLowerName[24:46]: BundleSenderTypeBeaver, - _BundleSenderTypeName[46:67]: BundleSenderTypeRsync, _BundleSenderTypeLowerName[46:67]: BundleSenderTypeRsync, - _BundleSenderTypeName[67:88]: BundleSenderTypeTitan, _BundleSenderTypeLowerName[67:88]: BundleSenderTypeTitan, - _BundleSenderTypeName[88:113]: BundleSenderTypeBloxroute, _BundleSenderTypeLowerName[88:113]: BundleSenderTypeBloxroute, - _BundleSenderTypeName[113:132]: BundleSenderTypeAll, _BundleSenderTypeLowerName[113:132]: BundleSenderTypeAll, - _BundleSenderTypeName[132:156]: BundleSenderTypeMevShare, _BundleSenderTypeLowerName[132:156]: BundleSenderTypeMevShare, - _BundleSenderTypeName[156:185]: BundleSenderTypeBackrunPublic, _BundleSenderTypeLowerName[156:185]: BundleSenderTypeBackrunPublic, - _BundleSenderTypeName[185:211]: BundleSenderTypeMevBlocker, _BundleSenderTypeLowerName[185:211]: BundleSenderTypeMevBlocker, - _BundleSenderTypeName[211:232]: BundleSenderTypeBlink, _BundleSenderTypeLowerName[211:232]: BundleSenderTypeBlink, - _BundleSenderTypeName[232:254]: BundleSenderTypeMerkle, _BundleSenderTypeLowerName[232:254]: BundleSenderTypeMerkle, - _BundleSenderTypeName[254:277]: BundleSenderTypeJetbldr, _BundleSenderTypeLowerName[254:277]: BundleSenderTypeJetbldr, - _BundleSenderTypeName[277:300]: BundleSenderTypePenguin, _BundleSenderTypeLowerName[277:300]: BundleSenderTypePenguin, - _BundleSenderTypeName[300:320]: BundleSenderTypeLoki, _BundleSenderTypeLowerName[300:320]: BundleSenderTypeLoki, - _BundleSenderTypeName[320:342]: BundleSenderTypeQuasar, _BundleSenderTypeLowerName[320:342]: BundleSenderTypeQuasar, - _BundleSenderTypeName[342:368]: BundleSenderTypeBuilderNet, _BundleSenderTypeLowerName[342:368]: BundleSenderTypeBuilderNet, - _BundleSenderTypeName[368:388]: BundleSenderTypeBTCS, _BundleSenderTypeLowerName[368:388]: BundleSenderTypeBTCS, - _BundleSenderTypeName[388:410]: BundleSenderTypeEureka, _BundleSenderTypeLowerName[388:410]: BundleSenderTypeEureka, - _BundleSenderTypeName[410:428]: BundleSenderTypeL2, _BundleSenderTypeLowerName[410:428]: BundleSenderTypeL2, - _BundleSenderTypeName[428:462]: BundleSenderTypeBloxrouteBackrunme, _BundleSenderTypeLowerName[428:462]: BundleSenderTypeBloxrouteBackrunme, - _BundleSenderTypeName[462:491]: BundleSenderTypePublicMempool, _BundleSenderTypeLowerName[462:491]: BundleSenderTypePublicMempool, - _BundleSenderTypeName[491:520]: BundleSenderTypeBobTheBuilder, _BundleSenderTypeLowerName[491:520]: BundleSenderTypeBobTheBuilder, - _BundleSenderTypeName[520:551]: BundleSenderTypeInternalMempool, _BundleSenderTypeLowerName[520:551]: BundleSenderTypeInternalMempool, - _BundleSenderTypeName[551:576]: BundleSenderTypeQuickNode, _BundleSenderTypeLowerName[551:576]: BundleSenderTypeQuickNode, - _BundleSenderTypeName[576:598]: BundleSenderType48Club, _BundleSenderTypeLowerName[576:598]: BundleSenderType48Club, - _BundleSenderTypeName[598:624]: BundleSenderTypeBlockRazor, _BundleSenderTypeLowerName[598:624]: BundleSenderTypeBlockRazor, - _BundleSenderTypeName[624:648]: BundleSenderTypeNodeReal, _BundleSenderTypeLowerName[624:648]: BundleSenderTypeNodeReal, - _BundleSenderTypeName[648:671]: BundleSenderTypeBombora, _BundleSenderTypeLowerName[648:671]: BundleSenderTypeBombora, - _BundleSenderTypeName[671:697]: BundleSenderTypeUltrasound, _BundleSenderTypeLowerName[671:697]: BundleSenderTypeUltrasound, - _BundleSenderTypeName[697:718]: BundleSenderTypeServo, _BundleSenderTypeLowerName[697:718]: BundleSenderTypeServo, + _BundleSenderTypeLowerName[718:740]: BundleSenderTypeEthGas, } var _BundleSenderTypeNames = []string{ @@ -153,6 +159,7 @@ var _BundleSenderTypeNames = []string{ _BundleSenderTypeName[648:671], _BundleSenderTypeName[671:697], _BundleSenderTypeName[697:718], + _BundleSenderTypeName[718:740], } // BundleSenderTypeString retrieves an enum value from the enum constants string name. @@ -162,7 +169,7 @@ func BundleSenderTypeString(s string) (BundleSenderType, error) { return val, nil } - if val, ok := _BundleSenderTypeNameToValueMap[strings.ToLower(s)]; ok { + if val, ok := _BundleSenderTypeLowerNameToValueMap[strings.ToLower(s)]; ok { return val, nil } return 0, fmt.Errorf("%s does not belong to BundleSenderType values", s) diff --git a/pkg/mev/pkg.go b/pkg/mev/pkg.go index 82b96c7..716687e 100644 --- a/pkg/mev/pkg.go +++ b/pkg/mev/pkg.go @@ -56,6 +56,7 @@ const ( BundleSenderTypeBombora BundleSenderTypeUltrasound BundleSenderTypeServo + BundleSenderTypeEthGas ) const ( @@ -396,16 +397,16 @@ type SendBundleV2Request struct { // (Optional) Array[String], A list of tx hashes that are allowed to revert RevertingTxs *[]string `json:"revertingTxHashes,omitempty"` // (Optional) Array[String], A list of tx hashes that may be omitted from the bundle, - // but must never be included in a reverted state. Bombora and Ultrasound only. + // but must never be included in a reverted state. Bombora, EthGas and Ultrasound only. DroppingTxs *[]string `json:"droppingTxHashes,omitempty"` // (Optional) Number, monotonically increasing sequence number for bundles sharing - // one replacement UUID. Bombora only. + // one replacement UUID. Bombora and EthGas only. ReplacementSeqNumber *uint64 `json:"replacementSeqNumber,omitempty"` - // (Optional) Number, percentage of the bundle MEV profit to refund, 0 to 99. Bombora and Ultrasound only. + // (Optional) Number, percentage of the bundle MEV profit to refund, 0 to 99. Bombora, EthGas and Ultrasound only. RefundPercent *uint64 `json:"refundPercent,omitempty"` - // (Optional) String, the address that receives the refund. Bombora and Ultrasound only. + // (Optional) String, the address that receives the refund. Bombora, EthGas and Ultrasound only. RefundRecipient string `json:"refundRecipient,omitempty"` - // (Optional) Array[String], one tx hash that anchors the refund calculation. Bombora and Ultrasound only. + // (Optional) Array[String], one tx hash that anchors the refund calculation. Bombora, EthGas and Ultrasound only. RefundTxHashes *[]string `json:"refundTxHashes,omitempty"` // (Optional) String, UUID that can be used to cancel/replace this bundle ReplacementUUID *string `json:"ReplacementUuid,omitempty"`