Skip to content

Commit

Permalink
Merge pull request ethereum#32 from QuarkChain/tm_w3q_single_val
Browse files Browse the repository at this point in the history
Enable single validator mode
  • Loading branch information
qizhou committed Mar 7, 2022
2 parents 1f35a08 + 8056ed6 commit 21d19e9
Show file tree
Hide file tree
Showing 9 changed files with 61 additions and 25 deletions.
1 change: 1 addition & 0 deletions cmd/geth/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ var (
utils.RinkebyFlag,
utils.GoerliFlag,
utils.Web3QTestnetFlag,
utils.Web3QGalileoFlag,
utils.Web3QMainnetFlag,
utils.VMEnableDebugFlag,
utils.NetworkIdFlag,
Expand Down
19 changes: 15 additions & 4 deletions consensus/tendermint/adapter/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@ type Store struct {
chain *core.BlockChain
governance *gov.Governance
verifyHeaderFunc func(chain consensus.ChainHeaderReader, header *types.Header, seal bool) error
makeBlock func(parentHash common.Hash, timestamp uint64) (block *types.FullBlock)
makeBlock func(parentHash common.Hash, coinbase common.Address, timestamp uint64) (block *types.FullBlock)
}

func NewStore(
chain *core.BlockChain,
governance *gov.Governance,
verifyHeaderFunc func(chain consensus.ChainHeaderReader, header *types.Header, seal bool) error,
makeBlock func(parentHash common.Hash, timestamp uint64) (block *types.FullBlock)) *Store {
makeBlock func(parentHash common.Hash, coinbase common.Address, timestamp uint64) (block *types.FullBlock)) *Store {
return &Store{chain: chain, governance: governance, verifyHeaderFunc: verifyHeaderFunc, makeBlock: makeBlock}
}

Expand Down Expand Up @@ -161,6 +161,17 @@ func updateState(
}, nil
}

func (s *Store) MakeBlock(parentHash common.Hash, timestamp uint64) *types.FullBlock {
return s.makeBlock(parentHash, timestamp)
func (s *Store) MakeBlock(state *pbft.ChainState, height uint64,
commit *pbft.Commit,
proposerAddress common.Address) *types.FullBlock {

// Set time.
var timestamp uint64
if height == state.InitialHeight {
timestamp = state.LastBlockTime + 1 // genesis time + 1
} else {
timestamp = pbft.MedianTime(commit, state.LastValidators)
}

return s.makeBlock(state.LastBlockID, proposerAddress, timestamp)
}
16 changes: 16 additions & 0 deletions consensus/tendermint/gov/gov.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,19 @@ func (g *Governance) NextValidators(height uint64) []common.Address {
return header.NextValidators
}
}

func (g *Governance) NextValidatorPowers(height uint64) []uint64 {
if height%g.epoch != 0 {
return nil
}

switch {
case height == 0:
header := g.chain.GetHeaderByNumber(0)
return header.NextValidatorPowers
default:
// TODO get real validators by calling contract
header := g.chain.GetHeaderByNumber(height - g.epoch)
return header.NextValidatorPowers
}
}
36 changes: 20 additions & 16 deletions consensus/tendermint/tendermint.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ import (
"fmt"
"io/ioutil"
"math/big"
"reflect"
"time"

pbftconsensus "github.com/QuarkChain/go-minimal-pbft/consensus"
Expand Down Expand Up @@ -111,7 +110,7 @@ func (c *Tendermint) SetBlockChain(chain *core.BlockChain) {
c.chain = chain
}

func (c *Tendermint) Init(makeBlock func(parent common.Hash, timestamp uint64) (*types.Block, error)) (err error) {
func (c *Tendermint) Init(makeBlock func(parent common.Hash, coinbase common.Address, timestamp uint64) (*types.Block, error)) (err error) {
chain := c.chain
// Outbound gossip message queue
sendC := make(chan pbftconsensus.Message, 1000)
Expand All @@ -124,9 +123,9 @@ func (c *Tendermint) Init(makeBlock func(parent common.Hash, timestamp uint64) (
c.rootCtxCancel = rootCtxCancel
c.rootCtx = rootCtx

makeFullBlock := func(parentHash common.Hash, timestamp uint64) *types.FullBlock {

block, err := makeBlock(parentHash, timestamp)
makeFullBlock := func(parentHash common.Hash, coinbase common.Address, timestamp uint64) *types.FullBlock {
log.Info("Making a block", "parent", parentHash)
block, err := makeBlock(parentHash, coinbase, timestamp)
if err != nil {
log.Warn("makeBlock", "err", err)
return nil
Expand Down Expand Up @@ -181,11 +180,12 @@ func (c *Tendermint) Init(makeBlock func(parent common.Hash, timestamp uint64) (
c.config.Epoch,
int64(c.config.ProposerRepetition),
)
gcs.LastBlockID = genesis.Hash()

// consensus
consensusState := pbftconsensus.NewConsensusState(
rootCtx,
pbftconsensus.NewDefaultConsesusConfig(),
&c.config.ConsensusConfig,
*gcs,
store,
store,
Expand Down Expand Up @@ -280,15 +280,12 @@ func (c *Tendermint) verifyHeader(chain consensus.ChainHeaderReader, header *typ
if header.Time > uint64(time.Now().Unix()) {
return consensus.ErrFutureBlock
}
// Checkpoint blocks need to enforce zero beneficiary
checkpoint := (number % c.config.Epoch) == 0
if checkpoint && header.Coinbase != (common.Address{}) {
return errInvalidCheckpointBeneficiary
}

nextValidators := c.governance.NextValidators(number)
if !reflect.DeepEqual(nextValidators, header.NextValidators) {
return errors.New("invalid NextValidators")
if number%c.config.Epoch != 0 && len(header.NextValidators) != 0 {
return errors.New("NextValidators must be empty for non-epoch block")
}
if len(header.NextValidatorPowers) != len(header.NextValidators) {
return errors.New("NextValidators must have the same len as powers")
}
if !bytes.Equal(header.Nonce[:], nonceDefault) {
return errors.New("invalid nonce")
Expand All @@ -303,7 +300,7 @@ func (c *Tendermint) verifyHeader(chain consensus.ChainHeaderReader, header *typ
}
// Ensure that the block's difficulty is meaningful (may not be correct at this point)
if number > 0 {
if header.Difficulty == nil || (header.Difficulty.Cmp(big.NewInt(0)) != 0) {
if header.Difficulty == nil || (header.Difficulty.Cmp(big.NewInt(1)) != 0) {
return errInvalidDifficulty
}
}
Expand Down Expand Up @@ -377,8 +374,15 @@ func (c *Tendermint) Prepare(chain consensus.ChainHeaderReader, header *types.He

header.TimeMs = timestamp
header.Time = timestamp / 1000
header.Difficulty = big.NewInt(1)

if (number % c.config.Epoch) != 0 {
header.NextValidators = []common.Address{}
header.NextValidatorPowers = []uint64{}
} else {
header.NextValidators = c.governance.NextValidators(number)
}

header.NextValidators = c.governance.NextValidators(number)
return nil
}

Expand Down
2 changes: 2 additions & 0 deletions core/blockchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -2306,6 +2306,8 @@ func (bc *BlockChain) PreExecuteBlock(block *types.Block) (err error) {
return
}

statedb.StartPrefetcher("pre_execute")

txHash := types.DeriveSha(block.Transactions(), trie.NewStackTrie(nil))
if block.TxHash() != txHash {
err = fmt.Errorf("txHash mismatch, got %s, expect %s", block.TxHash(), txHash)
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ go 1.15

require (
github.com/Azure/azure-storage-blob-go v0.7.0
github.com/QuarkChain/go-minimal-pbft v0.0.0-20220303075012-6084b729db36
github.com/QuarkChain/go-minimal-pbft v0.0.0-20220306083522-1c8dc76afb94
github.com/VictoriaMetrics/fastcache v1.6.0
github.com/aws/aws-sdk-go-v2 v1.2.0
github.com/aws/aws-sdk-go-v2/config v1.1.1
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ github.com/Kubuxu/go-os-helper v0.0.1/go.mod h1:N8B+I7vPCT80IcP58r50u4+gEEcsZETF
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/QuarkChain/go-minimal-pbft v0.0.0-20220303075012-6084b729db36 h1:2SJS7tfMZdmXSWpB1DsLIImaq/BKxfaYv9OvOJqY0hw=
github.com/QuarkChain/go-minimal-pbft v0.0.0-20220303075012-6084b729db36/go.mod h1:nC/gDMz8G2h+K5KGDiEwEGJ//D70G8mwOBgHraRUab8=
github.com/QuarkChain/go-minimal-pbft v0.0.0-20220306083522-1c8dc76afb94 h1:T2Ogn+k7G/0hybvozBlps68CWpfvczJ5MT+wgwqKJgQ=
github.com/QuarkChain/go-minimal-pbft v0.0.0-20220306083522-1c8dc76afb94/go.mod h1:nC/gDMz8G2h+K5KGDiEwEGJ//D70G8mwOBgHraRUab8=
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
Expand Down
4 changes: 2 additions & 2 deletions miner/worker.go
Original file line number Diff line number Diff line change
Expand Up @@ -409,9 +409,9 @@ func recalcRecommit(minRecommit, prev time.Duration, target float64, inc bool) t
return time.Duration(int64(next))
}

func (w *worker) makeBlock(parent common.Hash, timestamp uint64) (*types.Block, error) {
func (w *worker) makeBlock(parent common.Hash, coinbase common.Address, timestamp uint64) (*types.Block, error) {

return w.getSealingBlock(parent, timestamp, w.coinbase, common.Hash{})
return w.getSealingBlock(parent, timestamp, coinbase, common.Hash{})
}

// newWorkLoop is a standalone goroutine to submit new sealing work upon received events.
Expand Down
4 changes: 2 additions & 2 deletions params/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ var (
P2pBootstrap: "/ip4/127.0.0.1/udp/33333/quic/p2p/12D3KooWRqZRJf6gYeLgeUnNCnKeRb29KiEVQcvRWk2tet9Q3Hmy",
NodeKeyPath: "/Users/qizhou/.ssh/node_galileo.key",
ValKeyPath: "/Users/qizhou/.ssh/val_galileo.key",
consensusConfig: ConsensusConfig{
ConsensusConfig: ConsensusConfig{
// WalPath: filepath.Join(defaultDataDir, "cs.wal", "wal"),
TimeoutPropose: 3000 * time.Millisecond,
TimeoutProposeDelta: 500 * time.Millisecond,
Expand Down Expand Up @@ -471,7 +471,7 @@ type TendermintConfig struct {
P2pBootstrap string
NodeName string
ProposerRepetition uint64
consensusConfig ConsensusConfig
ConsensusConfig ConsensusConfig
}

// String implements the stringer interface, returning the consensus engine details.
Expand Down

0 comments on commit 21d19e9

Please sign in to comment.