Skip to content

Commit

Permalink
devp2p: add IP filter and ronin mainnet/testnet filter for nodeset fi…
Browse files Browse the repository at this point in the history
…lter (#343)

* devp2p: add IP filter and ronin mainnet/testnet filter for nodeset filter

This commit adds IP or-filter, updates the ronin mainnet and testnet
configuration that are used for nodeset filter. This also allows DNS sign to use
password file instead of entering via prompt.

* script: add script to generate DNS TXT record from list of nodes
  • Loading branch information
minh-bq authored Aug 29, 2023
1 parent 6e45232 commit 16ee23b
Show file tree
Hide file tree
Showing 4 changed files with 189 additions and 9 deletions.
30 changes: 23 additions & 7 deletions cmd/devp2p/dnscmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"io/ioutil"
"os"
"path/filepath"
"strings"
"time"

"github.com/ethereum/go-ethereum/accounts/keystore"
Expand Down Expand Up @@ -151,10 +152,11 @@ func dnsSign(ctx *cli.Context) error {
return fmt.Errorf("need tree definition directory and key file as arguments")
}
var (
defdir = ctx.Args().Get(0)
keyfile = ctx.Args().Get(1)
def = loadTreeDefinition(defdir)
domain = directoryName(defdir)
defdir = ctx.Args().Get(0)
keyfile = ctx.Args().Get(1)
def = loadTreeDefinition(defdir)
domain = directoryName(defdir)
passwordfile string
)
if def.Meta.URL != "" {
d, _, err := dnsdisc.ParseURL(def.Meta.URL)
Expand All @@ -176,7 +178,10 @@ func dnsSign(ctx *cli.Context) error {
return err
}

key := loadSigningKey(keyfile)
if ctx.NArg() == 3 {
passwordfile = ctx.Args().Get(2)
}
key := loadSigningKey(keyfile, passwordfile)
url, err := t.Sign(key, domain)
if err != nil {
return fmt.Errorf("can't sign: %v", err)
Expand Down Expand Up @@ -252,12 +257,23 @@ func dnsNukeRoute53(ctx *cli.Context) error {
}

// loadSigningKey loads a private key in Ethereum keystore format.
func loadSigningKey(keyfile string) *ecdsa.PrivateKey {
func loadSigningKey(keyfile, passwordfile string) *ecdsa.PrivateKey {
keyjson, err := ioutil.ReadFile(keyfile)
if err != nil {
exit(fmt.Errorf("failed to read the keyfile at '%s': %v", keyfile, err))
}
password, _ := prompt.Stdin.PromptPassword("Please enter the password for '" + keyfile + "': ")

var password string
if passwordfile != "" {
rawPassword, err := ioutil.ReadFile(passwordfile)
if err != nil {
exit(fmt.Errorf("failed to read the passwordfile at '%s': %v", passwordfile, err))
}
password = strings.TrimRight(string(rawPassword), "\r\n")
} else {
password, _ = prompt.Stdin.PromptPassword("Please enter the password for '" + keyfile + "': ")
}

key, err := keystore.DecryptKey(keyjson, password)
if err != nil {
exit(fmt.Errorf("error decrypting key: %v", err))
Expand Down
24 changes: 24 additions & 0 deletions cmd/devp2p/nodesetcmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ type nodeFilterC struct {
var filterFlags = map[string]nodeFilterC{
"-limit": {1, trueFilter}, // needed to skip over -limit
"-ip": {1, ipFilter},
"-ip-list": {1, ipListFilter},
"-min-age": {1, minAgeFilter},
"-eth-network": {1, ethFilter},
"-les-server": {0, lesFilter},
Expand Down Expand Up @@ -212,6 +213,25 @@ func ipFilter(args []string) (nodeFilter, error) {
return f, nil
}

func ipListFilter(args []string) (nodeFilter, error) {
rawIpList := strings.Split(args[0], ",")
var ipList []net.IP
for _, rawIp := range rawIpList {
ip := net.ParseIP(rawIp)
ipList = append(ipList, ip)
}

f := func(n nodeJSON) bool {
for _, ip := range ipList {
if ip.Equal(n.N.IP()) {
return true
}
}
return false
}
return f, nil
}

func minAgeFilter(args []string) (nodeFilter, error) {
minage, err := time.ParseDuration(args[0])
if err != nil {
Expand All @@ -237,6 +257,10 @@ func ethFilter(args []string) (nodeFilter, error) {
filter = forkid.NewStaticFilter(params.RopstenChainConfig, params.RopstenGenesisHash)
case "sepolia":
filter = forkid.NewStaticFilter(params.SepoliaChainConfig, params.SepoliaGenesisHash)
case "ronin-mainnet":
filter = forkid.NewStaticFilter(params.RoninMainnetChainConfig, params.RoninMainnetGenesisHash)
case "ronin-testnet":
filter = forkid.NewStaticFilter(params.RoninTestnetChainConfig, params.RoninTestnetGenesisHash)
default:
return nil, fmt.Errorf("unknown network %q", args[0])
}
Expand Down
54 changes: 52 additions & 2 deletions params/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ var (
RinkebyGenesisHash = common.HexToHash("0x6341fd3daf94b748c72ced5a5b26028f2474f5f00d824504e4fa37a75767e177")
GoerliGenesisHash = common.HexToHash("0xbf7e331f7f7c1dd2e05159666b3bf8bc7a8a3a9eb1d518969eab529dd9b88c1a")
RoninMainnetGenesisHash = common.HexToHash("0x6e675ee97607f4e695188786c3c1853fb1562f1c075629eb5dbcff269422a1a4")
RoninTestnetGenesisHash = common.HexToHash("0x13e47595099383189b8b0d5f3b67aa161495e478bb3fea64f4cf85cdf69cac4d")
)

// TrustedCheckpoints associates each known checkpoint with the genesis hash of
Expand Down Expand Up @@ -235,6 +236,9 @@ var (

RoninMainnetBlacklistContract = common.HexToAddress("0x313b24994c93FA0471CB4D7aB796b07467041806")
RoninMainnetFenixValidatorContractAddress = common.HexToAddress("0x7f13232Bdc3a010c3f749a1c25bF99f1C053CE70")
RoninMainnetRoninValidatorSetAddress = common.HexToAddress("0x617c5d73662282EA7FfD231E020eCa6D2B0D552f")
RoninMainnetSlashIndicatorAddress = common.HexToAddress("0xEBFFF2b32fA0dF9C5C8C5d5AAa7e8b51d5207bA3")
RoninMainnetStakingContractAddress = common.HexToAddress("0x545edb750eB8769C868429BE9586F5857A768758")

RoninMainnetChainConfig = &ChainConfig{
ChainID: big.NewInt(2020),
Expand All @@ -251,9 +255,55 @@ var (
BlacklistContractAddress: &RoninMainnetBlacklistContract,
FenixValidatorContractAddress: &RoninMainnetFenixValidatorContractAddress,
Consortium: &ConsortiumConfig{
Period: 3,
Epoch: 600,
Period: 3,
Epoch: 600,
EpochV2: 200,
},
ConsortiumV2Contracts: &ConsortiumV2Contracts{
RoninValidatorSet: RoninMainnetRoninValidatorSetAddress,
SlashIndicator: RoninMainnetSlashIndicatorAddress,
StakingContract: RoninMainnetStakingContractAddress,
},
ConsortiumV2Block: big.NewInt(23155200),
PuffyBlock: big.NewInt(0),
BubaBlock: big.NewInt(0),
OlekBlock: big.NewInt(24935500),
}

RoninTestnetBlacklistContract = common.HexToAddress("0xF53EED5210c9cF308abFe66bA7CF14884c95A8aC")
RoninTestnetFenixValidatorContractAddress = common.HexToAddress("0x1454cAAd1637b662432Bb795cD5773d21281eDAb")
RoninTestnetRoninValidatorSetAddress = common.HexToAddress("0x54B3AC74a90E64E8dDE60671b6fE8F8DDf18eC9d")
RoninTestnetSlashIndicatorAddress = common.HexToAddress("0xF7837778b6E180Df6696C8Fa986d62f8b6186752")
RoninTestnetStakingContractAddress = common.HexToAddress("0x9C245671791834daf3885533D24dce516B763B28")

RoninTestnetChainConfig = &ChainConfig{
ChainID: big.NewInt(2021),
HomesteadBlock: big.NewInt(0),
EIP150Block: big.NewInt(0),
EIP155Block: big.NewInt(0),
EIP158Block: big.NewInt(0),
ByzantiumBlock: big.NewInt(0),
ConstantinopleBlock: big.NewInt(0),
PetersburgBlock: big.NewInt(0),
IstanbulBlock: big.NewInt(0),
OdysseusBlock: big.NewInt(3315095),
FenixBlock: big.NewInt(6770400),
BlacklistContractAddress: &RoninTestnetBlacklistContract,
FenixValidatorContractAddress: &RoninTestnetFenixValidatorContractAddress,
Consortium: &ConsortiumConfig{
Period: 3,
Epoch: 30,
EpochV2: 200,
},
ConsortiumV2Contracts: &ConsortiumV2Contracts{
RoninValidatorSet: RoninTestnetRoninValidatorSetAddress,
SlashIndicator: RoninTestnetSlashIndicatorAddress,
StakingContract: RoninTestnetStakingContractAddress,
},
ConsortiumV2Block: big.NewInt(11706000),
PuffyBlock: big.NewInt(12254000),
BubaBlock: big.NewInt(14260600),
OlekBlock: big.NewInt(16849000),
}

// GoerliTrustedCheckpoint contains the light client trusted checkpoint for the Görli test network.
Expand Down
90 changes: 90 additions & 0 deletions script/gen_dns_txt.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
#!/bin/bash

# Create the DNS TXT record from the list of nodes

unset BOOTNODES
unset NETWORK
unset DOMAIN
unset IP_LIST
PROGNAME=$(basename "$0")

USAGE="$PROGNAME -b bootnodes -n network -d domain [-i ip_list]
where:
bootnodes: list of bootnodes to crawl from (comma separated)
network: ronin-mainnet | ronin-testnet to choose the network
domain: the DNS domain name
ip_list: the list of IPs to include in ENR tree (comma separated)
"

set -e

while getopts :hb:n:d:i: option; do
case $option in
h)
echo "$USAGE"
exit 0
;;
b) BOOTNODES=$OPTARG ;;
n) NETWORK=$OPTARG ;;
d) DOMAIN=$OPTARG ;;
i) IP_LIST=$OPTARG ;;
:)
echo "$PROGNAME: option requires an argument -- '$OPTARG'" >&2
exit 1
;;
*)
echo "$PROGNAME: bad option -$OPTARG" >&2
echo "Try '$PROGNAME -h' for more information" >&2
exit 1
;;
esac
done
shift $((OPTIND - 1))

if [[ -z $BOOTNODES || -z $NETWORK || -z $DOMAIN ]]; then
echo "$PROGNAME: missing mandatory option" >&2
echo "Try '$(basename "$0") -h' for more information" >&2
exit 1
fi

DNS_DIR=dns_record

if [[ -z $PRIVATE_KEY ]]; then
echo "The PRIVATE_KEY environment for signing DNS record must be provided"
exit 1
fi

if [[ -z $PASSWORD ]]; then
echo "The PASSWORD environment for decrypting the private key must be provided"
exit 1
fi

echo "$PASSWORD" > password
echo "$PRIVATE_KEY" > private_key
unset PASSWORD
unset PRIVATE_KEY

set -x
# Create an encrypted keyfile.json
ethkey generate --passwordfile password --privatekey private_key

devp2p discv4 crawl --timeout 1m --bootnodes $BOOTNODES all_nodes.json

mkdir -p $DNS_DIR

set +x
IP_LIST_PARAMS=""
if [[ ! -z $IP_LIST ]]; then
IP_LIST_PARAMS="-ip-list $IP_LIST"
fi
set -x

devp2p nodeset filter all_nodes.json -eth-network $NETWORK $IP_LIST_PARAMS > $DNS_DIR/nodes.json
devp2p dns sign $DNS_DIR keyfile.json password --domain $DOMAIN
devp2p dns to-txt $DNS_DIR $DNS_DIR/txt_record.json

echo "Cleanup files"
rm private_key
rm password
rm keyfile.json

0 comments on commit 16ee23b

Please sign in to comment.