Merge branch 'dev' into hip30/testing

pull/4510/head
Diego Nava 1 year ago committed by GitHub
commit 51ed6b6b40
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 34
      core/block_validator.go
  2. 2
      core/blockchain.go
  3. 40
      core/blockchain_impl.go
  4. 19
      core/staking_verifier.go
  5. 16
      core/staking_verifier_test.go
  6. 31
      core/state_processor.go
  7. 4
      core/types.go
  8. 8
      internal/params/config.go
  9. 4
      node/node.go
  10. 10
      node/node_newblock.go
  11. 36
      node/worker/worker.go
  12. 4
      node/worker/worker_test.go
  13. 6
      p2p/stream/protocols/sync/chain.go
  14. 17
      p2p/stream/protocols/sync/chain_test.go
  15. 16
      p2p/stream/protocols/sync/message/parse.go
  16. 31
      p2p/stream/protocols/sync/stream_test.go
  17. 2
      test/chain/chain/chain_makers.go
  18. 2
      test/chain/main.go

@ -40,17 +40,13 @@ import (
//
// BlockValidator implements validator.
type BlockValidator struct {
config *params.ChainConfig // Chain configuration options
bc BlockChain // Canonical blockchain
engine consensus_engine.Engine // Consensus engine used for validating
bc BlockChain // Canonical blockchain
}
// NewBlockValidator returns a new block validator which is safe for re-use
func NewBlockValidator(config *params.ChainConfig, blockchain BlockChain, engine consensus_engine.Engine) *BlockValidator {
func NewBlockValidator(blockchain BlockChain) *BlockValidator {
validator := &BlockValidator{
config: config,
engine: engine,
bc: blockchain,
bc: blockchain,
}
return validator
}
@ -103,7 +99,7 @@ func (v *BlockValidator) ValidateState(block *types.Block, statedb *state.DB, re
return fmt.Errorf("invalid receipt root hash (remote: %x local: %x)", header.ReceiptHash(), receiptSha)
}
if v.config.AcceptsCrossTx(block.Epoch()) {
if v.bc.Config().AcceptsCrossTx(block.Epoch()) {
cxsSha := cxReceipts.ComputeMerkleRoot()
if cxsSha != header.OutgoingReceiptHash() {
legacySha := types.DeriveMultipleShardsSha(cxReceipts)
@ -115,7 +111,7 @@ func (v *BlockValidator) ValidateState(block *types.Block, statedb *state.DB, re
// Validate the state root against the received state root and throw
// an error if they don't match.
if root := statedb.IntermediateRoot(v.config.IsS3(header.Epoch())); header.Root() != root {
if root := statedb.IntermediateRoot(v.bc.Config().IsS3(header.Epoch())); header.Root() != root {
dump, _ := rlp.EncodeToBytes(header)
const msg = "invalid merkle root (remote: %x local: %x, rlp dump %s)"
return fmt.Errorf(msg, header.Root(), root, hex.EncodeToString(dump))
@ -131,25 +127,11 @@ func (v *BlockValidator) ValidateHeader(block *types.Block, seal bool) error {
return errors.New("block is nil")
}
if h := block.Header(); h != nil {
return v.engine.VerifyHeader(v.bc, h, true)
return v.bc.Engine().VerifyHeader(v.bc, h, true)
}
return errors.New("header field was nil")
}
// ValidateHeaders verifies a batch of blocks' headers concurrently. The method returns a quit channel
// to abort the operations and a results channel to retrieve the async verifications
func (v *BlockValidator) ValidateHeaders(chain []*types.Block) (chan<- struct{}, <-chan error) {
// Start the parallel header verifier
headers := make([]*block.Header, len(chain))
seals := make([]bool, len(chain))
for i, block := range chain {
headers[i] = block.Header()
seals[i] = true
}
return v.engine.VerifyHeaders(v.bc, headers, seals)
}
// CalcGasLimit computes the gas limit of the next block after parent. It aims
// to keep the baseline gas above the provided floor, and increase it towards the
// ceil if the blocks are full. If the ceil is exceeded, it will always decrease
@ -189,7 +171,7 @@ func CalcGasLimit(parent *block.Header, gasFloor, gasCeil uint64) uint64 {
// ValidateCXReceiptsProof checks whether the given CXReceiptsProof is consistency with itself
func (v *BlockValidator) ValidateCXReceiptsProof(cxp *types.CXReceiptsProof) error {
if !v.config.AcceptsCrossTx(cxp.Header.Epoch()) {
if !v.bc.Config().AcceptsCrossTx(cxp.Header.Epoch()) {
return errors.New("[ValidateCXReceiptsProof] cross shard receipt received before cx fork")
}
@ -249,5 +231,5 @@ func (v *BlockValidator) ValidateCXReceiptsProof(cxp *types.CXReceiptsProof) err
// (4) verify blockHeader with seal
var commitSig bls.SerializedSignature
copy(commitSig[:], cxp.CommitSig)
return v.engine.VerifyHeaderSignature(v.bc, cxp.Header, commitSig, cxp.CommitBitmap)
return v.bc.Engine().VerifyHeaderSignature(v.bc, cxp.Header, commitSig, cxp.CommitBitmap)
}

@ -56,8 +56,6 @@ type BlockChain interface {
// CurrentBlock retrieves the current head block of the canonical chain. The
// block is retrieved from the blockchain's internal cache.
CurrentBlock() *types.Block
// Validator returns the current validator.
Validator() Validator
// Processor returns the current processor.
Processor() Processor
// State returns a new mutable state based on the current HEAD block.

@ -216,8 +216,8 @@ type BlockChainImpl struct {
procInterrupt int32 // interrupt signaler for block processing
engine consensus_engine.Engine
processor Processor // block processor interface
validator Validator // block and state validator interface
processor *StateProcessor // block processor interface
validator *BlockValidator
vmConfig vm.Config
badBlocks *lru.Cache // Bad block cache
pendingSlashes slash.Records
@ -336,8 +336,8 @@ func newBlockChainWithOptions(
beaconChain = bc
}
bc.SetValidator(NewBlockValidator(chainConfig, bc, engine))
bc.SetProcessor(NewStateProcessor(chainConfig, bc, beaconChain, engine))
bc.validator = NewBlockValidator(bc)
bc.processor = NewStateProcessor(bc, beaconChain)
// Load any existing snapshot, regenerating it if loading failed
if bc.cacheConfig.SnapshotLimit > 0 {
@ -461,7 +461,7 @@ func VerifyIncomingReceipts(blockchain BlockChain, block *types.Block) error {
}
}
if err := blockchain.Validator().ValidateCXReceiptsProof(cxp); err != nil {
if err := NewBlockValidator(blockchain).ValidateCXReceiptsProof(cxp); err != nil {
return errors.Wrapf(err, "[verifyIncomingReceipts] verification failed")
}
}
@ -493,7 +493,7 @@ func (bc *BlockChainImpl) ValidateNewBlock(block *types.Block, beaconChain Block
if block.NumberU64() <= bc.CurrentBlock().NumberU64() {
return errors.Errorf("block with the same block number is already committed: %d", block.NumberU64())
}
if err := bc.Validator().ValidateHeader(block, true); err != nil {
if err := bc.validator.ValidateHeader(block, true); err != nil {
utils.Logger().Error().
Str("blockHash", block.Hash().Hex()).
Err(err).
@ -555,7 +555,7 @@ func (bc *BlockChainImpl) validateNewBlock(block *types.Block) error {
}
// Verify all the hash roots (state, txns, receipts, cross-shard)
if err := bc.Validator().ValidateState(
if err := bc.validator.ValidateState(
block, state, receipts, cxReceipts, usedGas,
); err != nil {
bc.reportBlock(block, receipts, err)
@ -741,24 +741,6 @@ func (bc *BlockChainImpl) CurrentFastBlock() *types.Block {
return bc.currentFastBlock.Load().(*types.Block)
}
func (bc *BlockChainImpl) SetProcessor(processor Processor) {
bc.procmu.Lock()
defer bc.procmu.Unlock()
bc.processor = processor
}
func (bc *BlockChainImpl) SetValidator(validator Validator) {
bc.procmu.Lock()
defer bc.procmu.Unlock()
bc.validator = validator
}
func (bc *BlockChainImpl) Validator() Validator {
bc.procmu.RLock()
defer bc.procmu.RUnlock()
return bc.validator
}
func (bc *BlockChainImpl) Processor() Processor {
bc.procmu.RLock()
defer bc.procmu.RUnlock()
@ -1693,8 +1675,8 @@ func (bc *BlockChainImpl) buildLeaderRotationMeta(curHeader *block.Header) error
return err
}
if curPubKey.Bytes != blockPubKey.Bytes || curHeader.Epoch().Uint64() != header.Epoch().Uint64() {
for j := i; i <= curHeader.NumberU64(); j++ {
header := bc.GetHeaderByNumber(i)
for j := i; j <= curHeader.NumberU64(); j++ {
header := bc.GetHeaderByNumber(j)
if header == nil {
return errors.New("header is nil")
}
@ -1815,7 +1797,7 @@ func (bc *BlockChainImpl) insertChain(chain types.Blocks, verifyHeaders bool) (i
err = <-verifyHeadersResults
}
if err == nil {
err = bc.Validator().ValidateBody(block)
err = NewBlockValidator(bc).ValidateBody(block)
}
switch {
case err == ErrKnownBlock:
@ -1933,7 +1915,7 @@ func (bc *BlockChainImpl) insertChain(chain types.Blocks, verifyHeaders bool) (i
// Validate the state using the default validator
substart = time.Now()
if err := bc.Validator().ValidateState(
if err := bc.validator.ValidateState(
block, state, receipts, cxReceipts, usedGas,
); err != nil {
bc.reportBlock(block, receipts, err)

@ -30,14 +30,9 @@ var (
)
func checkDuplicateFields(
bc ChainContext, state vm.StateDB,
addrs []common.Address, state vm.StateDB,
validator common.Address, identity string, blsKeys []bls.SerializedPublicKey,
) error {
addrs, err := bc.ReadValidatorList()
if err != nil {
return err
}
checkIdentity := identity != ""
checkBlsKeys := len(blsKeys) != 0
@ -99,8 +94,12 @@ func VerifyAndCreateValidatorFromMsg(
errValidatorExist, common2.MustAddressToBech32(msg.ValidatorAddress),
)
}
addrs, err := chainContext.ReadValidatorList()
if err != nil {
return nil, err
}
if err := checkDuplicateFields(
chainContext, stateDB,
addrs, stateDB,
msg.ValidatorAddress,
msg.Identity,
msg.SlotPubKeys); err != nil {
@ -151,8 +150,12 @@ func VerifyAndEditValidatorFromMsg(
if msg.SlotKeyToAdd != nil {
newBlsKeys = append(newBlsKeys, *msg.SlotKeyToAdd)
}
addrs, err := chainContext.ReadValidatorList()
if err != nil {
return nil, err
}
if err := checkDuplicateFields(
chainContext, stateDB,
addrs, stateDB,
msg.ValidatorAddress,
msg.Identity,
newBlsKeys); err != nil {

@ -153,16 +153,6 @@ func TestCheckDuplicateFields(t *testing.T) {
expErr: nil,
},
{
// chain error
bc: &fakeErrChainContext{},
sdb: makeStateDBForStake(t),
validator: createValidatorAddr,
identity: makeIdentityStr("new validator"),
pubs: []bls.SerializedPublicKey{blsKeys[11].pub},
expErr: errors.New("error intended"),
},
{
// validators read from chain not in state
bc: func() *fakeChainContext {
@ -201,7 +191,11 @@ func TestCheckDuplicateFields(t *testing.T) {
},
}
for i, test := range tests {
err := checkDuplicateFields(test.bc, test.sdb, test.validator, test.identity, test.pubs)
addrs, err := test.bc.ReadValidatorList()
if err != nil {
t.Fatal(err)
}
err = checkDuplicateFields(addrs, test.sdb, test.validator, test.identity, test.pubs)
if assErr := assertError(err, test.expErr); assErr != nil {
t.Errorf("Test %v: %v", i, assErr)

@ -28,7 +28,6 @@ import (
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/rlp"
"github.com/harmony-one/harmony/block"
consensus_engine "github.com/harmony-one/harmony/consensus/engine"
"github.com/harmony-one/harmony/consensus/reward"
"github.com/harmony-one/harmony/core/rawdb"
"github.com/harmony-one/harmony/core/state"
@ -58,11 +57,9 @@ const (
//
// StateProcessor implements Processor.
type StateProcessor struct {
config *params.ChainConfig // Chain configuration options
bc BlockChain // Canonical blockchain
beacon BlockChain // Beacon chain
engine consensus_engine.Engine // Consensus engine used for block rewards
resultCache *lru.Cache // Cache for result after a certain block is processed
bc BlockChain // Canonical blockchain
beacon BlockChain // Beacon chain
resultCache *lru.Cache // Cache for result after a certain block is processed
}
// this structure is cached, and each individual element is returned
@ -78,7 +75,7 @@ type ProcessorResult struct {
// NewStateProcessor initialises a new StateProcessor.
func NewStateProcessor(
config *params.ChainConfig, bc BlockChain, beacon BlockChain, engine consensus_engine.Engine,
bc BlockChain, beacon BlockChain,
) *StateProcessor {
if bc == nil {
panic("bc is nil")
@ -88,14 +85,14 @@ func NewStateProcessor(
}
resultCache, _ := lru.New(resultCacheLimit)
return &StateProcessor{
config: config,
bc: bc,
beacon: beacon,
engine: engine,
resultCache: resultCache,
}
}
type UsedGas = uint64
// Process processes the state changes according to the Ethereum rules by running
// the transaction messages using the statedb and applying any rewards to both
// the processor (coinbase) and any included uncles.
@ -107,7 +104,7 @@ func (p *StateProcessor) Process(
block *types.Block, statedb *state.DB, cfg vm.Config, readCache bool,
) (
types.Receipts, types.CXReceipts, []staking.StakeMsg,
[]*types.Log, uint64, reward.Reader, *state.DB, error,
[]*types.Log, UsedGas, reward.Reader, *state.DB, error,
) {
cacheKey := block.Hash()
if readCache {
@ -155,6 +152,7 @@ func (p *StateProcessor) Process(
processTxsAndStxs = false
}
}
if processTxsAndStxs {
startTime := time.Now()
// Iterate over and process the individual transactions
@ -197,7 +195,7 @@ func (p *StateProcessor) Process(
// after transactions (to be consistent with the block proposal)
for _, cx := range block.IncomingReceipts() {
if err := ApplyIncomingReceipt(
p.config, statedb, header, cx,
p.bc.Config(), statedb, header, cx,
); err != nil {
return nil, nil,
nil, nil, 0, nil, statedb, errors.New("[Process] Cannot apply incoming receipts")
@ -223,7 +221,7 @@ func (p *StateProcessor) Process(
// Block processing don't need to block on reward computation as in block proposal
sigsReady <- true
}()
_, payout, err := p.engine.Finalize(
_, payout, err := p.bc.Engine().Finalize(
p.bc,
p.beacon,
header, statedb, block.Transactions(),
@ -274,8 +272,9 @@ func getTransactionType(
// and uses the input parameters for its environment. It returns the receipt
// for the transaction, gas used and an error if the transaction failed,
// indicating the block was invalid.
func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *common.Address, gp *GasPool, statedb *state.DB, header *block.Header, tx *types.Transaction, usedGas *uint64, cfg vm.Config) (*types.Receipt, *types.CXReceipt, []staking.StakeMsg, uint64, error) {
txType := getTransactionType(config, header, tx)
func ApplyTransaction(bc ChainContext, author *common.Address, gp *GasPool, statedb *state.DB, header *block.Header, tx *types.Transaction, usedGas *uint64, cfg vm.Config) (*types.Receipt, *types.CXReceipt, []staking.StakeMsg, uint64, error) {
config := bc.Config()
txType := getTransactionType(bc.Config(), header, tx)
if txType == types.InvalidTx {
return nil, nil, nil, 0, errors.New("Invalid Transaction Type")
}
@ -378,9 +377,9 @@ func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *commo
// indicating the block was invalid.
// staking transaction will use the code field in the account to store the staking information
func ApplyStakingTransaction(
config *params.ChainConfig, bc ChainContext, author *common.Address, gp *GasPool, statedb *state.DB,
bc ChainContext, author *common.Address, gp *GasPool, statedb *state.DB,
header *block.Header, tx *staking.StakingTransaction, usedGas *uint64, cfg vm.Config) (receipt *types.Receipt, gas uint64, err error) {
config := bc.Config()
msg, err := StakingToMessage(tx, header.Number())
if err != nil {
return nil, 0, err

@ -40,10 +40,6 @@ type Validator interface {
// via the VerifySeal method.
ValidateHeader(block *types.Block, seal bool) error
// ValidateHeaders verifies a batch of blocks' headers concurrently. The method returns a quit channel
// to abort the operations and a results channel to retrieve the async verifications
ValidateHeaders(chain []*types.Block) (chan<- struct{}, <-chan error)
// ValidateCXReceiptsProof checks whether the given CXReceiptsProof is consistency with itself
ValidateCXReceiptsProof(cxp *types.CXReceiptsProof) error
}

@ -329,6 +329,7 @@ var (
big.NewInt(1), // LeaderRotationExternalBeaconLeaders
big.NewInt(0), // FeeCollectEpoch
big.NewInt(0), // ValidatorCodeFixEpoch
big.NewInt(0), // BlockGas30M
big.NewInt(0), // HIP30Epoch
}
@ -374,6 +375,7 @@ var (
big.NewInt(0), // FeeCollectEpoch
big.NewInt(0), // ValidatorCodeFixEpoch
big.NewInt(0), // HIP30Epoch
big.NewInt(0), // BlockGas30M
}
// TestRules ...
@ -537,6 +539,8 @@ type ChainConfig struct {
// 3. Change from 250 to 200 nodes for remaining shards (mainnet and localnet)
// 4. Change the minimum validator commission from 5 to 7% (all nets)
HIP30Epoch *big.Int `json:"hip30-epoch,omitempty"`
BlockGas30MEpoch *big.Int `json:"block-gas-30m-epoch,omitempty"`
}
// String implements the fmt.Stringer interface.
@ -772,6 +776,10 @@ func (c *ChainConfig) IsLeaderRotation(epoch *big.Int) bool {
return isForked(c.LeaderRotationExternalNonBeaconLeaders, epoch)
}
func (c *ChainConfig) IsBlockGas30M(epoch *big.Int) bool {
return isForked(c.BlockGas30MEpoch, epoch)
}
func (c *ChainConfig) IsLeaderRotationExternalValidatorsAllowed(epoch *big.Int, shardID uint32) bool {
if !c.IsLeaderRotation(epoch) {
return false

@ -392,7 +392,7 @@ func (node *Node) AddPendingReceipts(receipts *types.CXReceiptsProof) {
// Sanity checks
if err := node.Blockchain().Validator().ValidateCXReceiptsProof(receipts); err != nil {
if err := core.NewBlockValidator(node.Blockchain()).ValidateCXReceiptsProof(receipts); err != nil {
if !strings.Contains(err.Error(), rawdb.MsgNoShardStateFromDB) {
utils.Logger().Error().Err(err).Msg("[AddPendingReceipts] Invalid CXReceiptsProof")
return
@ -1126,7 +1126,7 @@ func New(
node.TxPool = core.NewTxPool(txPoolConfig, node.Blockchain().Config(), blockchain, node.TransactionErrorSink)
node.registry.SetTxPool(node.TxPool)
node.CxPool = node.registry.GetCxPool()
node.Worker = worker.New(node.Blockchain().Config(), blockchain, beaconChain, engine)
node.Worker = worker.New(blockchain, beaconChain)
node.deciderCache, _ = lru.New(16)
node.committeeCache, _ = lru.New(16)

@ -7,6 +7,7 @@ import (
"time"
"github.com/harmony-one/harmony/consensus"
"github.com/harmony-one/harmony/core"
"github.com/harmony-one/harmony/crypto/bls"
staking "github.com/harmony-one/harmony/staking/types"
@ -292,8 +293,11 @@ func (node *Node) ProposeNewBlock(commitSigs chan []byte) (*types.Block, error)
utils.Logger().Error().Err(err).Msg("[ProposeNewBlock] Failed finalizing the new block")
return nil, err
}
utils.Logger().Info().Msgf("[ProposeNewBlock] verifying the new block: shard %d, number %d, epoch %d", finalizedBlock.ShardID(), finalizedBlock.NumberU64(), finalizedBlock.Epoch().Uint64())
err = node.Blockchain().Validator().ValidateHeader(finalizedBlock, true)
utils.Logger().Info().Msg("[ProposeNewBlock] verifying the new block header")
// err = node.Blockchain().Validator().ValidateHeader(finalizedBlock, true)
err = core.NewBlockValidator(node.Blockchain()).ValidateHeader(finalizedBlock, true)
if err != nil {
utils.Logger().Error().Err(err).Msg("[ProposeNewBlock] Failed verifying the new block header")
@ -360,7 +364,7 @@ Loop:
}
}
if err := node.Blockchain().Validator().ValidateCXReceiptsProof(cxp); err != nil {
if err := core.NewBlockValidator(node.Blockchain()).ValidateCXReceiptsProof(cxp); err != nil {
if strings.Contains(err.Error(), rawdb.MsgNoShardStateFromDB) {
pendingReceiptsList = append(pendingReceiptsList, cxp)
} else {

@ -19,7 +19,6 @@ import (
"github.com/ethereum/go-ethereum/rlp"
"github.com/harmony-one/harmony/block"
blockfactory "github.com/harmony-one/harmony/block/factory"
consensus_engine "github.com/harmony-one/harmony/consensus/engine"
"github.com/harmony-one/harmony/core"
"github.com/harmony-one/harmony/core/state"
"github.com/harmony-one/harmony/core/types"
@ -59,7 +58,6 @@ type Worker struct {
chain core.BlockChain
beacon core.BlockChain
current *environment // An environment for current running cycle.
engine consensus_engine.Engine
gasFloor uint64
gasCeil uint64
}
@ -70,12 +68,6 @@ func (w *Worker) CommitSortedTransactions(
coinbase common.Address,
) {
for {
if w.current.gasPool.Gas() < 50000000 {
// Temporary solution to reduce the fullness of the block. Break here when the available gas left hit 50M.
// Effectively making the gas limit 30M (since 80M is the default gas limit)
utils.Logger().Info().Uint64("have", w.current.gasPool.Gas()).Uint64("want", params.TxGas).Msg("[Temp Gas Limit] Not enough gas for further transactions")
break
}
// If we don't have enough gas for any further transactions then we're done
if w.current.gasPool.Gas() < params.TxGas {
utils.Logger().Info().Uint64("have", w.current.gasPool.Gas()).Uint64("want", params.TxGas).Msg("Not enough gas for further transactions")
@ -96,7 +88,7 @@ func (w *Worker) CommitSortedTransactions(
from, _ := types.Sender(signer, tx)
// Check whether the tx is replay protected. If we're not in the EIP155 hf
// phase, start ignoring the sender until we do.
if tx.Protected() && !w.config.IsEIP155(w.current.header.Epoch()) {
if tx.Protected() && !w.chain.Config().IsEIP155(w.current.header.Epoch()) {
utils.Logger().Info().Str("hash", tx.Hash().Hex()).Str("eip155Epoch", w.config.EIP155Epoch.String()).Msg("Ignoring reply protected transaction")
txs.Pop()
continue
@ -235,7 +227,7 @@ func (w *Worker) commitStakingTransaction(
snap := w.current.state.Snapshot()
gasUsed := w.current.header.GasUsed()
receipt, _, err := core.ApplyStakingTransaction(
w.config, w.chain, &coinbase, w.current.gasPool,
w.chain, &coinbase, w.current.gasPool,
w.current.state, w.current.header, tx, &gasUsed, vm.Config{},
)
w.current.header.SetGasUsed(gasUsed)
@ -272,7 +264,6 @@ func (w *Worker) commitTransaction(
snap := w.current.state.Snapshot()
gasUsed := w.current.header.GasUsed()
receipt, cx, stakeMsgs, _, err := core.ApplyTransaction(
w.config,
w.chain,
&coinbase,
w.current.gasPool,
@ -341,7 +332,7 @@ func (w *Worker) UpdateCurrent() error {
header := w.factory.NewHeader(epoch).With().
ParentHash(parent.Hash()).
Number(num.Add(num, common.Big1)).
GasLimit(core.CalcGasLimit(parent, w.gasFloor, w.gasCeil)).
GasLimit(core.CalcGasLimit(parent, w.GasFloor(epoch), w.gasCeil)).
Time(big.NewInt(timestamp)).
ShardID(w.chain.ShardID()).
Header()
@ -581,7 +572,7 @@ func (w *Worker) FinalizeNewBlock(
}
}()
block, payout, err := w.engine.Finalize(
block, payout, err := w.chain.Engine().Finalize(
w.chain,
w.beacon,
copyHeader, state, w.current.txs, w.current.receipts,
@ -597,14 +588,13 @@ func (w *Worker) FinalizeNewBlock(
// New create a new worker object.
func New(
config *params.ChainConfig, chain core.BlockChain, beacon core.BlockChain, engine consensus_engine.Engine,
chain core.BlockChain, beacon core.BlockChain,
) *Worker {
worker := &Worker{
config: config,
factory: blockfactory.NewFactory(config),
config: chain.Config(),
factory: blockfactory.NewFactory(chain.Config()),
chain: chain,
beacon: beacon,
engine: engine,
}
worker.gasFloor = 80000000
worker.gasCeil = 120000000
@ -625,3 +615,15 @@ func New(
return worker
}
func (w *Worker) GasFloor(epoch *big.Int) uint64 {
if w.chain.Config().IsBlockGas30M(epoch) {
return 30_000_000
}
return w.gasFloor
}
func (w *Worker) GasCeil() uint64 {
return w.gasCeil
}

@ -50,7 +50,7 @@ func TestNewWorker(t *testing.T) {
t.Error(err)
}
// Create a new worker
worker := New(params.TestChainConfig, chain, nil, engine)
worker := New(chain, nil)
if worker.GetCurrentState().GetBalance(crypto.PubkeyToAddress(testBankKey.PublicKey)).Cmp(testBankFunds) != 0 {
t.Error("Worker state is not setup correctly")
@ -75,7 +75,7 @@ func TestCommitTransactions(t *testing.T) {
chain, _ := core.NewBlockChain(database, nil, nil, cacheConfig, gspec.Config, engine, vm.Config{})
// Create a new worker
worker := New(params.TestChainConfig, chain, nil, engine)
worker := New(chain, nil)
// Generate a test tx
baseNonce := worker.GetCurrentState().GetNonce(crypto.PubkeyToAddress(testBankKey.PublicKey))

@ -168,8 +168,7 @@ func (ch *chainHelperImpl) getNodeData(hs []common.Hash) ([][]byte, error) {
// getReceipts assembles the response to a receipt query.
func (ch *chainHelperImpl) getReceipts(hs []common.Hash) ([]types.Receipts, error) {
var receipts []types.Receipts
receipts := make([]types.Receipts, len(hs))
for i, hash := range hs {
// Retrieve the requested block's receipts
results := ch.chain.GetReceiptsByHash(hash)
@ -177,8 +176,9 @@ func (ch *chainHelperImpl) getReceipts(hs []common.Hash) ([]types.Receipts, erro
if header := ch.chain.GetHeaderByHash(hash); header == nil || header.ReceiptHash() != types.EmptyRootHash {
continue
}
return nil, errors.New("invalid hashes to get receipts")
}
receipts[i] = append(receipts[i], results...)
receipts[i] = results
}
return receipts, nil
}

@ -53,13 +53,28 @@ func (tch *testChainHelper) getNodeData(hs []common.Hash) ([][]byte, error) {
func (tch *testChainHelper) getReceipts(hs []common.Hash) ([]types.Receipts, error) {
testReceipts := makeTestReceipts(len(hs), 3)
receipts := make([]types.Receipts, len(hs)*3)
receipts := make([]types.Receipts, len(hs))
for i, _ := range hs {
receipts[i] = testReceipts
}
return receipts, nil
}
func checkGetReceiptsResult(b []byte, hs []common.Hash) error {
var msg = &syncpb.Message{}
if err := protobuf.Unmarshal(b, msg); err != nil {
return err
}
bhResp, err := msg.GetReceiptsResponse()
if err != nil {
return err
}
if len(hs) != len(bhResp.Receipts) {
return errors.New("unexpected size")
}
return nil
}
func numberToHash(bn uint64) common.Hash {
var h common.Hash
binary.LittleEndian.PutUint64(h[:], bn)

@ -79,3 +79,19 @@ func (msg *Message) GetBlocksByHashesResponse() (*GetBlocksByHashesResponse, err
}
return gbResp, nil
}
// GetReceiptsResponse parse the message to GetReceiptsResponse
func (msg *Message) GetReceiptsResponse() (*GetReceiptsResponse, error) {
resp := msg.GetResp()
if resp == nil {
return nil, errors.New("not response message")
}
if errResp := resp.GetErrorResponse(); errResp != nil {
return nil, &ResponseError{errResp.Error}
}
grResp := resp.GetGetReceiptsResponse()
if grResp == nil {
return nil, errors.New("not GetGetReceiptsResponse")
}
return grResp, nil
}

@ -40,6 +40,16 @@ var (
}
testGetBlocksByHashesRequest = syncpb.MakeGetBlocksByHashesRequest(testGetBlockByHashes)
testGetBlocksByHashesRequestMsg = syncpb.MakeMessageFromRequest(testGetBlocksByHashesRequest)
testGetReceipts = []common.Hash{
numberToHash(1),
numberToHash(2),
numberToHash(3),
numberToHash(4),
numberToHash(5),
}
testGetReceiptsRequest = syncpb.MakeGetReceiptsRequest(testGetReceipts)
testGetReceiptsRequestMsg = syncpb.MakeMessageFromRequest(testGetReceiptsRequest)
)
func TestSyncStream_HandleGetBlocksByRequest(t *testing.T) {
@ -126,6 +136,27 @@ func TestSyncStream_HandleGetBlocksByHashes(t *testing.T) {
}
}
func TestSyncStream_HandleGetReceipts(t *testing.T) {
st, remoteSt := makeTestSyncStream()
go st.run()
defer close(st.closeC)
req := testGetReceiptsRequestMsg
b, _ := protobuf.Marshal(req)
err := remoteSt.WriteBytes(b)
if err != nil {
t.Fatal(err)
}
time.Sleep(200 * time.Millisecond)
receivedBytes, _ := remoteSt.ReadBytes()
if err := checkGetReceiptsResult(receivedBytes, testGetBlockByHashes); err != nil {
t.Fatal(err)
}
}
func makeTestSyncStream() (*syncStream, *testRemoteBaseStream) {
localRaw, remoteRaw := makePairP2PStreams()
remote := newTestRemoteBaseStream(remoteRaw)

@ -102,7 +102,7 @@ func (b *BlockGen) AddTxWithChain(bc core.BlockChain, tx *types.Transaction) {
b.statedb.Prepare(tx.Hash(), common.Hash{}, len(b.txs))
coinbase := b.header.Coinbase()
gasUsed := b.header.GasUsed()
receipt, _, _, _, err := core.ApplyTransaction(b.config, bc, &coinbase, b.gasPool, b.statedb, b.header, tx, &gasUsed, vm.Config{})
receipt, _, _, _, err := core.ApplyTransaction(bc, &coinbase, b.gasPool, b.statedb, b.header, tx, &gasUsed, vm.Config{})
b.header.SetGasUsed(gasUsed)
b.header.SetCoinbase(coinbase)
if err != nil {

@ -93,7 +93,7 @@ func fundFaucetContract(chain core.BlockChain) {
fmt.Println("--------- Funding addresses for Faucet Contract Call ---------")
fmt.Println()
contractworker = pkgworker.New(params.TestChainConfig, chain, nil, chain.Engine())
contractworker = pkgworker.New(chain, nil)
nonce = contractworker.GetCurrentState().GetNonce(crypto.PubkeyToAddress(FaucetPriKey.PublicKey))
dataEnc = common.FromHex(FaucetContractBinary)
ftx, _ := types.SignTx(

Loading…
Cancel
Save