Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: add optimistic geth client #514

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 53 additions & 0 deletions clients/opgeth/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# Docker container spec for building the master branch of go-ethereum.
#
# The build process it potentially longer running but every effort was made to
# produce a very minimalistic container that can be reused many times without
# needing to constantly rebuild.

ARG branch=latest
FROM javedop/opgeth:$branch

RUN apk add --update bash curl jq

# FROM alpine:latest
# ARG branch=master

# Build go-ethereum on the fly and delete all build tools afterwards
# RUN \
# apk add --update bash curl jq go git make gcc musl-dev \
# ca-certificates linux-headers && \
# git clone --depth 1 --branch $branch https://github.com/ethereum/go-ethereum && \
# (cd go-ethereum && make geth) && \
# (cd go-ethereum && \
# echo "{}" \
# | jq ".+ {\"repo\":\"$(git config --get remote.origin.url)\"}" \
# | jq ".+ {\"branch\":\"$(git rev-parse --abbrev-ref HEAD)\"}" \
# | jq ".+ {\"commit\":\"$(git rev-parse HEAD)\"}" \
# > /version.json) && \
# cp go-ethereum/build/bin/geth /geth && \
# apk del go git make gcc musl-dev linux-headers && \
# rm -rf /go-ethereum && rm -rf /var/cache/apk/*

RUN /usr/local/bin/geth console --exec 'console.log(admin.nodeInfo.name)' --maxpeers=0 --nodiscover --dev 2>/dev/null | head -1 > /version.txt

# Inject the startup script
ADD geth.sh /geth.sh
ADD mapper.jq /mapper.jq
RUN chmod +x /geth.sh

# Inject the enode id retriever script
RUN mkdir /hive-bin
ADD enode.sh /hive-bin/enode.sh
RUN chmod +x /hive-bin/enode.sh

ADD genesis.json /genesis.json

# Export the usual networking ports to allow outside access to the node
EXPOSE 8545 8546 8547 30303 30303/udp

# Generate the ethash verification caches
RUN \
/usr/local/bin/geth makecache 1 ~/.ethereum/geth/ethash && \
/usr/local/bin/geth makecache 30001 ~/.ethereum/geth/ethash

ENTRYPOINT ["/geth.sh"]
17 changes: 17 additions & 0 deletions clients/opgeth/enode.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#!/bin/bash

# Script to retrieve the enode
#
# This is copied into the validator container by Hive
# and used to provide a client-specific enode id retriever
#

# Immediately abort the script on any error encountered
set -e


TARGET_RESPONSE=$(curl -s -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"admin_nodeInfo","params":[],"id":1}' "localhost:8545" )


TARGET_ENODE=$(echo ${TARGET_RESPONSE}| jq -r '.result.enode')
echo "$TARGET_ENODE"
15 changes: 15 additions & 0 deletions clients/opgeth/genesis.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1",
"difficulty" : "0x020000",
"extraData" : "0x42",
"gasLimit" : "0x2fefd8",
"mixHash" : "0x2c85bcbce56429100b2108254bb56906257582aeafcbd682bc9af67a9f5aee46",
"nonce" : "0x78cc16f7b4f65485",
"parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
"timestamp" : "0x54c98c81",
"alloc" : {
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b": {
"balance" : "0x09184e72a000"
}
}
}
171 changes: 171 additions & 0 deletions clients/opgeth/geth.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
#!/bin/bash

