diff --git a/go.mod b/go.mod index 52322519..d49befa9 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/charmbracelet/lipgloss v1.0.0 github.com/docker/docker v28.0.1+incompatible github.com/dustinkirkland/golang-petname v0.0.0-20240428194347-eebcea082ee0 - github.com/ethereum/go-ethereum v1.15.10 + github.com/ethereum/go-ethereum v1.16.8 github.com/fatih/color v1.18.0 github.com/flashbots/go-boost-utils v1.9.1-0.20250819134059-e5294cb450c9 github.com/flashbots/go-template v1.0.0 @@ -33,7 +33,8 @@ require ( github.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c // indirect github.com/Microsoft/go-winio v0.6.2 // indirect github.com/NYTimes/gziphandler v1.1.1 // indirect - github.com/VictoriaMetrics/fastcache v1.12.2 // indirect + github.com/ProjectZKM/Ziren/crates/go-runtime/zkvm_runtime v0.0.0-20251001021608-1fe7b43fc4d6 // indirect + github.com/VictoriaMetrics/fastcache v1.13.0 // indirect github.com/alicebob/gopher-json v0.0.0-20230218143504-906a9b012302 // indirect github.com/allegro/bigcache v1.2.1 // indirect github.com/aohorodnyk/mimeheader v0.0.6 // indirect @@ -49,12 +50,11 @@ require ( github.com/charmbracelet/bubbletea v1.3.4 // indirect github.com/charmbracelet/x/ansi v0.8.0 // indirect github.com/charmbracelet/x/term v0.2.1 // indirect - github.com/consensys/bavard v0.1.30 // indirect - github.com/consensys/gnark-crypto v0.17.0 // indirect + github.com/consensys/gnark-crypto v0.18.0 // indirect github.com/containerd/log v0.1.0 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.6 // indirect + github.com/crate-crypto/go-eth-kzg v1.4.0 // indirect github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a // indirect - github.com/crate-crypto/go-kzg-4844 v1.1.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/deckarep/golang-set/v2 v2.6.0 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 // indirect @@ -64,7 +64,8 @@ require ( github.com/docker/go-units v0.5.0 // indirect github.com/emicklei/dot v1.8.0 // indirect github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect - github.com/ethereum/c-kzg-4844 v1.0.3 // indirect + github.com/ethereum/c-kzg-4844/v2 v2.1.5 // indirect + github.com/ethereum/go-bigmodexpfix v0.0.0-20250911101455-f9e208c548ab // indirect github.com/ethereum/go-verkle v0.2.2 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/ferranbt/fastssz v0.1.4 // indirect @@ -78,7 +79,7 @@ require ( github.com/goccy/go-json v0.10.4 // indirect github.com/gofrs/flock v0.12.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang/snappy v0.0.5-0.20231225225746-43d5d4cd4e0e // indirect + github.com/golang/snappy v1.0.0 // indirect github.com/google/go-cmp v0.7.0 // indirect github.com/google/gofuzz v1.2.0 // indirect github.com/google/uuid v1.6.0 // indirect @@ -102,7 +103,6 @@ require ( github.com/minio/highwayhash v1.0.2 // indirect github.com/minio/sha256-simd v1.0.1 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect - github.com/mmcloughlin/addchain v0.4.0 // indirect github.com/moby/docker-image-spec v1.3.1 // indirect github.com/moby/term v0.5.2 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect @@ -133,7 +133,7 @@ require ( github.com/rubenv/sql-migrate v1.7.1 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/shirou/gopsutil v3.21.11+incompatible // indirect - github.com/supranational/blst v0.3.14 // indirect + github.com/supranational/blst v0.3.16-0.20250831170142-f48500c1fdbe // indirect github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect github.com/thomaso-mirodin/intmath v0.0.0-20160323211736-5dc6d854e46e // indirect github.com/tidwall/gjson v1.18.0 // indirect @@ -162,7 +162,7 @@ require ( golang.org/x/crypto v0.37.0 // indirect golang.org/x/net v0.38.0 // indirect golang.org/x/oauth2 v0.26.0 // indirect - golang.org/x/sys v0.33.0 // indirect + golang.org/x/sys v0.36.0 // indirect golang.org/x/term v0.31.0 // indirect golang.org/x/text v0.24.0 // indirect golang.org/x/time v0.9.0 // indirect @@ -178,7 +178,6 @@ require ( k8s.io/client-go v0.30.4 // indirect k8s.io/klog/v2 v2.120.1 // indirect k8s.io/utils v0.0.0-20230726121419-3b25d923346b // indirect - rsc.io/tmplfunc v0.0.3 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect sigs.k8s.io/yaml v1.3.0 // indirect diff --git a/go.sum b/go.sum index f48aeb6e..12c4f497 100644 --- a/go.sum +++ b/go.sum @@ -12,13 +12,14 @@ github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cq github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= github.com/OffchainLabs/prysm/v6 v6.0.2 h1:GrHNvZlOoaPYeA4uL2xoUqplAelImteWxhJDap1yVBs= github.com/OffchainLabs/prysm/v6 v6.0.2/go.mod h1:lMkHT3gWiCOqo4rbuhLTU4FoQ/THni9v6z4w9P6FRyU= -github.com/VictoriaMetrics/fastcache v1.12.2 h1:N0y9ASrJ0F6h0QaC3o6uJb3NIZ9VKLjCM7NQbSmF7WI= -github.com/VictoriaMetrics/fastcache v1.12.2/go.mod h1:AmC+Nzz1+3G2eCPapF6UcsnkThDcMsQicp4xDukwJYI= +github.com/ProjectZKM/Ziren/crates/go-runtime/zkvm_runtime v0.0.0-20251001021608-1fe7b43fc4d6 h1:1zYrtlhrZ6/b6SAjLSfKzWtdgqK0U+HtH/VcBWh1BaU= +github.com/ProjectZKM/Ziren/crates/go-runtime/zkvm_runtime v0.0.0-20251001021608-1fe7b43fc4d6/go.mod h1:ioLG6R+5bUSO1oeGSDxOV3FADARuMoytZCSX6MEMQkI= +github.com/VictoriaMetrics/fastcache v1.13.0 h1:AW4mheMR5Vd9FkAPUv+NH6Nhw+fmbTMGMsNAoA/+4G0= +github.com/VictoriaMetrics/fastcache v1.13.0/go.mod h1:hHXhl4DA2fTL2HTZDJFXWgW0LNjo6B+4aj2Wmng3TjU= github.com/alicebob/gopher-json v0.0.0-20230218143504-906a9b012302 h1:uvdUDbHQHO85qeSydJtItA4T55Pw6BtAejd0APRJOCE= github.com/alicebob/gopher-json v0.0.0-20230218143504-906a9b012302/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc= github.com/alicebob/miniredis/v2 v2.34.0 h1:mBFWMaJSNL9RwdGRyEDoAAv8OQc5UlEhLDQggTglU/0= github.com/alicebob/miniredis/v2 v2.34.0/go.mod h1:kWShP4b58T1CW0Y5dViCd5ztzrDqRWqM3nksiyXk5s8= -github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/allegro/bigcache v1.2.1 h1:hg1sY1raCwic3Vnsvje6TT7/pnZba83LeFck5NrFKSc= github.com/allegro/bigcache v1.2.1/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/aohorodnyk/mimeheader v0.0.6 h1:WCV4NQjtbqnd2N3FT5MEPesan/lfvaLYmt5v4xSaX/M= @@ -47,7 +48,6 @@ github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK3 github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/cespare/cp v1.1.1 h1:nCb6ZLdB7NRaqsm91JtQTAme2SKJzXVsdPIPkyJr1MU= github.com/cespare/cp v1.1.1/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= -github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/charmbracelet/bubbles v0.20.0 h1:jSZu6qD8cRQ6k9OMfR1WlM+ruM8fkPWkHvQWD9LIutE= @@ -69,20 +69,20 @@ github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce h1:giXvy4KSc/6g/e github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce/go.mod h1:9/y3cnZ5GKakj/H4y9r9GTjCvAFta7KLgSHPJJYc52M= github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b h1:r6VH0faHjZeQy818SGhaone5OnYfxFR/+AzdY3sf5aE= github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= -github.com/cockroachdb/pebble v1.1.2 h1:CUh2IPtR4swHlEj48Rhfzw6l/d0qA31fItcIszQVIsA= -github.com/cockroachdb/pebble v1.1.2/go.mod h1:4exszw1r40423ZsmkG/09AFEG83I0uDgfujJdbL6kYU= +github.com/cockroachdb/pebble v1.1.5 h1:5AAWCBWbat0uE0blr8qzufZP5tBjkRyy/jWe1QWLnvw= +github.com/cockroachdb/pebble v1.1.5/go.mod h1:17wO9el1YEigxkP/YtV8NtCivQDgoCyBg5c4VR/eOWo= github.com/cockroachdb/redact v1.1.5 h1:u1PMllDkdFfPWaNGMyLD1+so+aq3uUItthCFqzwPJ30= github.com/cockroachdb/redact v1.1.5/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 h1:zuQyyAKVxetITBuuhv3BI9cMrmStnpT18zmgmTxunpo= github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06/go.mod h1:7nc4anLGjupUW/PeY5qiNYsdNXj7zopG+eqsS7To5IQ= -github.com/consensys/bavard v0.1.30 h1:wwAj9lSnMLFXjEclKwyhf7Oslg8EoaFz9u1QGgt0bsk= -github.com/consensys/bavard v0.1.30/go.mod h1:k/zVjHHC4B+PQy1Pg7fgvG3ALicQw540Crag8qx+dZs= -github.com/consensys/gnark-crypto v0.17.0 h1:vKDhZMOrySbpZDCvGMOELrHFv/A9mJ7+9I8HEfRZSkI= -github.com/consensys/gnark-crypto v0.17.0/go.mod h1:A2URlMHUT81ifJ0UlLzSlm7TmnE3t7VxEThApdMukJw= +github.com/consensys/gnark-crypto v0.18.0 h1:vIye/FqI50VeAr0B3dx+YjeIvmc3LWz4yEfbWBpTUf0= +github.com/consensys/gnark-crypto v0.18.0/go.mod h1:L3mXGFTe1ZN+RSJ+CLjUt9x7PNdx8ubaYfDROyp2Z8c= github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= github.com/cpuguy83/go-md2man/v2 v2.0.6 h1:XJtiaUW6dEEqVuZiMTn1ldk455QWwEIsMIJlo5vtkx0= github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= +github.com/crate-crypto/go-eth-kzg v1.4.0 h1:WzDGjHk4gFg6YzV0rJOAsTK4z3Qkz5jd4RE3DAvPFkg= +github.com/crate-crypto/go-eth-kzg v1.4.0/go.mod h1:J9/u5sWfznSObptgfa92Jq8rTswn6ahQWEuiLHOjCUI= github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a h1:W8mUrRp6NOVl3J+MYp5kPMoUZPp7aOYHtaua31lwRHg= github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a/go.mod h1:sTwzHBvIzm2RfVCGNEBZgRyjwK40bVoun3ZnGOCafNM= github.com/crate-crypto/go-kzg-4844 v1.1.0 h1:EN/u9k2TF6OWSHrCCDBBU6GLNMq88OspHHlMnHfoyU4= @@ -92,6 +92,8 @@ github.com/d4l3k/messagediff v1.2.1/go.mod h1:Oozbb1TVXFac9FtSIxHBMnBCq2qeH/2KkE github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dchest/siphash v1.2.3 h1:QXwFc8cFOR2dSa/gE6o/HokBMWtLUaNDVd+22aKHeEA= +github.com/dchest/siphash v1.2.3/go.mod h1:0NvQU092bT0ipiFN++/rXm69QG9tVxLAlQHIXMPAkHc= github.com/deckarep/golang-set/v2 v2.6.0 h1:XfcQbWM1LlMB8BsJ8N9vW5ehnnPVIw0je80NsVHagjM= github.com/deckarep/golang-set/v2 v2.6.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= github.com/decred/dcrd/crypto/blake256 v1.1.0 h1:zPMNGQCm0g4QTY27fOCorQW7EryeQ/U0x++OzVrdms8= @@ -118,12 +120,12 @@ github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxER github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4= github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f/go.mod h1:vw97MGsxSvLiUE2X8qFplwetxpGLQrlU1Q9AUEIzCaM= -github.com/ethereum/c-kzg-4844 v1.0.3 h1:IEnbOHwjixW2cTvKRUlAAUOeleV7nNM/umJR+qy4WDs= -github.com/ethereum/c-kzg-4844 v1.0.3/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0= -github.com/ethereum/c-kzg-4844/v2 v2.1.1 h1:KhzBVjmURsfr1+S3k/VE35T02+AW2qU9t9gr4R6YpSo= -github.com/ethereum/c-kzg-4844/v2 v2.1.1/go.mod h1:TC48kOKjJKPbN7C++qIgt0TJzZ70QznYR7Ob+WXl57E= -github.com/ethereum/go-ethereum v1.15.10 h1:UxqBhpsF2TNF1f7Z/k3RUUHEuLvDGAlHuh/lQ99ZA0w= -github.com/ethereum/go-ethereum v1.15.10/go.mod h1:+S9k+jFzlyVTNcYGvqFhzN/SFhI6vA+aOY4T5tLSPL0= +github.com/ethereum/c-kzg-4844/v2 v2.1.5 h1:aVtoLK5xwJ6c5RiqO8g8ptJ5KU+2Hdquf6G3aXiHh5s= +github.com/ethereum/c-kzg-4844/v2 v2.1.5/go.mod h1:u59hRTTah4Co6i9fDWtiCjTrblJv0UwsqZKCc0GfgUs= +github.com/ethereum/go-bigmodexpfix v0.0.0-20250911101455-f9e208c548ab h1:rvv6MJhy07IMfEKuARQ9TKojGqLVNxQajaXEp/BoqSk= +github.com/ethereum/go-bigmodexpfix v0.0.0-20250911101455-f9e208c548ab/go.mod h1:IuLm4IsPipXKF7CW5Lzf68PIbZ5yl7FFd74l/E0o9A8= +github.com/ethereum/go-ethereum v1.16.8 h1:LLLfkZWijhR5m6yrAXbdlTeXoqontH+Ga2f9igY7law= +github.com/ethereum/go-ethereum v1.16.8/go.mod h1:Fs6QebQbavneQTYcA39PEKv2+zIjX7rPUZ14DER46wk= github.com/ethereum/go-verkle v0.2.2 h1:I2W0WjnrFUIzzVPwm8ykY+7pL2d4VhlsePn4j7cnFk8= github.com/ethereum/go-verkle v0.2.2/go.mod h1:M3b90YRnzqKyyzBEWJGqj8Qff4IDeXnzFw0P9bFw3uk= github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= @@ -197,8 +199,8 @@ github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiu github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.5-0.20231225225746-43d5d4cd4e0e h1:4bw4WeyTYPp0smaXiJZCNnLrvVBqirQVreixayXezGc= -github.com/golang/snappy v0.0.5-0.20231225225746-43d5d4cd4e0e/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v1.0.0 h1:Oy607GVXHs7RtbggtPBnr2RmDArIsAefDwvrdWvRhGs= +github.com/golang/snappy v1.0.0/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -212,7 +214,6 @@ github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/ github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -233,8 +234,8 @@ github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d/go.mod h1:i github.com/herumi/bls-eth-go-binary v0.0.0-20210130185500-57372fb27371/go.mod h1:luAnRm3OsMQeokhGzpYmc0ZKwawY7o87PUEP11Z7r7U= github.com/herumi/bls-eth-go-binary v1.31.0 h1:9eeW3EA4epCb7FIHt2luENpAW69MvKGL5jieHlBiP+w= github.com/herumi/bls-eth-go-binary v1.31.0/go.mod h1:luAnRm3OsMQeokhGzpYmc0ZKwawY7o87PUEP11Z7r7U= -github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4 h1:X4egAf/gcS1zATw6wn4Ej8vjuVGxeHdan+bRb2ebyv4= -github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4/go.mod h1:5GuXa7vkL8u9FkFuWdVvfR5ix8hRB7DbOAaYULamFpc= +github.com/holiman/billy v0.0.0-20250707135307-f2f9b9aae7db h1:IZUYC/xb3giYwBLMnr8d0TGTzPKFGNTCGgGLoyeX330= +github.com/holiman/billy v0.0.0-20250707135307-f2f9b9aae7db/go.mod h1:xTEYN9KCHxuYHs+NmrmzFcnvHMzLLNiGFafCb1n3Mfg= github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao= github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= github.com/holiman/uint256 v1.3.2 h1:a9EgMPSC1AAaj1SZL5zIQD3WbwTuHrMGOerLjGmM/TA= @@ -308,9 +309,6 @@ github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyua github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/pointerstructure v1.2.0 h1:O+i9nHnXS3l/9Wu7r4NrEdwA2VFTicjUEN1uBnDo34A= github.com/mitchellh/pointerstructure v1.2.0/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4= -github.com/mmcloughlin/addchain v0.4.0 h1:SobOdjm2xLj1KkXN5/n0xTIWyZA2+s99UCY1iPfkHRY= -github.com/mmcloughlin/addchain v0.4.0/go.mod h1:A86O+tHqZLMNO4w6ZZ4FlVQEadcoqkyU72HC5wJ4RlU= -github.com/mmcloughlin/profile v0.1.1/go.mod h1:IhHD7q1ooxgwTgjxQYkACGA77oFTDdFVejUS1/tS/qU= github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0= github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo= github.com/moby/term v0.5.2 h1:6qk3FJAFDs6i/q3W/pQ97SX192qKfZgGjCQqfCJkgzQ= @@ -424,8 +422,8 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/supranational/blst v0.3.14 h1:xNMoHRJOTwMn63ip6qoWJ2Ymgvj7E2b9jY2FAwY+qRo= -github.com/supranational/blst v0.3.14/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= +github.com/supranational/blst v0.3.16-0.20250831170142-f48500c1fdbe h1:nbdqkIGOGfUAD54q1s2YBcBz/WcsxCO9HUQ4aGV5hUw= +github.com/supranational/blst v0.3.16-0.20250831170142-f48500c1fdbe/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d h1:vfofYNRScrDdvS342BElfbETmL1Aiz3i2t0zfRj16Hs= github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d/go.mod h1:RRCYJbIwD5jmqPI9XoAFR0OcDxqUctll6zUj/+B4S48= github.com/thomaso-mirodin/intmath v0.0.0-20160323211736-5dc6d854e46e h1:cR8/SYRgyQCt5cNCMniB/ZScMkhI9nk8U5C7SbISXjo= @@ -547,9 +545,8 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw= -golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k= +golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -629,8 +626,6 @@ k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 h1:BZqlfIlq5YbRMFko6/PM7F k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340/go.mod h1:yD4MZYeKMBwQKVht279WycxKyM84kkAx2DPrTXaeb98= k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI= k8s.io/utils v0.0.0-20230726121419-3b25d923346b/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -rsc.io/tmplfunc v0.0.3 h1:53XFQh69AfOa8Tw0Jm7t+GV7KZhOi6jzsCzTtKbMvzU= -rsc.io/tmplfunc v0.0.3/go.mod h1:AG3sTPzElb1Io3Yg4voV9AGZJuleGAwaVRxL9M49PhA= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4= diff --git a/playground/artifacts.go b/playground/artifacts.go index 4cd79a23..f38a38a9 100644 --- a/playground/artifacts.go +++ b/playground/artifacts.go @@ -59,6 +59,9 @@ var opState []byte //go:embed config.yaml.tmpl var clConfigContent []byte +//go:embed utils/builderhub-config.yaml +var defaultBuilderHubConfig []byte + type ArtifactsBuilder struct { // Shared options prefundedAccounts []string @@ -168,6 +171,7 @@ func (b *ArtifactsBuilder) Build(out *output) error { genesisTime := uint64(time.Now().Add(time.Duration(b.genesisDelay) * time.Second).Unix()) config := params.BeaconConfig() + config.ElectraForkEpoch = 0 gen := interop.GethTestnetGenesis(genesisTime, config) // HACK: fix this in prysm? diff --git a/playground/components.go b/playground/components.go index 8d9ec990..17eeacac 100644 --- a/playground/components.go +++ b/playground/components.go @@ -11,6 +11,7 @@ import ( mevboostrelay "github.com/flashbots/builder-playground/mev-boost-relay" "github.com/flashbots/go-boost-utils/bls" "github.com/flashbots/go-boost-utils/utils" + "github.com/goccy/go-yaml" ) var ( @@ -510,7 +511,9 @@ func (l *LighthouseBeaconNode) Apply(manifest *Manifest) { "--http-address", "0.0.0.0", "--http-allow-origin", "*", "--disable-packet-filter", - "--target-peers", "0", + "--target-peers", "1", + //"--target-peers", "0", + "--subscribe-all-subnets", "--execution-endpoint", Connect(l.ExecutionNode, "authrpc"), "--execution-jwt", "/data/jwtsecret", "--always-prepare-payload", @@ -521,7 +524,8 @@ func (l *LighthouseBeaconNode) Apply(manifest *Manifest) { WithArtifact("/data/jwtsecret", "jwtsecret"). WithVolume("data", "/data_beacon") - UseHealthmon(manifest, svc, healthmonBeacon) + // TODO: Enable later - doesn't work with --target-peers=1 which is required for builder VM + //UseHealthmon(manifest, svc, healthmonBeacon) if l.MevBoostNode != "" { svc.WithArgs( @@ -586,7 +590,8 @@ func (m *MevBoostRelay) Apply(manifest *Manifest) { WithTag(latestPlaygroundUtilsTag). WithEnv("ALLOW_SYNCING_BEACON_NODE", "1"). WithEntrypoint("mev-boost-relay"). - DependsOnHealthy(m.BeaconClient). + // TODO: Enable later - doesn't work when beacon healthmon is disabled. + //DependsOnHealthy(m.BeaconClient). WithArgs( "--api-listen-addr", "0.0.0.0", "--api-listen-port", `{{Port "http" 5555}}`, @@ -852,7 +857,7 @@ func (b *BuilderHub) Apply(manifest *Manifest) { }) // API service - apiSrv := manifest.NewService("builder-hub-api"). + manifest.NewService("builder-hub-api"). WithImage("docker.io/flashbots/builder-hub"). WithTag("0.3.1-alpha1"). DependsOnHealthy("builder-hub-db"). @@ -874,15 +879,14 @@ func (b *BuilderHub) Apply(manifest *Manifest) { Timeout: 30 * time.Second, Retries: 3, StartPeriod: 1 * time.Second, + }). + WithPostHook(&postHook{ + Name: "register-builder", + Action: func(s *Service) error { + return registerBuilderHook(manifest, b) + }, }) - apiSrv.WithPostHook(&postHook{ - Name: "register-builder", - Action: func(s *Service) error { - return registerBuilderHook(manifest, s, b) - }, - }) - // Proxy service manifest.NewService("builder-hub-proxy"). WithImage("docker.io/flashbots/builder-hub-mock-proxy"). @@ -899,14 +903,33 @@ func (b *BuilderHub) Apply(manifest *Manifest) { }) } -func registerBuilderHook(manifest *Manifest, s *Service, b *BuilderHub) error { +type builderHubConfig struct { + Playground struct { + BuilderHubConfig struct { + BuilderID string `yaml:"builder_id"` + BuilderIP string `yaml:"builder_ip"` + MeasurementID string `yaml:"measurement_id"` + Network string `yaml:"network"` + } `yaml:"builder_hub_config"` + } `yaml:"playground"` +} + +func registerBuilderHook(manifest *Manifest, b *BuilderHub) error { genesis, err := manifest.out.Read("genesis.json") if err != nil { return err } - configYaml, err := os.ReadFile(b.BuilderConfig) - if err != nil { + configYaml := defaultBuilderHubConfig + if len(b.BuilderConfig) > 0 { + configYaml, err = os.ReadFile(b.BuilderConfig) + if err != nil { + return err + } + } + + var config builderHubConfig + if err := yaml.Unmarshal([]byte(configYaml), &config); err != nil { return err } @@ -923,15 +946,17 @@ func registerBuilderHook(manifest *Manifest, s *Service, b *BuilderHub) error { return err } - endpoint := fmt.Sprintf("http://localhost:%d", s.MustGetPort("admin").HostPort) input := &builderHubRegisterBuilderInput{ - BuilderID: "builder", - BuilderIP: b.BuilderIP, - MeasurementID: "test", - Network: "playground", + BuilderID: config.Playground.BuilderHubConfig.BuilderID, + BuilderIP: config.Playground.BuilderHubConfig.BuilderIP, + MeasurementID: config.Playground.BuilderHubConfig.MeasurementID, + Network: config.Playground.BuilderHubConfig.Network, Config: string(configJSON), } - if err := registerBuilder(endpoint, input); err != nil { + adminApi := fmt.Sprintf("http://localhost:%d", manifest.MustGetService("builder-hub-api").MustGetPort("admin").HostPort) + beaconApi := fmt.Sprintf("http://localhost:%d", manifest.MustGetService("beacon").MustGetPort("http").HostPort) + rethApi := fmt.Sprintf("http://localhost:%d", manifest.MustGetService("el").MustGetPort("http").HostPort) + if err := registerBuilder(adminApi, beaconApi, rethApi, input); err != nil { return err } return nil @@ -959,3 +984,21 @@ func UseHealthmon(m *Manifest, s *Service, chain string) { StartPeriod: 1 * time.Second, }) } + +// Fileserver serves genesis and testnet files over HTTP using Caddy. +// This allows VMs or external clients to fetch configuration files. +type Fileserver struct{} + +func (f *Fileserver) Apply(manifest *Manifest) { + manifest.NewService("fileserver"). + WithImage("caddy"). + WithTag("2-alpine"). + WithArgs( + "caddy", "file-server", + "--root", "/data", + "--listen", `:{{Port "http" 8100}}`, + "--browse", + ). + WithArtifact("/data/genesis.json", "genesis.json"). + WithArtifact("/data/testnet", "testnet") +} diff --git a/playground/components_test.go b/playground/components_test.go index 34963162..281ad89a 100644 --- a/playground/components_test.go +++ b/playground/components_test.go @@ -135,7 +135,7 @@ func TestRecipeBuilderHub_RegisterBuilder(t *testing.T) { apiPort := manifest.MustGetService("builder-hub-api").MustGetPort("admin") endpoint := fmt.Sprintf("http://localhost:%d", apiPort.HostPort) - err := registerBuilder(endpoint, &builderHubRegisterBuilderInput{ + err := registerBuilder(endpoint, "", "", &builderHubRegisterBuilderInput{ BuilderID: "test_builder", BuilderIP: "1.2.3.4", MeasurementID: "test", diff --git a/playground/genesis_op.go b/playground/genesis_op.go index c2bc17bf..224b4367 100644 --- a/playground/genesis_op.go +++ b/playground/genesis_op.go @@ -206,7 +206,7 @@ func hashAlloc(ga *types.GenesisAlloc, isVerkle, isIsthmus bool) (common.Hash, c if account.Balance != nil { statedb.AddBalance(addr, uint256.MustFromBig(account.Balance), tracing.BalanceIncreaseGenesisBalance) } - statedb.SetCode(addr, account.Code) + statedb.SetCode(addr, account.Code, tracing.CodeChangeContractCreation) statedb.SetNonce(addr, account.Nonce, tracing.NonceChangeGenesis) for key, value := range account.Storage { statedb.SetState(addr, key, value) diff --git a/playground/recipe_buildernet.go b/playground/recipe_buildernet.go index f99c5f63..564bae23 100644 --- a/playground/recipe_buildernet.go +++ b/playground/recipe_buildernet.go @@ -5,12 +5,17 @@ import ( "encoding/json" "fmt" "io" + "log/slog" "net/http" + "regexp" + "strings" "github.com/goccy/go-yaml" flag "github.com/spf13/pflag" ) +const BuilderHostIPAddress = "10.0.2.2" + var _ Recipe = &BuilderNetRecipe{} // BuilderNetRecipe is a recipe that extends the L1 recipe to include builder-hub @@ -74,38 +79,38 @@ func (b *BuilderNetRecipe) Output(manifest *Manifest) map[string]interface{} { return output } -func postRequest(endpoint, path string, input interface{}) error { +func postRequest(endpoint, path string, input interface{}) ([]byte, error) { var data []byte if dataBytes, ok := input.([]byte); ok { data = dataBytes } else if dataMap, ok := input.(map[string]interface{}); ok { dataBytes, err := json.Marshal(dataMap) if err != nil { - return err + return nil, err } data = dataBytes } else if dataStr, ok := input.(string); ok { data = []byte(dataStr) } else { - return fmt.Errorf("input type not expected") + return nil, fmt.Errorf("input type not expected") } fullEndpoint := endpoint + path resp, err := http.Post(fullEndpoint, "application/json", bytes.NewReader(data)) if err != nil { - return fmt.Errorf("failed to request endpoint '%s': %v", fullEndpoint, err) + return nil, fmt.Errorf("failed to request endpoint '%s': %v", fullEndpoint, err) } defer resp.Body.Close() dataResp, err := io.ReadAll(resp.Body) if err != nil { - return err + return dataResp, err } if resp.StatusCode != http.StatusOK { - return fmt.Errorf("incorrect status code %s: %s", resp.Status, string(dataResp)) + return nil, fmt.Errorf("incorrect status code %s: %s", resp.Status, string(dataResp)) } - return nil + return dataResp, nil } type builderHubRegisterBuilderInput struct { @@ -116,8 +121,58 @@ type builderHubRegisterBuilderInput struct { Config string } -func registerBuilder(httpEndpoint string, input *builderHubRegisterBuilderInput) error { - httpEndpoint = httpEndpoint + "/api/admin/v1" +type identityResponse struct { + Data struct { + PeerID string `json:"peer_id"` + } `json:"data"` +} + +type enodeResponse struct { + Result struct { + Enode string `json:"enode"` + } `json:"result"` + Error struct { + Code int `json:"code"` + Message string `json:"message"` + } +} + +func registerBuilder(builderAdminApi, beaconApi, rethApi string, input *builderHubRegisterBuilderInput) error { + builderAdminApi = builderAdminApi + "/api/admin/v1" + beaconApi = beaconApi + "/eth/v1/node/identity" + + resp, err := http.Get(beaconApi) + if err != nil { + return fmt.Errorf("failed to get beacon node identity: %v", err) + } + var identityRespPayload identityResponse + if err := json.NewDecoder(resp.Body).Decode(&identityRespPayload); err != nil { + return fmt.Errorf("failed to decode identity resp payload: %v", err) + } + peerID := identityRespPayload.Data.PeerID + libP2PAddr := fmt.Sprintf("/ip4/%s/tcp/9001/p2p/%s", BuilderHostIPAddress, peerID) + slog.Info("setting builder config var", "libp2p-addr", libP2PAddr) + + respData, err := postRequest(rethApi, "/", map[string]interface{}{ + "jsonrpc": "2.0", + "method": "admin_nodeInfo", + "id": 1, + }) + var enodeRespPayload enodeResponse + if err := json.Unmarshal(respData, &enodeRespPayload); err != nil { + return fmt.Errorf("failed to decode enode resp payload: %v", err) + } + if enodeRespPayload.Error.Code != 0 { + return fmt.Errorf("error from reth admin_nodeInfo: %s", enodeRespPayload.Error.Message) + } + + // Replace the ip addr with the host ip address known in the builder vm + bootNode := replaceEnodeIP(enodeRespPayload.Result.Enode, BuilderHostIPAddress) + slog.Info("setting builder config var", "bootnode", bootNode) + + // Replace template vars. + input.Config = strings.ReplaceAll(input.Config, "{{EL_BOOTNODE}}", bootNode) + input.Config = strings.ReplaceAll(input.Config, "{{CL_LIBP2P_ADDR}}", libP2PAddr) // Validate input.Config, it must be a valid json file var configMap map[string]interface{} @@ -126,50 +181,61 @@ func registerBuilder(httpEndpoint string, input *builderHubRegisterBuilderInput) } // Create Allow-All Measurements - err := postRequest(httpEndpoint, "/measurements", map[string]interface{}{ + _, err = postRequest(builderAdminApi, "/measurements", map[string]interface{}{ "measurement_id": input.MeasurementID, "attestation_type": "test", "measurements": map[string]interface{}{}, }) if err != nil { - return err + return fmt.Errorf("failed to create measurements: %v", err) } // Enable Measurements - err = postRequest(httpEndpoint, fmt.Sprintf("/measurements/activation/%s", input.MeasurementID), map[string]interface{}{ + _, err = postRequest(builderAdminApi, fmt.Sprintf("/measurements/activation/%s", input.MeasurementID), map[string]interface{}{ "enabled": true, }) if err != nil { - return err + return fmt.Errorf("failed to activate measurements: %v", err) } // create the builder - err = postRequest(httpEndpoint, "/builders", map[string]interface{}{ + _, err = postRequest(builderAdminApi, "/builders", map[string]interface{}{ "name": input.BuilderID, "ip_address": input.BuilderIP, "network": input.Network, }) if err != nil { - return err + return fmt.Errorf("failed to create builder: %v", err) } // Create Builder Configuration - err = postRequest(httpEndpoint, fmt.Sprintf("/builders/configuration/%s", input.BuilderID), input.Config) + _, err = postRequest(builderAdminApi, fmt.Sprintf("/builders/configuration/%s", input.BuilderID), input.Config) if err != nil { - return err + return fmt.Errorf("failed to set builder configuration: %v", err) + } + + // Create Builder Secrets + _, err = postRequest(builderAdminApi, fmt.Sprintf("/builders/secrets/%s", input.BuilderID), input.Config) + if err != nil { + return fmt.Errorf("failed to set builder secrets: %v", err) } // Enable Builder - err = postRequest(httpEndpoint, fmt.Sprintf("/builders/activation/%s", input.BuilderID), map[string]interface{}{ + _, err = postRequest(builderAdminApi, fmt.Sprintf("/builders/activation/%s", input.BuilderID), map[string]interface{}{ "enabled": true, }) if err != nil { - return err + return fmt.Errorf("failed to activate builder: %v", err) } return nil } +func replaceEnodeIP(enodeRaw, vmHostIP string) string { + re := regexp.MustCompile(`@[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+:`) + return re.ReplaceAllString(enodeRaw, "@"+vmHostIP+":") +} + // YAMLToJSON converts a YAML string to a JSON string func yamlToJson(yamlStr []byte) ([]byte, error) { // Unmarshal YAML into a map diff --git a/playground/recipe_l1.go b/playground/recipe_l1.go index 38bcabf1..a30f3470 100644 --- a/playground/recipe_l1.go +++ b/playground/recipe_l1.go @@ -133,6 +133,8 @@ func (l *L1Recipe) Apply(svcManager *Manifest) { } svcManager.RunContenderIfEnabled() + + svcManager.AddComponent(&Fileserver{}) } func (l *L1Recipe) Output(manifest *Manifest) map[string]interface{} { diff --git a/playground/utils/builderhub-config.yaml b/playground/utils/builderhub-config.yaml new file mode 100644 index 00000000..c6dd5092 --- /dev/null +++ b/playground/utils/builderhub-config.yaml @@ -0,0 +1,66 @@ +bidding_service: + config: | + slot_delta_to_start_bidding_ms = -1000 + subsidy = "0.01" + +rbuilder: + enabled: true + # blocklist: "" + evm_caching_enable: true + ignore_blobs: false + extra_data: BuilderNet (playground) + require_non_empty_blocklist: false + root_hash_threads: 4 + # BLS secret key for signing relay submissions (matches mev-boost-relay default) + relay_secret_key: "0x5eae315483f028b5cdd5d1090ff0c7618b18737ea9bf3c35047189db22835c48" + # 0 for debugging + watchdog_timeout_sec: 0 + max_order_execution_duration_warning_us: 50000 + time_to_keep_mempool_txs_secs: 300 + live_builders: '["mgp-ordering", "mp-ordering"]' + system_recipient_allowlist: '[]' + builders: | + [[builders]] + name = "mgp-ordering" + algo = "ordering-builder" + discard_txs = true + sorting = "mev-gas-price" + failed_order_retries = 1 + drop_failed_orders = true + + [[builders]] + name = "mp-ordering" + algo = "ordering-builder" + discard_txs = true + sorting = "max-profit" + failed_order_retries = 1 + drop_failed_orders = true + + relays: | + [[relays]] + name = "playground" + url = "http://10.0.2.2:5555" + + relay_bid_scrapers: | + [[relay_bid_scrapers]] + type = "external-ws" + name = "playground" + url = "ws://10.0.2.2:5555" + auth_header = "" + +disk_encryption: + key: 5d7052c0c3aff5834f45e3f33aca0a55ef9f43ca9cf6c5c8e8375ab82564ddb6 # playground value +instance_name: buildernet-playground-vm + +playground: + builder_hub_config: + builder_id: "playground_vm_builder" + builder_ip: "1.2.3.4" + measurement_id: "test1" + network: "playground" + artifacts_url: http://10.0.2.2:8100 + # Reth P2P bootnode + el_bootnode: "{{EL_BOOTNODE}}" + # Lighthouse libp2p multiaddr + # Format: /ip4//tcp//p2p/ + cl_libp2p_addr: "{{CL_LIBP2P_ADDR}}" diff --git a/scripts/buildernet-vm/.gitignore b/scripts/buildernet-vm/.gitignore new file mode 100644 index 00000000..13500e09 --- /dev/null +++ b/scripts/buildernet-vm/.gitignore @@ -0,0 +1,2 @@ +.flashbots-images/ +.runtime/ diff --git a/scripts/buildernet-vm/README.md b/scripts/buildernet-vm/README.md new file mode 100644 index 00000000..5dcbb960 --- /dev/null +++ b/scripts/buildernet-vm/README.md @@ -0,0 +1,106 @@ +# BuilderNet VM Scripts + +Temporary bash scripts for running BuilderNet VM alongside builder-playground. +Feel free to translate them to Go and integrate into the CLI. + +## Information: + +Changes are made in two repos: +- [flashbots-images](https://github.com/flashbots/flashbots-images/tree/fryd/mkosi-playground) on `fryd/mkosi-playground` branch, +- [builder-playground](https://github.com/flashbots/builder-playground/tree/fryd/mkosi-playground) on `fryd/mkosi-playground` branch, + +There are no plans of using [buildernet-playground](https://github.com/flashbots/buildernet-playground) repo. + +## Start playground + +Start playground with: `--bind-external` (expose ports to the VM) and `--contender` (create transactions) + +```bash +builder-playground \ + start buildernet \ + --bind-external \ + --output ".playground-home" \ + --contender \ + --detached fryd-vm-builder +``` + +## First Time Setup + +```bash +./sync.sh # Clone / fetch flashbots-images repo +./build.sh # Build VM image with mkosi +./prepare.sh # Extract image + create data disk +``` + +`sync.sh` clones/updates the `fryd/mkosi-playground` branch of flashbots-images. + +## Run VM + +```bash +./start.sh # Start VM (background) +./console.sh # Open console to the VM +./ssh.sh # SSH into running VM (requires SSH key setup) +./stop.sh # Stop VM +``` + +## Builder Hub + +```bash +./builderhub-configure.sh # Register VM with builder-hub and update config for the VM +./builderhub-get-config.sh # Get configuration for the VM +``` + +## Operator API + +Scripts to interact with the operator-api service running inside the VM. + +> **Note:** Actions and File Uploads could potentially be used for various things, like injecting genesis config instead of BuilderHub - still exploring this functionality. + +```bash +./operator-api-health.sh # Check if operator-api is healthy +./operator-api-logs.sh # Get event logs +./operator-api-action.sh # Execute an action +``` + +Available actions: +- `reboot` - Reboot the system +- `rbuilder_restart` - Restart rbuilder-operator service +- `rbuilder_stop` - Stop rbuilder-operator service +- `fetch_config` - Fetch config from BuilderHub +- `rbuilder_bidding_restart` - Restart rbuilder-bidding service +- `ssh_stop` - Stop SSH service +- `ssh_start` - Start SSH service +- `haproxy_restart` - Restart HAProxy service + +### File Uploads + +Upload files to predefined paths. Only whitelisted names from `[file_uploads]` config are allowed: + +```toml +[file_uploads] +rbuilder_blocklist = "/var/lib/persistent/rbuilder-operator/rbuilder.blocklist.json" +``` + +```bash +# Stores local blocklist.json content to the configured remote path +curl -k --data-binary "@blocklist.json" https://localhost:13535/api/v1/file-upload/rbuilder_blocklist +``` + +### Customization + +To add more actions or file uploads, modify the config template: +https://github.com/flashbots/flashbots-images/blob/fryd/mkosi-playground/mkosi.profiles/playground/mkosi.extra/usr/lib/mustache-templates/etc/operator-api/config.toml.mustache + +## Maintenance + +```bash +./sync.sh # Update flashbots-images to latest +./clean.sh # Clean build artifacts + runtime files +``` + +## Ports + +| Port | Service | +|------|---------| +| 2222 | SSH (maps to VM:40192) | +| 13535 | Operator API (maps to VM:3535) | diff --git a/scripts/buildernet-vm/build.sh b/scripts/buildernet-vm/build.sh new file mode 100755 index 00000000..91aea375 --- /dev/null +++ b/scripts/buildernet-vm/build.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash +# Build the BuilderNet VM image +set -eu -o pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + +FLASHBOTS_IMAGES_DIR="${SCRIPT_DIR}/.flashbots-images" + +if [[ ! -d "${FLASHBOTS_IMAGES_DIR}" ]]; then + echo "Error: flashbots-images not found. Run ./sync.sh first." + exit 1 +fi + +make -C "${FLASHBOTS_IMAGES_DIR}" build-playground diff --git a/scripts/buildernet-vm/builderhub-get-config.sh b/scripts/buildernet-vm/builderhub-get-config.sh new file mode 100755 index 00000000..88477f4b --- /dev/null +++ b/scripts/buildernet-vm/builderhub-get-config.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash +# Check builder-hub configuration +set -eu -o pipefail + +echo "Builder Configuration:" +curl -s http://localhost:8888/api/l1-builder/v1/configuration | jq . diff --git a/scripts/buildernet-vm/clean.sh b/scripts/buildernet-vm/clean.sh new file mode 100755 index 00000000..eb087eb3 --- /dev/null +++ b/scripts/buildernet-vm/clean.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env bash +# Clean build artifacts and runtime files +set -eu -o pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + +FLASHBOTS_IMAGES_DIR="${SCRIPT_DIR}/.flashbots-images" +RUNTIME_DIR="${SCRIPT_DIR}/.runtime" +PIDFILE="${RUNTIME_DIR}/qemu.pid" + +# Check if VM is running +if [[ -f "${PIDFILE}" ]] && kill -0 $(cat "${PIDFILE}") 2>/dev/null; then + echo "Error: VM is still running. Run ./stop.sh first." + exit 1 +fi + +if [[ -d "${FLASHBOTS_IMAGES_DIR}" ]]; then + make -C "${FLASHBOTS_IMAGES_DIR}" clean +fi + +rm -rf "${RUNTIME_DIR}" diff --git a/scripts/buildernet-vm/console.sh b/scripts/buildernet-vm/console.sh new file mode 100755 index 00000000..a7f73b23 --- /dev/null +++ b/scripts/buildernet-vm/console.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash +# Connect to the BuilderNet VM console (auto-login with devtools profile) +set -eu -o pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +CONSOLE_SOCK="${SCRIPT_DIR}/.runtime/console.sock" + +if [[ ! -S "${CONSOLE_SOCK}" ]]; then + echo "Error: Console socket not found. Is the VM running?" + echo "Run ./start.sh first." + exit 1 +fi + +echo "Connecting to VM console... (Ctrl+] to exit)" +socat -,raw,echo=0,escape=0x1d UNIX-CONNECT:"${CONSOLE_SOCK}" + +echo "" +echo "Disconnected from VM console." diff --git a/scripts/buildernet-vm/operator-api-action.sh b/scripts/buildernet-vm/operator-api-action.sh new file mode 100755 index 00000000..3e26f5c0 --- /dev/null +++ b/scripts/buildernet-vm/operator-api-action.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env bash +# Execute an operator-api action +set -eu -o pipefail + +OPERATOR_API_PORT=${OPERATOR_API_PORT:-13535} +OPERATOR_API_HOST=${OPERATOR_API_HOST:-localhost} + +ACTION=${1:-} + +if [ -z "$ACTION" ]; then + echo "Usage: $0 " + echo "" + echo "Available actions:" + echo " reboot - Reboot the system" + echo " rbuilder_restart - Restart rbuilder-operator service" + echo " rbuilder_stop - Stop rbuilder-operator service" + echo " fetch_config - Fetch config from BuilderHub" + echo " rbuilder_bidding_restart - Restart rbuilder-bidding service" + echo " ssh_stop - Stop SSH service" + echo " ssh_start - Start SSH service" + echo " haproxy_restart - Restart HAProxy service" + exit 1 +fi + +curl -s -k "https://${OPERATOR_API_HOST}:${OPERATOR_API_PORT}/api/v1/actions/${ACTION}" diff --git a/scripts/buildernet-vm/operator-api-health.sh b/scripts/buildernet-vm/operator-api-health.sh new file mode 100755 index 00000000..943f3d03 --- /dev/null +++ b/scripts/buildernet-vm/operator-api-health.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash +# Check operator-api health +set -eu -o pipefail + +OPERATOR_API_PORT=${OPERATOR_API_PORT:-13535} +OPERATOR_API_HOST=${OPERATOR_API_HOST:-localhost} + +# /livez returns HTTP 200 with empty body on success +HTTP_CODE=$(curl -s -k -o /dev/null -w "%{http_code}" "https://${OPERATOR_API_HOST}:${OPERATOR_API_PORT}/livez") + +if [ "$HTTP_CODE" = "200" ]; then + echo "OK" + exit 0 +else + echo "FAIL (HTTP $HTTP_CODE)" + exit 1 +fi diff --git a/scripts/buildernet-vm/operator-api-logs.sh b/scripts/buildernet-vm/operator-api-logs.sh new file mode 100755 index 00000000..f1951178 --- /dev/null +++ b/scripts/buildernet-vm/operator-api-logs.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash +# Get operator-api event logs +set -eu -o pipefail + +OPERATOR_API_PORT=${OPERATOR_API_PORT:-13535} +OPERATOR_API_HOST=${OPERATOR_API_HOST:-localhost} + +curl -s -k "https://${OPERATOR_API_HOST}:${OPERATOR_API_PORT}/logs" diff --git a/scripts/buildernet-vm/prepare.sh b/scripts/buildernet-vm/prepare.sh new file mode 100755 index 00000000..c03fbf00 --- /dev/null +++ b/scripts/buildernet-vm/prepare.sh @@ -0,0 +1,30 @@ +#!/usr/bin/env bash +# Extract VM image and create data disk +set -eu -o pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + +FLASHBOTS_IMAGES_DIR="${SCRIPT_DIR}/.flashbots-images" +RUNTIME_DIR="${SCRIPT_DIR}/.runtime" + +QEMU_QCOW2="${FLASHBOTS_IMAGES_DIR}/mkosi.output/buildernet-qemu_latest.qcow2" + +VM_IMAGE="${RUNTIME_DIR}/buildernet-vm.qcow2" +VM_DATA_DISK="${RUNTIME_DIR}/persistent.raw" + +if [[ ! -f "${QEMU_QCOW2}" ]]; then + echo "Error: QEMU qcow2 image not found: ${QEMU_QCOW2}" + echo "Run ./build.sh first." + exit 1 +fi + +rm -rf "${RUNTIME_DIR}" +mkdir -p "${RUNTIME_DIR}" + +rm -f "${VM_IMAGE}" +cp --sparse=never "${QEMU_QCOW2}" "${VM_IMAGE}" + +qemu-img create -f raw "${VM_DATA_DISK}" 100G + +echo "Runtime ready: ${RUNTIME_DIR}" +ls -lah "${RUNTIME_DIR}" diff --git a/scripts/buildernet-vm/send-tx.sh b/scripts/buildernet-vm/send-tx.sh new file mode 100755 index 00000000..6d5909ce --- /dev/null +++ b/scripts/buildernet-vm/send-tx.sh @@ -0,0 +1,56 @@ +#!/usr/bin/env bash + +FROM_ADDR="0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" + +CHAIN_ID_HEX=$(curl -s -X POST http://localhost:8545 \ + -H "Content-Type: application/json" \ + -d '{"jsonrpc":"2.0","method":"eth_chainId","params":[],"id":1}' | jq -r '.result') +CHAIN_ID=$((CHAIN_ID_HEX)) + +NONCE_HEX=$(curl -s -X POST http://localhost:8545 \ + -H "Content-Type: application/json" \ + -d "{\"jsonrpc\":\"2.0\",\"method\":\"eth_getTransactionCount\",\"params\":[\"$FROM_ADDR\",\"pending\"],\"id\":1}" | jq -r '.result') +NONCE=$((NONCE_HEX)) + +TX_PAYLOAD=$(cast mktx \ + --private-key 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 \ + 0x70997970C51812dc3A010C7d01b50e0d17dc79C8 \ + --value 0.1ether --nonce "$NONCE" --gas-limit 21000 --gas-price 1gwei --chain "$CHAIN_ID") + +# Change this to set the target. 8545 for playground reth, 18645 for buildernet vm rbuilder. +date +%H:%M:%S +SEND_RESULT=$(curl -s --fail-with-body -X POST http://localhost:18645 \ + -H "Content-Type: application/json" \ + -d "{\"jsonrpc\":\"2.0\",\"method\":\"eth_sendRawTransaction\",\"params\":[\"$TX_PAYLOAD\"],\"id\":1}") +CURL_EXIT=$? + +if [ $CURL_EXIT -ne 0 ]; then + echo "Error: curl failed with exit code $CURL_EXIT" + exit 1 +fi + +echo "Send result: $SEND_RESULT" + +TX_HASH=$(echo "$SEND_RESULT" | jq -r '.result') + +if [ -z "$TX_HASH" ] || [ "$TX_HASH" = "null" ]; then + echo "Error: Failed to get transaction hash" + echo "$SEND_RESULT" | jq . + exit 1 +fi + +echo "TX_HASH: $TX_HASH" + +echo "Waiting for receipt..." +while true; do + RECEIPT=$(curl -s -X POST http://localhost:8545 \ + -H "Content-Type: application/json" \ + -d "{\"jsonrpc\":\"2.0\",\"method\":\"eth_getTransactionReceipt\",\"params\":[\"$TX_HASH\"],\"id\":1}") + + RESULT=$(echo "$RECEIPT" | jq -r '.result') + if [ "$RESULT" != "null" ]; then + echo "Receipt: $RECEIPT" + break + fi + sleep 1 +done diff --git a/scripts/buildernet-vm/ssh.sh b/scripts/buildernet-vm/ssh.sh new file mode 100755 index 00000000..2f275024 --- /dev/null +++ b/scripts/buildernet-vm/ssh.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash +# SSH into the BuilderNet VM +set -eu -o pipefail + +SSH_PORT=2222 + +ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -p ${SSH_PORT} bnet@localhost diff --git a/scripts/buildernet-vm/start.sh b/scripts/buildernet-vm/start.sh new file mode 100755 index 00000000..c9a971a2 --- /dev/null +++ b/scripts/buildernet-vm/start.sh @@ -0,0 +1,83 @@ +#!/usr/bin/env bash +# Start the BuilderNet VM +set -eu -o pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + +RUNTIME_DIR="${SCRIPT_DIR}/.runtime" +VM_IMAGE="${RUNTIME_DIR}/buildernet-vm.qcow2" +VM_DATA_DISK="${RUNTIME_DIR}/persistent.raw" +PIDFILE="${RUNTIME_DIR}/qemu.pid" +CONSOLE_LOG="${RUNTIME_DIR}/console.log" +CONSOLE_SOCK="${RUNTIME_DIR}/console.sock" + +CPU=8 +RAM=32G +SSH_PORT=2222 +OPERATOR_API_PORT=13535 +RBUILDER_RPC_PORT=18645 + +if [[ ! -f "${VM_IMAGE}" ]]; then + echo "Error: VM image not found. Run ./prepare.sh first." + exit 1 +fi + +if [[ -f "${PIDFILE}" ]] && kill -0 $(cat "${PIDFILE}") 2>/dev/null; then + echo "Error: VM already running (PID: $(cat ${PIDFILE}))" + exit 1 +fi + +echo "Starting VM..." +echo " SSH: localhost:${SSH_PORT}" +echo " Operator API: localhost:${OPERATOR_API_PORT}" +echo " rbuilder RPC: localhost:${RBUILDER_RPC_PORT}" +echo " Console log: ${CONSOLE_LOG}" +echo " Console socket: ${CONSOLE_SOCK}" + +# /usr/share/OVMF/... could be different for your system. Please adjust if needed. + +qemu-system-x86_64 \ + -daemonize \ + -pidfile "${PIDFILE}" \ + -serial file:"${CONSOLE_LOG}" \ + -name buildernet-playground \ + -drive if=pflash,format=raw,readonly=on,file=/usr/share/OVMF/x64/OVMF_CODE.4m.fd \ + -drive if=pflash,format=raw,readonly=on,file=/usr/share/OVMF/x64/OVMF_VARS.4m.fd \ + -drive format=qcow2,if=none,cache=none,id=osdisk,file="${VM_IMAGE}" \ + -device nvme,drive=osdisk,serial=nvme-os,bootindex=0 \ + -enable-kvm -cpu host -m "${RAM}" -smp "${CPU}" -display none \ + -device virtio-scsi-pci,id=scsi0 \ + -drive file="${VM_DATA_DISK}",format=raw,if=none,id=datadisk \ + -device nvme,id=nvme0,serial=nvme-data \ + -device nvme-ns,drive=datadisk,bus=nvme0,nsid=12 \ + -nic user,model=virtio-net-pci,hostfwd=tcp:127.0.0.1:${SSH_PORT}-:40192,hostfwd=tcp:127.0.0.1:${OPERATOR_API_PORT}-:3535,hostfwd=tcp:127.0.0.1:${RBUILDER_RPC_PORT}-:8645 \ + -chardev socket,id=virtcon,path="${CONSOLE_SOCK}",server=on,wait=off \ + -device virtio-serial-pci \ + -device virtconsole,chardev=virtcon,name=org.qemu.console.0 + +echo "VM started (PID: $(cat ${PIDFILE}))" +echo "Use './stop.sh' to stop, './console.sh' to connect" +echo "Use 'tail -f ${CONSOLE_LOG}' to watch console output" + + +# TRIED TO DISABLE SERVICES - DID NOT WORK +# error: +# qemu-system-x86_64: -append only allowed with -kernel option + +# PLAYGROUND_DISABLE_SERVICES=( +# reth-sync # Downloads Reth snapshot from S3 bucket +# acme-le # Issues Let's Encrypt TLS certificates +# acme-le-renewal # Renews Let's Encrypt certificates +# rbuilder-bidding-downloader # Downloads binary from private GitHub repo +# vector # Observability pipeline (logs/metrics) +# rbuilder-rebalancer # ETH balance rebalancing across wallets +# operator-api # Management API for node operators +# config-watchdog # Watches and reloads rbuilder config +# ) + +# mask_args() { +# [[ $# -gt 0 ]] && printf "systemd.mask=%s.service " "$@" +# } +# # # add argument to qemu-system-x86_64: +# # \ +# # -append "console=ttyS0 $(mask_args "${PLAYGROUND_DISABLE_SERVICES[@]}")" diff --git a/scripts/buildernet-vm/stop.sh b/scripts/buildernet-vm/stop.sh new file mode 100755 index 00000000..9c1fd92b --- /dev/null +++ b/scripts/buildernet-vm/stop.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env bash +# Stop the BuilderNet VM +set -eu -o pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PIDFILE="${SCRIPT_DIR}/.runtime/qemu.pid" + +if [[ ! -f "${PIDFILE}" ]]; then + echo "No pidfile found" + exit 0 +fi + +PID=$(cat "${PIDFILE}") +if kill -0 "${PID}" 2>/dev/null; then + kill "${PID}" + rm "${PIDFILE}" + echo "VM stopped (PID: ${PID})" +else + rm "${PIDFILE}" + echo "Stale pidfile removed (process not running)" +fi \ No newline at end of file diff --git a/scripts/buildernet-vm/sync.sh b/scripts/buildernet-vm/sync.sh new file mode 100755 index 00000000..a561dfcc --- /dev/null +++ b/scripts/buildernet-vm/sync.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash +# Clone or update flashbots-images repository +set -eu -o pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + +FLASHBOTS_IMAGES_DIR="${SCRIPT_DIR}/.flashbots-images" +FLASHBOTS_IMAGES_BRANCH="fryd/mkosi-playground" +FLASHBOTS_IMAGES_REPO="https://github.com/flashbots/flashbots-images.git" + +if [[ ! -d "${FLASHBOTS_IMAGES_DIR}" ]]; then + git clone --branch "${FLASHBOTS_IMAGES_BRANCH}" "${FLASHBOTS_IMAGES_REPO}" "${FLASHBOTS_IMAGES_DIR}" +else + git -C "${FLASHBOTS_IMAGES_DIR}" fetch origin + git -C "${FLASHBOTS_IMAGES_DIR}" checkout "${FLASHBOTS_IMAGES_BRANCH}" + git -C "${FLASHBOTS_IMAGES_DIR}" pull origin "${FLASHBOTS_IMAGES_BRANCH}" +fi