From 5028205b03133d580056d94d771eaadce0c57a9f Mon Sep 17 00:00:00 2001 From: Qi Zhou Date: Sat, 5 Mar 2022 23:32:38 -0800 Subject: [PATCH 1/3] add web3q galileo flag --- cmd/geth/main.go | 1 + 1 file changed, 1 insertion(+) diff --git a/cmd/geth/main.go b/cmd/geth/main.go index 6cb90a4d7e1d..5044ae85bcd6 100644 --- a/cmd/geth/main.go +++ b/cmd/geth/main.go @@ -147,6 +147,7 @@ var ( utils.RinkebyFlag, utils.GoerliFlag, utils.Web3QTestnetFlag, + utils.Web3QGalileoFlag, utils.Web3QMainnetFlag, utils.VMEnableDebugFlag, utils.NetworkIdFlag, From 82a12deafd74cb90e2dab946a0c0e43132314e24 Mon Sep 17 00:00:00 2001 From: Qi Zhou Date: Sat, 5 Mar 2022 23:43:27 -0800 Subject: [PATCH 2/3] enable single validator - header.Difficulty = number - NextValidators should be empty if non-epoch - NextValidatorPowers should have the same len as NextValidators - use custom MakeBlock --- consensus/tendermint/adapter/store.go | 19 +++++++++++--- consensus/tendermint/gov/gov.go | 16 ++++++++++++ consensus/tendermint/tendermint.go | 36 +++++++++++++++------------ core/blockchain.go | 2 ++ go.mod | 2 +- go.sum | 2 ++ miner/worker.go | 4 +-- params/config.go | 4 +-- 8 files changed, 60 insertions(+), 25 deletions(-) diff --git a/consensus/tendermint/adapter/store.go b/consensus/tendermint/adapter/store.go index 1c6610b09420..881250ff90a8 100644 --- a/consensus/tendermint/adapter/store.go +++ b/consensus/tendermint/adapter/store.go @@ -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} } @@ -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) } diff --git a/consensus/tendermint/gov/gov.go b/consensus/tendermint/gov/gov.go index dad17e96ad0f..d18a3085888c 100644 --- a/consensus/tendermint/gov/gov.go +++ b/consensus/tendermint/gov/gov.go @@ -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 + } +} diff --git a/consensus/tendermint/tendermint.go b/consensus/tendermint/tendermint.go index 8a914364fda4..8a1007c82ec9 100644 --- a/consensus/tendermint/tendermint.go +++ b/consensus/tendermint/tendermint.go @@ -25,7 +25,6 @@ import ( "fmt" "io/ioutil" "math/big" - "reflect" "time" pbftconsensus "github.com/QuarkChain/go-minimal-pbft/consensus" @@ -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) @@ -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 @@ -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, @@ -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") @@ -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(int64(number))) != 0) { return errInvalidDifficulty } } @@ -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(int64(number)) + + 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 } diff --git a/core/blockchain.go b/core/blockchain.go index 11828e349b94..df1dded06608 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -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) diff --git a/go.mod b/go.mod index af326f40060a..ba6700a523d5 100644 --- a/go.mod +++ b/go.mod @@ -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 diff --git a/go.sum b/go.sum index fa1cd0237237..ee776593a4a9 100644 --- a/go.sum +++ b/go.sum @@ -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= diff --git a/miner/worker.go b/miner/worker.go index 7cb89f4ed51e..c596716f40c0 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -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. diff --git a/params/config.go b/params/config.go index 7a818a2c907f..a146b19eb49f 100644 --- a/params/config.go +++ b/params/config.go @@ -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, @@ -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. From 8056ed6df12b762d5295ddf0f2a845c1a308a35e Mon Sep 17 00:00:00 2001 From: Qi Zhou Date: Mon, 7 Mar 2022 11:47:33 -0800 Subject: [PATCH 3/3] set diff = 1 for tm --- consensus/tendermint/tendermint.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/consensus/tendermint/tendermint.go b/consensus/tendermint/tendermint.go index 8a1007c82ec9..7cd1111570e7 100644 --- a/consensus/tendermint/tendermint.go +++ b/consensus/tendermint/tendermint.go @@ -300,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(int64(number))) != 0) { + if header.Difficulty == nil || (header.Difficulty.Cmp(big.NewInt(1)) != 0) { return errInvalidDifficulty } } @@ -374,7 +374,7 @@ func (c *Tendermint) Prepare(chain consensus.ChainHeaderReader, header *types.He header.TimeMs = timestamp header.Time = timestamp / 1000 - header.Difficulty = big.NewInt(int64(number)) + header.Difficulty = big.NewInt(1) if (number % c.config.Epoch) != 0 { header.NextValidators = []common.Address{}