# Startup script to initialize and boot a go-ethereum instance.
#
# This script assumes the following files:
# - `geth` binary is located in the filesystem root
# - `genesis.json` file is located in the filesystem root (mandatory)
# - `chain.rlp` file is located in the filesystem root (optional)
# - `blocks` folder is located in the filesystem root (optional)
# - `keys` folder is located in the filesystem root (optional)
#
# This script assumes the following environment variables:
#
# - HIVE_BOOTNODE enode URL of the remote bootstrap node
# - HIVE_NETWORK_ID network ID number to use for the eth protocol
# - HIVE_TESTNET whether testnet nonces (2^20) are needed
# - HIVE_NODETYPE sync and pruning selector (archive, full, light)
#
# Forks:
#
# - HIVE_FORK_HOMESTEAD block number of the homestead hard-fork transition
# - HIVE_FORK_DAO_BLOCK block number of the DAO hard-fork transition
# - HIVE_FORK_DAO_VOTE whether the node support (or opposes) the DAO fork
# - HIVE_FORK_TANGERINE block number of Tangerine Whistle transition
# - HIVE_FORK_SPURIOUS block number of Spurious Dragon transition
# - HIVE_FORK_BYZANTIUM block number for Byzantium transition
# - HIVE_FORK_CONSTANTINOPLE block number for Constantinople transition
# - HIVE_FORK_PETERSBURG block number for ConstantinopleFix/PetersBurg transition
# - HIVE_FORK_ISTANBUL block number for Istanbul transition
# - HIVE_FORK_MUIRGLACIER block number for Muir Glacier transition
# - HIVE_FORK_BERLIN block number for Berlin transition
# - HIVE_FORK_LONDON block number for London
#
# Clique PoA:
#
# - HIVE_CLIQUE_PERIOD enables clique support. value is block time in seconds.
# - HIVE_CLIQUE_PRIVATEKEY private key for clique mining
#
# Other:
#
# - HIVE_MINER enable mining. value is coinbase address.
# - HIVE_MINER_EXTRA extra-data field to set for newly minted blocks
# - HIVE_SKIP_POW if set, skip PoW verification during block import
# - HIVE_LOGLEVEL client loglevel (0-5)
# - HIVE_GRAPHQL_ENABLED enables graphql on port 8545
# - HIVE_LES_SERVER set to '1' to enable LES server

# Immediately abort the script on any error encountered
set -e

geth=/usr/local/bin/geth
FLAGS="--pcscdpath=\"\""

if [ "$HIVE_LOGLEVEL" != "" ]; then
FLAGS="$FLAGS --verbosity=$HIVE_LOGLEVEL"
fi

# It doesn't make sense to dial out, use only a pre-set bootnode.
FLAGS="$FLAGS --bootnodes=$HIVE_BOOTNODE"

if [ "$HIVE_SKIP_POW" != "" ]; then
FLAGS="$FLAGS --fakepow"
fi

# If a specific network ID is requested, use that
if [ "$HIVE_NETWORK_ID" != "" ]; then
FLAGS="$FLAGS --networkid $HIVE_NETWORK_ID"
else
# Unless otherwise specified by hive, we try to avoid mainnet networkid. If geth detects mainnet network id,
# then it tries to bump memory quite a lot
FLAGS="$FLAGS --networkid 1337"
fi

# If the client is to be run in testnet mode, flag it as such
if [ "$HIVE_TESTNET" == "1" ]; then
FLAGS="$FLAGS --testnet"
fi

# Handle any client mode or operation requests
if [ "$HIVE_NODETYPE" == "archive" ]; then
FLAGS="$FLAGS --syncmode full --gcmode archive"
fi
if [ "$HIVE_NODETYPE" == "full" ]; then
FLAGS="$FLAGS --syncmode snap"
fi
if [ "$HIVE_NODETYPE" == "light" ]; then
FLAGS="$FLAGS --syncmode light"
fi

# Configure the chain.
mv /genesis.json /genesis-input.json
jq -f /mapper.jq /genesis-input.json > /genesis.json

# Dump genesis
echo "Supplied genesis state:"
cat /genesis.json

# Initialize the local testchain with the genesis state
echo "Initializing database with genesis state..."
$geth $FLAGS init /genesis.json

# Don't immediately abort, some imports are meant to fail
set +e

# Load the test chain if present
echo "Loading initial blockchain..."
if [ -f /chain.rlp ]; then
$geth $FLAGS --gcmode=archive import /chain.rlp
else
echo "Warning: chain.rlp not found."
fi

# Load the remainder of the test chain
echo "Loading remaining individual blocks..."
if [ -d /blocks ]; then
(cd /blocks && $geth $FLAGS --gcmode=archive --verbosity=$HIVE_LOGLEVEL --nocompaction import `ls | sort -n`)
else
echo "Warning: blocks folder not found."
fi

set -e

# Import clique signing key.
if [ "$HIVE_CLIQUE_PRIVATEKEY" != "" ]; then
# Create password file.
echo "Importing clique key..."
echo "secret" > /geth-password-file.txt
$geth --nousb account import --password /geth-password-file.txt <(echo "$HIVE_CLIQUE_PRIVATEKEY")

# Ensure password file is used when running geth in mining mode.
if [ "$HIVE_MINER" != "" ]; then
FLAGS="$FLAGS --password /geth-password-file.txt --unlock $HIVE_MINER --allow-insecure-unlock"
fi
fi

