Merge pull request #2295 from LeoHChen/master_receipt_log

Master receipt log
pull/2297/head
Leo Chen 5 years ago committed by GitHub
commit 3be4594e87
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 11
      core/block_validator.go
  2. 5
      core/state_processor.go
  3. 30
      internal/params/config.go

@ -34,9 +34,6 @@ import (
"github.com/harmony-one/harmony/internal/params" "github.com/harmony-one/harmony/internal/params"
) )
// Beacon chain block 1213181 is a one-off block with empty receipts which is expected to be non-empty.
const beaconBadBlock = 1213181
// BlockValidator is responsible for validating block headers, uncles and // BlockValidator is responsible for validating block headers, uncles and
// processed state. // processed state.
// //
@ -96,16 +93,12 @@ func (v *BlockValidator) ValidateState(block *types.Block, statedb *state.DB, re
// Validate the received block's bloom with the one derived from the generated receipts. // Validate the received block's bloom with the one derived from the generated receipts.
// For valid blocks this should always validate to true. // For valid blocks this should always validate to true.
rbloom := types.CreateBloom(receipts) rbloom := types.CreateBloom(receipts)
// Beacon chain block 1213181 is a one-off block with empty receipts which is expected to be non-empty. if rbloom != header.Bloom() {
// Skip the validation for it to avoid failure.
if rbloom != header.Bloom() && (block.NumberU64() != beaconBadBlock || block.ShardID() != 0) {
return fmt.Errorf("invalid bloom (remote: %x local: %x)", header.Bloom(), rbloom) return fmt.Errorf("invalid bloom (remote: %x local: %x)", header.Bloom(), rbloom)
} }
// Tre receipt Trie's root (R = (Tr [[H1, R1], ... [Hn, R1]])) // Tre receipt Trie's root (R = (Tr [[H1, R1], ... [Hn, R1]]))
receiptSha := types.DeriveSha(receipts) receiptSha := types.DeriveSha(receipts)
// Beacon chain block 1213181 is a one-off block with empty receipts which is expected to be non-empty. if receiptSha != header.ReceiptHash() {
// Skip the validation for it to avoid failure.
if receiptSha != header.ReceiptHash() && (block.NumberU64() != beaconBadBlock || block.ShardID() != 0) {
return fmt.Errorf("invalid receipt root hash (remote: %x local: %x)", header.ReceiptHash(), receiptSha) return fmt.Errorf("invalid receipt root hash (remote: %x local: %x)", header.ReceiptHash(), receiptSha)
} }

@ -188,8 +188,11 @@ func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *commo
if msg.To() == nil { if msg.To() == nil {
receipt.ContractAddress = crypto.CreateAddress(vmenv.Context.Origin, tx.Nonce()) receipt.ContractAddress = crypto.CreateAddress(vmenv.Context.Origin, tx.Nonce())
} }
// Set the receipt logs and create a bloom for filtering // Set the receipt logs and create a bloom for filtering
receipt.Logs = statedb.GetLogs(tx.Hash()) if config.IsReceiptLog(header.Epoch()) {
receipt.Logs = statedb.GetLogs(tx.Hash())
}
receipt.Bloom = types.CreateBloom(types.Receipts{receipt}) receipt.Bloom = types.CreateBloom(types.Receipts{receipt})
var cxReceipt *types.CXReceipt var cxReceipt *types.CXReceipt

