mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-11 23:44:27 +00:00
Merge pull request #1280 from XinFinOrg/XDPoSv2-privatenet-improve-genesis
Improve genesis for easy privatechain deployment
This commit is contained in:
commit
1f6bd2bae5
11 changed files with 373 additions and 160 deletions
|
|
@ -5,6 +5,9 @@ ENV GODEBUG=randseednop=0
|
||||||
RUN apk add make build-base linux-headers
|
RUN apk add make build-base linux-headers
|
||||||
|
|
||||||
COPY . /builder
|
COPY . /builder
|
||||||
|
|
||||||
|
RUN cd /builder && make puppeth
|
||||||
|
|
||||||
RUN cd /builder && make && mv /builder/build/bin/XDC /builder/build/bin/XDC-mainnet
|
RUN cd /builder && make && mv /builder/build/bin/XDC /builder/build/bin/XDC-mainnet
|
||||||
|
|
||||||
RUN mv /builder/common/constants/constants.go.testnet /builder/common/constants.go
|
RUN mv /builder/common/constants/constants.go.testnet /builder/common/constants.go
|
||||||
|
|
@ -23,6 +26,7 @@ WORKDIR /work
|
||||||
|
|
||||||
RUN apk add --no-cache bash curl
|
RUN apk add --no-cache bash curl
|
||||||
|
|
||||||
|
COPY --from=builder /builder/build/bin/puppeth /usr/bin
|
||||||
COPY --from=builder /builder/build/bin/XDC-local /usr/bin
|
COPY --from=builder /builder/build/bin/XDC-local /usr/bin
|
||||||
COPY --from=builder /builder/build/bin/XDC-devnet /usr/bin
|
COPY --from=builder /builder/build/bin/XDC-devnet /usr/bin
|
||||||
COPY --from=builder /builder/build/bin/XDC-testnet /usr/bin
|
COPY --from=builder /builder/build/bin/XDC-testnet /usr/bin
|
||||||
|
|
@ -33,7 +37,8 @@ ADD cicd/local /work/local
|
||||||
ADD cicd/devnet /work/devnet
|
ADD cicd/devnet /work/devnet
|
||||||
ADD cicd/testnet /work/testnet
|
ADD cicd/testnet /work/testnet
|
||||||
ADD cicd/mainnet /work/mainnet
|
ADD cicd/mainnet /work/mainnet
|
||||||
ADD cicd/entry.sh /work/
|
ADD cicd/entry.sh /work/entry.sh
|
||||||
|
ADD cicd/puppeth.sh /work/puppeth.sh
|
||||||
|
|
||||||
# Create an empty pwd file
|
# Create an empty pwd file
|
||||||
RUN touch /work/.pwd
|
RUN touch /work/.pwd
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,4 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
set -eo pipefail
|
|
||||||
|
|
||||||
if [ ! -d /work/xdcchain/XDC/chaindata ]
|
if [ ! -d /work/xdcchain/XDC/chaindata ]
|
||||||
then
|
then
|
||||||
if test -z "$PRIVATE_KEY"
|
if test -z "$PRIVATE_KEY"
|
||||||
|
|
@ -27,41 +25,87 @@ do
|
||||||
fi
|
fi
|
||||||
done < "$input"
|
done < "$input"
|
||||||
|
|
||||||
log_level="${LOG_LEVEL:-3}"
|
log_level=3
|
||||||
|
if test -z "$LOG_LEVEL"
|
||||||
|
then
|
||||||
|
echo "Log level not set, default to verbosity of $log_level"
|
||||||
|
else
|
||||||
|
echo "Log level found, set to $LOG_LEVEL"
|
||||||
|
log_level=$LOG_LEVEL
|
||||||
|
fi
|
||||||
|
|
||||||
port="${PORT:-30303}"
|
port=30303
|
||||||
|
if test -z "$PORT"
|
||||||
|
then
|
||||||
|
echo "PORT not set, default to $port"
|
||||||
|
else
|
||||||
|
echo "PORT found, set to $PORT"
|
||||||
|
port=$PORT
|
||||||
|
fi
|
||||||
|
|
||||||
rpc_port="${RPC_PORT:-8545}"
|
rpc_port=8545
|
||||||
|
if test -z "$RPC_PORT"
|
||||||
|
then
|
||||||
|
echo "RPC_PORT not set, default to $rpc_port"
|
||||||
|
else
|
||||||
|
echo "RPC_PORT found, set to $RPC_PORT"
|
||||||
|
rpc_port=$RPC_PORT
|
||||||
|
fi
|
||||||
|
|
||||||
ws_port="${WS_PORT:-8555}"
|
ws_port=8555
|
||||||
|
if test -z "$WS_PORT"
|
||||||
|
then
|
||||||
|
echo "WS_PORT not set, default to $ws_port"
|
||||||
|
else
|
||||||
|
echo "WS_PORT found, set to $WS_PORT"
|
||||||
|
ws_port=$WS_PORT
|
||||||
|
fi
|
||||||
|
|
||||||
netstats="${NODE_NAME}-${wallet}:xinfin_xdpos_hybrid_network_stats@devnetstats.apothem.network:2000"
|
instance_ip=$(ifconfig eth0 | awk '/inet addr:/ {print $2}' | cut -d: -f2)
|
||||||
|
if test -z "$INSTANCE_IP"
|
||||||
|
then
|
||||||
|
echo "INSTANCE_IP not set, default to $instance_ip"
|
||||||
|
else
|
||||||
|
echo "INSTANCE_IP found, set to $INSTANCE_IP"
|
||||||
|
instance_ip=$INSTANCE_IP
|
||||||
|
fi
|
||||||
|
|
||||||
|
sync_mode=full
|
||||||
|
if test -z "$SYNC_MODE"
|
||||||
|
then
|
||||||
|
echo "SYNC_MODE not set, default to full" #full or fast
|
||||||
|
else
|
||||||
|
echo "SYNC_MODE found, set to $SYNC_MODE"
|
||||||
|
sync_mode=$SYNC_MODE
|
||||||
|
fi
|
||||||
|
|
||||||
|
gc_mode=archive
|
||||||
|
if test -z "$GC_MODE"
|
||||||
|
then
|
||||||
|
echo "GC_MODE not set, default to archive" #full or archive
|
||||||
|
else
|
||||||
|
echo "GC_MODE found, set to $GC_MODE"
|
||||||
|
gc_mode=$GC_MODE
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
echo "Running a node with wallet: ${wallet}"
|
echo "Running a node with wallet: ${wallet} at IP: ${instance_ip}"
|
||||||
echo "Starting nodes with $bootnodes ..."
|
echo "Starting nodes with $bootnodes ..."
|
||||||
|
|
||||||
# Note: --gcmode=archive means node will store all historical data. This will lead to high memory usage. But sync mode require archive to sync
|
# Note: --gcmode=archive means node will store all historical data. This will lead to high memory usage. But sync mode require archive to sync
|
||||||
# https://github.com/XinFinOrg/XDPoSChain/issues/268
|
# https://github.com/XinFinOrg/XDPoSChain/issues/268
|
||||||
|
|
||||||
XDC --ethstats ${netstats} \
|
XDC \
|
||||||
--gcmode archive \
|
--gcmode ${gc_mode} --syncmode ${sync_mode} \
|
||||||
|
--nat extip:${instance_ip} \
|
||||||
--bootnodes ${bootnodes} \
|
--bootnodes ${bootnodes} \
|
||||||
--syncmode full \
|
|
||||||
--datadir /work/xdcchain \
|
--datadir /work/xdcchain \
|
||||||
--networkid 551 \
|
--port $port --http --http-corsdomain "*" --http-addr 0.0.0.0 \
|
||||||
-port $port \
|
--http-port $rpc_port \
|
||||||
--rpc --rpccorsdomain "*" \
|
--http-api db,eth,net,txpool,web3,XDPoS \
|
||||||
--rpcaddr 0.0.0.0 \
|
--http-vhosts "*" --unlock "${wallet}" --password /work/.pwd --mine \
|
||||||
--rpcport $rpc_port \
|
--miner-gasprice "1" --miner-gaslimit "50000000" --verbosity ${log_level} \
|
||||||
--rpcapi db,eth,debug,net,shh,txpool,personal,web3,XDPoS \
|
|
||||||
--rpcvhosts "*" \
|
|
||||||
--unlock "${wallet}" \
|
|
||||||
--password /work/.pwd --mine \
|
|
||||||
--gasprice "1" --targetgaslimit "420000000" \
|
|
||||||
--verbosity ${log_level} \
|
|
||||||
--debugdatadir /work/xdcchain \
|
--debugdatadir /work/xdcchain \
|
||||||
--ws \
|
--store-reward \
|
||||||
--wsaddr=0.0.0.0 \
|
--ws --ws-addr=0.0.0.0 --ws-port $ws_port \
|
||||||
--wsport $ws_port \
|
--ws-origins "*" 2>&1 >>/work/xdcchain/xdc.log | tee -a /work/xdcchain/xdc.log
|
||||||
--wsorigins "*" 2>&1 >>/work/xdcchain/xdc.log | tee -a /work/xdcchain/xdc.log
|
|
||||||
|
|
|
||||||
2
cicd/puppeth.sh
Executable file
2
cicd/puppeth.sh
Executable file
|
|
@ -0,0 +1,2 @@
|
||||||
|
#!/bin/bash
|
||||||
|
puppeth --inpath /app/generated/genesis_input.yml --outpath /app/generated/genesis.json
|
||||||
|
|
@ -42,6 +42,16 @@ func main() {
|
||||||
Value: 3,
|
Value: 3,
|
||||||
Usage: "log level to emit to the screen",
|
Usage: "log level to emit to the screen",
|
||||||
},
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "outpath",
|
||||||
|
Value: "",
|
||||||
|
Usage: "output genesis file path",
|
||||||
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "inpath",
|
||||||
|
Value: "",
|
||||||
|
Usage: "input file to generate genesis file (optional)",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
app.Action = func(c *cli.Context) error {
|
app.Action = func(c *cli.Context) error {
|
||||||
// Set up the logger to print everything and the random generator
|
// Set up the logger to print everything and the random generator
|
||||||
|
|
@ -53,7 +63,7 @@ func main() {
|
||||||
log.Crit("No spaces or hyphens allowed in network name")
|
log.Crit("No spaces or hyphens allowed in network name")
|
||||||
}
|
}
|
||||||
// Start the wizard and relinquish control
|
// Start the wizard and relinquish control
|
||||||
makeWizard(c.String("network")).run()
|
makeWizard(c.String("network"), c.String("inpath"), c.String("outpath")).run()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
app.Run(os.Args)
|
app.Run(os.Args)
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,8 @@ import (
|
||||||
// config contains all the configurations needed by puppeth that should be saved
|
// config contains all the configurations needed by puppeth that should be saved
|
||||||
// between sessions.
|
// between sessions.
|
||||||
type config struct {
|
type config struct {
|
||||||
path string // File containing the configuration values
|
path string // Output file containing the configuration values
|
||||||
|
inpath string // Input file to read genesis generation parameters (optional)
|
||||||
bootnodes []string // Bootnodes to always connect to by all nodes
|
bootnodes []string // Bootnodes to always connect to by all nodes
|
||||||
ethstats string // Ethstats settings to cache for node deploys
|
ethstats string // Ethstats settings to cache for node deploys
|
||||||
|
|
||||||
|
|
@ -62,6 +63,7 @@ func (c config) flush() {
|
||||||
os.MkdirAll(filepath.Dir(c.path), 0755)
|
os.MkdirAll(filepath.Dir(c.path), 0755)
|
||||||
|
|
||||||
out, _ := json.MarshalIndent(c.Genesis, "", " ")
|
out, _ := json.MarshalIndent(c.Genesis, "", " ")
|
||||||
|
log.Warn("writing to file", "filename", c.path)
|
||||||
if err := os.WriteFile(c.path, out, 0644); err != nil {
|
if err := os.WriteFile(c.path, out, 0644); err != nil {
|
||||||
log.Warn("Failed to save puppeth configs", "file", c.path, "err", err)
|
log.Warn("Failed to save puppeth configs", "file", c.path, "err", err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@ import (
|
||||||
"github.com/XinFinOrg/XDPoSChain/core/types"
|
"github.com/XinFinOrg/XDPoSChain/core/types"
|
||||||
"github.com/XinFinOrg/XDPoSChain/log"
|
"github.com/XinFinOrg/XDPoSChain/log"
|
||||||
"github.com/XinFinOrg/XDPoSChain/params"
|
"github.com/XinFinOrg/XDPoSChain/params"
|
||||||
|
"gopkg.in/yaml.v3"
|
||||||
|
|
||||||
"context"
|
"context"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
@ -40,9 +41,68 @@ import (
|
||||||
randomizeContract "github.com/XinFinOrg/XDPoSChain/contracts/randomize"
|
randomizeContract "github.com/XinFinOrg/XDPoSChain/contracts/randomize"
|
||||||
validatorContract "github.com/XinFinOrg/XDPoSChain/contracts/validator"
|
validatorContract "github.com/XinFinOrg/XDPoSChain/contracts/validator"
|
||||||
"github.com/XinFinOrg/XDPoSChain/crypto"
|
"github.com/XinFinOrg/XDPoSChain/crypto"
|
||||||
"github.com/XinFinOrg/XDPoSChain/rlp"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type GenesisInput struct {
|
||||||
|
Name string
|
||||||
|
ChainId uint64
|
||||||
|
Denom string
|
||||||
|
Period uint64
|
||||||
|
Epoch uint64
|
||||||
|
Gap uint64
|
||||||
|
TimeoutPeriod int
|
||||||
|
TimeoutSyncThreshold int
|
||||||
|
V2SwitchBlock uint64
|
||||||
|
CertThreshold float64
|
||||||
|
MasternodesOwner common.Address
|
||||||
|
Masternodes []common.Address
|
||||||
|
StakingThreshold uint64
|
||||||
|
RewardYield uint64
|
||||||
|
FoundationWalletAddress common.Address
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewGenesisInput() *GenesisInput {
|
||||||
|
return &GenesisInput{
|
||||||
|
Name: "xdc-custom-network",
|
||||||
|
ChainId: 5551,
|
||||||
|
Denom: "xdc",
|
||||||
|
Period: 2,
|
||||||
|
Epoch: 900,
|
||||||
|
Gap: 450,
|
||||||
|
TimeoutPeriod: 10,
|
||||||
|
TimeoutSyncThreshold: 3,
|
||||||
|
V2SwitchBlock: 0,
|
||||||
|
CertThreshold: 0.667,
|
||||||
|
StakingThreshold: 10_000_000, // 10M
|
||||||
|
RewardYield: 10,
|
||||||
|
FoundationWalletAddress: common.FoudationAddrBinary,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *wizard) loadGenesisInput() *GenesisInput {
|
||||||
|
input := NewGenesisInput()
|
||||||
|
file, err := os.Open(w.conf.inpath)
|
||||||
|
if err != nil {
|
||||||
|
log.Warn("Failed to open genesis input file", "err", err)
|
||||||
|
os.Exit(1)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
log.Warn("Decoding genesis input file", "path", w.conf.inpath)
|
||||||
|
log.Warn("File content", "file", file)
|
||||||
|
decoder := yaml.NewDecoder(file)
|
||||||
|
if err := decoder.Decode(&input); err != nil {
|
||||||
|
log.Warn("Failed to decode genesis input file (expect yaml format)", "err", err)
|
||||||
|
os.Exit(1)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
fmt.Println("Generating genesis file with the below input")
|
||||||
|
fmt.Printf("%+v\n", input)
|
||||||
|
|
||||||
|
return input
|
||||||
|
}
|
||||||
|
|
||||||
// makeGenesis creates a new genesis struct based on some user input.
|
// makeGenesis creates a new genesis struct based on some user input.
|
||||||
func (w *wizard) makeGenesis() {
|
func (w *wizard) makeGenesis() {
|
||||||
// Construct a default genesis block
|
// Construct a default genesis block
|
||||||
|
|
@ -66,7 +126,13 @@ func (w *wizard) makeGenesis() {
|
||||||
fmt.Println(" 2. Clique - proof-of-authority")
|
fmt.Println(" 2. Clique - proof-of-authority")
|
||||||
fmt.Println(" 3. XDPoS - delegated-proof-of-stake")
|
fmt.Println(" 3. XDPoS - delegated-proof-of-stake")
|
||||||
|
|
||||||
choice := w.read()
|
input := w.loadGenesisInput()
|
||||||
|
var choice string
|
||||||
|
if input != nil {
|
||||||
|
choice = "3"
|
||||||
|
} else {
|
||||||
|
choice = w.read()
|
||||||
|
}
|
||||||
switch {
|
switch {
|
||||||
case choice == "1":
|
case choice == "1":
|
||||||
// In case of ethash, we're pretty much done
|
// In case of ethash, we're pretty much done
|
||||||
|
|
@ -125,48 +191,83 @@ func (w *wizard) makeGenesis() {
|
||||||
}
|
}
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
fmt.Println("How many seconds should blocks take? (default = 2)")
|
fmt.Println("How many seconds should blocks take? (default = 2)")
|
||||||
genesis.Config.XDPoS.Period = uint64(w.readDefaultInt(2))
|
if input != nil {
|
||||||
|
genesis.Config.XDPoS.Period = input.Period
|
||||||
|
} else {
|
||||||
|
genesis.Config.XDPoS.Period = uint64(w.readDefaultInt(2))
|
||||||
|
}
|
||||||
genesis.Config.XDPoS.V2.CurrentConfig.MinePeriod = int(genesis.Config.XDPoS.Period)
|
genesis.Config.XDPoS.V2.CurrentConfig.MinePeriod = int(genesis.Config.XDPoS.Period)
|
||||||
|
|
||||||
fmt.Println()
|
|
||||||
fmt.Println("How many Ethers should be rewarded to masternode? (default = 10)")
|
|
||||||
genesis.Config.XDPoS.Reward = uint64(w.readDefaultInt(10))
|
|
||||||
|
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
fmt.Println("Which block number start v2 consesus? (default = 0)")
|
fmt.Println("Which block number start v2 consesus? (default = 0)")
|
||||||
genesis.Config.XDPoS.V2.SwitchBlock = w.readDefaultBigInt(genesis.Config.XDPoS.V2.SwitchBlock)
|
if input != nil {
|
||||||
|
genesis.Config.XDPoS.V2.SwitchBlock = big.NewInt(int64(input.V2SwitchBlock))
|
||||||
|
} else {
|
||||||
|
genesis.Config.XDPoS.V2.SwitchBlock = w.readDefaultBigInt(genesis.Config.XDPoS.V2.SwitchBlock)
|
||||||
|
}
|
||||||
genesis.Config.XDPoS.V2.CurrentConfig.SwitchRound = 0
|
genesis.Config.XDPoS.V2.CurrentConfig.SwitchRound = 0
|
||||||
|
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
fmt.Println("How long is the v2 timeout period? (default = 10)")
|
fmt.Println("How long is the v2 timeout period? (default = 10)")
|
||||||
genesis.Config.XDPoS.V2.CurrentConfig.TimeoutPeriod = w.readDefaultInt(10)
|
if input != nil {
|
||||||
|
genesis.Config.XDPoS.V2.CurrentConfig.TimeoutPeriod = input.TimeoutPeriod
|
||||||
|
} else {
|
||||||
|
genesis.Config.XDPoS.V2.CurrentConfig.TimeoutPeriod = w.readDefaultInt(10)
|
||||||
|
}
|
||||||
|
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
fmt.Println("How many v2 timeout reach to send Synchronize message? (default = 3)")
|
fmt.Println("How many v2 timeout reach to send Synchronize message? (default = 3)")
|
||||||
genesis.Config.XDPoS.V2.CurrentConfig.TimeoutSyncThreshold = w.readDefaultInt(3)
|
if input != nil {
|
||||||
|
genesis.Config.XDPoS.V2.CurrentConfig.TimeoutSyncThreshold = input.TimeoutSyncThreshold
|
||||||
|
} else {
|
||||||
|
genesis.Config.XDPoS.V2.CurrentConfig.TimeoutSyncThreshold = w.readDefaultInt(3)
|
||||||
|
}
|
||||||
|
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
fmt.Printf("Proportion of total masternodes v2 vote collection to generate a QC (float value), should be two thirds of masternodes? (default = %f)\n", 0.667)
|
fmt.Printf("Proportion of total masternodes v2 vote collection to generate a QC (float value), should be two thirds of masternodes? (default = %f)\n", 0.667)
|
||||||
genesis.Config.XDPoS.V2.CurrentConfig.CertThreshold = w.readDefaultFloat(0.667)
|
if input != nil {
|
||||||
|
genesis.Config.XDPoS.V2.CurrentConfig.CertThreshold = input.CertThreshold
|
||||||
|
} else {
|
||||||
|
genesis.Config.XDPoS.V2.CurrentConfig.CertThreshold = w.readDefaultFloat(0.667)
|
||||||
|
}
|
||||||
genesis.Config.XDPoS.V2.CurrentConfig.MaxMasternodes = 108
|
genesis.Config.XDPoS.V2.CurrentConfig.MaxMasternodes = 108
|
||||||
|
// TODO: config to add after rewards upgrade enabled
|
||||||
|
// genesis.Config.XDPoS.V2.CurrentConfig.MaxProtectornodes
|
||||||
|
// genesis.Config.XDPoS.V2.CurrentConfig.MaxObservernodes
|
||||||
|
// genesis.Config.XDPoS.V2.CurrentConfig.MinProtectornodes
|
||||||
|
// genesis.Config.XDPoS.V2.CurrentConfig.MasternodeReward
|
||||||
|
// genesis.Config.XDPoS.V2.CurrentConfig.ProtectornodeReward
|
||||||
|
// genesis.Config.XDPoS.V2.CurrentConfig.ObservernodeReward
|
||||||
|
|
||||||
genesis.Config.XDPoS.V2.AllConfigs[0] = genesis.Config.XDPoS.V2.CurrentConfig
|
genesis.Config.XDPoS.V2.AllConfigs[0] = genesis.Config.XDPoS.V2.CurrentConfig
|
||||||
|
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
fmt.Println("Who own the first masternodes? (mandatory)")
|
fmt.Println("Who own the first masternodes? (mandatory)")
|
||||||
owner := *w.readAddress()
|
var owner common.Address
|
||||||
|
if input != nil {
|
||||||
|
owner = input.MasternodesOwner
|
||||||
|
} else {
|
||||||
|
owner = *w.readAddress()
|
||||||
|
}
|
||||||
|
|
||||||
// We also need the initial list of signers
|
// We also need the initial list of signers
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
fmt.Println("Which accounts are allowed to seal (signers)? (mandatory at least one)")
|
fmt.Println("Which accounts are Masternodes? (mandatory at least one)")
|
||||||
|
|
||||||
var signers []common.Address
|
var signers []common.Address
|
||||||
for {
|
if input != nil {
|
||||||
if address := w.readAddress(); address != nil {
|
for _, addr := range input.Masternodes {
|
||||||
signers = append(signers, *address)
|
signers = append(signers, addr)
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
if len(signers) > 0 {
|
} else {
|
||||||
break
|
for {
|
||||||
|
if address := w.readAddress(); address != nil {
|
||||||
|
signers = append(signers, *address)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if len(signers) > 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Sort the signers and embed into the extra-data section
|
// Sort the signers and embed into the extra-data section
|
||||||
|
|
@ -177,28 +278,58 @@ func (w *wizard) makeGenesis() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
validatorCap := new(big.Int)
|
|
||||||
validatorCap.SetString("50000000000000000000000", 10)
|
|
||||||
var validatorCaps []*big.Int
|
|
||||||
genesis.ExtraData = make([]byte, 32+len(signers)*common.AddressLength+crypto.SignatureLength)
|
|
||||||
for i, signer := range signers {
|
|
||||||
validatorCaps = append(validatorCaps, validatorCap)
|
|
||||||
copy(genesis.ExtraData[32+i*common.AddressLength:], signer[:])
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
fmt.Println("How many blocks per epoch? (default = 900)")
|
fmt.Println("How many blocks per epoch? (default = 900)")
|
||||||
epochNumber := uint64(w.readDefaultInt(900))
|
if input != nil {
|
||||||
genesis.Config.XDPoS.Epoch = epochNumber
|
genesis.Config.XDPoS.Epoch = input.Epoch
|
||||||
genesis.Config.XDPoS.RewardCheckpoint = epochNumber
|
} else {
|
||||||
|
genesis.Config.XDPoS.Epoch = uint64(w.readDefaultInt(900))
|
||||||
|
}
|
||||||
|
genesis.Config.XDPoS.RewardCheckpoint = genesis.Config.XDPoS.Epoch
|
||||||
|
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
fmt.Println("How many blocks before checkpoint need to prepare new set of masternodes? (default = 450)")
|
fmt.Println("How many blocks before checkpoint need to prepare new set of masternodes? (default = 450)")
|
||||||
genesis.Config.XDPoS.Gap = uint64(w.readDefaultInt(450))
|
if input != nil {
|
||||||
|
genesis.Config.XDPoS.Gap = uint64(input.Gap)
|
||||||
|
} else {
|
||||||
|
genesis.Config.XDPoS.Gap = uint64(w.readDefaultInt(450))
|
||||||
|
}
|
||||||
|
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
fmt.Println("What is foundation wallet address? (default = xdc0000000000000000000000000000000000000068)")
|
fmt.Println("What is minimum staking threshold to become a Validator? (default = 10M)")
|
||||||
genesis.Config.XDPoS.FoudationWalletAddr = w.readDefaultAddress(common.FoudationAddrBinary)
|
var threshold uint64
|
||||||
|
if input != nil {
|
||||||
|
threshold = input.StakingThreshold
|
||||||
|
} else {
|
||||||
|
threshold = uint64(w.readDefaultInt(10000000))
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println()
|
||||||
|
// fmt.Println("How many Ethers should be rewarded to masternode each Epoch? (default = 10)")
|
||||||
|
fmt.Println("What should be the reward yield of Masternodes in APY% (default = 10)")
|
||||||
|
yield := uint64(0)
|
||||||
|
if input != nil {
|
||||||
|
yield = input.RewardYield
|
||||||
|
} else {
|
||||||
|
yield = uint64(w.readDefaultInt(10))
|
||||||
|
}
|
||||||
|
blocksPerYear := uint64(31536000 / genesis.Config.XDPoS.Period)
|
||||||
|
epochsPerYear := blocksPerYear / genesis.Config.XDPoS.Epoch
|
||||||
|
rewardsPerYear := float64(threshold) * (float64(yield) / float64(100))
|
||||||
|
rewardPerEpochPerMN := uint64(rewardsPerYear / float64(epochsPerYear))
|
||||||
|
totalRewardPerEpoch := rewardPerEpochPerMN * uint64(len(signers))
|
||||||
|
fmt.Println()
|
||||||
|
fmt.Println("Calculated Total Masternode rewards per epoch based on yield: ", totalRewardPerEpoch)
|
||||||
|
genesis.Config.XDPoS.Reward = totalRewardPerEpoch
|
||||||
|
|
||||||
|
fmt.Println()
|
||||||
|
fmt.Println("What is foundation wallet address (collect 10% of all rewards)? (default = xdc0000000000000000000000000000000000000068)")
|
||||||
|
if input != nil {
|
||||||
|
genesis.Config.XDPoS.FoudationWalletAddr = input.FoundationWalletAddress
|
||||||
|
} else {
|
||||||
|
genesis.Config.XDPoS.FoudationWalletAddr = w.readDefaultAddress(common.FoudationAddrBinary)
|
||||||
|
}
|
||||||
|
|
||||||
// Validator Smart Contract Code
|
// Validator Smart Contract Code
|
||||||
pKey, _ := crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
|
pKey, _ := crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
|
||||||
|
|
@ -206,7 +337,16 @@ func (w *wizard) makeGenesis() {
|
||||||
contractBackend := backends.NewXDCSimulatedBackend(types.GenesisAlloc{addr: {Balance: big.NewInt(1000000000)}}, 10000000, params.TestXDPoSMockChainConfig)
|
contractBackend := backends.NewXDCSimulatedBackend(types.GenesisAlloc{addr: {Balance: big.NewInt(1000000000)}}, 10000000, params.TestXDPoSMockChainConfig)
|
||||||
transactOpts := bind.NewKeyedTransactor(pKey)
|
transactOpts := bind.NewKeyedTransactor(pKey)
|
||||||
|
|
||||||
validatorAddress, _, err := validatorContract.DeployValidator(transactOpts, contractBackend, signers, validatorCaps, owner)
|
minDeposit := new(big.Int).SetUint64(threshold)
|
||||||
|
minDeposit.Mul(minDeposit, big.NewInt(1e18)) //convert to wei
|
||||||
|
validatorCap := new(big.Int).Set(minDeposit)
|
||||||
|
var validatorCaps []*big.Int
|
||||||
|
genesis.ExtraData = make([]byte, 32+len(signers)*common.AddressLength+crypto.SignatureLength)
|
||||||
|
for i, signer := range signers {
|
||||||
|
validatorCaps = append(validatorCaps, validatorCap)
|
||||||
|
copy(genesis.ExtraData[32+i*common.AddressLength:], signer[:])
|
||||||
|
}
|
||||||
|
validatorAddress, _, err := validatorContract.DeployValidator(transactOpts, contractBackend, signers, validatorCaps, owner, minDeposit, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("Can't deploy root registry")
|
fmt.Println("Can't deploy root registry")
|
||||||
}
|
}
|
||||||
|
|
@ -218,10 +358,7 @@ func (w *wizard) makeGenesis() {
|
||||||
code, _ := contractBackend.CodeAt(ctx, validatorAddress, nil)
|
code, _ := contractBackend.CodeAt(ctx, validatorAddress, nil)
|
||||||
storage := make(map[common.Hash]common.Hash)
|
storage := make(map[common.Hash]common.Hash)
|
||||||
f := func(key, val common.Hash) bool {
|
f := func(key, val common.Hash) bool {
|
||||||
decode := []byte{}
|
storage[key] = common.BytesToHash(val.Bytes())
|
||||||
trim := bytes.TrimLeft(val.Bytes(), "\x00")
|
|
||||||
rlp.DecodeBytes(trim, &decode)
|
|
||||||
storage[key] = common.BytesToHash(decode)
|
|
||||||
log.Info("DecodeBytes", "value", val.String(), "decode", storage[key].String())
|
log.Info("DecodeBytes", "value", val.String(), "decode", storage[key].String())
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
@ -235,21 +372,31 @@ func (w *wizard) makeGenesis() {
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
fmt.Println("Which accounts are allowed to confirm in Foudation MultiSignWallet?")
|
fmt.Println("Which accounts are allowed to confirm in Foudation MultiSignWallet?")
|
||||||
var owners []common.Address
|
var owners []common.Address
|
||||||
for {
|
if input != nil {
|
||||||
if address := w.readAddress(); address != nil {
|
owners = append(owners, input.MasternodesOwner)
|
||||||
owners = append(owners, *address)
|
} else {
|
||||||
continue
|
for {
|
||||||
}
|
if address := w.readAddress(); address != nil {
|
||||||
if len(owners) > 0 {
|
owners = append(owners, *address)
|
||||||
break
|
continue
|
||||||
|
}
|
||||||
|
if len(owners) > 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
fmt.Println("How many require for confirm tx in Foudation MultiSignWallet? (default = 2)")
|
fmt.Println("How many require for confirm tx in Foudation MultiSignWallet? (default = 1)")
|
||||||
required := int64(w.readDefaultInt(2))
|
var required uint64
|
||||||
|
if input != nil {
|
||||||
|
required = 1
|
||||||
|
} else {
|
||||||
|
required = uint64(w.readDefaultInt(1))
|
||||||
|
}
|
||||||
|
|
||||||
// MultiSigWallet.
|
// MultiSigWallet.
|
||||||
multiSignWalletAddr, _, err := multiSignWalletContract.DeployMultiSigWallet(transactOpts, contractBackend, owners, big.NewInt(required))
|
multiSignWalletAddr, _, err := multiSignWalletContract.DeployMultiSigWallet(transactOpts, contractBackend, owners, big.NewInt(int64(required)))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("Can't deploy MultiSignWallet SMC")
|
fmt.Println("Can't deploy MultiSignWallet SMC")
|
||||||
}
|
}
|
||||||
|
|
@ -267,7 +414,7 @@ func (w *wizard) makeGenesis() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Block Signers Smart Contract
|
// Block Signers Smart Contract
|
||||||
blockSignerAddress, _, err := blockSignerContract.DeployBlockSigner(transactOpts, contractBackend, big.NewInt(int64(epochNumber)))
|
blockSignerAddress, _, err := blockSignerContract.DeployBlockSigner(transactOpts, contractBackend, big.NewInt(int64(genesis.Config.XDPoS.Epoch)))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("Can't deploy root registry")
|
fmt.Println("Can't deploy root registry")
|
||||||
}
|
}
|
||||||
|
|
@ -301,21 +448,31 @@ func (w *wizard) makeGenesis() {
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
fmt.Println("Which accounts are allowed to confirm in Team MultiSignWallet?")
|
fmt.Println("Which accounts are allowed to confirm in Team MultiSignWallet?")
|
||||||
var teams []common.Address
|
var teams []common.Address
|
||||||
for {
|
if input != nil {
|
||||||
if address := w.readAddress(); address != nil {
|
owners = append(owners, input.MasternodesOwner)
|
||||||
teams = append(teams, *address)
|
} else {
|
||||||
continue
|
for {
|
||||||
}
|
if address := w.readAddress(); address != nil {
|
||||||
if len(teams) > 0 {
|
teams = append(teams, *address)
|
||||||
break
|
continue
|
||||||
|
}
|
||||||
|
if len(teams) > 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
fmt.Println("How many require for confirm tx in Team MultiSignWallet? (default = 2)")
|
fmt.Println("How many require for confirm tx in Team MultiSignWallet? (default = 2)")
|
||||||
required = int64(w.readDefaultInt(2))
|
var requiredTeam int64
|
||||||
|
if input != nil {
|
||||||
|
requiredTeam = 1
|
||||||
|
} else {
|
||||||
|
requiredTeam = int64(w.readDefaultInt(1))
|
||||||
|
}
|
||||||
|
|
||||||
// MultiSigWallet.
|
// MultiSigWallet.
|
||||||
multiSignWalletTeamAddr, _, err := multiSignWalletContract.DeployMultiSigWallet(transactOpts, contractBackend, teams, big.NewInt(required))
|
multiSignWalletTeamAddr, _, err := multiSignWalletContract.DeployMultiSigWallet(transactOpts, contractBackend, teams, big.NewInt(requiredTeam))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("Can't deploy MultiSignWallet SMC")
|
fmt.Println("Can't deploy MultiSignWallet SMC")
|
||||||
}
|
}
|
||||||
|
|
@ -337,32 +494,33 @@ func (w *wizard) makeGenesis() {
|
||||||
Storage: storage,
|
Storage: storage,
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println()
|
|
||||||
fmt.Println("What is swap wallet address for fund 55m XDC?")
|
|
||||||
swapAddr := *w.readAddress()
|
|
||||||
baseBalance := big.NewInt(0) // 55m
|
|
||||||
baseBalance.Add(baseBalance, big.NewInt(55*1000*1000))
|
|
||||||
baseBalance.Mul(baseBalance, big.NewInt(1000000000000000000))
|
|
||||||
genesis.Alloc[swapAddr] = types.Account{
|
|
||||||
Balance: baseBalance,
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
log.Crit("Invalid consensus engine choice", "choice", choice)
|
log.Crit("Invalid consensus engine choice", "choice", choice)
|
||||||
}
|
}
|
||||||
// Consensus all set, just ask for initial funds and go
|
// Consensus all set, just ask for initial funds and go
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
fmt.Println("Which accounts should be pre-funded? (advisable at least one)")
|
fmt.Println("Which accounts should be pre-funded? (advisable at least one)")
|
||||||
for {
|
var addresses []common.Address
|
||||||
// Read the address of the account to fund
|
if input != nil {
|
||||||
if address := w.readAddress(); address != nil {
|
addresses = append(addresses, input.MasternodesOwner)
|
||||||
genesis.Alloc[*address] = types.Account{
|
} else {
|
||||||
Balance: new(big.Int).Lsh(big.NewInt(1), 256-7), // 2^256 / 128 (allow many pre-funds without balance overflows)
|
for {
|
||||||
|
if address := w.readAddress(); address != nil {
|
||||||
|
addresses = append(addresses, *address)
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
continue
|
break
|
||||||
}
|
}
|
||||||
break
|
|
||||||
}
|
}
|
||||||
|
for _, address := range addresses {
|
||||||
|
baseBalance := big.NewInt(0) // 21m
|
||||||
|
baseBalance.Add(baseBalance, big.NewInt(21_000_000))
|
||||||
|
baseBalance.Mul(baseBalance, big.NewInt(1e18))
|
||||||
|
genesis.Alloc[address] = types.Account{
|
||||||
|
Balance: baseBalance,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Add a batch of precompile balances to avoid them getting deleted
|
// Add a batch of precompile balances to avoid them getting deleted
|
||||||
for i := int64(0); i < 2; i++ {
|
for i := int64(0); i < 2; i++ {
|
||||||
genesis.Alloc[common.BigToAddress(big.NewInt(i))] = types.Account{Balance: big.NewInt(0)}
|
genesis.Alloc[common.BigToAddress(big.NewInt(i))] = types.Account{Balance: big.NewInt(0)}
|
||||||
|
|
@ -370,7 +528,11 @@ func (w *wizard) makeGenesis() {
|
||||||
// Query the user for some custom extras
|
// Query the user for some custom extras
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
fmt.Println("Specify your chain/network ID if you want an explicit one (default = random)")
|
fmt.Println("Specify your chain/network ID if you want an explicit one (default = random)")
|
||||||
genesis.Config.ChainID = new(big.Int).SetUint64(uint64(w.readDefaultInt(rand.Intn(65536))))
|
if input != nil {
|
||||||
|
genesis.Config.ChainID = new(big.Int).SetUint64(input.ChainId)
|
||||||
|
} else {
|
||||||
|
genesis.Config.ChainID = new(big.Int).SetUint64(uint64(w.readDefaultInt(rand.Intn(65536))))
|
||||||
|
}
|
||||||
|
|
||||||
// All done, store the genesis and flush to disk
|
// All done, store the genesis and flush to disk
|
||||||
log.Info("Configured new genesis block")
|
log.Info("Configured new genesis block")
|
||||||
|
|
|
||||||
|
|
@ -18,23 +18,31 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
|
||||||
|
|
||||||
"github.com/XinFinOrg/XDPoSChain/log"
|
"github.com/XinFinOrg/XDPoSChain/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
// makeWizard creates and returns a new puppeth wizard.
|
// makeWizard creates and returns a new puppeth wizard.
|
||||||
func makeWizard(network string) *wizard {
|
func makeWizard(network string, inputPath string, outputPath string) *wizard {
|
||||||
|
conf := config{
|
||||||
|
Servers: make(map[string][]byte),
|
||||||
|
}
|
||||||
|
if inputPath != "" {
|
||||||
|
conf.inpath = inputPath
|
||||||
|
}
|
||||||
|
if outputPath != "" {
|
||||||
|
conf.path = outputPath
|
||||||
|
} else {
|
||||||
|
conf.path = filepath.Join(os.Getenv("HOME"), ".puppeth", network)
|
||||||
|
}
|
||||||
|
|
||||||
return &wizard{
|
return &wizard{
|
||||||
network: network,
|
network: network,
|
||||||
conf: config{
|
conf: conf,
|
||||||
Servers: make(map[string][]byte),
|
|
||||||
},
|
|
||||||
servers: make(map[string]*sshClient),
|
servers: make(map[string]*sshClient),
|
||||||
services: make(map[string][]string),
|
services: make(map[string][]string),
|
||||||
in: bufio.NewReader(os.Stdin),
|
in: bufio.NewReader(os.Stdin),
|
||||||
|
|
@ -44,6 +52,10 @@ func makeWizard(network string) *wizard {
|
||||||
// run displays some useful infos to the user, starting on the journey of
|
// run displays some useful infos to the user, starting on the journey of
|
||||||
// setting up a new or managing an existing Ethereum private network.
|
// setting up a new or managing an existing Ethereum private network.
|
||||||
func (w *wizard) run() {
|
func (w *wizard) run() {
|
||||||
|
if w.conf.inpath != "" { //don't use interactive mode if run with input option
|
||||||
|
w.makeGenesis()
|
||||||
|
return
|
||||||
|
}
|
||||||
fmt.Println("+-----------------------------------------------------------+")
|
fmt.Println("+-----------------------------------------------------------+")
|
||||||
fmt.Println("| Welcome to puppeth, your Ethereum private network manager |")
|
fmt.Println("| Welcome to puppeth, your Ethereum private network manager |")
|
||||||
fmt.Println("| |")
|
fmt.Println("| |")
|
||||||
|
|
@ -72,36 +84,6 @@ func (w *wizard) run() {
|
||||||
}
|
}
|
||||||
log.Info("Administering Ethereum network", "name", w.network)
|
log.Info("Administering Ethereum network", "name", w.network)
|
||||||
|
|
||||||
// Load initial configurations and connect to all live servers
|
|
||||||
w.conf.path = filepath.Join(os.Getenv("HOME"), ".puppeth", w.network)
|
|
||||||
|
|
||||||
blob, err := os.ReadFile(w.conf.path)
|
|
||||||
if err != nil {
|
|
||||||
log.Warn("No previous configurations found", "path", w.conf.path)
|
|
||||||
} else if err := json.Unmarshal(blob, &w.conf); err != nil {
|
|
||||||
log.Crit("Previous configuration corrupted", "path", w.conf.path, "err", err)
|
|
||||||
} else {
|
|
||||||
// Dial all previously known servers concurrently
|
|
||||||
var pend sync.WaitGroup
|
|
||||||
for server, pubkey := range w.conf.Servers {
|
|
||||||
pend.Add(1)
|
|
||||||
|
|
||||||
go func(server string, pubkey []byte) {
|
|
||||||
defer pend.Done()
|
|
||||||
|
|
||||||
log.Info("Dialing previously configured server", "server", server)
|
|
||||||
client, err := dial(server, pubkey)
|
|
||||||
if err != nil {
|
|
||||||
log.Error("Previous server unreachable", "server", server, "err", err)
|
|
||||||
}
|
|
||||||
w.lock.Lock()
|
|
||||||
w.servers[server] = client
|
|
||||||
w.lock.Unlock()
|
|
||||||
}(server, pubkey)
|
|
||||||
}
|
|
||||||
pend.Wait()
|
|
||||||
w.networkStats()
|
|
||||||
}
|
|
||||||
// Basics done, loop ad infinitum about what to do
|
// Basics done, loop ad infinitum about what to do
|
||||||
for {
|
for {
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
|
|
|
||||||
|
|
@ -128,15 +128,15 @@ func IsInBlacklist(address *Address) bool {
|
||||||
// It skips mainnet since the default value is from mainnet.
|
// It skips mainnet since the default value is from mainnet.
|
||||||
func CopyConstants(chainID uint64) {
|
func CopyConstants(chainID uint64) {
|
||||||
var c *constant
|
var c *constant
|
||||||
if chainID == TestnetConstant.chainID {
|
if chainID == MaintnetConstant.chainID {
|
||||||
|
return
|
||||||
|
} else if chainID == TestnetConstant.chainID {
|
||||||
c = &TestnetConstant
|
c = &TestnetConstant
|
||||||
IsTestnet = true
|
IsTestnet = true
|
||||||
} else if chainID == DevnetConstant.chainID {
|
} else if chainID == DevnetConstant.chainID {
|
||||||
c = &DevnetConstant
|
c = &DevnetConstant
|
||||||
} else if chainID == localConstant.chainID {
|
} else { // local custom chain, it can have any chainID
|
||||||
c = &localConstant
|
c = &localConstant
|
||||||
} else {
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MaxMasternodesV2 = c.maxMasternodesV2
|
MaxMasternodesV2 = c.maxMasternodesV2
|
||||||
|
|
|
||||||
|
|
@ -28,9 +28,9 @@ var localConstant = constant{
|
||||||
tipXDCXReceiverDisable: big.NewInt(0),
|
tipXDCXReceiverDisable: big.NewInt(0),
|
||||||
eip1559Block: big.NewInt(0),
|
eip1559Block: big.NewInt(0),
|
||||||
cancunBlock: big.NewInt(0),
|
cancunBlock: big.NewInt(0),
|
||||||
tipUpgradeReward: big.NewInt(0),
|
tipUpgradeReward: big.NewInt(999999999),
|
||||||
tipUpgradePenalty: big.NewInt(0),
|
tipUpgradePenalty: big.NewInt(999999999),
|
||||||
tipEpochHalving: big.NewInt(0),
|
tipEpochHalving: big.NewInt(999999999),
|
||||||
|
|
||||||
trc21IssuerSMC: HexToAddress("0x8c0faeb5C6bEd2129b8674F262Fd45c4e9468bee"),
|
trc21IssuerSMC: HexToAddress("0x8c0faeb5C6bEd2129b8674F262Fd45c4e9468bee"),
|
||||||
xdcxListingSMC: HexToAddress("0xDE34dD0f536170993E8CFF639DdFfCF1A85D3E53"),
|
xdcxListingSMC: HexToAddress("0xDE34dD0f536170993E8CFF639DdFfCF1A85D3E53"),
|
||||||
|
|
|
||||||
|
|
@ -43,17 +43,23 @@ func NewValidator(transactOpts *bind.TransactOpts, contractAddr common.Address,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func DeployValidator(transactOpts *bind.TransactOpts, contractBackend bind.ContractBackend, validatorAddress []common.Address, caps []*big.Int, ownerAddress common.Address) (common.Address, *Validator, error) {
|
func DeployValidator(transactOpts *bind.TransactOpts, contractBackend bind.ContractBackend, validatorAddress []common.Address, caps []*big.Int, ownerAddress common.Address, minDeposit *big.Int, minVoterCap *big.Int) (common.Address, *Validator, error) {
|
||||||
minDeposit := new(big.Int)
|
if minDeposit == nil {
|
||||||
minDeposit.SetString("10000000000000000000000000", 10)
|
minDeposit = new(big.Int)
|
||||||
minVoterCap := new(big.Int)
|
minDeposit.SetString("10000000", 10) // 10M
|
||||||
minVoterCap.SetString("25000000000000000000000", 10)
|
minDeposit.Mul(minDeposit, big.NewInt(1e18)) //convert to wei
|
||||||
// Deposit 50K XDC
|
}
|
||||||
// Min Voter Cap 10 XDC
|
if minVoterCap == nil {
|
||||||
// 150 masternodes
|
minVoterCap = new(big.Int).Set(minDeposit)
|
||||||
|
minVoterCap.Div(minVoterCap, big.NewInt(400)) //set votercap to 0.25% of candidate deposit (25K XDC)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deposit 10M XDC
|
||||||
|
// Min Voter Cap 25K XDC
|
||||||
|
// 108 masternodes
|
||||||
// Candidate Delay Withdraw 30 days = 1296000 blocks
|
// Candidate Delay Withdraw 30 days = 1296000 blocks
|
||||||
// Voter Delay Withdraw 10 days = 432000 blocks
|
// Voter Delay Withdraw 10 days = 432000 blocks
|
||||||
validatorAddr, _, _, err := contract.DeployXDCValidator(transactOpts, contractBackend, validatorAddress, caps, ownerAddress, minDeposit, minVoterCap, big.NewInt(18), big.NewInt(1296000), big.NewInt(432000))
|
validatorAddr, _, _, err := contract.DeployXDCValidator(transactOpts, contractBackend, validatorAddress, caps, ownerAddress, minDeposit, minVoterCap, big.NewInt(108), big.NewInt(1296000), big.NewInt(432000))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return validatorAddr, nil, err
|
return validatorAddr, nil, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@ func TestValidator(t *testing.T) {
|
||||||
|
|
||||||
validatorCap := new(big.Int)
|
validatorCap := new(big.Int)
|
||||||
validatorCap.SetString("50000000000000000000000", 10)
|
validatorCap.SetString("50000000000000000000000", 10)
|
||||||
validatorAddress, validator, err := DeployValidator(transactOpts, contractBackend, []common.Address{addr}, []*big.Int{validatorCap}, addr)
|
validatorAddress, validator, err := DeployValidator(transactOpts, contractBackend, []common.Address{addr}, []*big.Int{validatorCap}, addr, nil, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("can't deploy root registry: %v", err)
|
t.Fatalf("can't deploy root registry: %v", err)
|
||||||
}
|
}
|
||||||
|
|
@ -280,7 +280,7 @@ func TestStatedbUtils(t *testing.T) {
|
||||||
contractBackend := backends.NewXDCSimulatedBackend(genesisAlloc, 10000000, params.TestXDPoSMockChainConfig)
|
contractBackend := backends.NewXDCSimulatedBackend(genesisAlloc, 10000000, params.TestXDPoSMockChainConfig)
|
||||||
transactOpts := bind.NewKeyedTransactor(key)
|
transactOpts := bind.NewKeyedTransactor(key)
|
||||||
|
|
||||||
validatorAddress, _, err := DeployValidator(transactOpts, contractBackend, []common.Address{addr, acc3Addr}, []*big.Int{validatorCap, validatorCap}, addr)
|
validatorAddress, _, err := DeployValidator(transactOpts, contractBackend, []common.Address{addr, acc3Addr}, []*big.Int{validatorCap, validatorCap}, addr, nil, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("can't deploy root registry: %v", err)
|
t.Fatalf("can't deploy root registry: %v", err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue