diff --git a/.dockerignore b/.dockerignore index d280741c6..a6de8ee0a 100644 --- a/.dockerignore +++ b/.dockerignore @@ -6,4 +6,5 @@ build/_workspace build/_bin +build/bin tests/testdata diff --git a/Makefile b/Makefile index c9147c38a..0224c34c9 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -.PHONY: XDC XDC-cross evm all test clean +.PHONY: XDC bootnode puppeth gc XDC-cross evm all test clean .PHONY: XDC-linux XDC-linux-386 XDC-linux-amd64 XDC-linux-mips64 XDC-linux-mips64le .PHONY: XDC-darwin XDC-darwin-386 XDC-darwin-amd64 diff --git a/bootnode/bootnodes.list b/bootnode/bootnodes.list new file mode 100644 index 000000000..d67ffd847 --- /dev/null +++ b/bootnode/bootnodes.list @@ -0,0 +1,58 @@ +enode://874589626a2b4fd7c57202533315885815eba51dbc434db88bbbebcec9b22cf2a01eafad2fd61651306fe85321669a30b3f41112eca230137ded24b86e064ba8@5.189.144.192:30303 +enode://ccdef92053c8b9622180d02a63edffb3e143e7627737ea812b930eacea6c51f0c93a5da3397f59408c3d3d1a9a381f7e0b07440eae47314685b649a03408cfdd@37.60.243.5:30303 +enode://81edfecc3df6994679daf67858ae34c0ae91aac944a84b09171532b45ad0f5d0c896eb8c023df04eaa2db743f5fccdf18cf7e2d12120d37a2c142a3be0a348cd@38.102.87.174:30303 +enode://053ba696174e7f115e38f0e3963d0035ac20dc18e9a5c5873f9e90fe338d777f726d68d053c987416ec0bd97d4d818c59a8a23bc9ea854069ea2310846e27e7d@162.250.189.221:30303 +enode://b3ce1f8894af033cc2adbcb0836fe18d283af8574c451e385fd362165a6e5eded1b59b640c4d92048283bad9855721345a28ebaf28f66ace00a7134871d1e2a2@38.143.58.166:30303 +enode://938f2e3f409a12573e6da6460b6497c45e2bec393756b989b8874f647911cca39d0ffef8554a45698a8f21a7e870288beb638b3770537a12118e30bd6f9ae806@109.199.104.176:30303 +enode://f8848e405142b8e88f054fe85ac5e4a75cfd7e353aee7e66797719828d3d5aa2cd62f1355140c0852d3dcb2439a076234c77415ca701318ea1f69a496a0b4b32@109.123.232.199:30303 +enode://0857894c01314e75520fbdb7e37869666f230c8ab96c0e3067561077209e8f48a9cefb3a71c3c8094448629c152f22c2e5e66bb7ed2c38bfbd9f24941f571beb@103.7.54.103:30303 +enode://91e59fa1b034ae35e9f4e8a99cc6621f09d74e76a6220abb6c93b29ed41a9e1fc4e5b70e2c5fc43f883cffbdcd6f4f6cbc1d23af077f28c2aecc22403355d4b1@144.126.142.140:30304 +enode://c665260ee724b0cdd9cb084bc010b40a23224b2d3b1ddc996bb101165c9853fae6062bacd1c8357b00f1d049c74917d7edea387245eeaadf136a33b7d59163f1@152.114.192.194:30303 +enode://adc64a4de268bfd401b9eeb65c02028cfef3b1a954eb86e0ed04250daf8b8f46039d3568a20f50a3a7dd467dca836e81f599ef9442f96ddaca08b85ea49d2d9f@38.102.87.214:30303 +enode://952fc1680beb470933a1d4c27945d1315888806bd40dc4c2e720c9b64bb838114acf55ae9113ca7470bfb215162b26b6734f2d8e6cf07ac9a7810b15badce46b@38.49.212.98:30303 +enode://35c8de40d9d8952aa0a0f892dc866e59e20b0ba5ad2aa4cbde88043739fadc1bf0b36492032bce8f2b673f6e201480929e131ce103435fbf774d63215c258b1f@145.239.253.161:30303 +enode://9e021b0d298174d649558df1808b45b3d6ffb82bf1a869ebcb4907ca2afb38f694a50f4e92f7e0fb30d506abf324d7ce769a24ec9332d163a90e858a3d706cb4@204.188.254.234:30303 +enode://766a2ca2b899e4f7b0d8dc0c15e32dc212030543feb6ed1cca981dd577b20b25094506d44343b9bb5840102716ab37d390731d5ca4fb41966a17109fe477d6ae@104.152.209.135:30303 +enode://55bb595b04759e545bb36b93c7f656524685bef692f06098f293a661bbd2b29b823db4d8a21c6d8757cf5111bfdb44dd22ecdeb6cf3531faa9ca0e928127320a@104.152.210.117:30303 +enode://b29fed5affa4ceda46e3a5ee8db1fe09fbddf98b92f94a0cf52e662701443c35e74ac854f009fcc23c5d8090baa406a8d3ebc10106ba2d284047682283c2aa59@209.209.8.252:30303 +enode://47c62b62194c98deab0de7d632451fa1cdced6992a985851655083c49ae76048df06e5fb0c2aaa8c2367e31186b8726526855337bfd843af273307e0abc7e17e@38.102.84.145:30303 +enode://4c77910fdd567184a7803da86be603680d161fa9ab4721890ac41ecd6696497da1c5d9076b74985a873900538cd32f94e86990f3197b4bf0a43923c6a42901f3@162.250.189.149:30303 +enode://7bb3e723a13254412cebe8d481de7afc053c2ce9d91e69aa7bffab6ff973fffff2b3c786838ca23376be8856239566a49970a7c08cd5dde7328f0beeb59a18fd@162.250.190.246:30303 +enode://53137ef0408a2e36804c95549e6e1cbd4b24c7fd713d08ce57390b08edf09f4de1ccd083e8e1dd01ad0ea1335c405f511e92e4db765575cb440da0ad49eac6b5@162.250.191.160:30303 +enode://436be9f289209f25e22b913ffc00693a35faa24b42d01aac38e9cc3fe11e311861ee24a6c9ce6dcd913ec6b3bb3aeac5c9c75278aea17b1a4b183b0d29b3e0e6@38.102.124.68:30303 +enode://8972335640e8b675ed135b16b80dfbdf905d56f64dc3bce4f23d0262ded4cde74139f26805def8cf96a574e042f3c937148b2cdc843b6c9a806d3a91a202c7db@104.152.211.94:30303 +enode://449f8e421fdc19b1f525fe524aace520309f7c2f002519a16067c0b24bb2fb24773d9ae3ddb0ca9d4104d75119187a5990958e41e3b3452fa2b71792928fa5fa@104.152.209.134:30303 +enode://815c89950fc77bf11acf432ea9c0ef180579bdec8bb7bb095117fece147185807e2d461194b2cfc3bd6cb72dc5fb6e64d32a9861dcfac4e79dc6c11f61833c29@162.250.191.14:30303 +enode://31bc9409f7618c2817fa081e40629b725bbff94cb7dd4113f3acb5fce517213ec5cb1f20eac2c4f5505119b987b670147da2c7a0fb4a58bdc7c1d56a788615a0@38.102.87.32:30303 +enode://1cf98a852975ccfd3e54b9fcd369a790e74d0e527f3452b11e3160f0b9e1fc9297e68837dabc3093c43c79a7740afad4e2a68b53161c5d711b3d06a79db72e5f@104.152.209.131:30303 +enode://560be672a5696a9079fbdb32343efb72d058cce72af001dc5c77a89f54a6cf1e1a914f5d7aa93527073447b3e26d34992b1a439235ad3225b1d3c6874f62494f@104.152.209.119:30303 +enode://29856324d63fbb6ca81080e105d6d2c935bf38013deefcaf05ac9107956dd0f068426edc2267789b06294bae7694c7be2d7b2d5740b8e4c9129cb3e50f11d82b@104.152.210.92:30303 +enode://3bb536b4137f9e1f03e34be32cc7ef7580c8ab10fbd3a9082ae0a553dc7d282c0d2927fab79b2476f81b29ca219651e21a08a0c5bfddd067f9eb038e30c49ed1@38.102.124.161:30303 +enode://a3e5bb9a97d543ad8f7fe694480135bae412f95af73fabf709eaf5e4b8656ee412075f651ab5ee7ad667023f727d4e8ed4f9f6d9d3ccd6ac2deefe5d6a1a77ec@38.102.87.241:30303 +enode://2e45eeb31cb86aa4a032d087220b86d0ee3d1d078f675bed807f6ddf049bb02a21aa259f5ac4cf0fffa2cf1dc5cce9c50ca2d28533f5f95ad4346ee8a0b99fbd@207.90.192.188:30303 +enode://62330195cec776dae468027c701ee6711db75c0e32d20654725f0c68eac6a7c48e8fa01451d04cc4e9b0735c0bbc184556f79b06fe5a9f8a21be9f92080db380@38.102.85.50:30303 +enode://dcfb15b4d8c8f2f6b9645ad160349ac24ac1e5db655e4dccc470da5c9d0e63e280169ae2d4d6ca43ef0ae5c1050b9c4a21954bbbef59f19083ef8a801672e23a@162.250.191.70:30303 +enode://8c7d843227a6bc95b3dcc8609c7926379ee2fde2dcac0b34847ca044f89ca4dd56167b077be18c7c6a3f049e9b85aabe66e87876cc1bb90e7e33ea6e4e0055a9@38.102.87.174:30303 +enode://ec53417068eb5f7318b3537f77bdbf241a05cb1aaaaaabb1a8fe645fb63929ffb8a81943af2a9d5a14b1d847ca1bf79ff00e73f75bc9ba5d42c8477e490e9b3d@38.49.209.177:30303 +enode://fa5795affb3c8ba13996d4eb3d226a044a29dcf8209833c7eb048411f7a727f0c6436234d053bba880d30c29337277eca57c981a9219d25d38b845d2f1ade100@185.252.234.115:30303 +enode://80ab40b2cbd5ee1e0f758cd2b129c854c9e97a7a8186bc2f7ac8b61a815a5530ab6f68cdefb5901a456878437098cf1a70f395740d6dd7907639f34b9f0cf95c@85.190.246.191:30303 +enode://f9ee4c28d442df3a90c374f802eb8c184f83d9171ab017e1c3a37e9537336c830bcbe0caaf810aee8bbe8b4a080621790bec284b88c617d7eceffd07b98d4b99@207.244.252.29:30303 +enode://4a18d266539766b3b5e1364f91a2d60268005ca43ab6c2a8a35327b539082fc41e4dfa6e7bf6cf0743e311a08cb95dc3b90c5103e54a31175495c4b45bcf542d@85.239.242.163:30303 +enode://f9c529a3ca35478ad468d9ed6f53413c0319ac985a4090c2bebe992d4af5fa5a711c5dd6c325340cee5e1115048ff4cf1089c8f185b94a9b0efb2e6eee167686@37.60.244.133:30303 +enode://a9682f01127b711cd3c42358f057fa730f3535aed9ffa7bfc0721830098b4afb3cfd7c2bd7bf60cf42a2089b4048f935c3b483727a3e17b73aeb6b5374695bbb@109.123.242.198:30303 +enode://342635ca1cae181f2132147175a9cae3159f547dc8b3b287b8cf03e86c1815ef3baec753b6d0ece121439e643cf12ae5a7b6ed1b902e82ae09c3302b133d139c@86.48.31.130:30303 +enode://ff039ecd75d99a1f51f83aa408baaad070f57e98073f33b2ad90b2bc1e056ff728254e0ea8dd866528130f62697b90be7100de14b2380cd366fa5ad4c4a4a338@85.239.236.10:30303 +enode://e5567ad0fab8f95880de949d1a50b384bef98a661084a9d9506eb936bef60c178b1d6311dc106230c032185db3b4ef358ad340a8e54fcf1a77e47f10ff9f09c1@45.10.162.64:30303 +enode://5491defdafdf29b919751f2e66c7da01d611d2aafc4e2e8a6edaab755dc509fb5c4dda995f8090bb24fcb9548f028ac263c4e15333b189a65c0d92bbc127c217@164.68.115.24:30303 +enode://0cbee8e5599530b412e24f1c21aca465d313ed7fbb039f204239c4fbd048b740ff9dabf6b3ce046f3dc0ddbf0650eae18f9c61ace0c9ecffbe4ff241d87f0791@84.247.183.213:30303 +enode://5847f682357453ab984e96481848bcf80e7ad5983822e5465a0499d808c377a18949f7c793d794485b746c57f4abb1a05fff9ffbab07a52097b84ba82ae251ea@147.93.157.137:30303 +enode://8a5fdb8f00b8237e95bc47e33752b622728c89d0f33cd34620d42a671c88820496b47403419534a3c33c48d2cfd97e15a5f1f71fbc0ea946256911ab4250bac8@147.93.152.231:30303 +enode://8e3ec3dd124e07c5b2e3edea314b9139d6fea02f5d37fe4f37fafc86c4e7c1fac77c3ac635ea67675209677ec45b77f9fde4776de4c6c88251445858d4713f12@46.250.240.52:30303 +enode://13f82d394ce912272747847d988361dc611ca2b4b910e64c9692e0054736eb428ab8da1aaca9ef887155e59634312a5eec657b251d08c0328da9d5a710e9afe4@149.102.148.150:30303 +enode://b9d448697d4f9d1f3ec64162c61fbc171fc9888137c024206fac04411c93edff4d4fc5079b16d92d83ecce0cf4866f0f118fc56dfa171436a3919c6eb45dde4f@207.180.240.193:30303 +enode://9d7dabb26acc8b2ca6e8fe3c8afdaa4aa8c8383add54dae10516949a3709f21c2c891ad8a37fcc5d2d5a85aab90cb6b07a186553f611c18e1131a827848efd64@45.58.169.153:30303 +enode://bc315e08ee6f2e8a4cde8abfb8b46873c449a5a9fee5ff2bccfdee114ecdea8d952be623dfd97d00b20657837d87dd963f44e83e7dd38d0f6c4aa13ca0bcf208@45.58.149.95:30303 +enode://2d5e3b19171f4d78f2dcb313d2fd28fdb6a5ffbc6c646a2027beff5da2ae2cc2a9ed72f829cac2f29f5a29fddff215caeafd76fb224c45ae161ddc49731a9635@208.98.38.217:30303 +enode://31866c03bab079baad7b0d5ffe74f456a9386fc9a42470682c0da2c5fe50052fb552b5b08119d0f553241b693a85b1a511a10cd77afcbb00f99a9ba2f3ed9fdf@204.188.254.226:30303 +enode://18e712438014ceb9711f0554897625f6981a0441042161cb3c2cf4611055b1bb770bac0cd70cb4c04063ae5f17deb268f6426238f230822edcce6c5bc18d17d3@45.58.169.158:30303 +enode://ec4ef1dd31fc945de188ab50d9c8e8a0dbacff196269624cbb47bf077feb5ab9155486e1f1c591a503d1cb35297291fa53f1ac6eb130abde2d26e306d8096f94@208.98.38.230:30303 \ No newline at end of file diff --git a/cmd/bootnode/main.go b/cmd/bootnode/main.go index 52fff2eba..89e91316a 100644 --- a/cmd/bootnode/main.go +++ b/cmd/bootnode/main.go @@ -23,6 +23,7 @@ import ( "fmt" "net" "os" + "strings" "github.com/XinFinOrg/XDC-Subnet/cmd/utils" "github.com/XinFinOrg/XDC-Subnet/crypto" @@ -35,16 +36,18 @@ import ( func main() { var ( - listenAddr = flag.String("addr", ":30301", "listen address") - genKey = flag.String("genkey", "", "generate a node key") - writeAddr = flag.Bool("writeaddress", false, "write out the node's pubkey hash and quit") - nodeKeyFile = flag.String("nodekey", "", "private key filename") - nodeKeyHex = flag.String("nodekeyhex", "", "private key as hex (for testing)") - natdesc = flag.String("nat", "none", "port mapping mechanism (any|none|upnp|pmp|extip:)") - netrestrict = flag.String("netrestrict", "", "restrict network communication to the given IP networks (CIDR masks)") - runv5 = flag.Bool("v5", false, "run a v5 topic discovery bootnode") - verbosity = flag.Int("verbosity", int(log.LvlInfo), "log verbosity (0-9)") - vmodule = flag.String("vmodule", "", "log verbosity pattern") + listenAddr = flag.String("addr", ":30301", "listen address") + genKey = flag.String("genkey", "", "generate a node key") + writeAddr = flag.Bool("writeaddress", false, "write out the node's pubkey hash and quit") + nodeKeyFile = flag.String("nodekey", "", "private key filename") + nodeKeyHex = flag.String("nodekeyhex", "", "private key as hex (for testing)") + bootnodes = flag.String("bootnodes", "", "comma-separated bootstrap node enode URLs") + bootnodesFile = flag.String("bootnodesfile", "", "file containing bootstrap node enode URLs") + natdesc = flag.String("nat", "none", "port mapping mechanism (any|none|upnp|pmp|extip:)") + netrestrict = flag.String("netrestrict", "", "restrict network communication to the given IP networks (CIDR masks)") + runv5 = flag.Bool("v5", false, "run a v5 topic discovery bootnode") + verbosity = flag.Int("verbosity", int(log.LvlInfo), "log verbosity (0-9)") + vmodule = flag.String("vmodule", "", "log verbosity pattern") nodeKey *ecdsa.PrivateKey err error @@ -97,6 +100,31 @@ func main() { } } + var bootnodeList []*discover.Node + if *bootnodesFile != "" { + data, err := os.ReadFile(*bootnodesFile) + if err != nil { + utils.Fatalf("-bootnodesfile: %v", err) + } + if *bootnodes != "" { + *bootnodes += "," + } + *bootnodes += string(data) + } + if *bootnodes != "" { + urls := strings.FieldsFunc(*bootnodes, func(r rune) bool { + return r == ',' || r == '\n' || r == '\r' || r == '\t' || r == ' ' + }) + bootnodeList = make([]*discover.Node, 0, len(urls)) + for _, url := range urls { + node, err := discover.ParseNode(url) + if err != nil { + utils.Fatalf("invalid bootnode %q: %v", url, err) + } + bootnodeList = append(bootnodeList, node) + } + } + addr, err := net.ResolveUDPAddr("udp", *listenAddr) if err != nil { utils.Fatalf("-ResolveUDPAddr: %v", err) @@ -126,6 +154,7 @@ func main() { PrivateKey: nodeKey, AnnounceAddr: realaddr, NetRestrict: restrictList, + Bootnodes: bootnodeList, } if _, err := discover.ListenUDP(conn, cfg); err != nil { utils.Fatalf("%v", err) diff --git a/docker-compose.bootnode.yml b/docker-compose.bootnode.yml new file mode 100644 index 000000000..d751439a7 --- /dev/null +++ b/docker-compose.bootnode.yml @@ -0,0 +1,22 @@ +services: + bootnode: + build: + context: . + dockerfile: docker/Dockerfile + image: xinfinorg/xdcsubnets:local + container_name: xdc-subnet-bootnode + entrypoint: ["bash", "/work/start-bootnode.sh"] + restart: unless-stopped + ports: + - "30301:30301" + - "30301:30301/udp" + volumes: + - ./bootnode:/work/bootnode + environment: + NODEKEY_FILE: /work/bootnode/bootnode.key + BOOTNODE_ENODE_OUT: /work/bootnode/bootnode.enode + LOG_FILE: /work/bootnode/bootnode.log + BOOTNODES_FILE: /work/bootnode/bootnodes.list + EXTIP: ${EXTIP:-} + DISABLE_EXTIP: ${DISABLE_EXTIP:-} + VERBOSITY: ${VERBOSITY:-5} diff --git a/docker/Dockerfile b/docker/Dockerfile index 2a1418ec1..020c6daa8 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -1,16 +1,18 @@ FROM golang:1.21 as builder -RUN apt-get update && apt-get install -y git build-essential +RUN apt-get update && apt-get install -y git build-essential curl \ + && rm -rf /var/lib/apt/lists/* COPY . /builder RUN go env -w GOFLAGS="-buildvcs=false" -RUN cd /builder && make XDC && make bootnode && make puppeth +RUN cd /builder && make XDC && make bootnode && make puppeth && test -f build/bin/bootnode # The actual image for subnet containers FROM golang:1.21 -RUN apt-get update && apt-get install -y git build-essential +RUN apt-get update && apt-get install -y git build-essential curl \ + && rm -rf /var/lib/apt/lists/* WORKDIR /work diff --git a/docker/start-bootnode.sh b/docker/start-bootnode.sh index 670c0a840..5a47bba20 100755 --- a/docker/start-bootnode.sh +++ b/docker/start-bootnode.sh @@ -1,21 +1,33 @@ #!/bin/bash -# Variables params="" -# extip -if [[ ! -z $EXTIP ]]; then -echo "Set the NAT to extip:${EXTIP}" +if [[ -n "${DISABLE_EXTIP:-}" ]]; then + echo "DISABLE_EXTIP set; starting without -nat extip" +elif [[ -z "${EXTIP:-}" ]]; then + if command -v curl >/dev/null 2>&1; then + EXTIP=$(curl -fsS --max-time 10 https://checkip.amazonaws.com 2>/dev/null | tr -d '[:space:]') + if [[ -n "$EXTIP" ]]; then + echo "Auto-detected public IP (EXTIP): ${EXTIP}" + export EXTIP + fi + fi +fi + +if [[ -n "${DISABLE_EXTIP:-}" ]]; then + : +elif [[ -n "${EXTIP:-}" ]]; then + echo "Set the NAT to extip:${EXTIP}" params="$params -nat extip:${EXTIP}" +else + echo "WARN: EXTIP not set and auto-detection failed; enode will use container/local IP" fi -# extip if [[ ! -z $NET_RESTRICTING ]]; then -echo "Restricting the network to: ${NET_RESTRICTING}" - params="$params -netrestrict NET_RESTRICTING" + echo "Restricting the network to: ${NET_RESTRICTING}" + params="$params -netrestrict ${NET_RESTRICTING}" fi -# file to env for env in PRIVATE_KEY; do file=$(eval echo "\$${env}_FILE") if [[ -f $file ]] && [[ ! -z $file ]]; then @@ -24,30 +36,43 @@ for env in PRIVATE_KEY; do fi done -# private key +NODEKEY_FILE="${NODEKEY_FILE:-bootnode/bootnode.key}" if [[ ! -z "$PRIVATE_KEY" ]]; then - echo "$PRIVATE_KEY" > bootnode.key -elif [[ ! -f ./bootnode.key ]]; then - bootnode -genkey bootnode.key + echo "$PRIVATE_KEY" > "$NODEKEY_FILE" +elif [[ ! -f "${NODEKEY_FILE}" ]]; then + mkdir -p "$(dirname "${NODEKEY_FILE}")" + bootnode -genkey "$NODEKEY_FILE" fi -# listen port if [[ ! -z "$BOOTNODE_PORT" ]]; then - params="$params --addr :${BOOTNODE_PORT}" + params="$params -addr :${BOOTNODE_PORT}" else BOOTNODE_PORT=30301 - params="$params --addr :${BOOTNODE_PORT}" + params="$params -addr :${BOOTNODE_PORT}" fi -# dump address -address="enode://$(bootnode -nodekey bootnode.key -writeaddress)@$(hostname -i):${BOOTNODE_PORT}" -if [[ ! -z $EXTIP ]]; then - address="enode://$(bootnode -nodekey bootnode.key -writeaddress)@$EXTIP:${BOOTNODE_PORT}" +BOOTNODES_FILE="${BOOTNODES_FILE:-bootnode/bootnodes.list}" +if [[ -f "${BOOTNODES_FILE}" ]]; then + params="$params -bootnodesfile ${BOOTNODES_FILE}" fi -echo "🥾 Starting the bootnode with address at $address" -echo $address > ./bootnodes/bootnodes.list +if [[ ! -z $VERBOSITY ]]; then + params="$params -verbosity ${VERBOSITY}" +fi +host=$(hostname -i | awk '{print $1}') +if [[ -z "${DISABLE_EXTIP:-}" && -n "${EXTIP:-}" ]]; then + host=$EXTIP +fi +address="enode://$(bootnode -nodekey ${NODEKEY_FILE} -writeaddress)@${host}:${BOOTNODE_PORT}" +echo "Starting the bootnode with address at $address" +BOOTNODE_ENODE_OUT="${BOOTNODE_ENODE_OUT:-bootnode/bootnode.enode}" +echo $address > "$BOOTNODE_ENODE_OUT" +LOG_FILE="${LOG_FILE:-bootnode/bootnode.log}" +if [[ -n "$LOG_FILE" && "$LOG_FILE" != "-" ]]; then + touch "$LOG_FILE" + exec > >(tee -a "$LOG_FILE") 2>&1 +fi -exec bootnode "$@" $params +exec bootnode -nodekey "$NODEKEY_FILE" $params "$@"