Merge pull request #1121 from rlan35/rj_fork

Cleanup mainnet genesis
pull/1126/head
Rongjian Lan 5 years ago committed by GitHub
commit b61f8c1a47
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      cmd/client/wallet/main.go
  2. 14
      cmd/harmony/main.go
  3. 14
      common/config/global_config.go
  4. 37
      internal/configs/node/config.go
  5. 63
      node/node.go
  6. 50
      node/node_genesis.go
  7. 79
      node/node_handler.go
  8. 2
      node/node_syncing.go
  9. 2
      test/deploy.sh

@ -646,7 +646,7 @@ func processTransferCommand() {
shardIDToAccountState := FetchBalance(senderAddress) shardIDToAccountState := FetchBalance(senderAddress)
state := shardIDToAccountState[shardID] state := shardIDToAccountState[shardID]
if state != nil { if state == nil {
fmt.Printf("Failed connecting to the shard %d\n", shardID) fmt.Printf("Failed connecting to the shard %d\n", shardID)
return return
} }

@ -97,6 +97,8 @@ var (
delayCommit = flag.String("delay_commit", "0ms", "how long to delay sending commit messages in consensus, ex: 500ms, 1s") delayCommit = flag.String("delay_commit", "0ms", "how long to delay sending commit messages in consensus, ex: 500ms, 1s")
// isExplorer indicates this node is a node to serve explorer // isExplorer indicates this node is a node to serve explorer
isExplorer = flag.Bool("is_explorer", false, "true means this node is a node to serve explorer") isExplorer = flag.Bool("is_explorer", false, "true means this node is a node to serve explorer")
// networkType indicates the type of the network
networkType = flag.String("network_type", "mainnet", "type of the network: mainnet, testnet, devnet...")
// isNewNode indicates this node is a new node // isNewNode indicates this node is a new node
isNewNode = flag.Bool("is_newnode", false, "true means this node is a new node") isNewNode = flag.Bool("is_newnode", false, "true means this node is a new node")
shardID = flag.Int("shard_id", -1, "the shard ID of this node") shardID = flag.Int("shard_id", -1, "the shard ID of this node")
@ -245,6 +247,18 @@ func createGlobalConfig() *nodeconfig.ConfigType {
nodeConfig = nodeconfig.GetShardConfig(uint32(*shardID)) nodeConfig = nodeconfig.GetShardConfig(uint32(*shardID))
} }
// Set network type
switch *networkType {
case "mainnet":
nodeConfig.SetNetworkType(nodeconfig.Mainnet)
case "testnet":
nodeConfig.SetNetworkType(nodeconfig.Testnet)
case "devnet":
nodeConfig.SetNetworkType(nodeconfig.Devnet)
default:
panic(fmt.Sprintf("invalid network type: %s", *networkType))
}
nodeConfig.SelfPeer = p2p.Peer{IP: *ip, Port: *port, ConsensusPubKey: nodeConfig.ConsensusPubKey} nodeConfig.SelfPeer = p2p.Peer{IP: *ip, Port: *port, ConsensusPubKey: nodeConfig.ConsensusPubKey}
if accountIndex < core.GenesisShardNum && !*isExplorer { // The first node in a shard is the leader at genesis if accountIndex < core.GenesisShardNum && !*isExplorer { // The first node in a shard is the leader at genesis

@ -1,14 +0,0 @@
package config
// NetworkType describes the type of Harmony network
type NetworkType int
// Constants for NetworkType
const (
Mainnet NetworkType = 0
Testnet NetworkType = 1
Devnet NetworkType = 2
)
// Network is the type of Harmony network
var Network = Testnet

@ -55,6 +55,31 @@ func (role Role) String() string {
return "Unknown" return "Unknown"
} }
// NetworkType describes the type of Harmony network
type NetworkType int
// Constants for NetworkType
const (
Mainnet NetworkType = iota
Testnet
Devnet
)
func (network NetworkType) String() string {
switch network {
case Mainnet:
return "Mainnet"
case Testnet:
return "Testnet"
case Devnet:
return "Devnet"
}
return "Unknown"
}
// Network is the type of Harmony network
var Network = Testnet
// Global is the index of the global node configuration // Global is the index of the global node configuration
const ( const (
Global = 0 Global = 0
@ -87,6 +112,8 @@ type ConfigType struct {
SelfPeer p2p.Peer SelfPeer p2p.Peer
Leader p2p.Peer Leader p2p.Peer
networkType NetworkType
} }
// configs is a list of node configuration. // configs is a list of node configuration.
@ -202,3 +229,13 @@ func (conf *ConfigType) IsLeader() bool {
func (conf *ConfigType) Role() Role { func (conf *ConfigType) Role() Role {
return conf.role return conf.role
} }
// SetNetworkType set the networkType
func (conf *ConfigType) SetNetworkType(networkType NetworkType) {
conf.networkType = networkType
}
// GetNetworkType gets the networkType
func (conf *ConfigType) GetNetworkType() NetworkType {
return conf.networkType
}

@ -10,7 +10,6 @@ import (
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/params"
"github.com/harmony-one/bls/ffi/go/bls" "github.com/harmony-one/bls/ffi/go/bls"
"github.com/harmony-one/harmony/accounts" "github.com/harmony-one/harmony/accounts"
"github.com/harmony-one/harmony/api/client" "github.com/harmony-one/harmony/api/client"
@ -289,22 +288,21 @@ func (node *Node) GetSyncID() [SyncIDLength]byte {
// New creates a new node. // New creates a new node.
func New(host p2p.Host, consensusObj *consensus.Consensus, chainDBFactory shardchain.DBFactory, isArchival bool) *Node { func New(host p2p.Host, consensusObj *consensus.Consensus, chainDBFactory shardchain.DBFactory, isArchival bool) *Node {
var err error
node := Node{} node := Node{}
// Get the node config that's created in the harmony.go program.
if consensusObj != nil {
node.NodeConfig = nodeconfig.GetShardConfig(consensusObj.ShardID)
} else {
node.NodeConfig = nodeconfig.GetDefaultConfig()
}
copy(node.syncID[:], GenerateRandomString(SyncIDLength)) copy(node.syncID[:], GenerateRandomString(SyncIDLength))
if host != nil { if host != nil {
node.host = host node.host = host
node.SelfPeer = host.GetSelfPeer() node.SelfPeer = host.GetSelfPeer()
} }
// Create test keys. Genesis will later need this.
node.TestBankKeys, err = CreateTestBankKeys(TestAccountNumber)
if err != nil {
utils.GetLogInstance().Crit("Error while creating test keys",
"error", err)
}
collection := shardchain.NewCollection( collection := shardchain.NewCollection(
chainDBFactory, &genesisInitializer{&node}, consensusObj) chainDBFactory, &genesisInitializer{&node}, consensusObj)
if isArchival { if isArchival {
@ -332,27 +330,37 @@ func New(host p2p.Host, consensusObj *consensus.Consensus, chainDBFactory shardc
// Add Faucet contract to all shards, so that on testnet, we can demo wallet in explorer // Add Faucet contract to all shards, so that on testnet, we can demo wallet in explorer
// TODO (leo): we need to have support of cross-shard tx later so that the token can be transferred from beacon chain shard to other tx shards. // TODO (leo): we need to have support of cross-shard tx later so that the token can be transferred from beacon chain shard to other tx shards.
if node.isFirstTime { if node.NodeConfig.GetNetworkType() != nodeconfig.Mainnet {
// Setup one time smart contracts
//node.AddFaucetContractToPendingTransactions()
} else {
node.AddContractKeyAndAddress(scFaucet)
}
if node.Consensus.ShardID == 0 {
// Contracts only exist in beacon chain
if node.isFirstTime { if node.isFirstTime {
// Setup one time smart contracts // Setup one time smart contracts
node.CurrentStakes = make(map[common.Address]*structs.StakeInfo) node.AddFaucetContractToPendingTransactions()
node.AddStakingContractToPendingTransactions() //This will save the latest information about staked nodes in current staked
} else { } else {
node.AddContractKeyAndAddress(scStaking) node.AddContractKeyAndAddress(scFaucet)
}
if node.Consensus.ShardID == 0 {
// Contracts only exist in beacon chain
if node.isFirstTime {
// Setup one time smart contracts
node.CurrentStakes = make(map[common.Address]*structs.StakeInfo)
node.AddStakingContractToPendingTransactions() //This will save the latest information about staked nodes in current staked
} else {
node.AddContractKeyAndAddress(scStaking)
}
}
node.ContractCaller = contracts.NewContractCaller(node.Blockchain(), node.Blockchain().Config())
// Create test keys. Genesis will later need this.
var err error
node.TestBankKeys, err = CreateTestBankKeys(TestAccountNumber)
if err != nil {
utils.GetLogInstance().Crit("Error while creating test keys",
"error", err)
} }
} }
} }
node.ContractCaller = contracts.NewContractCaller(node.Blockchain(), params.TestChainConfig)
if consensusObj != nil && nodeconfig.GetDefaultConfig().IsLeader() { if consensusObj != nil && nodeconfig.GetDefaultConfig().IsLeader() {
node.State = NodeLeader node.State = NodeLeader
} else { } else {
@ -375,13 +383,6 @@ func New(host p2p.Host, consensusObj *consensus.Consensus, chainDBFactory shardc
node.startConsensus = make(chan struct{}) node.startConsensus = make(chan struct{})
// Get the node config that's created in the harmony.go program.
if consensusObj != nil {
node.NodeConfig = nodeconfig.GetShardConfig(consensusObj.ShardID)
} else {
node.NodeConfig = nodeconfig.GetDefaultConfig()
}
return &node return &node
} }

@ -6,7 +6,9 @@ import (
"math/rand" "math/rand"
"strings" "strings"
"github.com/harmony-one/harmony/common/config" nodeconfig "github.com/harmony-one/harmony/internal/configs/node"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/ethdb"
@ -17,18 +19,19 @@ import (
"github.com/harmony-one/harmony/core" "github.com/harmony-one/harmony/core"
"github.com/harmony-one/harmony/core/types" "github.com/harmony-one/harmony/core/types"
common2 "github.com/harmony-one/harmony/internal/common" common2 "github.com/harmony-one/harmony/internal/common"
"github.com/harmony-one/harmony/internal/ctxerror"
"github.com/harmony-one/harmony/internal/genesis" "github.com/harmony-one/harmony/internal/genesis"
"github.com/harmony-one/harmony/internal/utils" "github.com/harmony-one/harmony/internal/utils"
) )
const ( const (
// TestAccountNumber is the number of test accounts // GenesisFund is the initial total fund in the genesis block for mainnet.
GenesisFund = 12600000000
// TestAccountNumber is the number of test accounts for testnet/devnet/
TestAccountNumber = 100 TestAccountNumber = 100
// TotalInitFund is the initial total fund for the contract deployer. // ContractDeployerInitFund is the initial fund for the contract deployer account in testnet/devnet.
TotalInitFund = 12600000000 ContractDeployerInitFund = 100000000
// InitFreeFundInEther is the initial fund for permissioned accounts. // InitFreeFund is the initial fund for permissioned accounts for testnet/devnet/
InitFreeFundInEther = 100 InitFreeFund = 100
) )
// genesisInitializer is a shardchain.DBInitializer adapter. // genesisInitializer is a shardchain.DBInitializer adapter.
@ -47,14 +50,12 @@ func (gi *genesisInitializer) InitChainDB(db ethdb.Database, shardID uint32) err
} }
shardState = types.ShardState{*c} shardState = types.ShardState{*c}
} }
if err := gi.node.SetupGenesisBlock(db, shardID, shardState); err != nil { gi.node.SetupGenesisBlock(db, shardID, shardState)
return ctxerror.New("cannot setup genesis block").WithCause(err)
}
return nil return nil
} }
// SetupGenesisBlock sets up a genesis blockchain. // SetupGenesisBlock sets up a genesis blockchain.
func (node *Node) SetupGenesisBlock(db ethdb.Database, shardID uint32, myShardState types.ShardState) error { func (node *Node) SetupGenesisBlock(db ethdb.Database, shardID uint32, myShardState types.ShardState) {
utils.GetLogger().Info("setting up a brand new chain database", utils.GetLogger().Info("setting up a brand new chain database",
"shardID", shardID) "shardID", shardID)
if shardID == node.Consensus.ShardID { if shardID == node.Consensus.ShardID {
@ -66,10 +67,15 @@ func (node *Node) SetupGenesisBlock(db ethdb.Database, shardID uint32, myShardSt
genesisAlloc := make(core.GenesisAlloc) genesisAlloc := make(core.GenesisAlloc)
chainConfig := params.ChainConfig{} chainConfig := params.ChainConfig{}
switch config.Network { switch node.NodeConfig.GetNetworkType() {
case config.Mainnet: case nodeconfig.Mainnet:
chainConfig = *params.MainnetChainConfig chainConfig = *params.MainnetChainConfig
case config.Testnet: foundationAddress := common.HexToAddress("0xE25ABC3f7C3d5fB7FB81EAFd421FF1621A61107c")
genesisFunds := big.NewInt(GenesisFund)
genesisFunds = genesisFunds.Mul(genesisFunds, big.NewInt(denominations.One))
genesisAlloc[foundationAddress] = core.GenesisAccount{Balance: genesisFunds}
case nodeconfig.Testnet:
case nodeconfig.Devnet:
chainConfig = *params.TestnetChainConfig chainConfig = *params.TestnetChainConfig
// Tests account for txgen to use // Tests account for txgen to use
node.AddTestingAddresses(genesisAlloc, TestAccountNumber) node.AddTestingAddresses(genesisAlloc, TestAccountNumber)
@ -77,20 +83,16 @@ func (node *Node) SetupGenesisBlock(db ethdb.Database, shardID uint32, myShardSt
// Smart contract deployer account used to deploy initial smart contract // Smart contract deployer account used to deploy initial smart contract
contractDeployerKey, _ := ecdsa.GenerateKey(crypto.S256(), strings.NewReader("Test contract key string stream that is fixed so that generated test key are deterministic every time")) contractDeployerKey, _ := ecdsa.GenerateKey(crypto.S256(), strings.NewReader("Test contract key string stream that is fixed so that generated test key are deterministic every time"))
contractDeployerAddress := crypto.PubkeyToAddress(contractDeployerKey.PublicKey) contractDeployerAddress := crypto.PubkeyToAddress(contractDeployerKey.PublicKey)
contractDeployerFunds := big.NewInt(TotalInitFund) contractDeployerFunds := big.NewInt(ContractDeployerInitFund)
contractDeployerFunds = contractDeployerFunds.Mul(contractDeployerFunds, big.NewInt(denominations.One)) contractDeployerFunds = contractDeployerFunds.Mul(contractDeployerFunds, big.NewInt(denominations.One))
genesisAlloc[contractDeployerAddress] = core.GenesisAccount{Balance: contractDeployerFunds} genesisAlloc[contractDeployerAddress] = core.GenesisAccount{Balance: contractDeployerFunds}
node.ContractDeployerKey = contractDeployerKey node.ContractDeployerKey = contractDeployerKey
} }
if shardID == 0 {
// Accounts used by validator/nodes to stake and participate in the network.
// AddNodeAddressesToGenesisAlloc(genesisAlloc)
}
// Initialize shard state // Initialize shard state
// TODO: add ShardID into chainconfig and change ChainID to NetworkID // TODO: add ShardID into chainconfig and change ChainID to NetworkID
chainConfig.ChainID = big.NewInt(int64(shardID)) // Use ChainID as piggybacked ShardID chainConfig.ChainID = big.NewInt(int64(shardID)) // Use ChainID as piggybacked ShardID
gspec := core.Genesis{ gspec := core.Genesis{
Config: &chainConfig, Config: &chainConfig,
Alloc: genesisAlloc, Alloc: genesisAlloc,
@ -100,9 +102,7 @@ func (node *Node) SetupGenesisBlock(db ethdb.Database, shardID uint32, myShardSt
} }
// Store genesis block into db. // Store genesis block into db.
_, err := gspec.Commit(db) gspec.MustCommit(db)
return err
} }
// CreateTestBankKeys deterministically generates testing addresses. // CreateTestBankKeys deterministically generates testing addresses.
@ -128,7 +128,7 @@ func CreateTestBankKeys(numAddresses int) (keys []*ecdsa.PrivateKey, err error)
func (node *Node) AddTestingAddresses(gAlloc core.GenesisAlloc, numAddress int) { func (node *Node) AddTestingAddresses(gAlloc core.GenesisAlloc, numAddress int) {
for _, testBankKey := range node.TestBankKeys { for _, testBankKey := range node.TestBankKeys {
testBankAddress := crypto.PubkeyToAddress(testBankKey.PublicKey) testBankAddress := crypto.PubkeyToAddress(testBankKey.PublicKey)
testBankFunds := big.NewInt(InitFreeFundInEther) testBankFunds := big.NewInt(InitFreeFund)
testBankFunds = testBankFunds.Mul(testBankFunds, big.NewInt(denominations.One)) testBankFunds = testBankFunds.Mul(testBankFunds, big.NewInt(denominations.One))
gAlloc[testBankAddress] = core.GenesisAccount{Balance: testBankFunds} gAlloc[testBankAddress] = core.GenesisAccount{Balance: testBankFunds}
} }
@ -138,7 +138,7 @@ func (node *Node) AddTestingAddresses(gAlloc core.GenesisAlloc, numAddress int)
// including the account used by the nodes of the initial beacon chain and later new nodes. // including the account used by the nodes of the initial beacon chain and later new nodes.
func AddNodeAddressesToGenesisAlloc(genesisAlloc core.GenesisAlloc) { func AddNodeAddressesToGenesisAlloc(genesisAlloc core.GenesisAlloc) {
for _, account := range genesis.HarmonyAccounts { for _, account := range genesis.HarmonyAccounts {
testBankFunds := big.NewInt(InitFreeFundInEther) testBankFunds := big.NewInt(InitFreeFund)
testBankFunds = testBankFunds.Mul(testBankFunds, big.NewInt(denominations.One)) testBankFunds = testBankFunds.Mul(testBankFunds, big.NewInt(denominations.One))
address := common2.ParseAddr(account.Address) address := common2.ParseAddr(account.Address)
genesisAlloc[address] = core.GenesisAccount{Balance: testBankFunds} genesisAlloc[address] = core.GenesisAccount{Balance: testBankFunds}

@ -403,56 +403,55 @@ func (node *Node) PostConsensusProcessing(newBlock *types.Block) {
node.AddNewBlock(newBlock) node.AddNewBlock(newBlock)
// Update contract deployer's nonce so default contract like faucet can issue transaction with current nonce if node.NodeConfig.GetNetworkType() != nodeconfig.Mainnet {
nonce := node.GetNonceOfAddress(crypto.PubkeyToAddress(node.ContractDeployerKey.PublicKey))
atomic.StoreUint64(&node.ContractDeployerCurrentNonce, nonce)
for _, tx := range newBlock.Transactions() {
msg, err := tx.AsMessage(types.HomesteadSigner{})
if err != nil {
utils.GetLogInstance().Error("Error when parsing tx into message")
}
if _, ok := node.AddressNonce.Load(msg.From()); ok {
nonce := node.GetNonceOfAddress(msg.From())
node.AddressNonce.Store(msg.From(), nonce)
}
}
if node.Consensus.ShardID == 0 {
// Update contract deployer's nonce so default contract like faucet can issue transaction with current nonce // Update contract deployer's nonce so default contract like faucet can issue transaction with current nonce
nonce := node.GetNonceOfAddress(crypto.PubkeyToAddress(node.ContractDeployerKey.PublicKey)) nonce := node.GetNonceOfAddress(crypto.PubkeyToAddress(node.ContractDeployerKey.PublicKey))
atomic.StoreUint64(&node.ContractDeployerCurrentNonce, nonce) atomic.StoreUint64(&node.ContractDeployerCurrentNonce, nonce)
// TODO: enable drand only for beacon chain for _, tx := range newBlock.Transactions() {
// ConfirmedBlockChannel which is listened by drand leader who will initiate DRG if its a epoch block (first block of a epoch) msg, err := tx.AsMessage(types.HomesteadSigner{})
if node.DRand != nil { if err != nil {
go func() { utils.GetLogInstance().Error("Error when parsing tx into message")
node.ConfirmedBlockChannel <- newBlock }
}() if _, ok := node.AddressNonce.Load(msg.From()); ok {
nonce := node.GetNonceOfAddress(msg.From())
node.AddressNonce.Store(msg.From(), nonce)
}
} }
// TODO: update staking information once per epoch. // TODO: Enable the following after v0
node.UpdateStakingList(node.QueryStakeInfo())
node.printStakingList()
}
newBlockHeader := newBlock.Header()
if newBlockHeader.ShardStateHash != (common.Hash{}) {
if node.Consensus.ShardID == 0 { if node.Consensus.ShardID == 0 {
// TODO ek – this is a temp hack until beacon chain sync is fixed // TODO: enable drand only for beacon chain
// End-of-epoch block on beacon chain; block's EpochState is the // ConfirmedBlockChannel which is listened by drand leader who will initiate DRG if its a epoch block (first block of a epoch)
// master resharding table. Broadcast it to the network. if node.DRand != nil {
if err := node.broadcastEpochShardState(newBlock); err != nil { go func() {
e := ctxerror.New("cannot broadcast shard state").WithCause(err) node.ConfirmedBlockChannel <- newBlock
}()
}
// TODO: update staking information once per epoch.
node.UpdateStakingList(node.QueryStakeInfo())
node.printStakingList()
}
newBlockHeader := newBlock.Header()
if newBlockHeader.ShardStateHash != (common.Hash{}) {
if node.Consensus.ShardID == 0 {
// TODO ek – this is a temp hack until beacon chain sync is fixed
// End-of-epoch block on beacon chain; block's EpochState is the
// master resharding table. Broadcast it to the network.
if err := node.broadcastEpochShardState(newBlock); err != nil {
e := ctxerror.New("cannot broadcast shard state").WithCause(err)
ctxerror.Log15(utils.GetLogInstance().Error, e)
}
}
shardState, err := newBlockHeader.GetShardState()
if err != nil {
e := ctxerror.New("cannot get shard state from header").WithCause(err)
ctxerror.Log15(utils.GetLogInstance().Error, e) ctxerror.Log15(utils.GetLogInstance().Error, e)
} else {
node.transitionIntoNextEpoch(shardState)
} }
} }
shardState, err := newBlockHeader.GetShardState()
if err != nil {
e := ctxerror.New("cannot get shard state from header").WithCause(err)
ctxerror.Log15(utils.GetLogInstance().Error, e)
} else {
node.transitionIntoNextEpoch(shardState)
}
} }
} }

@ -237,7 +237,7 @@ func (node *Node) CalculateResponse(request *downloader_pb.DownloaderRequest) (*
copy(startHashHeader[:], request.BlockHash[:]) copy(startHashHeader[:], request.BlockHash[:])
startBlock := node.Blockchain().GetBlockByHash(startHashHeader) startBlock := node.Blockchain().GetBlockByHash(startHashHeader)
if startBlock == nil { if startBlock == nil {
return response, fmt.Errorf("[SYNC] GetBlockHashes Request cannot find startHash %v", startHashHeader) return response, fmt.Errorf("[SYNC] GetBlockHashes Request cannot find startHash %s", startHashHeader.Hex())
} }
startHeight := startBlock.NumberU64() startHeight := startBlock.NumberU64()
endHeight := node.Blockchain().CurrentBlock().NumberU64() endHeight := node.Blockchain().CurrentBlock().NumberU64()

@ -176,7 +176,7 @@ while IFS='' read -r line || [[ -n "$line" ]]; do
args=("${base_args[@]}" -ip "${ip}" -port "${port}" -key "/tmp/${ip}-${port}.key" -db_dir "db-${ip}-${port}" -accounts "${account}" -blspass file:blspass.txt -blskey_file "${blspub}.key") args=("${base_args[@]}" -ip "${ip}" -port "${port}" -key "/tmp/${ip}-${port}.key" -db_dir "db-${ip}-${port}" -accounts "${account}" -blspass file:blspass.txt -blskey_file "${blspub}.key")
fi fi
args=("${base_args[@]}" -ip "${ip}" -port "${port}" -key "/tmp/${ip}-${port}.key" -db_dir "db-${ip}-${port}" -blspass file:blspass.txt -blskey_file "${blspub}.key") args=("${base_args[@]}" -ip "${ip}" -port "${port}" -key "/tmp/${ip}-${port}.key" -db_dir "db-${ip}-${port}" -blspass file:blspass.txt -blskey_file "${blspub}.key" -dns=false -network_type="testnet")
case "${mode}" in case "${mode}" in
leader*|validator*) args=("${args[@]}" -is_genesis);; leader*|validator*) args=("${args[@]}" -is_genesis);;
esac esac

Loading…
Cancel
Save