package main
import (
"flag"
"fmt"
"io/ioutil"
"math/big"
"math/rand"
"net/http"
_ "net/http/pprof"
"os"
"os/signal"
"path"
"path/filepath"
"runtime"
"strconv"
"strings"
"syscall"
"time"
ethCommon "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/log"
"github.com/harmony-one/bls/ffi/go/bls"
"github.com/harmony-one/harmony/api/service/syncing"
"github.com/harmony-one/harmony/consensus"
"github.com/harmony-one/harmony/consensus/quorum"
"github.com/harmony-one/harmony/core"
"github.com/harmony-one/harmony/internal/blsgen"
"github.com/harmony-one/harmony/internal/common"
nodeconfig "github.com/harmony-one/harmony/internal/configs/node"
shardingconfig "github.com/harmony-one/harmony/internal/configs/sharding"
viperconfig "github.com/harmony-one/harmony/internal/configs/viper"
"github.com/harmony-one/harmony/internal/genesis"
"github.com/harmony-one/harmony/internal/shardchain"
"github.com/harmony-one/harmony/internal/utils"
"github.com/harmony-one/harmony/multibls"
"github.com/harmony-one/harmony/node"
"github.com/harmony-one/harmony/numeric"
"github.com/harmony-one/harmony/p2p"
"github.com/harmony-one/harmony/shard"
"github.com/harmony-one/harmony/webhooks"
[slash][consensus] Notice double sign & broadcast, factor out tech debt of consensus (#2152)
* [slash] Remove dead interface, associated piping
* [slash] Expand out structs
* [consensus] Write to a chan when find a case of double-signing, remove dead code
* [slash] Broadcast the noticing of a double signing
* [rawdb] CRUD for slashing candidates
* [slashing][node][proto] Broadcast the slash record after receive from consensus, handle received proto message, persist in off-chain db while pending
* [slash][node][propose-block] Add verified slashes proposed into the header in block proposal
* [slash][shard] Factor out external validator as method on shard state, add double-signature field
* [slash][engine] Apply slash, name boolean expression for sorts, use stable sort
* [slash] Abstract Ballot results so keep track of both pre and post double sign event
* [slash] Fix type errors on test code
* [slash] Read from correct rawdb
* [slash] Add epoch based guards in CRUD of slashing
* [slash] Write to correct cache for slashing candidates
* [shard] Use explicit named type of BLS Signature, use convention
* [slash] Fix mistake done in refactor, improper header used. Factor out fromSlice to set
* [slash][node] Restore newblock to master, try again minimial change
* [cx-receipts] Break up one-liner, use SliceStable, not Slice
* [network] Finish refactor that makes network message headers once
* [network] Simplify creation further of headers write
* [slash] Adjust data structure of slash after offline discussion with RJ, Chao
* [slash] Still did need signature of the double signature
* [consensus] Prepare message does not have block header
* [consensus] Soft reset three files to 968517d~1
* [consensus] Begin factor consensus network intended message out with prepare first
* [consensus] Factor out Prepared message
* [consensus] Factor out announce message creation
* [consensus] Committed Message, branch on verify sender key for clearer log
* [consensus] Committed Message Factor out
* [consensus] Do jenkins MVP of signatures adjustment
* [main][slash] Provide YAML config as webhook config for double sign event
* [consensus] Adjust signatures, whitespace, lessen GC pressure
* [consensus] Remove dead code
* [consensus] Factor out commit overloaded message, give commit payload override in construct
* [consensus] Fix travis tests
* [consensus] Provide block bytes in SubmitVote(quorum.Commit)
* [consensus] Factor out noisy sanity checks in BFT, move existing commit check earlier as was before
* [quorum] Adjust signatures in quorum
* [staking] Adjust after merge from master
* [consensus] Finish refactor of consensus
* [node] Fix import
* [consensus] Fix travis
* [consensus] Use origin/master copy of block, fix mistake of pointer to empty byte
* [consensus] Less verbose bools
* [consensus] Remove unused trailing mutation hook in message construct
* [consensus] Address some TODOs on err, comment out double sign
5 years ago
"github.com/pkg/errors"
)
// Version string variables
var (
version string
builtBy string
builtAt string
commit string
)
// Host
var (
myHost p2p . Host
initialAccounts = [ ] * genesis . DeployAccount { }
)
func printVersion ( ) {
fmt . Fprintln ( os . Stderr , nodeconfig . GetVersion ( ) )
os . Exit ( 0 )
}
var (
ip = flag . String ( "ip" , "127.0.0.1" , "ip of the node" )
port = flag . String ( "port" , "9000" , "port of the node." )
logFolder = flag . String ( "log_folder" , "latest" , "the folder collecting the logs of this execution" )
logMaxSize = flag . Int ( "log_max_size" , 100 , "the max size in megabytes of the log file before it gets rotated" )
freshDB = flag . Bool ( "fresh_db" , false , "true means the existing disk based db will be removed" )
pprof = flag . String ( "pprof" , "" , "what address and port the pprof profiling server should listen on" )
versionFlag = flag . Bool ( "version" , false , "Output version info" )
dnsZone = flag . String ( "dns_zone" , "" , "if given and not empty, use peers from the zone (default: use libp2p peer discovery instead)" )
dnsFlag = flag . Bool ( "dns" , true , "[deprecated] equivalent to -dns_zone t.hmny.io" )
dnsPort = flag . String ( "dns_port" , "9000" , "port of dns node" )
//Leader needs to have a minimal number of peers to start consensus
minPeers = flag . Int ( "min_peers" , 32 , "Minimal number of Peers in shard" )
// Key file to store the private key
keyFile = flag . String ( "key" , "./.hmykey" , "the p2p key file of the harmony node" )
// isArchival indicates this node is an archival node that will save and archive current blockchain
isArchival = flag . Bool ( "is_archival" , false , "false will enable cached state pruning" )
// delayCommit is the commit-delay timer, used by Harmony nodes
delayCommit = flag . String ( "delay_commit" , "0ms" , "how long to delay sending commit messages in consensus, ex: 500ms, 1s" )
// nodeType indicates the type of the node: validator, explorer
nodeType = flag . String ( "node_type" , "validator" , "node type: validator, explorer" )
// networkType indicates the type of the network
networkType = flag . String ( "network_type" , "mainnet" , "type of the network: mainnet, testnet, pangaea, partner, stressnet, devnet, localnet" )
// blockPeriod indicates the how long the leader waits to propose a new block.
blockPeriod = flag . Int ( "block_period" , 8 , "how long in second the leader waits to propose a new block." )
// staking indicates whether the node is operating in staking mode.
stakingFlag = flag . Bool ( "staking" , false , "whether the node should operate in staking mode" )
// shardID indicates the shard ID of this node
shardID = flag . Int ( "shard_id" , - 1 , "the shard ID of this node" )
cmkEncryptedBLSKey = flag . String ( "aws_blskey" , "" , "The aws CMK encrypted bls private key file." )
blsKeyFile = flag . String ( "blskey_file" , "" , "The encrypted file of bls serialized private key by passphrase." )
blsFolder = flag . String ( "blsfolder" , ".hmy/blskeys" , "The folder that stores the bls keys and corresponding passphrases; e.g. <blskey>.key and <blskey>.pass; all bls keys mapped to same shard" )
blsPass = flag . String ( "blspass" , "" , "The file containing passphrase to decrypt the encrypted bls file." )
blsPassphrase string
maxBLSKeysPerNode = flag . Int ( "max_bls_keys_per_node" , 4 , "maximum number of bls keys allowed per node (default 4)" )
// Sharding configuration parameters for devnet
devnetNumShards = flag . Uint ( "dn_num_shards" , 2 , "number of shards for -network_type=devnet (default: 2)" )
devnetShardSize = flag . Int ( "dn_shard_size" , 10 , "number of nodes per shard for -network_type=devnet (default 10)" )
devnetHarmonySize = flag . Int ( "dn_hmy_size" , - 1 , "number of Harmony-operated nodes per shard for -network_type=devnet; negative (default) means equal to -dn_shard_size" )
// logging verbosity
verbosity = flag . Int ( "verbosity" , 5 , "Logging verbosity: 0=silent, 1=error, 2=warn, 3=info, 4=debug, 5=detail (default: 5)" )
// dbDir is the database directory.
dbDir = flag . String ( "db_dir" , "" , "blockchain database directory" )
publicRPC = flag . Bool ( "public_rpc" , false , "Enable Public RPC Access (default: false)" )
// Bad block revert
doRevertBefore = flag . Int ( "do_revert_before" , 0 , "If the current block is less than do_revert_before, revert all blocks until (including) revert_to block" )
revertTo = flag . Int ( "revert_to" , 0 , "The revert will rollback all blocks until and including block number revert_to" )
revertBeacon = flag . Bool ( "revert_beacon" , false , "Whether to revert beacon chain or the chain this node is assigned to" )
// Blacklist of addresses
blacklistPath = flag . String ( "blacklist" , "./.hmy/blacklist.txt" , "Path to newline delimited file of blacklisted wallet addresses" )
broadcastInvalidTx = flag . Bool ( "broadcast_invalid_tx" , false , "Broadcast invalid transactions to sync pool state (default: false)" )
webHookYamlPath = flag . String (
[slash][consensus] Notice double sign & broadcast, factor out tech debt of consensus (#2152)
* [slash] Remove dead interface, associated piping
* [slash] Expand out structs
* [consensus] Write to a chan when find a case of double-signing, remove dead code
* [slash] Broadcast the noticing of a double signing
* [rawdb] CRUD for slashing candidates
* [slashing][node][proto] Broadcast the slash record after receive from consensus, handle received proto message, persist in off-chain db while pending
* [slash][node][propose-block] Add verified slashes proposed into the header in block proposal
* [slash][shard] Factor out external validator as method on shard state, add double-signature field
* [slash][engine] Apply slash, name boolean expression for sorts, use stable sort
* [slash] Abstract Ballot results so keep track of both pre and post double sign event
* [slash] Fix type errors on test code
* [slash] Read from correct rawdb
* [slash] Add epoch based guards in CRUD of slashing
* [slash] Write to correct cache for slashing candidates
* [shard] Use explicit named type of BLS Signature, use convention
* [slash] Fix mistake done in refactor, improper header used. Factor out fromSlice to set
* [slash][node] Restore newblock to master, try again minimial change
* [cx-receipts] Break up one-liner, use SliceStable, not Slice
* [network] Finish refactor that makes network message headers once
* [network] Simplify creation further of headers write
* [slash] Adjust data structure of slash after offline discussion with RJ, Chao
* [slash] Still did need signature of the double signature
* [consensus] Prepare message does not have block header
* [consensus] Soft reset three files to 968517d~1
* [consensus] Begin factor consensus network intended message out with prepare first
* [consensus] Factor out Prepared message
* [consensus] Factor out announce message creation
* [consensus] Committed Message, branch on verify sender key for clearer log
* [consensus] Committed Message Factor out
* [consensus] Do jenkins MVP of signatures adjustment
* [main][slash] Provide YAML config as webhook config for double sign event
* [consensus] Adjust signatures, whitespace, lessen GC pressure
* [consensus] Remove dead code
* [consensus] Factor out commit overloaded message, give commit payload override in construct
* [consensus] Fix travis tests
* [consensus] Provide block bytes in SubmitVote(quorum.Commit)
* [consensus] Factor out noisy sanity checks in BFT, move existing commit check earlier as was before
* [quorum] Adjust signatures in quorum
* [staking] Adjust after merge from master
* [consensus] Finish refactor of consensus
* [node] Fix import
* [consensus] Fix travis
* [consensus] Use origin/master copy of block, fix mistake of pointer to empty byte
* [consensus] Less verbose bools
* [consensus] Remove unused trailing mutation hook in message construct
* [consensus] Address some TODOs on err, comment out double sign
5 years ago
"webhook_yaml" , "" , "path for yaml config reporting double signing" ,
)
// aws credentials
awsSettingString = ""
)
func initSetup ( ) {
// Setup pprof
if addr := * pprof ; addr != "" {
go func ( ) { http . ListenAndServe ( addr , nil ) } ( )
}
// maybe request passphrase for bls key.
if * cmkEncryptedBLSKey == "" {
passphraseForBLS ( )
} else {
// Get aws credentials from stdin prompt
awsSettingString , _ = blsgen . Readln ( 1 * time . Second )
}
// Configure log parameters
utils . SetLogContext ( * port , * ip )
utils . SetLogVerbosity ( log . Lvl ( * verbosity ) )
utils . AddLogFile ( fmt . Sprintf ( "%v/validator-%v-%v.log" , * logFolder , * ip , * port ) , * logMaxSize )
// Don't set higher than num of CPU. It will make go scheduler slower.
runtime . GOMAXPROCS ( runtime . NumCPU ( ) )
// Set port and ip to global config.
nodeconfig . GetDefaultConfig ( ) . Port = * port
nodeconfig . GetDefaultConfig ( ) . IP = * ip
// Set sharding schedule
nodeconfig . SetShardingSchedule ( shard . Schedule )
// Set up randomization seed.
rand . Seed ( int64 ( time . Now ( ) . Nanosecond ( ) ) )
if len ( p2p . BootNodes ) == 0 {
bootNodeAddrs , err := p2p . StringsToAddrs ( p2p . DefaultBootNodeAddrStrings )
if err != nil {
utils . FatalErrMsg ( err , "cannot parse default bootnode list %#v" ,
p2p . DefaultBootNodeAddrStrings )
}
p2p . BootNodes = bootNodeAddrs
}
}
func passphraseForBLS ( ) {
// If FN node running, they should either specify blsPrivateKey or the file with passphrase
// However, explorer or non-validator nodes need no blskey
if * nodeType != "validator" {
return
}
if * blsKeyFile == "" && * blsFolder == "" {
fmt . Println ( "blskey_file or blsfolder option must be provided" )
os . Exit ( 101 )
}
if * blsPass == "" {
fmt . Println ( "Internal nodes need to have blspass to decrypt blskey" )
os . Exit ( 101 )
}
passphrase , err := utils . GetPassphraseFromSource ( * blsPass )
if err != nil {
_ , _ = fmt . Fprintf ( os . Stderr , "ERROR when reading passphrase file: %v\n" , err )
os . Exit ( 100 )
}
blsPassphrase = passphrase
}
func findAccountsByPubKeys ( config shardingconfig . Instance , pubKeys multibls . PublicKeys ) {
for _ , key := range pubKeys {
keyStr := key . Bytes . Hex ( )
_ , account := config . FindAccount ( keyStr )
if account != nil {
initialAccounts = append ( initialAccounts , account )
}
}
}
func setupLegacyNodeAccount ( ) error {
genesisShardingConfig := shard . Schedule . InstanceForEpoch ( big . NewInt ( core . GenesisEpoch ) )
multiBLSPubKey := setupConsensusKey ( nodeconfig . GetDefaultConfig ( ) ) . GetPublicKeys ( )
reshardingEpoch := genesisShardingConfig . ReshardingEpoch ( )
if len ( reshardingEpoch ) > 0 {
for _ , epoch := range reshardingEpoch {
config := shard . Schedule . InstanceForEpoch ( epoch )
findAccountsByPubKeys ( config , multiBLSPubKey )
if len ( initialAccounts ) != 0 {
break
}
}
} else {
findAccountsByPubKeys ( genesisShardingConfig , multiBLSPubKey )
}
if len ( initialAccounts ) == 0 {
fmt . Fprintf (
os . Stderr ,
"ERROR cannot find your BLS key in the genesis/FN tables: %s\n" ,
multiBLSPubKey . SerializeToHexStr ( ) ,
)
os . Exit ( 100 )
}
for _ , account := range initialAccounts {
fmt . Printf ( "My Genesis Account: %v\n" , * account )
}
return nil
}
func setupStakingNodeAccount ( ) error {
pubKey := setupConsensusKey ( nodeconfig . GetDefaultConfig ( ) ) . GetPublicKeys ( )
shardID , err := nodeconfig . GetDefaultConfig ( ) . ShardIDFromConsensusKey ( )
if err != nil {
return errors . Wrap ( err , "cannot determine shard to join" )
}
if err := nodeconfig . GetDefaultConfig ( ) . ValidateConsensusKeysForSameShard (
pubKey , shardID ,
) ; err != nil {
return err
}
for _ , blsKey := range pubKey {
initialAccount := & genesis . DeployAccount { }
initialAccount . ShardID = shardID
initialAccount . BLSPublicKey = blsKey . Bytes . Hex ( )
initialAccount . Address = ""
initialAccounts = append ( initialAccounts , initialAccount )
}
return nil
}
func readMultiBLSKeys ( consensusMultiBLSPriKey * multibls . PrivateKeys ) error {
keyPasses := map [ string ] string { }
blsKeyFiles := [ ] os . FileInfo { }
awsEncryptedBLSKeyFiles := [ ] os . FileInfo { }
if err := filepath . Walk ( * blsFolder , func ( path string , info os . FileInfo , err error ) error {
if info . IsDir ( ) {
return nil
}
fullName := info . Name ( )
ext := filepath . Ext ( fullName )
if ext == ".key" {
blsKeyFiles = append ( blsKeyFiles , info )
} else if ext == ".pass" {
passFileName := "file:" + path
passphrase , err := utils . GetPassphraseFromSource ( passFileName )
if err != nil {
return err
}
name := fullName [ : len ( fullName ) - len ( ext ) ]
keyPasses [ name ] = passphrase
} else if ext == ".bls" {
awsEncryptedBLSKeyFiles = append ( awsEncryptedBLSKeyFiles , info )
} else {
return errors . Errorf (
"[Multi-BLS] found file: %s that does not have .bls, .key or .pass file extension" ,
path ,
)
}
return nil
} ) ; err != nil {
fmt . Fprintf ( os . Stderr ,
"[Multi-BLS] ERROR when reading blskey file under %s: %v\n" ,
* blsFolder ,
err ,
)
os . Exit ( 100 )
}
var keyFiles [ ] os . FileInfo
legacyBLSFile := true
if len ( awsEncryptedBLSKeyFiles ) > 0 {
keyFiles = awsEncryptedBLSKeyFiles
legacyBLSFile = false
} else {
keyFiles = blsKeyFiles
}
if len ( keyFiles ) > * maxBLSKeysPerNode {
fmt . Fprintf ( os . Stderr ,
"[Multi-BLS] maximum number of bls keys per node is %d, found: %d\n" ,
* maxBLSKeysPerNode ,
len ( keyFiles ) ,
)
os . Exit ( 100 )
}
for _ , blsKeyFile := range keyFiles {
var consensusPriKey * bls . SecretKey
var err error
blsKeyFilePath := path . Join ( * blsFolder , blsKeyFile . Name ( ) )
if legacyBLSFile {
fullName := blsKeyFile . Name ( )
ext := filepath . Ext ( fullName )
name := fullName [ : len ( fullName ) - len ( ext ) ]
if val , ok := keyPasses [ name ] ; ok {
blsPassphrase = val
}
consensusPriKey , err = blsgen . LoadBLSKeyWithPassPhrase ( blsKeyFilePath , blsPassphrase )
} else {
consensusPriKey , err = blsgen . LoadAwsCMKEncryptedBLSKey ( blsKeyFilePath , awsSettingString )
}
if err != nil {
return err
}
* consensusMultiBLSPriKey = append ( * consensusMultiBLSPriKey , multibls . GetPrivateKeys ( consensusPriKey ) ... )
}
return nil
}
func setupConsensusKey ( nodeConfig * nodeconfig . ConfigType ) multibls . PrivateKeys {
consensusMultiPriKey := multibls . PrivateKeys { }
if * blsKeyFile != "" {
consensusPriKey , err := blsgen . LoadBLSKeyWithPassPhrase ( * blsKeyFile , blsPassphrase )
if err != nil {
fmt . Fprintf ( os . Stderr , "ERROR when loading bls key, err :%v\n" , err )
os . Exit ( 100 )
}
consensusMultiPriKey = append ( consensusMultiPriKey , multibls . GetPrivateKeys ( consensusPriKey ) ... )
} else if * cmkEncryptedBLSKey != "" {
consensusPriKey , err := blsgen . LoadAwsCMKEncryptedBLSKey ( * cmkEncryptedBLSKey , awsSettingString )
if err != nil {
fmt . Fprintf ( os . Stderr , "ERROR when loading aws CMK encrypted bls key, err :%v\n" , err )
os . Exit ( 100 )
}
consensusMultiPriKey = append ( consensusMultiPriKey , multibls . GetPrivateKeys ( consensusPriKey ) ... )
} else {
err := readMultiBLSKeys ( & consensusMultiPriKey )
if err != nil {
fmt . Fprintf ( os . Stderr , "[Multi-BLS] ERROR when loading bls keys, err :%v\n" , err )
os . Exit ( 100 )
}
}
// Consensus keys are the BLS12-381 keys used to sign consensus messages
nodeConfig . ConsensusPriKey = consensusMultiPriKey
return consensusMultiPriKey
}
func createGlobalConfig ( ) ( * nodeconfig . ConfigType , error ) {
var err error
if len ( initialAccounts ) == 0 {
initialAccounts = append ( initialAccounts , & genesis . DeployAccount { ShardID : uint32 ( * shardID ) } )
}
nodeConfig := nodeconfig . GetShardConfig ( initialAccounts [ 0 ] . ShardID )
if * nodeType == "validator" {
// Set up consensus keys.
setupConsensusKey ( nodeConfig )
} else {
// set dummy bls key for consensus object
nodeConfig . ConsensusPriKey = multibls . GetPrivateKeys ( & bls . SecretKey { } )
}
// Set network type
netType := nodeconfig . NetworkType ( * networkType )
nodeconfig . SetNetworkType ( netType ) // sets for both global and shard configs
nodeConfig . SetArchival ( * isArchival )
// P2P private key is used for secure message transfer between p2p nodes.
nodeConfig . P2PPriKey , _ , err = utils . LoadKeyFromFile ( * keyFile )
if err != nil {
return nil , errors . Wrapf ( err , "cannot load or create P2P key at %#v" ,
* keyFile )
}
selfPeer := p2p . Peer {
IP : * ip ,
Port : * port ,
ConsensusPubKey : nodeConfig . ConsensusPriKey [ 0 ] . Pub . Object ,
}
myHost , err = p2p . NewHost ( & selfPeer , nodeConfig . P2PPriKey )
if err != nil {
return nil , errors . Wrap ( err , "cannot create P2P network host" )
}
nodeConfig . DBDir = * dbDir
[double-sign] Provide proof of double sign in slash record sent to beaconchain (#2253)
* [double-sign] Commit changes in consensus needed for double-sign
* [double-sign] Leader captures when valdator double signs, broadcasts to beaconchain
* [slash] Add quick iteration tool for testing double-signing
* [slash] Add webhook example
* [slash] Add http server for hook to trigger double sign behavior
* [double-sign] Use bin/trigger-double-sign to cause a double-sign
* [double-sign] Full feedback loop working
* [slash] Thread through the slash records in the block proposal step
* [slash] Compute the slashing rate
* [double-sign] Generalize yaml malicious for many keys
* [double-sign][slash] Modify data structures, verify via webhook handler
* [slash][double-sign] Find one address of bls public key signer, seemingly settle on data structures
* [slash] Apply to state slashing for double signing
* [slash][double-sign] Checkpoint for working code that slashes on beaconchain
* [slash] Keep track of the total slash and total reporters reward
* [slash] Dump account state before and after the slash
* [slash] Satisfy Travis
* [slash][state] Apply slash to the snapshot at beginning of epoch, now need to capture also the new delegates
* [slash] Capture the unique new delegations since snapshot as well
* [slash] Filter undelegation by epoch of double sign
* [slash] Add TODO of correctness needed in slash needs on off-chain data
* [rpc] Fix closure issue on shardID
* [slash] Add delegator to double-sign testing script
* [slash] Expand crt-validator.sh with commenting printfs and make delegation
* [slash] Finish track payment of leftover slash debt after undelegation runs out
* [slash] Now be explicit about error wrt delegatorSlashApply
* [slash] Capture specific sanity check on slash paidoff
* [slash] Track slash from undelegation piecemeal
* [slash][delegation] Named slice types, .String()
* [slash] Do no RLP encode twice, once is enough
* [slash] Remove special case of validators own delegation
* [slash] Refactor approach to slash state application
* [slash] Begin expanding out Verify
* [slash] Slash on snapshot delegations, not current
* [slash] Fix Epoch Cmp
* [slash] Third iteration on slash logic
* [slash] Use full slash amount
* [slash] More log, whitespace
* [slash] Remove Println, add log
* [slash] Remove debug Println
* [slash] Add record in unit test
* [slash] Build Validator snapshot, current. Fill out slash record
* [slash] Need to get RLP dump of a header to use in test
* [slash] Factor out double sign test constants
* [slash] Factor out common for validator, stub out slash application, finish out deserialization setup
* [slash] Factor out data structure creation because of var lexical scoping
* [slash] Seem to have pipeline of unit test e2e executing
* [slash] Add expected snitch, slash amounts
* [slash] Checkpoint
* [slash] Unit test correctly checks case of validator own stake which could drop below 1 ONE in slashing
* [config] add double-sign testnet config (#1)
Signed-off-by: Leo Chen <leo@harmony.one>
* [slash] Commit for as is code & data of current dump.json
* [slash] Order of state operation not correct in test, hence bad results, thank you dlv
* [slash] Add snapshot state dump
* [slash] Pay off slash of validator own delegation correctly
* [slash] Pay off slash debt with special case for min-self
* [slash] Pass first scenario conclusively
* [slash] 2% slash passes unit test for own delegation and external
* [slash] Parameterize unit test to easily test .02 vs .80 slash
* [slash] Handle own delegation correctly at 80% slash
* [slash] Have 80% slash working with external delegator
* [slash] Remove debug code from slash
* [slash] Adjust Apply signature, test again for 2% slash
* [slash] Factor out scenario in testing so can test 2% and 80% at same time
* [slash] Correct balance deduction on plan delegation
* [slash] Mock out ChainReader for TestVerify
* [slash] Small surface area interface, now feedback loop for verify
* [slash] Remove development json
* [slash] trigger-double-sign consumes yaml
* [slash] Remove dead code
* [slash][test] Factor ValidatorWrapper into scenario
* [slash][test] Add example from local-testing dump - caution might be off
* [slash] Factor out mutation of slashDebt
* [slash][test] Factor out tests so can easily load test-case from bytes
* [slash] Fix payment mistake in validator own delegation wrt min-self-delgation respected
* [slash] Satisfy Travis
* [slash] Begin cleanup of PR
* [slash] Apply slash from header to Finalize via state processor
* [slash] Productionize code, Println => logs; adjust slash picked in newblock
* [slash] Need pointer for rlp.Decode
* [slash] ValidatorInformation use full wrapper
* Fix median stake
* [staking] Adjust MarshalJSON for Validator, Wrapper
* Refactor offchain data commit; Make block onchain/offchain commit atomic (#2279)
* Refactor offchain data; Add epoch to ValidatorSnapshot
* Make block onchain/offchain data commit atomically
* [slash][committee] Set .Active to false on double sign, do not consider banned or inactive for committee assignment
* [effective] VC eligible.go
* [consensus] Redundant field in printf
* [docker] import-ks for a dev account
* [slash] Create BLS key for dockerfile and crt-validator.sh
* [slash][docker] Easy deployment of double-sign testing
* [docker] Have slash work as single docker command
* [rpc] Fix median-stake RPC
* [slash] Update webhook with default docker BLS key
* [docker][slash] Fresh yaml copy for docker build, remove dev code in main.go
* [slash] Remove helper binary, commented out code, change to local config
* [params] Factor out test genesis value
* Add shard checking to Tx-Pool & correct blacklist (#2301)
* [core] Fix blacklist & add shardID check
* [staking + node + cmd] Fix blacklist & add shardID check
* [slash] Adjust to PR comments part 1
* [docker] Use different throw away funded account
* [docker] Create easier testing for delegation with private keys
* [docker] Update yaml
* [slash] Remove special case for slashing validator own delegation wrt min-self-delegate
* [docker] Install nano as well
* [slash] Early error if banned
* [quorum] Expose earning account in decider marshal json
* Revert "Refactor offchain data commit; Make block onchain/offchain commit atomic (#2279)"
This reverts commit 9ffbf682c075b49188923c65a0bbf39ac188be00.
* [slash] Add non-sanity check way to update validator
* [reward] Increase percision on percentage in schedule
* [slash] Adjust logs
* [committee] Check eligibility of validator before doing sanity check
* [slash] Update docker
* [slash] Move create validator script to test
* [slash] More log
* [param] Make things faster
* [slash][off-chain] Clear out slashes from pending in writeblockwithstate
* [cross-link] Log is not error, just info
* [blockchain] Not necessary to guard DeletePendingSlashingCandidates
* [slash][consensus] Use plain []byte for signature b/c bls.Sign has private impl fields, rlp does not encode that
* [slash][test] Use faucet as sender, assume user imported
* [slash] Test setup
* [slash] reserve error for real error in logs
* [slash][availability] Apply availability correct, bump signing count each block
* [slash][staking] Consider banned field in sanity check, pay snitch only half of what was actually slashed
* [slash] Pay as much as can
* [slash] use right nowAmt
* [slash] Take away from rewards as well
* [slash] iterate faster
* [slash] Remove dev based timing
* [slash] Add more log, sanity check incoming slash records, only count external for slash rate
* [availability][state] Adjust signature of ValidatorWrapper wrt state, filter out for staked validators, correct availaibility measure on running counters
* [availability] More log
* [slash] Simply pre slash erra slashing
* [slash] Remove development code
* [slash] Use height from recvMsg, todo on epoch
* [staking] Not necessary to touch LastEpochInCommittee in staking_verifier
* [slash] Undo ds in endpoint pattern config
* [slash] Add TODO and log when delegation becomes 0 b/c slash debt payment
* [slash] Abstract staked validators from shard.State into type, set slash rate based BLSKey count
Co-authored-by: Leo Chen <leo@harmony.one>
Co-authored-by: flicker-harmony <52401354+flicker-harmony@users.noreply.github.com>
Co-authored-by: Rongjian Lan <rongjian@harmony.one>
Co-authored-by: Daniel Van Der Maden <daniel@harmony.one>
5 years ago
if p := * webHookYamlPath ; p != "" {
config , err := webhooks . NewWebHooksFromPath ( p )
[double-sign] Provide proof of double sign in slash record sent to beaconchain (#2253)
* [double-sign] Commit changes in consensus needed for double-sign
* [double-sign] Leader captures when valdator double signs, broadcasts to beaconchain
* [slash] Add quick iteration tool for testing double-signing
* [slash] Add webhook example
* [slash] Add http server for hook to trigger double sign behavior
* [double-sign] Use bin/trigger-double-sign to cause a double-sign
* [double-sign] Full feedback loop working
* [slash] Thread through the slash records in the block proposal step
* [slash] Compute the slashing rate
* [double-sign] Generalize yaml malicious for many keys
* [double-sign][slash] Modify data structures, verify via webhook handler
* [slash][double-sign] Find one address of bls public key signer, seemingly settle on data structures
* [slash] Apply to state slashing for double signing
* [slash][double-sign] Checkpoint for working code that slashes on beaconchain
* [slash] Keep track of the total slash and total reporters reward
* [slash] Dump account state before and after the slash
* [slash] Satisfy Travis
* [slash][state] Apply slash to the snapshot at beginning of epoch, now need to capture also the new delegates
* [slash] Capture the unique new delegations since snapshot as well
* [slash] Filter undelegation by epoch of double sign
* [slash] Add TODO of correctness needed in slash needs on off-chain data
* [rpc] Fix closure issue on shardID
* [slash] Add delegator to double-sign testing script
* [slash] Expand crt-validator.sh with commenting printfs and make delegation
* [slash] Finish track payment of leftover slash debt after undelegation runs out
* [slash] Now be explicit about error wrt delegatorSlashApply
* [slash] Capture specific sanity check on slash paidoff
* [slash] Track slash from undelegation piecemeal
* [slash][delegation] Named slice types, .String()
* [slash] Do no RLP encode twice, once is enough
* [slash] Remove special case of validators own delegation
* [slash] Refactor approach to slash state application
* [slash] Begin expanding out Verify
* [slash] Slash on snapshot delegations, not current
* [slash] Fix Epoch Cmp
* [slash] Third iteration on slash logic
* [slash] Use full slash amount
* [slash] More log, whitespace
* [slash] Remove Println, add log
* [slash] Remove debug Println
* [slash] Add record in unit test
* [slash] Build Validator snapshot, current. Fill out slash record
* [slash] Need to get RLP dump of a header to use in test
* [slash] Factor out double sign test constants
* [slash] Factor out common for validator, stub out slash application, finish out deserialization setup
* [slash] Factor out data structure creation because of var lexical scoping
* [slash] Seem to have pipeline of unit test e2e executing
* [slash] Add expected snitch, slash amounts
* [slash] Checkpoint
* [slash] Unit test correctly checks case of validator own stake which could drop below 1 ONE in slashing
* [config] add double-sign testnet config (#1)
Signed-off-by: Leo Chen <leo@harmony.one>
* [slash] Commit for as is code & data of current dump.json
* [slash] Order of state operation not correct in test, hence bad results, thank you dlv
* [slash] Add snapshot state dump
* [slash] Pay off slash of validator own delegation correctly
* [slash] Pay off slash debt with special case for min-self
* [slash] Pass first scenario conclusively
* [slash] 2% slash passes unit test for own delegation and external
* [slash] Parameterize unit test to easily test .02 vs .80 slash
* [slash] Handle own delegation correctly at 80% slash
* [slash] Have 80% slash working with external delegator
* [slash] Remove debug code from slash
* [slash] Adjust Apply signature, test again for 2% slash
* [slash] Factor out scenario in testing so can test 2% and 80% at same time
* [slash] Correct balance deduction on plan delegation
* [slash] Mock out ChainReader for TestVerify
* [slash] Small surface area interface, now feedback loop for verify
* [slash] Remove development json
* [slash] trigger-double-sign consumes yaml
* [slash] Remove dead code
* [slash][test] Factor ValidatorWrapper into scenario
* [slash][test] Add example from local-testing dump - caution might be off
* [slash] Factor out mutation of slashDebt
* [slash][test] Factor out tests so can easily load test-case from bytes
* [slash] Fix payment mistake in validator own delegation wrt min-self-delgation respected
* [slash] Satisfy Travis
* [slash] Begin cleanup of PR
* [slash] Apply slash from header to Finalize via state processor
* [slash] Productionize code, Println => logs; adjust slash picked in newblock
* [slash] Need pointer for rlp.Decode
* [slash] ValidatorInformation use full wrapper
* Fix median stake
* [staking] Adjust MarshalJSON for Validator, Wrapper
* Refactor offchain data commit; Make block onchain/offchain commit atomic (#2279)
* Refactor offchain data; Add epoch to ValidatorSnapshot
* Make block onchain/offchain data commit atomically
* [slash][committee] Set .Active to false on double sign, do not consider banned or inactive for committee assignment
* [effective] VC eligible.go
* [consensus] Redundant field in printf
* [docker] import-ks for a dev account
* [slash] Create BLS key for dockerfile and crt-validator.sh
* [slash][docker] Easy deployment of double-sign testing
* [docker] Have slash work as single docker command
* [rpc] Fix median-stake RPC
* [slash] Update webhook with default docker BLS key
* [docker][slash] Fresh yaml copy for docker build, remove dev code in main.go
* [slash] Remove helper binary, commented out code, change to local config
* [params] Factor out test genesis value
* Add shard checking to Tx-Pool & correct blacklist (#2301)
* [core] Fix blacklist & add shardID check
* [staking + node + cmd] Fix blacklist & add shardID check
* [slash] Adjust to PR comments part 1
* [docker] Use different throw away funded account
* [docker] Create easier testing for delegation with private keys
* [docker] Update yaml
* [slash] Remove special case for slashing validator own delegation wrt min-self-delegate
* [docker] Install nano as well
* [slash] Early error if banned
* [quorum] Expose earning account in decider marshal json
* Revert "Refactor offchain data commit; Make block onchain/offchain commit atomic (#2279)"
This reverts commit 9ffbf682c075b49188923c65a0bbf39ac188be00.
* [slash] Add non-sanity check way to update validator
* [reward] Increase percision on percentage in schedule
* [slash] Adjust logs
* [committee] Check eligibility of validator before doing sanity check
* [slash] Update docker
* [slash] Move create validator script to test
* [slash] More log
* [param] Make things faster
* [slash][off-chain] Clear out slashes from pending in writeblockwithstate
* [cross-link] Log is not error, just info
* [blockchain] Not necessary to guard DeletePendingSlashingCandidates
* [slash][consensus] Use plain []byte for signature b/c bls.Sign has private impl fields, rlp does not encode that
* [slash][test] Use faucet as sender, assume user imported
* [slash] Test setup
* [slash] reserve error for real error in logs
* [slash][availability] Apply availability correct, bump signing count each block
* [slash][staking] Consider banned field in sanity check, pay snitch only half of what was actually slashed
* [slash] Pay as much as can
* [slash] use right nowAmt
* [slash] Take away from rewards as well
* [slash] iterate faster
* [slash] Remove dev based timing
* [slash] Add more log, sanity check incoming slash records, only count external for slash rate
* [availability][state] Adjust signature of ValidatorWrapper wrt state, filter out for staked validators, correct availaibility measure on running counters
* [availability] More log
* [slash] Simply pre slash erra slashing
* [slash] Remove development code
* [slash] Use height from recvMsg, todo on epoch
* [staking] Not necessary to touch LastEpochInCommittee in staking_verifier
* [slash] Undo ds in endpoint pattern config
* [slash] Add TODO and log when delegation becomes 0 b/c slash debt payment
* [slash] Abstract staked validators from shard.State into type, set slash rate based BLSKey count
Co-authored-by: Leo Chen <leo@harmony.one>
Co-authored-by: flicker-harmony <52401354+flicker-harmony@users.noreply.github.com>
Co-authored-by: Rongjian Lan <rongjian@harmony.one>
Co-authored-by: Daniel Van Der Maden <daniel@harmony.one>
5 years ago
if err != nil {
fmt . Fprintf (
os . Stderr , "yaml path is bad: %s" , p ,
)
os . Exit ( 1 )
}
nodeConfig . WebHooks . Hooks = config
[double-sign] Provide proof of double sign in slash record sent to beaconchain (#2253)
* [double-sign] Commit changes in consensus needed for double-sign
* [double-sign] Leader captures when valdator double signs, broadcasts to beaconchain
* [slash] Add quick iteration tool for testing double-signing
* [slash] Add webhook example
* [slash] Add http server for hook to trigger double sign behavior
* [double-sign] Use bin/trigger-double-sign to cause a double-sign
* [double-sign] Full feedback loop working
* [slash] Thread through the slash records in the block proposal step
* [slash] Compute the slashing rate
* [double-sign] Generalize yaml malicious for many keys
* [double-sign][slash] Modify data structures, verify via webhook handler
* [slash][double-sign] Find one address of bls public key signer, seemingly settle on data structures
* [slash] Apply to state slashing for double signing
* [slash][double-sign] Checkpoint for working code that slashes on beaconchain
* [slash] Keep track of the total slash and total reporters reward
* [slash] Dump account state before and after the slash
* [slash] Satisfy Travis
* [slash][state] Apply slash to the snapshot at beginning of epoch, now need to capture also the new delegates
* [slash] Capture the unique new delegations since snapshot as well
* [slash] Filter undelegation by epoch of double sign
* [slash] Add TODO of correctness needed in slash needs on off-chain data
* [rpc] Fix closure issue on shardID
* [slash] Add delegator to double-sign testing script
* [slash] Expand crt-validator.sh with commenting printfs and make delegation
* [slash] Finish track payment of leftover slash debt after undelegation runs out
* [slash] Now be explicit about error wrt delegatorSlashApply
* [slash] Capture specific sanity check on slash paidoff
* [slash] Track slash from undelegation piecemeal
* [slash][delegation] Named slice types, .String()
* [slash] Do no RLP encode twice, once is enough
* [slash] Remove special case of validators own delegation
* [slash] Refactor approach to slash state application
* [slash] Begin expanding out Verify
* [slash] Slash on snapshot delegations, not current
* [slash] Fix Epoch Cmp
* [slash] Third iteration on slash logic
* [slash] Use full slash amount
* [slash] More log, whitespace
* [slash] Remove Println, add log
* [slash] Remove debug Println
* [slash] Add record in unit test
* [slash] Build Validator snapshot, current. Fill out slash record
* [slash] Need to get RLP dump of a header to use in test
* [slash] Factor out double sign test constants
* [slash] Factor out common for validator, stub out slash application, finish out deserialization setup
* [slash] Factor out data structure creation because of var lexical scoping
* [slash] Seem to have pipeline of unit test e2e executing
* [slash] Add expected snitch, slash amounts
* [slash] Checkpoint
* [slash] Unit test correctly checks case of validator own stake which could drop below 1 ONE in slashing
* [config] add double-sign testnet config (#1)
Signed-off-by: Leo Chen <leo@harmony.one>
* [slash] Commit for as is code & data of current dump.json
* [slash] Order of state operation not correct in test, hence bad results, thank you dlv
* [slash] Add snapshot state dump
* [slash] Pay off slash of validator own delegation correctly
* [slash] Pay off slash debt with special case for min-self
* [slash] Pass first scenario conclusively
* [slash] 2% slash passes unit test for own delegation and external
* [slash] Parameterize unit test to easily test .02 vs .80 slash
* [slash] Handle own delegation correctly at 80% slash
* [slash] Have 80% slash working with external delegator
* [slash] Remove debug code from slash
* [slash] Adjust Apply signature, test again for 2% slash
* [slash] Factor out scenario in testing so can test 2% and 80% at same time
* [slash] Correct balance deduction on plan delegation
* [slash] Mock out ChainReader for TestVerify
* [slash] Small surface area interface, now feedback loop for verify
* [slash] Remove development json
* [slash] trigger-double-sign consumes yaml
* [slash] Remove dead code
* [slash][test] Factor ValidatorWrapper into scenario
* [slash][test] Add example from local-testing dump - caution might be off
* [slash] Factor out mutation of slashDebt
* [slash][test] Factor out tests so can easily load test-case from bytes
* [slash] Fix payment mistake in validator own delegation wrt min-self-delgation respected
* [slash] Satisfy Travis
* [slash] Begin cleanup of PR
* [slash] Apply slash from header to Finalize via state processor
* [slash] Productionize code, Println => logs; adjust slash picked in newblock
* [slash] Need pointer for rlp.Decode
* [slash] ValidatorInformation use full wrapper
* Fix median stake
* [staking] Adjust MarshalJSON for Validator, Wrapper
* Refactor offchain data commit; Make block onchain/offchain commit atomic (#2279)
* Refactor offchain data; Add epoch to ValidatorSnapshot
* Make block onchain/offchain data commit atomically
* [slash][committee] Set .Active to false on double sign, do not consider banned or inactive for committee assignment
* [effective] VC eligible.go
* [consensus] Redundant field in printf
* [docker] import-ks for a dev account
* [slash] Create BLS key for dockerfile and crt-validator.sh
* [slash][docker] Easy deployment of double-sign testing
* [docker] Have slash work as single docker command
* [rpc] Fix median-stake RPC
* [slash] Update webhook with default docker BLS key
* [docker][slash] Fresh yaml copy for docker build, remove dev code in main.go
* [slash] Remove helper binary, commented out code, change to local config
* [params] Factor out test genesis value
* Add shard checking to Tx-Pool & correct blacklist (#2301)
* [core] Fix blacklist & add shardID check
* [staking + node + cmd] Fix blacklist & add shardID check
* [slash] Adjust to PR comments part 1
* [docker] Use different throw away funded account
* [docker] Create easier testing for delegation with private keys
* [docker] Update yaml
* [slash] Remove special case for slashing validator own delegation wrt min-self-delegate
* [docker] Install nano as well
* [slash] Early error if banned
* [quorum] Expose earning account in decider marshal json
* Revert "Refactor offchain data commit; Make block onchain/offchain commit atomic (#2279)"
This reverts commit 9ffbf682c075b49188923c65a0bbf39ac188be00.
* [slash] Add non-sanity check way to update validator
* [reward] Increase percision on percentage in schedule
* [slash] Adjust logs
* [committee] Check eligibility of validator before doing sanity check
* [slash] Update docker
* [slash] Move create validator script to test
* [slash] More log
* [param] Make things faster
* [slash][off-chain] Clear out slashes from pending in writeblockwithstate
* [cross-link] Log is not error, just info
* [blockchain] Not necessary to guard DeletePendingSlashingCandidates
* [slash][consensus] Use plain []byte for signature b/c bls.Sign has private impl fields, rlp does not encode that
* [slash][test] Use faucet as sender, assume user imported
* [slash] Test setup
* [slash] reserve error for real error in logs
* [slash][availability] Apply availability correct, bump signing count each block
* [slash][staking] Consider banned field in sanity check, pay snitch only half of what was actually slashed
* [slash] Pay as much as can
* [slash] use right nowAmt
* [slash] Take away from rewards as well
* [slash] iterate faster
* [slash] Remove dev based timing
* [slash] Add more log, sanity check incoming slash records, only count external for slash rate
* [availability][state] Adjust signature of ValidatorWrapper wrt state, filter out for staked validators, correct availaibility measure on running counters
* [availability] More log
* [slash] Simply pre slash erra slashing
* [slash] Remove development code
* [slash] Use height from recvMsg, todo on epoch
* [staking] Not necessary to touch LastEpochInCommittee in staking_verifier
* [slash] Undo ds in endpoint pattern config
* [slash] Add TODO and log when delegation becomes 0 b/c slash debt payment
* [slash] Abstract staked validators from shard.State into type, set slash rate based BLSKey count
Co-authored-by: Leo Chen <leo@harmony.one>
Co-authored-by: flicker-harmony <52401354+flicker-harmony@users.noreply.github.com>
Co-authored-by: Rongjian Lan <rongjian@harmony.one>
Co-authored-by: Daniel Van Der Maden <daniel@harmony.one>
5 years ago
}
return nodeConfig , nil
}
func setupConsensusAndNode ( nodeConfig * nodeconfig . ConfigType ) * node . Node {
// Consensus object.
// TODO: consensus object shouldn't start here
[rpc][availability][apr] Richer validator information, implement APR, unify EPoS computation, remove fall 2019 tech debt (#2484)
* [rpc][validator] Extend hmy blockchain validator information
* [availability] Optimize bump count
* [staking][validator][rpc] Remove validator stats rpc, fold into validator information, make existing pattern default behavior
* [slash] Reimplement SetDifference
* [reward][engine][network] Remove bad API from fall, begin setup for Per validator awards
* [header] Custom Marshal header for downstream, remove dev code
* [effective][committee] Factor out EPoS round of computation thereby unification in codebase of EPoS
* [unit-test] Fix semantically wrong validator unit tests, punt on maxBLS key wrt tx-pool test
* [reward] Use excellent singleflight package for caching lookup of subcommittees
* [apr][reward] Begin APR package itself, iterate on iterface signatures
* [reward] Handle possible error from singleflight
* [rpc][validator][reward] Adjust RPC committees, singleflight on votingPower, foldStats into Validator Information
* [apr] Stub out computation of APR
* [effective][committee] Upgrade SlotPurchase with named fields, provide marshal
* [effective] Update Tests
* [blockchain] TODO Remove the validators no longer in committee
* [validator][effective] More expressive string representation of eligibilty, ValidatorRPC explicit say if in committee now
* [rpc] Median-stake more semantic meaningful
* [validator] Iterate on semantic meaning of JSON representation
* [offchain] Make validator stats return explicit error
* [availability] Small typo
* [rpc] Quick visual hack until fix delete out kicked out validators
* [offchain] Delete validator from offchain that lost their slot
* [apr] Forgot to update interface signature
* [apr] Mul instead of Div
* [protocol][validator] Fold block reward accum per vaidator into validator-wrapper, off-chain => on-chain
* [votepower] Refactor votepower Roster, simplify aggregation of network wide rosters
* [votepower][shard] Adjust roster, optimize usage of BLSPublicKey as key, use MarshalText trick
* [shard] Granular errors
* [votepower][validator] Unify votepower data structure with off-chain usage
* [votepower][consensus][validator] Further simplify and unify votepower with off-chain, validator stats
* [votepower] Use RJs naming convention group,overall
* [votepower] Remove Println, do keep enforcing order
* [effective][reward] Expand semantics of eligibility as it was overloaded and confusing, evict old voting power computations
* [apr] Adjust json field name
* [votepower] Only aggregate on external validator
* [votepower] Mistake on aggregation, custom presentation network-wide
* [rpc][validator][availability] Remove parameter, take into account empty snapshot
* [apr] Use snapshots from two, one epochs ago. Still have question on header
* [apr] Use GetHeaderByNumber for the header needed for time stamp
* [chain] Evict > 3 epoch old voting power
* [blockchain] Leave Delete Validator snapshot as TODO
* [validator][rpc][effective] Undo changes to Protocol field, use virtual construct at RPC layer for meaning
* [project] Address PR comments
* [committee][rpc] Move +1 to computation of epos round rather than hack mutation
* [reward] Remove entire unnecessary loop, hook on AddReward. Remove unnecessary new big int
* [votepower][rpc][validator] Stick with numeric.Dec for token involved with computation, expose accumulate block-reward in RPC
* [effective][committee] Track the candidates for the EPoS auction, RPC median-stake benefits
* [node] Add hack way to get real error reason of why cannot load shardchain
* [consensus] Expand log on current issue on nil block
* [apr] Do the actual call to compute for validator's APR
* [committee] Wrap SlotOrder with validator address, manifests in median-stake RPC
* [apr] Incorrect error handle order
* [quorum] Remove incorrect compare on bls Key, (typo), remove redundant error check
* [shard] Add log if stakedSlots is 0
* [apr] More sanity check on div by zero, more lenient on error when dont have historical data yet
* [committee] Remove + 1 on seat count
* [apr] Use int64() directly
* [apr] Log when odd empty nil header
* [apr] Do not crash on empty header, figure out later
5 years ago
decider := quorum . NewDecider ( quorum . SuperMajorityVote , uint32 ( * shardID ) )
currentConsensus , err := consensus . New (
myHost , nodeConfig . ShardID , p2p . Peer { } , nodeConfig . ConsensusPriKey , decider ,
)
currentConsensus . Decider . SetMyPublicKeyProvider ( func ( ) ( multibls . PublicKeys , error ) {
return currentConsensus . GetPublicKeys ( ) , nil
} )
if err != nil {
_ , _ = fmt . Fprintf ( os . Stderr , "Error :%v \n" , err )
os . Exit ( 1 )
}
commitDelay , err := time . ParseDuration ( * delayCommit )
if err != nil || commitDelay < 0 {
_ , _ = fmt . Fprintf ( os . Stderr , "ERROR invalid commit delay %#v" , * delayCommit )
os . Exit ( 1 )
}
currentConsensus . SetCommitDelay ( commitDelay )
currentConsensus . MinPeers = * minPeers
blacklist , err := setupBlacklist ( )
if err != nil {
utils . Logger ( ) . Warn ( ) . Msgf ( "Blacklist setup error: %s" , err . Error ( ) )
}
// Current node.
chainDBFactory := & shardchain . LDBFactory { RootDir : nodeConfig . DBDir }
[slash][consensus] Notice double sign & broadcast, factor out tech debt of consensus (#2152)
* [slash] Remove dead interface, associated piping
* [slash] Expand out structs
* [consensus] Write to a chan when find a case of double-signing, remove dead code
* [slash] Broadcast the noticing of a double signing
* [rawdb] CRUD for slashing candidates
* [slashing][node][proto] Broadcast the slash record after receive from consensus, handle received proto message, persist in off-chain db while pending
* [slash][node][propose-block] Add verified slashes proposed into the header in block proposal
* [slash][shard] Factor out external validator as method on shard state, add double-signature field
* [slash][engine] Apply slash, name boolean expression for sorts, use stable sort
* [slash] Abstract Ballot results so keep track of both pre and post double sign event
* [slash] Fix type errors on test code
* [slash] Read from correct rawdb
* [slash] Add epoch based guards in CRUD of slashing
* [slash] Write to correct cache for slashing candidates
* [shard] Use explicit named type of BLS Signature, use convention
* [slash] Fix mistake done in refactor, improper header used. Factor out fromSlice to set
* [slash][node] Restore newblock to master, try again minimial change
* [cx-receipts] Break up one-liner, use SliceStable, not Slice
* [network] Finish refactor that makes network message headers once
* [network] Simplify creation further of headers write
* [slash] Adjust data structure of slash after offline discussion with RJ, Chao
* [slash] Still did need signature of the double signature
* [consensus] Prepare message does not have block header
* [consensus] Soft reset three files to 968517d~1
* [consensus] Begin factor consensus network intended message out with prepare first
* [consensus] Factor out Prepared message
* [consensus] Factor out announce message creation
* [consensus] Committed Message, branch on verify sender key for clearer log
* [consensus] Committed Message Factor out
* [consensus] Do jenkins MVP of signatures adjustment
* [main][slash] Provide YAML config as webhook config for double sign event
* [consensus] Adjust signatures, whitespace, lessen GC pressure
* [consensus] Remove dead code
* [consensus] Factor out commit overloaded message, give commit payload override in construct
* [consensus] Fix travis tests
* [consensus] Provide block bytes in SubmitVote(quorum.Commit)
* [consensus] Factor out noisy sanity checks in BFT, move existing commit check earlier as was before
* [quorum] Adjust signatures in quorum
* [staking] Adjust after merge from master
* [consensus] Finish refactor of consensus
* [node] Fix import
* [consensus] Fix travis
* [consensus] Use origin/master copy of block, fix mistake of pointer to empty byte
* [consensus] Less verbose bools
* [consensus] Remove unused trailing mutation hook in message construct
* [consensus] Address some TODOs on err, comment out double sign
5 years ago
currentNode := node . New ( myHost , currentConsensus , chainDBFactory , blacklist , * isArchival )
currentNode . BroadcastInvalidTx = * broadcastInvalidTx
[slash][consensus] Notice double sign & broadcast, factor out tech debt of consensus (#2152)
* [slash] Remove dead interface, associated piping
* [slash] Expand out structs
* [consensus] Write to a chan when find a case of double-signing, remove dead code
* [slash] Broadcast the noticing of a double signing
* [rawdb] CRUD for slashing candidates
* [slashing][node][proto] Broadcast the slash record after receive from consensus, handle received proto message, persist in off-chain db while pending
* [slash][node][propose-block] Add verified slashes proposed into the header in block proposal
* [slash][shard] Factor out external validator as method on shard state, add double-signature field
* [slash][engine] Apply slash, name boolean expression for sorts, use stable sort
* [slash] Abstract Ballot results so keep track of both pre and post double sign event
* [slash] Fix type errors on test code
* [slash] Read from correct rawdb
* [slash] Add epoch based guards in CRUD of slashing
* [slash] Write to correct cache for slashing candidates
* [shard] Use explicit named type of BLS Signature, use convention
* [slash] Fix mistake done in refactor, improper header used. Factor out fromSlice to set
* [slash][node] Restore newblock to master, try again minimial change
* [cx-receipts] Break up one-liner, use SliceStable, not Slice
* [network] Finish refactor that makes network message headers once
* [network] Simplify creation further of headers write
* [slash] Adjust data structure of slash after offline discussion with RJ, Chao
* [slash] Still did need signature of the double signature
* [consensus] Prepare message does not have block header
* [consensus] Soft reset three files to 968517d~1
* [consensus] Begin factor consensus network intended message out with prepare first
* [consensus] Factor out Prepared message
* [consensus] Factor out announce message creation
* [consensus] Committed Message, branch on verify sender key for clearer log
* [consensus] Committed Message Factor out
* [consensus] Do jenkins MVP of signatures adjustment
* [main][slash] Provide YAML config as webhook config for double sign event
* [consensus] Adjust signatures, whitespace, lessen GC pressure
* [consensus] Remove dead code
* [consensus] Factor out commit overloaded message, give commit payload override in construct
* [consensus] Fix travis tests
* [consensus] Provide block bytes in SubmitVote(quorum.Commit)
* [consensus] Factor out noisy sanity checks in BFT, move existing commit check earlier as was before
* [quorum] Adjust signatures in quorum
* [staking] Adjust after merge from master
* [consensus] Finish refactor of consensus
* [node] Fix import
* [consensus] Fix travis
* [consensus] Use origin/master copy of block, fix mistake of pointer to empty byte
* [consensus] Less verbose bools
* [consensus] Remove unused trailing mutation hook in message construct
* [consensus] Address some TODOs on err, comment out double sign
5 years ago
switch {
case * networkType == nodeconfig . Localnet :
epochConfig := shard . Schedule . InstanceForEpoch ( ethCommon . Big0 )
selfPort , err := strconv . ParseUint ( * port , 10 , 16 )
if err != nil {
utils . Logger ( ) . Fatal ( ) .
Err ( err ) .
Str ( "self_port_string" , * port ) .
Msg ( "cannot convert self port string into port number" )
}
currentNode . SyncingPeerProvider = node . NewLocalSyncingPeerProvider (
6000 , uint16 ( selfPort ) , epochConfig . NumShards ( ) , uint32 ( epochConfig . NumNodesPerShard ( ) ) )
case * dnsZone != "" :
currentNode . SyncingPeerProvider = node . NewDNSSyncingPeerProvider ( * dnsZone , syncing . GetSyncingPort ( * dnsPort ) )
case * dnsFlag :
currentNode . SyncingPeerProvider = node . NewDNSSyncingPeerProvider ( "t.hmny.io" , syncing . GetSyncingPort ( * dnsPort ) )
default :
currentNode . SyncingPeerProvider = node . NewLegacySyncingPeerProvider ( currentNode )
}
// TODO: refactor the creation of blockchain out of node.New()
currentConsensus . ChainReader = currentNode . Blockchain ( )
currentNode . NodeConfig . DNSZone = * dnsZone
[slash][consensus] Notice double sign & broadcast, factor out tech debt of consensus (#2152)
* [slash] Remove dead interface, associated piping
* [slash] Expand out structs
* [consensus] Write to a chan when find a case of double-signing, remove dead code
* [slash] Broadcast the noticing of a double signing
* [rawdb] CRUD for slashing candidates
* [slashing][node][proto] Broadcast the slash record after receive from consensus, handle received proto message, persist in off-chain db while pending
* [slash][node][propose-block] Add verified slashes proposed into the header in block proposal
* [slash][shard] Factor out external validator as method on shard state, add double-signature field
* [slash][engine] Apply slash, name boolean expression for sorts, use stable sort
* [slash] Abstract Ballot results so keep track of both pre and post double sign event
* [slash] Fix type errors on test code
* [slash] Read from correct rawdb
* [slash] Add epoch based guards in CRUD of slashing
* [slash] Write to correct cache for slashing candidates
* [shard] Use explicit named type of BLS Signature, use convention
* [slash] Fix mistake done in refactor, improper header used. Factor out fromSlice to set
* [slash][node] Restore newblock to master, try again minimial change
* [cx-receipts] Break up one-liner, use SliceStable, not Slice
* [network] Finish refactor that makes network message headers once
* [network] Simplify creation further of headers write
* [slash] Adjust data structure of slash after offline discussion with RJ, Chao
* [slash] Still did need signature of the double signature
* [consensus] Prepare message does not have block header
* [consensus] Soft reset three files to 968517d~1
* [consensus] Begin factor consensus network intended message out with prepare first
* [consensus] Factor out Prepared message
* [consensus] Factor out announce message creation
* [consensus] Committed Message, branch on verify sender key for clearer log
* [consensus] Committed Message Factor out
* [consensus] Do jenkins MVP of signatures adjustment
* [main][slash] Provide YAML config as webhook config for double sign event
* [consensus] Adjust signatures, whitespace, lessen GC pressure
* [consensus] Remove dead code
* [consensus] Factor out commit overloaded message, give commit payload override in construct
* [consensus] Fix travis tests
* [consensus] Provide block bytes in SubmitVote(quorum.Commit)
* [consensus] Factor out noisy sanity checks in BFT, move existing commit check earlier as was before
* [quorum] Adjust signatures in quorum
* [staking] Adjust after merge from master
* [consensus] Finish refactor of consensus
* [node] Fix import
* [consensus] Fix travis
* [consensus] Use origin/master copy of block, fix mistake of pointer to empty byte
* [consensus] Less verbose bools
* [consensus] Remove unused trailing mutation hook in message construct
* [consensus] Address some TODOs on err, comment out double sign
5 years ago
currentNode . NodeConfig . SetBeaconGroupID (
nodeconfig . NewGroupIDByShardID ( shard . BeaconChainShardID ) ,
)
nodeconfig . GetDefaultConfig ( ) . DBDir = nodeConfig . DBDir
switch * nodeType {
case "explorer" :
nodeconfig . SetDefaultRole ( nodeconfig . ExplorerNode )
currentNode . NodeConfig . SetRole ( nodeconfig . ExplorerNode )
case "validator" :
nodeconfig . SetDefaultRole ( nodeconfig . Validator )
currentNode . NodeConfig . SetRole ( nodeconfig . Validator )
}
currentNode . NodeConfig . SetShardGroupID ( nodeconfig . NewGroupIDByShardID ( nodeconfig . ShardID ( nodeConfig . ShardID ) ) )
currentNode . NodeConfig . SetClientGroupID ( nodeconfig . NewClientGroupIDByShardID ( shard . BeaconChainShardID ) )
currentNode . NodeConfig . ConsensusPriKey = nodeConfig . ConsensusPriKey
// This needs to be executed after consensus setup
if err := currentNode . InitConsensusWithValidators ( ) ; err != nil {
utils . Logger ( ) . Warn ( ) .
Int ( "shardID" , * shardID ) .
Err ( err ) .
Msg ( "InitConsensusWithMembers failed" )
}
// Set the consensus ID to be the current block number
viewID := currentNode . Blockchain ( ) . CurrentBlock ( ) . Header ( ) . ViewID ( ) . Uint64 ( )
currentConsensus . SetViewID ( viewID + 1 )
utils . Logger ( ) . Info ( ) .
Uint64 ( "viewID" , viewID ) .
Msg ( "Init Blockchain" )
// Assign closure functions to the consensus object
currentConsensus . BlockVerifier = currentNode . VerifyNewBlock
currentConsensus . OnConsensusDone = currentNode . PostConsensusProcessing
// update consensus information based on the blockchain
currentConsensus . SetMode ( currentConsensus . UpdateConsensusInformation ( ) )
// Setup block period and block due time.
currentConsensus . BlockPeriod = time . Duration ( * blockPeriod ) * time . Second
currentConsensus . NextBlockDue = time . Now ( )
return currentNode
}
func setupBlacklist ( ) ( map [ ethCommon . Address ] struct { } , error ) {
utils . Logger ( ) . Debug ( ) . Msgf ( "Using blacklist file at `%s`" , * blacklistPath )
dat , err := ioutil . ReadFile ( * blacklistPath )
if err != nil {
return nil , err
}
addrMap := make ( map [ ethCommon . Address ] struct { } )
for _ , line := range strings . Split ( string ( dat ) , "\n" ) {
if len ( line ) != 0 { // blacklist file may have trailing empty string line
b32 := strings . TrimSpace ( strings . Split ( string ( line ) , "#" ) [ 0 ] )
addr , err := common . Bech32ToAddress ( b32 )
if err != nil {
return nil , err
}
addrMap [ addr ] = struct { } { }
}
}
return addrMap , nil
}
func setupViperConfig ( ) {
// read from environment
envViper := viperconfig . CreateEnvViper ( )
//read from config file
configFileViper := viperconfig . CreateConfFileViper ( "./.hmy" , "nodeconfig" , "json" )
viperconfig . ResetConfString ( ip , envViper , configFileViper , "" , "ip" )
viperconfig . ResetConfString ( port , envViper , configFileViper , "" , "port" )
viperconfig . ResetConfString ( logFolder , envViper , configFileViper , "" , "log_folder" )
viperconfig . ResetConfInt ( logMaxSize , envViper , configFileViper , "" , "log_max_size" )
viperconfig . ResetConfBool ( freshDB , envViper , configFileViper , "" , "fresh_db" )
viperconfig . ResetConfString ( pprof , envViper , configFileViper , "" , "pprof" )
viperconfig . ResetConfBool ( versionFlag , envViper , configFileViper , "" , "version" )
viperconfig . ResetConfString ( dnsZone , envViper , configFileViper , "" , "dns_zone" )
viperconfig . ResetConfBool ( dnsFlag , envViper , configFileViper , "" , "dns" )
viperconfig . ResetConfInt ( minPeers , envViper , configFileViper , "" , "min_peers" )
viperconfig . ResetConfString ( keyFile , envViper , configFileViper , "" , "key" )
viperconfig . ResetConfBool ( isArchival , envViper , configFileViper , "" , "is_archival" )
viperconfig . ResetConfString ( delayCommit , envViper , configFileViper , "" , "delay_commit" )
viperconfig . ResetConfString ( nodeType , envViper , configFileViper , "" , "node_type" )
viperconfig . ResetConfString ( networkType , envViper , configFileViper , "" , "network_type" )
viperconfig . ResetConfInt ( blockPeriod , envViper , configFileViper , "" , "block_period" )
viperconfig . ResetConfBool ( stakingFlag , envViper , configFileViper , "" , "staking" )
viperconfig . ResetConfInt ( shardID , envViper , configFileViper , "" , "shard_id" )
viperconfig . ResetConfString ( blsKeyFile , envViper , configFileViper , "" , "blskey_file" )
viperconfig . ResetConfString ( blsFolder , envViper , configFileViper , "" , "blsfolder" )
viperconfig . ResetConfString ( blsPass , envViper , configFileViper , "" , "blsPass" )
viperconfig . ResetConfUInt ( devnetNumShards , envViper , configFileViper , "" , "dn_num_shards" )
viperconfig . ResetConfInt ( devnetShardSize , envViper , configFileViper , "" , "dn_shard_size" )
viperconfig . ResetConfInt ( devnetHarmonySize , envViper , configFileViper , "" , "dn_hmy_size" )
viperconfig . ResetConfInt ( verbosity , envViper , configFileViper , "" , "verbosity" )
viperconfig . ResetConfString ( dbDir , envViper , configFileViper , "" , "db_dir" )
viperconfig . ResetConfBool ( publicRPC , envViper , configFileViper , "" , "public_rpc" )
viperconfig . ResetConfInt ( doRevertBefore , envViper , configFileViper , "" , "do_revert_before" )
viperconfig . ResetConfInt ( revertTo , envViper , configFileViper , "" , "revert_to" )
viperconfig . ResetConfBool ( revertBeacon , envViper , configFileViper , "" , "revert_beacon" )
viperconfig . ResetConfString ( blacklistPath , envViper , configFileViper , "" , "blacklist" )
viperconfig . ResetConfString ( webHookYamlPath , envViper , configFileViper , "" , "webhook_yaml" )
}
func main ( ) {
// HACK Force usage of go implementation rather than the C based one. Do the right way, see the
// notes one line 66,67 of https://golang.org/src/net/net.go that say can make the decision at
// build time.
os . Setenv ( "GODEBUG" , "netdns=go" )
flag . Var ( & p2p . BootNodes , "bootnodes" , "a list of bootnode multiaddress (delimited by ,)" )
flag . Parse ( )
switch * nodeType {
case "validator" :
case "explorer" :
break
default :
_ , _ = fmt . Fprintf ( os . Stderr , "Unknown node type: %s\n" , * nodeType )
os . Exit ( 1 )
}
nodeconfig . SetPublicRPC ( * publicRPC )
nodeconfig . SetVersion (
fmt . Sprintf ( "Harmony (C) 2020. %v, version %v-%v (%v %v)" ,
path . Base ( os . Args [ 0 ] ) , version , commit , builtBy , builtAt ) ,
)
if * versionFlag {
printVersion ( )
}
switch * networkType {
case nodeconfig . Mainnet :
shard . Schedule = shardingconfig . MainnetSchedule
case nodeconfig . Testnet :
shard . Schedule = shardingconfig . TestnetSchedule
case nodeconfig . Pangaea :
shard . Schedule = shardingconfig . PangaeaSchedule
case nodeconfig . Localnet :
shard . Schedule = shardingconfig . LocalnetSchedule
case nodeconfig . Partner :
shard . Schedule = shardingconfig . PartnerSchedule
case nodeconfig . Stressnet :
shard . Schedule = shardingconfig . StressNetSchedule
case nodeconfig . Devnet :
if * devnetHarmonySize < 0 {
* devnetHarmonySize = * devnetShardSize
}
// TODO (leo): use a passing list of accounts here
devnetConfig , err := shardingconfig . NewInstance (
uint32 ( * devnetNumShards ) , * devnetShardSize , * devnetHarmonySize , numeric . OneDec ( ) , genesis . HarmonyAccounts , genesis . FoundationalNodeAccounts , nil , shardingconfig . VLBPE )
if err != nil {
_ , _ = fmt . Fprintf ( os . Stderr , "ERROR invalid devnet sharding config: %s" ,
err )
os . Exit ( 1 )
}
shard . Schedule = shardingconfig . NewFixedSchedule ( devnetConfig )
default :
_ , _ = fmt . Fprintf ( os . Stderr , "invalid network type: %#v\n" , * networkType )
os . Exit ( 2 )
}
setupViperConfig ( )
initSetup ( )
if * nodeType == "validator" {
var err error
if * stakingFlag {
err = setupStakingNodeAccount ( )
} else {
err = setupLegacyNodeAccount ( )
}
if err != nil {
fmt . Fprintf ( os . Stderr , "cannot set up node account: %s\n" , err )
os . Exit ( 1 )
}
}
if * nodeType == "validator" {
fmt . Printf ( "%s mode; node key %s -> shard %d\n" ,
map [ bool ] string { false : "Legacy" , true : "Staking" } [ * stakingFlag ] ,
nodeconfig . GetDefaultConfig ( ) . ConsensusPriKey . GetPublicKeys ( ) . SerializeToHexStr ( ) ,
initialAccounts [ 0 ] . ShardID )
}
if * nodeType != "validator" && * shardID >= 0 {
for _ , initialAccount := range initialAccounts {
utils . Logger ( ) . Info ( ) .
Uint32 ( "original" , initialAccount . ShardID ) .
Int ( "override" , * shardID ) .
Msg ( "ShardID Override" )
initialAccount . ShardID = uint32 ( * shardID )
}
}
nodeConfig , err := createGlobalConfig ( )
if err != nil {
fmt . Fprintf ( os . Stderr , "ERROR cannot configure node: %s\n" , err )
os . Exit ( 1 )
}
currentNode := setupConsensusAndNode ( nodeConfig )
nodeconfig . GetDefaultConfig ( ) . ShardID = nodeConfig . ShardID
// Prepare for graceful shutdown from os signals
osSignal := make ( chan os . Signal )
signal . Notify ( osSignal , os . Interrupt , syscall . SIGTERM )
go func ( ) {
for sig := range osSignal {
if sig == syscall . SIGTERM || sig == os . Interrupt {
const msg = "Got %s signal. Gracefully shutting down...\n"
utils . Logger ( ) . Printf ( msg , sig )
fmt . Printf ( msg , sig )
currentNode . ShutDown ( )
}
}
} ( )
if nodeConfig . ShardID != shard . BeaconChainShardID {
utils . Logger ( ) . Info ( ) .
Uint32 ( "shardID" , currentNode . Blockchain ( ) . ShardID ( ) ) .
Uint32 ( "shardID" , nodeConfig . ShardID ) . Msg ( "SupportBeaconSyncing" )
currentNode . SupportBeaconSyncing ( )
}
if uint64 ( * doRevertBefore ) != 0 && uint64 ( * revertTo ) != 0 {
chain := currentNode . Blockchain ( )
if * revertBeacon {
chain = currentNode . Beaconchain ( )
}
curNum := chain . CurrentBlock ( ) . NumberU64 ( )
if curNum < uint64 ( * doRevertBefore ) && curNum >= uint64 ( * revertTo ) {
// Remove invalid blocks
for chain . CurrentBlock ( ) . NumberU64 ( ) >= uint64 ( * revertTo ) {
curBlock := chain . CurrentBlock ( )
rollbacks := [ ] ethCommon . Hash { curBlock . Hash ( ) }
chain . Rollback ( rollbacks )
lastSig := curBlock . Header ( ) . LastCommitSignature ( )
sigAndBitMap := append ( lastSig [ : ] , curBlock . Header ( ) . LastCommitBitmap ( ) ... )
chain . WriteCommitSig ( curBlock . NumberU64 ( ) - 1 , sigAndBitMap )
}
}
}
startMsg := "==== New Harmony Node ===="
if * nodeType == "explorer" {
startMsg = "==== New Explorer Node ===="
}
utils . Logger ( ) . Info ( ) .
Str ( "BLSPubKey" , nodeConfig . ConsensusPriKey . GetPublicKeys ( ) . SerializeToHexStr ( ) ) .
Uint32 ( "ShardID" , nodeConfig . ShardID ) .
Str ( "ShardGroupID" , nodeConfig . GetShardGroupID ( ) . String ( ) ) .
Str ( "BeaconGroupID" , nodeConfig . GetBeaconGroupID ( ) . String ( ) ) .
Str ( "ClientGroupID" , nodeConfig . GetClientGroupID ( ) . String ( ) ) .
Str ( "Role" , currentNode . NodeConfig . Role ( ) . String ( ) ) .
Str ( "multiaddress" ,
fmt . Sprintf ( "/ip4/%s/tcp/%s/p2p/%s" , * ip , * port , myHost . GetID ( ) . Pretty ( ) ) ,
) .
Msg ( startMsg )
nodeconfig . SetPeerID ( myHost . GetID ( ) )
currentNode . SupportSyncing ( )
currentNode . ServiceManagerSetup ( )
currentNode . RunServices ( )
if err := currentNode . StartRPC ( * port ) ; err != nil {
utils . Logger ( ) . Warn ( ) .
Err ( err ) .
Msg ( "StartRPC failed" )
}
if err := currentNode . BootstrapConsensus ( ) ; err != nil {
fmt . Println ( "could not bootstrap consensus" , err . Error ( ) )
os . Exit ( - 1 )
}
if err := currentNode . Start ( ) ; err != nil {
fmt . Println ( "could not begin network message handling for node" , err . Error ( ) )
os . Exit ( - 1 )
}
}