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"
"github.com/harmony-one/harmony/internal/genesis"
hmykey "github.com/harmony-one/harmony/internal/keystore"
"github.com/harmony-one/harmony/internal/memprofiling"
"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/p2p"
"github.com/harmony-one/harmony/p2p/p2pimpl"
p2putils "github.com/harmony-one/harmony/p2p/utils"
"github.com/harmony-one/harmony/shard"
"github.com/harmony-one/harmony/staking/webhooks"
golog "github.com/ipfs/go-log"
[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"
gologging "github.com/whyrusleeping/go-logging"
)
// Version string variables
var (
version string
builtBy string
builtAt string
commit string
)
// Host
var (
myHost p2p . Host
)
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" )
profile = flag . Bool ( "profile" , false , "Turn on profiling (CPU, Memory)." )
metricsReportURL = flag . String ( "metrics_report_url" , "" , "If set, reports metrics to this URL." )
pprof = flag . String ( "pprof" , "" , "what address and port the pprof profiling server should listen on" )
versionFlag = flag . Bool ( "version" , false , "Output version info" )
onlyLogTps = flag . Bool ( "only_log_tps" , false , "Only log TPS if true" )
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" )
//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" )
// isGenesis indicates this node is a genesis node
isGenesis = flag . Bool ( "is_genesis" , true , "true means this node is a genesis 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, devnet, localnet" )
// syncFreq indicates sync frequency
syncFreq = flag . Int ( "sync_freq" , 60 , "unit in seconds" )
// beaconSyncFreq indicates beaconchain sync frequency
beaconSyncFreq = flag . Int ( "beacon_sync_freq" , 60 , "unit in seconds" )
// 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." )
leaderOverride = flag . Bool ( "leader_override" , false , "true means override the default leader role and acts as validator" )
// 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" )
enableMemProfiling = flag . Bool ( "enableMemProfiling" , false , "Enable memsize logging." )
enableGC = flag . Bool ( "enableGC" , true , "Enable calling garbage collector manually ." )
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; same blspass is used to decrypt all bls keys; all bls keys mapped to same shard" )
blsPass = flag . String ( "blspass" , "" , "The file containing passphrase to decrypt the encrypted bls file." )
blsPassphrase string
// 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" )
// logConn logs incoming/outgoing connections
logConn = flag . Bool ( "log_conn" , false , "log incoming/outgoing connections" )
keystoreDir = flag . String ( "keystore" , hmykey . DefaultKeyStoreDir , "The default keystore directory" )
// Use a separate log file to log libp2p traces
logP2P = flag . Bool ( "log_p2p" , false , "log libp2p debug info" )
initialAccounts = [ ] * genesis . DeployAccount { }
// 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" )
// Disable view change.
disableViewChange = flag . Bool ( "disable_view_change" , false , "Do not propose view change (testing only)" )
// metrics flag to collct meetrics or not, pushgateway ip and port for metrics
metricsFlag = flag . Bool ( "metrics" , false , "Collect and upload node metrics" )
pushgatewayIP = flag . String ( "pushgateway_ip" , "grafana.harmony.one" , "Metrics view ip" )
pushgatewayPort = flag . String ( "pushgateway_port" , "9091" , "Metrics view port" )
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
[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
blacklistPath = flag . String ( "blacklist" , "./.hmy/blacklist.txt" , "Path to newline delimited file of blacklisted wallet addresses" )
webHookYamlPath = flag . String (
"webhook_yaml" , "" , "path for yaml config reporting double signing" ,
)
)
func initSetup ( ) {
// Setup pprof
if addr := * pprof ; addr != "" {
go func ( ) { http . ListenAndServe ( addr , nil ) } ( )
}
// maybe request passphrase for bls key.
passphraseForBls ( )
// 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 )
if * onlyLogTps {
matchFilterHandler := log . MatchFilterHandler ( "msg" , "TPS Report" , utils . GetLogInstance ( ) . GetHandler ( ) )
utils . GetLogInstance ( ) . SetHandler ( matchFilterHandler )
}
// Add GOMAXPROCS to achieve max performance.
runtime . GOMAXPROCS ( runtime . NumCPU ( ) * 4 )
// Set port and ip to global config.
nodeconfig . GetDefaultConfig ( ) . Port = * port
nodeconfig . GetDefaultConfig ( ) . IP = * ip
// Set sharding schedule
nodeconfig . SetShardingSchedule ( shard . Schedule )
// Setup mem profiling.
memprofiling . GetMemProfiling ( ) . Config ( )
// Set default keystore Dir
hmykey . DefaultKeyStoreDir = * keystoreDir
// Set up randomization seed.
rand . Seed ( int64 ( time . Now ( ) . Nanosecond ( ) ) )
if len ( p2putils . BootNodes ) == 0 {
bootNodeAddrs , err := p2putils . StringsToAddrs ( p2putils . DefaultBootNodeAddrStrings )
if err != nil {
utils . FatalErrMsg ( err , "cannot parse default bootnode list %#v" ,
p2putils . DefaultBootNodeAddrStrings )
}
p2putils . 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 [ ] * bls . PublicKey ) {
for _ , key := range pubKeys {
keyStr := key . SerializeToHexStr ( )
_ , 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 ( ) )
reshardingEpoch := genesisShardingConfig . ReshardingEpoch ( )
if reshardingEpoch != nil && len ( reshardingEpoch ) > 0 {
for _ , epoch := range reshardingEpoch {
config := shard . Schedule . InstanceForEpoch ( epoch )
findAccountsByPubKeys ( config , multiBlsPubKey . PublicKey )
if len ( initialAccounts ) != 0 {
break
}
}
} else {
findAccountsByPubKeys ( genesisShardingConfig , multiBlsPubKey . PublicKey )
}
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 ( ) )
shardID , err := nodeconfig . GetDefaultConfig ( ) . ShardIDFromConsensusKey ( )
if err != nil {
return errors . Wrap ( err , "cannot determine shard to join" )
}
if err := nodeconfig . GetDefaultConfig ( ) . ValidateConsensusKeysForSameShard ( pubKey . PublicKey , shardID ) ; err != nil {
return err
}
for _ , blsKey := range pubKey . PublicKey {
initialAccount := & genesis . DeployAccount { }
initialAccount . ShardID = shardID
initialAccount . BlsPublicKey = blsKey . SerializeToHexStr ( )
initialAccount . Address = ""
initialAccounts = append ( initialAccounts , initialAccount )
}
return nil
}
func readMultiBlsKeys ( consensusMultiBlsPriKey * multibls . PrivateKey , consensusMultiBlsPubKey * multibls . PublicKey ) error {
multiBlsKeyDir := blsFolder
blsKeyFiles , err := ioutil . ReadDir ( * multiBlsKeyDir )
if err != nil {
return err
}
for _ , blsKeyFile := range blsKeyFiles {
if filepath . Ext ( blsKeyFile . Name ( ) ) != ".key" {
fmt . Println ( "BLS key file should have .key file extension, found" , blsKeyFile . Name ( ) )
continue
}
blsKeyFilePath := path . Join ( * multiBlsKeyDir , blsKeyFile . Name ( ) )
consensusPriKey , err := blsgen . LoadBlsKeyWithPassPhrase ( blsKeyFilePath , blsPassphrase ) // uses the same bls passphrase for multiple bls keys
if err != nil {
return err
}
// TODO: assumes order between public/private key pairs
multibls . AppendPriKey ( consensusMultiBlsPriKey , consensusPriKey )
multibls . AppendPubKey ( consensusMultiBlsPubKey , consensusPriKey . GetPublicKey ( ) )
}
return nil
}
func setupConsensusKey ( nodeConfig * nodeconfig . ConfigType ) multibls . PublicKey {
consensusMultiPriKey := & multibls . PrivateKey { }
consensusMultiPubKey := & multibls . PublicKey { }
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 )
}
multibls . AppendPriKey ( consensusMultiPriKey , consensusPriKey )
multibls . AppendPubKey ( consensusMultiPubKey , consensusPriKey . GetPublicKey ( ) )
} else {
err := readMultiBlsKeys ( consensusMultiPriKey , consensusMultiPubKey )
if err != nil {
_ , _ = fmt . Fprintf ( os . Stderr , "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
nodeConfig . ConsensusPubKey = consensusMultiPubKey
return * consensusMultiPubKey
}
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 . GetPrivateKey ( & bls . SecretKey { } )
nodeConfig . ConsensusPubKey = multibls . GetPublicKey ( & bls . PublicKey { } )
}
// Set network type
netType := nodeconfig . NetworkType ( * networkType )
nodeconfig . SetNetworkType ( netType ) // sets for both global and shard configs
nodeConfig . SetPushgatewayIP ( * pushgatewayIP )
nodeConfig . SetPushgatewayPort ( * pushgatewayPort )
nodeConfig . SetMetricsFlag ( * metricsFlag )
// 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 . ConsensusPubKey . PublicKey [ 0 ] }
myHost , err = p2pimpl . NewHost ( & selfPeer , nodeConfig . P2pPriKey )
if err != nil {
return nil , errors . Wrap ( err , "cannot create P2P network host" )
}
if * logConn && nodeConfig . GetNetworkType ( ) != nodeconfig . Mainnet {
myHost . GetP2PHost ( ) . Network ( ) . Notify ( utils . NewConnLogger ( utils . GetLogger ( ) ) )
}
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
// TODO(minhdoan): During refactoring, found out that the peers list is actually empty. Need to clean up the logic of consensus later.
decider := quorum . NewDecider ( quorum . SuperMajorityVote )
currentConsensus , err := consensus . New (
myHost , nodeConfig . ShardID , p2p . Peer { } , nodeConfig . ConsensusPriKey , decider ,
)
currentConsensus . Decider . SetShardIDProvider ( func ( ) ( uint32 , error ) {
return currentConsensus . ShardID , nil
} )
currentConsensus . Decider . SetMyPublicKeyProvider ( func ( ) ( * multibls . PublicKey , error ) {
return currentConsensus . PubKey , nil
} )
// staking validator doesn't have to specify ECDSA address
currentConsensus . SelfAddresses = map [ string ] ethCommon . Address { }
for _ , initialAccount := range initialAccounts {
currentConsensus . SelfAddresses [ initialAccount . BlsPublicKey ] = common . ParseAddr ( initialAccount . Address )
}
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
if * disableViewChange {
currentConsensus . DisableViewChangeForTestingOnly ( )
}
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
[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
currentNode := node . New ( myHost , currentConsensus , chainDBFactory , blacklist , true )
[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 ( * port ) )
case * dnsFlag :
currentNode . SyncingPeerProvider = node . NewDNSSyncingPeerProvider ( "t.hmny.io" , syncing . GetSyncingPort ( * port ) )
default :
currentNode . SyncingPeerProvider = node . NewLegacySyncingPeerProvider ( currentNode )
}
// TODO: refactor the creation of blockchain out of node.New()
currentConsensus . ChainReader = currentNode . Blockchain ( )
currentNode . NodeConfig . DNSZone = * dnsZone
// Set up prometheus pushgateway for metrics monitoring serivce.
currentNode . NodeConfig . SetPushgatewayIP ( nodeConfig . PushgatewayIP )
currentNode . NodeConfig . SetPushgatewayPort ( nodeConfig . PushgatewayPort )
currentNode . NodeConfig . SetMetricsFlag ( nodeConfig . MetricsFlag )
[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 ) ,
)
switch * nodeType {
case "explorer" :
nodeconfig . SetDefaultRole ( nodeconfig . ExplorerNode )
currentNode . NodeConfig . SetRole ( nodeconfig . ExplorerNode )
[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 . SetShardGroupID (
nodeconfig . NewGroupIDByShardID ( nodeconfig . ShardID ( * shardID ) ) ,
)
currentNode . NodeConfig . SetClientGroupID (
nodeconfig . NewClientGroupIDByShardID ( nodeconfig . ShardID ( * shardID ) ) ,
)
case "validator" :
nodeconfig . SetDefaultRole ( nodeconfig . Validator )
currentNode . NodeConfig . SetRole ( nodeconfig . Validator )
if nodeConfig . ShardID == shard . BeaconChainShardID {
currentNode . NodeConfig . SetShardGroupID ( nodeconfig . NewGroupIDByShardID ( shard . BeaconChainShardID ) )
currentNode . NodeConfig . SetClientGroupID ( nodeconfig . NewClientGroupIDByShardID ( shard . BeaconChainShardID ) )
} else {
currentNode . NodeConfig . SetShardGroupID ( nodeconfig . NewGroupIDByShardID ( nodeconfig . ShardID ( nodeConfig . ShardID ) ) )
currentNode . NodeConfig . SetClientGroupID ( nodeconfig . NewClientGroupIDByShardID ( nodeconfig . ShardID ( nodeConfig . ShardID ) ) )
}
}
currentNode . NodeConfig . ConsensusPubKey = nodeConfig . ConsensusPubKey
currentNode . NodeConfig . ConsensusPriKey = nodeConfig . ConsensusPriKey
// Setup block period for currentNode.
currentNode . BlockPeriod = time . Duration ( * blockPeriod ) * time . Second
// TODO: Disable drand. Currently drand isn't functioning but we want to compeletely turn it off for full protection.
// Enable it back after mainnet.
// dRand := drand.New(nodeConfig.Host, nodeConfig.ShardID, []p2p.Peer{}, nodeConfig.Leader, currentNode.ConfirmedBlockChannel, nodeConfig.ConsensusPriKey)
// currentNode.Consensus.RegisterPRndChannel(dRand.PRndChannel)
// currentNode.Consensus.RegisterRndChannel(dRand.RndChannel)
// currentNode.DRand = dRand
// This needs to be executed after consensus and drand are 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
currentNode . State = node . NodeWaitToJoin
// update consensus information based on the blockchain
currentConsensus . SetMode ( currentConsensus . UpdateConsensusInformation ( ) )
// Watching currentNode and currentConsensus.
memprofiling . GetMemProfiling ( ) . Add ( "currentNode" , currentNode )
memprofiling . GetMemProfiling ( ) . Add ( "currentConsensus" , currentConsensus )
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 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 ( & p2putils . 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 . Devnet :
if * devnetHarmonySize < 0 {
* devnetHarmonySize = * devnetShardSize
}
// TODO (leo): use a passing list of accounts here
devnetConfig , err := shardingconfig . NewInstance (
uint32 ( * devnetNumShards ) , * devnetShardSize , * devnetHarmonySize , 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 )
}
initSetup ( )
// Set up manual call for garbage collection.
if * enableGC {
memprofiling . MaybeCallGCPeriodically ( )
}
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 ( ) . ConsensusPubKey . 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 )
// Prepare for graceful shutdown from os signals
osSignal := make ( chan os . Signal )
signal . Notify ( osSignal , os . Interrupt , syscall . SIGTERM )
go func ( ) {
for {
select {
case sig := <- osSignal :
if sig == syscall . SIGTERM || sig == os . Interrupt {
msg := "Got %s signal. Gracefully shutting down...\n"
utils . Logger ( ) . Printf ( msg , sig )
fmt . Printf ( msg , sig )
currentNode . ShutDown ( )
}
}
}
} ( )
//setup state syncing and beacon syncing frequency
currentNode . SetSyncFreq ( * syncFreq )
currentNode . SetBeaconSyncFreq ( * beaconSyncFreq )
if nodeConfig . ShardID != shard . BeaconChainShardID &&
currentNode . NodeConfig . Role ( ) != nodeconfig . ExplorerNode {
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 . WriteLastCommits ( sigAndBitMap )
}
}
}
startMsg := "==== New Harmony Node ===="
if * nodeType == "explorer" {
startMsg = "==== New Explorer Node ===="
}
utils . Logger ( ) . Info ( ) .
Str ( "BlsPubKey" , nodeConfig . ConsensusPubKey . 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 )
if * enableMemProfiling {
memprofiling . GetMemProfiling ( ) . Start ( )
}
if * logP2P {
f , err := os . OpenFile ( path . Join ( * logFolder , "libp2p.log" ) , os . O_APPEND | os . O_CREATE | os . O_WRONLY , 0644 )
if err != nil {
fmt . Fprintf ( os . Stderr , "Failed to open libp2p.log. %v\n" , err )
} else {
defer f . Close ( )
backend1 := gologging . NewLogBackend ( f , "" , 0 )
gologging . SetBackend ( backend1 )
golog . SetAllLoggers ( gologging . DEBUG ) // Change to DEBUG for extra info
}
}
go currentNode . SupportSyncing ( )
currentNode . ServiceManagerSetup ( )
currentNode . RunServices ( )
// RPC for SDK not supported for mainnet.
if err := currentNode . StartRPC ( * port ) ; err != nil {
utils . Logger ( ) . Warn ( ) .
Err ( err ) .
Msg ( "StartRPC failed" )
}
// Run additional node collectors
// Collect node metrics if metrics flag is set
if currentNode . NodeConfig . GetMetricsFlag ( ) {
go currentNode . CollectMetrics ( )
}
currentNode . StartServer ( )
}