diff --git a/config/config.go b/config/config.go index 7c776ec69..2a3437dc6 100644 --- a/config/config.go +++ b/config/config.go @@ -4,16 +4,19 @@ import ( "bufio" "errors" "fmt" - carmen "github.com/Fantom-foundation/Carmen/go/state" - "github.com/Fantom-foundation/go-opera/config/flags" - "github.com/Fantom-foundation/go-opera/gossip/evmstore" - "github.com/ethereum/go-ethereum/common/fdlimit" + "net" "os" "path" "path/filepath" "reflect" + "regexp" "strings" + carmen "github.com/Fantom-foundation/Carmen/go/state" + "github.com/Fantom-foundation/go-opera/config/flags" + "github.com/Fantom-foundation/go-opera/gossip/evmstore" + "github.com/ethereum/go-ethereum/common/fdlimit" + "github.com/Fantom-foundation/lachesis-base/abft" "github.com/Fantom-foundation/lachesis-base/utils/cachescale" "github.com/ethereum/go-ethereum/common" @@ -103,18 +106,61 @@ func loadAllConfigs(file string, cfg *Config) error { func setBootnodes(ctx *cli.Context, urls []string, cfg *node.Config) { cfg.P2P.BootstrapNodesV5 = []*enode.Node{} for _, url := range urls { - if url != "" { - node, err := enode.Parse(enode.ValidSchemes, url) - if err != nil { - log.Error("Bootstrap URL invalid", "enode", url, "err", err) - continue - } - cfg.P2P.BootstrapNodesV5 = append(cfg.P2P.BootstrapNodesV5, node) + if url == "" { + continue + } + + _, modified, err := resolveHostNameInEnodeURL(url) + if err != nil { + log.Error("Failed to resolve hostname Bootnode", "url", url, "err", err) + continue } + + bootNode, err := enode.Parse(enode.ValidSchemes, modified) + if err != nil { + log.Error("Bootstrap URL invalid", "enode", modified, "err", err) + continue + } + cfg.P2P.BootstrapNodesV5 = append(cfg.P2P.BootstrapNodesV5, bootNode) } cfg.P2P.BootstrapNodes = cfg.P2P.BootstrapNodesV5 } +func resolveHostNameInEnodeURL(url string) (hostname string, modified string, err error) { + return resolveHostNameInEnodeURLInternal(url, func(hostname string) (string, error) { + ips, err := net.LookupIP(hostname) + if err != nil { + return "", err + } + if len(ips) == 0 { + return "", fmt.Errorf("no IPs found for hostname %v", hostname) + } + return ips[0].String(), nil + }) +} + +var _enodeHostnameRE = regexp.MustCompile(`enode:\/\/[0-9a-f]+@([^:]+):[0-9]+`) + +func resolveHostNameInEnodeURLInternal( + url string, + resolve func(string) (string, error), +) ( + hostname string, + modified string, + err error, +) { + match := _enodeHostnameRE.FindStringSubmatch(url) + if len(match) != 2 { + return "", "", fmt.Errorf("failed to match enode URL") + } + hostname = match[1] + ip, err := resolve(hostname) + if err != nil { + return "", "", fmt.Errorf("failed to resolve hostname %v: %v", hostname, err) + } + return hostname, strings.Replace(url, hostname, ip, 1), nil +} + func setTxPool(ctx *cli.Context, cfg *evmcore.TxPoolConfig) error { if ctx.GlobalIsSet(flags.TxPoolLocalsFlag.Name) { locals := strings.Split(ctx.GlobalString(flags.TxPoolLocalsFlag.Name), ",") @@ -187,7 +233,7 @@ func gossipConfigWithFlags(ctx *cli.Context, src gossip.Config) gossip.Config { return cfg } -func setEvmStore(ctx *cli.Context, datadir string, src evmstore.StoreConfig) (evmstore.StoreConfig, error) { +func setEvmStore(ctx *cli.Context, datadir string, src evmstore.StoreConfig) (evmstore.StoreConfig, error) { cfg := src cfg.StateDb.Directory = filepath.Join(datadir, "carmen") diff --git a/config/config_test.go b/config/config_test.go new file mode 100644 index 000000000..7dcfb0ea5 --- /dev/null +++ b/config/config_test.go @@ -0,0 +1,35 @@ +package config + +import ( + "strings" + "testing" +) + +func TestBootstrapNodes_AreValid(t *testing.T) { + fakeIp := "1.2.3.4" + fakeResolver := func(url string) (string, error) { + return fakeIp, nil + } + + for name, node := range Bootnodes { + t.Run(name, func(t *testing.T) { + for _, url := range node { + t.Run(url, func(t *testing.T) { + hostname, modified, err := resolveHostNameInEnodeURLInternal(url, fakeResolver) + if err != nil { + t.Fatalf("Failed to resolve hostname in enode URL: %v", err) + } + if !strings.Contains(url, hostname) { + t.Fatalf("Hostname %q not found in URL", hostname) + } + if strings.Contains(modified, hostname) { + t.Fatalf("failed to replace hostname in URL %q", modified) + } + if !strings.Contains(modified, fakeIp) { + t.Fatalf("failed to insert IP in URL %q", modified) + } + }) + } + }) + } +} diff --git a/config/params.go b/config/params.go index 72f6dc8a8..475067fb8 100644 --- a/config/params.go +++ b/config/params.go @@ -7,18 +7,20 @@ import ( var ( Bootnodes = map[string][]string{ "main": { - "enode://969654fc30f10e45903ee2d107cfc165feaff6f9acbd2a9472120a3581f7c717ded76113aa116e35b8389dfcc9129ecfc85a409f6c46fc864ce077cb85316ac8@3.252.226.57:5050", - "enode://15dde1f31ff775da40d06a5529c15cce5bcdfec6055f8e8782b0df3f2ad3eab30b31fbb91037c6b3dacb8e612e177bdfaf4d82e9080feda31e54412efb56a34a@34.251.109.79:5050", - "enode://41943a0269fc573355ff6a5e5980195cea68eb7bc703cc9937a3cd0debc9a795396aa9560bce65c8f329a9343f88ee4084daabcca76c5a6a8054aa163973a735@3.10.205.205:5050", - "enode://b781fa90f63ef497c02ef6da8f32c2e14cc47921403d21083d5ebc69b5a85f77d6f124f084e3abbf3984e07aa5810b250658c04d6d3f3bc76e3735b2512847db@3.73.43.156:5050", - "enode://fe97ec5b6c2073e4074067f3e513e66cf0a157c449bbb179dc8876803dc9cd3a18b03e735b87393c843cdc3be9c12989c2dd8ddaf88eda2f73a7183f2d65e95e@54.242.2.27:5050", - "enode://2591357319aaa566897854f225d3a60194a8d193410de28e9ea74df2bb2615af63766351d8950c0582c970e3688ad85a8e454c5a601b9b091f094869fe603350@18.234.231.118:5050", - "enode://7c6dbe419f79852536f3fc850912eaf657f50f378f6f6bc238bfe16bcf830c06ef3c0358774313eb94d959475a8bfa221bb53a4b0dcf3025ac071396199a3462@13.212.202.99:5050", - "enode://e6c658978b95bcb29354f5a4a808b3d17d62201bcbd6ac36fa937e134c18b89ca23ee6f9f3893beabf07ec2f3e07b19d02d705ebc67ba671bff9830fa002c635@3.26.147.192:5050", - "enode://9554ca82fb2cc3a2e3f30b847304e26e0ec6e73993c19610443a9fcd7c2a38796089a0ebe24c2c0bde6fb4155433c04104e049e9c6bd73a758c01e8cb93a7d9d@13.125.201.204:5050", - "enode://b3699ce7ee4a8c6efb07707256a2a08872576f438664c6437cb263989116747d8d7332fb9cfc35c8f3ba04a024ecc6893cda1782db6fed221d9de2ec11746cfd@18.170.86.32:5050", - "enode://c3e35344cde52f82f9a0fdcf54429f72d9613a8ba031176b88d727a94f00c604cf01ebbf1454684421eb4e29743bf7c0131a74c933ae44eb1ce922aa130a6504@35.193.106.34:5050", - "enode://5e00a67b3cfeb086becb1dd58401f28e3568f1b6da58fa0760b192c9faa8c19cd22a6efbd8058b8ccdbfe9776f91e1b43c09d8d7f6603f07ab5e0eb43f0bcb33@35.228.218.253:5050", + "enode://9e407268042abab1cf66efe9edf4e9913ada7be030c4601f8cbab53350ccd616d4348b5e39811fe22796b7870ea8af8c79c5afb003c40769887fbe5cbccfec40@opera-bootstrap-a.fantom.network:5050", + "enode://0689c518755a50a0cc631d145ceefe94d0e52ac2f839a1b244bcf32d53cdb9de0be60bb6426b70bf7343876b05a4491ca589aa7e7e72ab4ace3c581aca151e97@opera-bootstrap-b.fantom.network:5050", + "enode://a7d40e0a98a80ee9387ffe23f6558af21a80b913169e3aa92de6d292adb5f26d85895202635afe7811149daa650dd2c0e71b8b9f82fef248f76141cc8729003d@opera-bootstrap-c.fantom.network:5050", + "enode://93e8251ac61ad7280badf6f8395fd285e5ffb159f0da6427ca948a3f1014b7c065d45b046bd113948a6f641b2b93eb4f71256024153ce641900cb0ef6703a816@opera-bootstrap-d.fantom.network:5050", + "enode://1587d5b7a283fd7b0f462555cc74a05a894d9247bfbef4ecf7f49a0dabca2a6f9bd6f1feaed1d0adc5bd29086979c9fc9c93eaa61f725056981577e8a52f5250@opera-bootstrap-e.fantom.network:5050", + "enode://1eea15c747111025dc46b7b7bc41cb8e09b31af666f0173fe9ee60e378381c5b6c51c903ef060f18e6da00f76006a363756bc0fad85a372b7e31e752b5639689@opera-bootstrap-f.fantom.network:5050", + "enode://6aa14c827cde8bc968edb24d0c13d79af3789e07544aa9f488e29fbc1b0041f9a197e9dd3272c83f717cda59c723c7a9b67af7d7cf5a7968982e45f4241ab61d@opera-bootstrap-g.fantom.network:5050", + "enode://7b195cc5a9a592056435d87533f28a2d144bb3e9c3f5b5aa11d9ecfac8a4bcabe85dbb9dfe08c71088e6235030aaa52a70d9bcee1eb0371b1ee2cf047cb4002c@opera-bootstrap-h.fantom.network:5050", + "enode://99013978c69683cb5ada1637e249c07ebdd789c528b26c2a869492ed4f21796ceb4ccba331f3d2ead52d8cc464e179d59b9e1c2786b6e5450c71e2d3a8569f06@opera-bootstrap-i.fantom.network:5050", + "enode://7954eaa72de345ab763cbd16078521e91afb561acaac94ec0338078adc736038908694ff79fd76dfaf3de5dba92c7af904c76566f73c9c4ff580abf191369bda@opera-bootstrap-j.fantom.network:5050", + "enode://c3e35344cde52f82f9a0fdcf54429f72d9613a8ba031176b88d727a94f00c604cf01ebbf1454684421eb4e29743bf7c0131a74c933ae44eb1ce922aa130a6504@opera-bootstrap-k.fantom.network:5050", + "enode://d10bd6e10c6405b0e98cdac24858df50b7e7ae174dda5abf3e548ff524febab007c9067f3507f0ee5d9eff5d862d90bf9d6ce30b50d1f89c995185e6e714ab46@opera-bootstrap-l.fantom.network:5050", + "enode://6b82fd3c58606e984c6874a2ee160464e7decb9fb0aed439b1a4bef811f347b18070949c694d5669d8ff6b05260cbe6ffec17e321055ff237701cd5cd7b036a7@opera-bootstrap-m.fantom.network:5050", + "enode://969654fc30f10e45903ee2d107cfc165feaff6f9acbd2a9472120a3581f7c717ded76113aa116e35b8389dfcc9129ecfc85a409f6c46fc864ce077cb85316ac8@opera-bootstrap-n.fantom.network:5050", }, "test": { "enode://52c84c99a4cca9524dc626261e932aa8b1c88a103523132a1d6c30fd7d1f3eab0cb105403971baa7255f9eb5eadde9761db23bb277c4c7d6c3eefaf133dcb35f@170.64.156.90:7946", diff --git a/go.mod b/go.mod index fd99b15f6..16cb94324 100644 --- a/go.mod +++ b/go.mod @@ -44,7 +44,10 @@ require ( gopkg.in/urfave/cli.v1 v1.20.0 ) -require github.com/Fantom-foundation/Carmen/go v0.0.0-20240919111317-5c737f72628f +require ( + github.com/Fantom-foundation/Carmen/go v0.0.0-20240919111317-5c737f72628f + go.uber.org/mock v0.2.0 +) require ( github.com/DataDog/zstd v1.4.5 // indirect @@ -103,7 +106,6 @@ require ( github.com/tklauser/numcpus v0.2.2 // indirect github.com/urfave/cli/v2 v2.25.7 // indirect github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect - go.uber.org/mock v0.2.0 // indirect golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect golang.org/x/lint v0.0.0-20200302205851-738671d3881b // indirect golang.org/x/net v0.21.0 // indirect