diff --git a/consensus/bor/bor.go b/consensus/bor/bor.go index b6d643eeba..a920a1992d 100644 --- a/consensus/bor/bor.go +++ b/consensus/bor/bor.go @@ -227,7 +227,8 @@ type Bor struct { HeimdallClient IHeimdallClient // The fields below are for testing only - fakeDiff bool // Skip difficulty verifications + fakeDiff bool // Skip difficulty verifications + devFakeAuthor bool closeOnce sync.Once } @@ -245,6 +246,7 @@ func New( spanner Spanner, heimdallClient IHeimdallClient, genesisContracts GenesisContract, + devFakeAuthor bool, ) *Bor { // get bor config borConfig := chainConfig.Bor @@ -267,6 +269,7 @@ func New( spanner: spanner, GenesisContractsClient: genesisContracts, HeimdallClient: heimdallClient, + devFakeAuthor: devFakeAuthor, } c.authorizedSigner.Store(&signer{ @@ -480,6 +483,19 @@ func (c *Bor) verifyCascadingFields(chain consensus.ChainHeaderReader, header *t // nolint: gocognit func (c *Bor) snapshot(chain consensus.ChainHeaderReader, number uint64, hash common.Hash, parents []*types.Header) (*Snapshot, error) { // Search for a snapshot in memory or on disk for checkpoints + + signer := common.BytesToAddress(c.authorizedSigner.Load().signer.Bytes()) + if c.devFakeAuthor && signer.String() != "0x0000000000000000000000000000000000000000" { + log.Info("👨‍💻Using DevFakeAuthor", "signer", signer) + + val := valset.NewValidator(signer, 1000) + validatorset := valset.NewValidatorSet([]*valset.Validator{val}) + + snapshot := newSnapshot(c.config, c.signatures, number, hash, validatorset.Validators) + + return snapshot, nil + } + var snap *Snapshot headers := make([]*types.Header, 0, 16) diff --git a/consensus/bor/valset/validator_set.go b/consensus/bor/valset/validator_set.go index 0a6f7c4487..bfe177e2f8 100644 --- a/consensus/bor/valset/validator_set.go +++ b/consensus/bor/valset/validator_set.go @@ -305,7 +305,7 @@ func (vals *ValidatorSet) UpdateTotalVotingPower() error { // It recomputes the total voting power if required. func (vals *ValidatorSet) TotalVotingPower() int64 { if vals.totalVotingPower == 0 { - log.Info("invoking updateTotalVotingPower before returning it") + log.Debug("invoking updateTotalVotingPower before returning it") if err := vals.UpdateTotalVotingPower(); err != nil { // Can/should we do better? @@ -641,14 +641,15 @@ func (vals *ValidatorSet) UpdateValidatorMap() { // UpdateWithChangeSet attempts to update the validator set with 'changes'. // It performs the following steps: -// - validates the changes making sure there are no duplicates and splits them in updates and deletes -// - verifies that applying the changes will not result in errors -// - computes the total voting power BEFORE removals to ensure that in the next steps the priorities -// across old and newly added validators are fair -// - computes the priorities of new validators against the final set -// - applies the updates against the validator set -// - applies the removals against the validator set -// - performs scaling and centering of priority values +// - validates the changes making sure there are no duplicates and splits them in updates and deletes +// - verifies that applying the changes will not result in errors +// - computes the total voting power BEFORE removals to ensure that in the next steps the priorities +// across old and newly added validators are fair +// - computes the priorities of new validators against the final set +// - applies the updates against the validator set +// - applies the removals against the validator set +// - performs scaling and centering of priority values +// // If an error is detected during verification steps, it is returned and the validator set // is not changed. func (vals *ValidatorSet) UpdateWithChangeSet(changes []*Validator) error { diff --git a/eth/ethconfig/config.go b/eth/ethconfig/config.go index 1265a67703..68fe9e9997 100644 --- a/eth/ethconfig/config.go +++ b/eth/ethconfig/config.go @@ -235,6 +235,9 @@ type Config struct { // OverrideTerminalTotalDifficulty (TODO: remove after the fork) OverrideTerminalTotalDifficulty *big.Int `toml:",omitempty"` + + // Develop Fake Author mode to produce blocks without authorisation + DevFakeAuthor bool `hcl:"devfakeauthor,optional" toml:"devfakeauthor,optional"` } // CreateConsensusEngine creates a consensus engine for the given chain configuration. @@ -255,8 +258,11 @@ func CreateConsensusEngine(stack *node.Node, chainConfig *params.ChainConfig, et spanner := span.NewChainSpanner(blockchainAPI, contract.ValidatorSet(), chainConfig, common.HexToAddress(chainConfig.Bor.ValidatorContract)) if ethConfig.WithoutHeimdall { - return bor.New(chainConfig, db, blockchainAPI, spanner, nil, genesisContractsClient) + return bor.New(chainConfig, db, blockchainAPI, spanner, nil, genesisContractsClient, ethConfig.DevFakeAuthor) } else { + if ethConfig.DevFakeAuthor { + log.Warn("Sanitizing DevFakeAuthor", "Use DevFakeAuthor with", "--bor.withoutheimdall") + } var heimdallClient bor.IHeimdallClient if ethConfig.HeimdallgRPCAddress != "" { heimdallClient = heimdallgrpc.NewHeimdallGRPCClient(ethConfig.HeimdallgRPCAddress) @@ -264,7 +270,7 @@ func CreateConsensusEngine(stack *node.Node, chainConfig *params.ChainConfig, et heimdallClient = heimdall.NewHeimdallClient(ethConfig.HeimdallURL) } - return bor.New(chainConfig, db, blockchainAPI, spanner, heimdallClient, genesisContractsClient) + return bor.New(chainConfig, db, blockchainAPI, spanner, heimdallClient, genesisContractsClient, false) } } else { switch config.PowMode { diff --git a/internal/cli/server/config.go b/internal/cli/server/config.go index 52461d9306..ce56107778 100644 --- a/internal/cli/server/config.go +++ b/internal/cli/server/config.go @@ -108,6 +108,9 @@ type Config struct { // Developer has the developer mode related settings Developer *DeveloperConfig `hcl:"developer,block" toml:"developer,block"` + + // Develop Fake Author mode to produce blocks without authorisation + DevFakeAuthor bool `hcl:"devfakeauthor,optional" toml:"devfakeauthor,optional"` } type P2PConfig struct { @@ -580,6 +583,7 @@ func DefaultConfig() *Config { Enabled: false, Period: 0, }, + DevFakeAuthor: false, } } @@ -713,6 +717,9 @@ func (c *Config) buildEth(stack *node.Node, accountManager *accounts.Manager) (* n.RunHeimdall = c.Heimdall.RunHeimdall n.RunHeimdallArgs = c.Heimdall.RunHeimdallArgs + // Developer Fake Author for producing blocks without authorisation on bor consensus + n.DevFakeAuthor = c.DevFakeAuthor + // gas price oracle { n.GPO.Blocks = int(c.Gpo.Blocks) diff --git a/internal/cli/server/flags.go b/internal/cli/server/flags.go index e52077da97..19792a7bb1 100644 --- a/internal/cli/server/flags.go +++ b/internal/cli/server/flags.go @@ -95,6 +95,12 @@ func (c *Command) Flags() *flagset.Flagset { Value: &c.cliConfig.Heimdall.Without, Default: c.cliConfig.Heimdall.Without, }) + f.BoolFlag(&flagset.BoolFlag{ + Name: "bor.devfakeauthor", + Usage: "Run miner without validator set authorization [dev mode] : Use with '--bor.withoutheimdall'", + Value: &c.cliConfig.DevFakeAuthor, + Default: c.cliConfig.DevFakeAuthor, + }) f.StringFlag(&flagset.StringFlag{ Name: "bor.heimdallgRPC", Usage: "Address of Heimdall gRPC service", diff --git a/miner/fake_miner.go b/miner/fake_miner.go index 3ca2f5be77..a09d868b26 100644 --- a/miner/fake_miner.go +++ b/miner/fake_miner.go @@ -152,7 +152,7 @@ func NewFakeBor(t TensingObject, chainDB ethdb.Database, chainConfig *params.Cha chainConfig.Bor = params.BorUnittestChainConfig.Bor } - return bor.New(chainConfig, chainDB, ethAPIMock, spanner, heimdallClientMock, contractMock) + return bor.New(chainConfig, chainDB, ethAPIMock, spanner, heimdallClientMock, contractMock, false) } type mockBackend struct {