@ -30,6 +30,7 @@ var (
PreStakingEpoch: EpochTBD, PreStakingEpoch: EpochTBD,
EIP155Epoch: big.NewInt(28), EIP155Epoch: big.NewInt(28),
S3Epoch: big.NewInt(28), S3Epoch: big.NewInt(28),
ReceiptLogEpoch: big.NewInt(101),
} }
// TestnetChainConfig contains the chain parameters to run a node on the harmony test network. // TestnetChainConfig contains the chain parameters to run a node on the harmony test network.
@ -41,6 +42,7 @@ var (
PreStakingEpoch: big.NewInt(2), PreStakingEpoch: big.NewInt(2),
EIP155Epoch: big.NewInt(0), EIP155Epoch: big.NewInt(0),
S3Epoch: big.NewInt(0), S3Epoch: big.NewInt(0),
ReceiptLogEpoch: big.NewInt(0),
} }
// PangaeaChainConfig contains the chain parameters for the Pangaea network. // PangaeaChainConfig contains the chain parameters for the Pangaea network.
@ -53,6 +55,7 @@ var (
PreStakingEpoch: big.NewInt(0), PreStakingEpoch: big.NewInt(0),
EIP155Epoch: big.NewInt(0), EIP155Epoch: big.NewInt(0),
S3Epoch: big.NewInt(0), S3Epoch: big.NewInt(0),
ReceiptLogEpoch: big.NewInt(0),
} }
// LocalnetChainConfig contains the chain parameters to run for local development. // LocalnetChainConfig contains the chain parameters to run for local development.
@ -64,6 +67,7 @@ var (
PreStakingEpoch: big.NewInt(2), PreStakingEpoch: big.NewInt(2),
EIP155Epoch: big.NewInt(0), EIP155Epoch: big.NewInt(0),
S3Epoch: big.NewInt(0), S3Epoch: big.NewInt(0),
ReceiptLogEpoch: big.NewInt(0),
} }
// AllProtocolChanges ... // AllProtocolChanges ...
@ -77,6 +81,7 @@ var (
big.NewInt(0), // PreStakingEpoch big.NewInt(0), // PreStakingEpoch
big.NewInt(0), // EIP155Epoch big.NewInt(0), // EIP155Epoch
big.NewInt(0), // S3Epoch big.NewInt(0), // S3Epoch
big.NewInt(0), // ReceiptLogEpoch
} }
// TestChainConfig ... // TestChainConfig ...
@ -90,6 +95,7 @@ var (
big.NewInt(0), // PreStakingEpoch big.NewInt(0), // PreStakingEpoch
big.NewInt(0), // EIP155Epoch big.NewInt(0), // EIP155Epoch
big.NewInt(0), // S3Epoch big.NewInt(0), // S3Epoch
big.NewInt(0), // ReceiptLogEpoch
} }
// TestRules ... // TestRules ...
@ -136,16 +142,20 @@ type ChainConfig struct {
// S3 epoch is the first epoch containing S3 mainnet and all ethereum update up to Constantinople // S3 epoch is the first epoch containing S3 mainnet and all ethereum update up to Constantinople
S3Epoch *big.Int `json:"s3-epoch,omitempty"` S3Epoch *big.Int `json:"s3-epoch,omitempty"`
// ReceiptLogEpoch is the first epoch support receiptlog
ReceiptLogEpoch *big.Int `json:"receipt-log-epoch,omitempty"`
} }
// String implements the fmt.Stringer interface. // String implements the fmt.Stringer interface.
func (c *ChainConfig) String() string { func (c *ChainConfig) String() string {
return fmt.Sprintf("{ChainID: %v EIP155: %v CrossTx: %v Staking: %v CrossLink: %v}", return fmt.Sprintf("{ChainID: %v EIP155: %v CrossTx: %v Staking: %v CrossLink: %v ReceiptLog: %v}",
c.ChainID, c.ChainID,
c.EIP155Epoch, c.EIP155Epoch,
c.CrossTxEpoch, c.CrossTxEpoch,
c.StakingEpoch, c.StakingEpoch,
c.CrossLinkEpoch, c.CrossLinkEpoch,
c.ReceiptLogEpoch,
) )
} }
@ -194,6 +204,11 @@ func (c *ChainConfig) IsS3(epoch *big.Int) bool {
return isForked(c.S3Epoch, epoch) return isForked(c.S3Epoch, epoch)
} }
// IsReceiptLog returns whether epoch is either equal to the ReceiptLog fork epoch or greater.
func (c *ChainConfig) IsReceiptLog(epoch *big.Int) bool {
return isForked(c.ReceiptLogEpoch, epoch)
}
// GasTable returns the gas table corresponding to the current phase (homestead or homestead reprice). // GasTable returns the gas table corresponding to the current phase (homestead or homestead reprice).
// //
// The returned GasTable's fields shouldn't, under any circumstances, be changed. // The returned GasTable's fields shouldn't, under any circumstances, be changed.
@ -302,8 +317,8 @@ func (err *ConfigCompatError) Error() string {
// Rules is a one time interface meaning that it shouldn't be used in between transition // Rules is a one time interface meaning that it shouldn't be used in between transition
// phases. // phases.
type Rules struct { type Rules struct {
ChainID *big.Int ChainID *big.Int
IsCrossLink, IsEIP155, IsS3 bool IsCrossLink, IsEIP155, IsS3, IsReceiptLog bool
} }
// Rules ensures c's ChainID is not nil. // Rules ensures c's ChainID is not nil.
@ -313,9 +328,10 @@ func (c *ChainConfig) Rules(epoch *big.Int) Rules {
chainID = new(big.Int) chainID = new(big.Int)
} }
return Rules{ return Rules{
ChainID: new(big.Int).Set(chainID), ChainID: new(big.Int).Set(chainID),
IsCrossLink: c.IsCrossLink(epoch), IsCrossLink: c.IsCrossLink(epoch),
IsEIP155: c.IsEIP155(epoch), IsEIP155: c.IsEIP155(epoch),
IsS3: c.IsS3(epoch), IsS3: c.IsS3(epoch),
IsReceiptLog: c.IsReceiptLog(epoch),
} }
} }

Loading…
Cancel
Save