# Configure any mining operation
if [ "$HIVE_MINER" != "" ] && [ "$HIVE_NODETYPE" != "light" ]; then
FLAGS="$FLAGS --mine --miner.threads 1 --miner.etherbase $HIVE_MINER"
fi
if [ "$HIVE_MINER_EXTRA" != "" ]; then
FLAGS="$FLAGS --miner.extradata $HIVE_MINER_EXTRA"
fi
FLAGS="$FLAGS --miner.gasprice 16000000000"

# Configure LES.
if [ "$HIVE_LES_SERVER" == "1" ]; then
FLAGS="$FLAGS --light.serve 50 --light.nosyncserve"
fi

# Configure RPC.
FLAGS="$FLAGS --http --http.addr=0.0.0.0 --http.port=8545 --http.api=admin,debug,eth,miner,net,personal,txpool,web3"
FLAGS="$FLAGS --ws --ws.addr=0.0.0.0 --ws.origins \"*\" --ws.api=admin,debug,eth,miner,net,personal,txpool,web3"

if [ "$HIVE_TERMINAL_TOTAL_DIFFICULTY" != "" ]; then
echo "0x7365637265747365637265747365637265747365637265747365637265747365" > /jwtsecret
FLAGS="$FLAGS --authrpc.host=0.0.0.0 --authrpc.port=8550 --authrpc.jwtsecret /jwtsecret"
fi

# Configure GraphQL.
if [ "$HIVE_GRAPHQL_ENABLED" != "" ]; then
FLAGS="$FLAGS --graphql"
fi
# used for the graphql to allow submission of unprotected tx
if [ "$HIVE_ALLOW_UNPROTECTED_TX" != "" ]; then
FLAGS="$FLAGS --rpc.allow-unprotected-txs"
fi

# Run the go-ethereum implementation with the requested flags.
FLAGS="$FLAGS --nat=none"
echo "Running go-ethereum with flags $FLAGS"
$geth $FLAGS
4 changes: 4 additions & 0 deletions clients/opgeth/hive.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
roles:
- "eth1"
- "eth1_les_client"
- "eth1_les_server"
56 changes: 56 additions & 0 deletions clients/opgeth/mapper.jq
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Removes all empty keys and values in input.
def remove_empty:
. | walk(
if type == "object" then
with_entries(
select(
.value != null and
.value != "" and
.value != [] and
.key != null and
.key != ""
)
)
else .
end
)
;

# Converts decimal string to number.
def to_int:
if . == null then . else .|tonumber end
;

# Converts "1" / "0" to boolean.
def to_bool:
if . == null then . else
if . == "1" then true else false end
end
;

# Replace config in input.
. + {
"config": {
"ethash": (if env.HIVE_CLIQUE_PERIOD then null else {} end),
"clique": (if env.HIVE_CLIQUE_PERIOD == null then null else {
"period": env.HIVE_CLIQUE_PERIOD|to_int,
} end),
"chainId": env.HIVE_CHAIN_ID|to_int,
"homesteadBlock": env.HIVE_FORK_HOMESTEAD|to_int,
"daoForkBlock": env.HIVE_FORK_DAO_BLOCK|to_int,
"daoForkSupport": env.HIVE_FORK_DAO_VOTE|to_bool,
"eip150Block": env.HIVE_FORK_TANGERINE|to_int,
"eip150Hash": env.HIVE_FORK_TANGERINE_HASH,
"eip155Block": env.HIVE_FORK_SPURIOUS|to_int,
"eip158Block": env.HIVE_FORK_SPURIOUS|to_int,
"byzantiumBlock": env.HIVE_FORK_BYZANTIUM|to_int,
"constantinopleBlock": env.HIVE_FORK_CONSTANTINOPLE|to_int,
"petersburgBlock": env.HIVE_FORK_PETERSBURG|to_int,
"istanbulBlock": env.HIVE_FORK_ISTANBUL|to_int,
"muirGlacierBlock": env.HIVE_FORK_MUIR_GLACIER|to_int,
"berlinBlock": env.HIVE_FORK_BERLIN|to_int,
"yolov2Block": env.HIVE_FORK_BERLIN|to_int,
"yolov3Block": env.HIVE_FORK_BERLIN|to_int,
"londonBlock": env.HIVE_FORK_LONDON|to_int,
}|remove_empty
}