Skip to content

Commit

Permalink
EVM-732 Tx hash calculation should include tx type and chainID (#1706)
Browse files Browse the repository at this point in the history
  • Loading branch information
igorcrevar committed Jul 20, 2023
1 parent 01d7791 commit 14ea06c
Show file tree
Hide file tree
Showing 38 changed files with 483 additions and 281 deletions.
4 changes: 2 additions & 2 deletions blockchain/blockchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -705,9 +705,9 @@ func (b *Blockchain) verifyBlockBody(block *types.Block) ([]*types.Receipt, erro
}

// Make sure the transactions root matches up
if hash := buildroot.CalculateTransactionsRoot(block.Transactions); hash != block.Header.TxRoot {
if hash := buildroot.CalculateTransactionsRoot(block.Transactions, block.Number()); hash != block.Header.TxRoot {
b.logger.Error(fmt.Sprintf(
"transaction root hash mismatch: have %s, want %s",
"incorrect tx root (expected: %s, actual: %s)",
hash,
block.Header.TxRoot,
))
Expand Down
23 changes: 13 additions & 10 deletions blockchain/blockchain_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -594,7 +594,7 @@ func TestBlockchainWriteBody(t *testing.T) {
},
}

tx.ComputeHash()
tx.ComputeHash(1)
block.Header.ComputeHash()

txFromByTxHash := map[types.Hash]types.Address{}
Expand Down Expand Up @@ -625,7 +625,7 @@ func TestBlockchainWriteBody(t *testing.T) {
},
}

tx.ComputeHash()
tx.ComputeHash(1)
block.Header.ComputeHash()

txFromByTxHash := map[types.Hash]types.Address{}
Expand Down Expand Up @@ -657,7 +657,7 @@ func TestBlockchainWriteBody(t *testing.T) {
},
}

tx.ComputeHash()
tx.ComputeHash(1)
block.Header.ComputeHash()

txFromByTxHash := map[types.Hash]types.Address{
Expand All @@ -668,7 +668,10 @@ func TestBlockchainWriteBody(t *testing.T) {
defer chain.db.Close()
batchWriter := storage.NewBatchWriter(chain.db)

batchWriter.PutHeader(block.Header)

assert.NoError(t, chain.writeBody(batchWriter, block))

assert.NoError(t, batchWriter.WriteBatch())

readBody, ok := chain.readBody(block.Hash())
Expand All @@ -689,7 +692,7 @@ func Test_recoverFromFieldsInBlock(t *testing.T) {

computeTxHashes := func(txs ...*types.Transaction) {
for _, tx := range txs {
tx.ComputeHash()
tx.ComputeHash(1)
}
}

Expand Down Expand Up @@ -774,7 +777,7 @@ func Test_recoverFromFieldsInTransactions(t *testing.T) {

computeTxHashes := func(txs ...*types.Transaction) {
for _, tx := range txs {
tx.ComputeHash()
tx.ComputeHash(1)
}
}

Expand Down Expand Up @@ -893,7 +896,7 @@ func TestBlockchainReadBody(t *testing.T) {
V: big.NewInt(1),
}

tx.ComputeHash()
tx.ComputeHash(1)

block := &types.Block{
Header: &types.Header{},
Expand All @@ -906,9 +909,9 @@ func TestBlockchainReadBody(t *testing.T) {

txFromByTxHash[tx.Hash] = types.ZeroAddress

if err := b.writeBody(batchWriter, block); err != nil {
t.Fatal(err)
}
batchWriter.PutCanonicalHeader(block.Header, big.NewInt(0))

require.NoError(t, b.writeBody(batchWriter, block))

assert.NoError(t, batchWriter.WriteBatch())

Expand Down Expand Up @@ -1469,7 +1472,7 @@ func TestBlockchain_WriteFullBlock(t *testing.T) {
Value: big.NewInt(1),
}

tx.ComputeHash()
tx.ComputeHash(1)
header.ComputeHash()
existingHeader.ComputeHash()
bc.currentHeader.Store(existingHeader)
Expand Down
16 changes: 14 additions & 2 deletions blockchain/storage/keyvalue.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,9 +143,21 @@ func (s *KeyValueStorage) ReadHeader(hash types.Hash) (*types.Header, error) {
// ReadBody reads the body
func (s *KeyValueStorage) ReadBody(hash types.Hash) (*types.Body, error) {
body := &types.Body{}
err := s.readRLP(BODY, hash.Bytes(), body)
if err := s.readRLP(BODY, hash.Bytes(), body); err != nil {
return nil, err
}

// must read header because block number is needed in order to calculate each tx hash
header := &types.Header{}
if err := s.readRLP(HEADER, hash.Bytes(), header); err != nil {
return nil, err
}

for _, tx := range body.Transactions {
tx.ComputeHash(header.Number)
}

return body, err
return body, nil
}

// RECEIPTS //
Expand Down
2 changes: 1 addition & 1 deletion blockchain/storage/leveldb/leveldb_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ func generateTxs(t *testing.T, startNonce, count int, from types.Address, to *ty

require.NoError(t, err)

tx.ComputeHash()
tx.ComputeHash(1)

txs[i] = tx
}
Expand Down
4 changes: 2 additions & 2 deletions blockchain/storage/testing.go
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ func testBody(t *testing.T, m PlaceholderStorage) {
Input: []byte{1, 2},
V: big.NewInt(1),
}
t0.ComputeHash()
t0.ComputeHash(1)

addr2 := types.StringToAddress("22")
t1 := &types.Transaction{
Expand All @@ -291,7 +291,7 @@ func testBody(t *testing.T, m PlaceholderStorage) {
Input: []byte{4, 5},
V: big.NewInt(2),
}
t1.ComputeHash()
t1.ComputeHash(1)

block := types.Block{
Header: header,
Expand Down
30 changes: 8 additions & 22 deletions chain/params.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import (
"errors"
"sort"

"github.com/0xPolygon/polygon-edge/helper/common"
"github.com/0xPolygon/polygon-edge/forkmanager"
"github.com/0xPolygon/polygon-edge/types"
)

Expand Down Expand Up @@ -88,6 +88,7 @@ const (
EIP158 = "EIP158"
EIP155 = "EIP155"
QuorumCalcAlignment = "quorumcalcalignment"
TxHashWithType = "txHashWithType"
)

// Forks is map which contains all forks and their starting blocks from genesis
Expand Down Expand Up @@ -122,30 +123,13 @@ func (f *Forks) At(block uint64) ForksInTime {
EIP158: f.IsActive(EIP158, block),
EIP155: f.IsActive(EIP155, block),
QuorumCalcAlignment: f.IsActive(QuorumCalcAlignment, block),
TxHashWithType: f.IsActive(TxHashWithType, block),
}
}

// ForkParams hard-coded fork params
type ForkParams struct {
// MaxValidatorSetSize indicates the maximum size of validator set
MaxValidatorSetSize *uint64 `json:"maxValidatorSetSize,omitempty"`

// EpochSize is size of epoch
EpochSize *uint64 `json:"epochSize,omitempty"`

// SprintSize is size of sprint
SprintSize *uint64 `json:"sprintSize,omitempty"`

// BlockTime is target frequency of blocks production
BlockTime *common.Duration `json:"blockTime,omitempty"`

// BlockTimeDrift defines the time slot in which a new block can be created
BlockTimeDrift *uint64 `json:"blockTimeDrift,omitempty"`
}

type Fork struct {
Block uint64 `json:"block"`
Params *ForkParams `json:"params,omitempty"`
Block uint64 `json:"block"`
Params *forkmanager.ForkParams `json:"params,omitempty"`
}

func NewFork(n uint64) Fork {
Expand All @@ -167,7 +151,8 @@ type ForksInTime struct {
EIP150,
EIP158,
EIP155,
QuorumCalcAlignment bool
QuorumCalcAlignment,
TxHashWithType bool
}

// AllForksEnabled should contain all supported forks by current edge version
Expand All @@ -182,4 +167,5 @@ var AllForksEnabled = &Forks{
Istanbul: NewFork(0),
London: NewFork(0),
QuorumCalcAlignment: NewFork(0),
TxHashWithType: NewFork(0),
}
5 changes: 5 additions & 0 deletions consensus/polybft/blockchain_wrapper.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,11 @@ func (p *blockchainWrapper) ProcessBlock(parent *types.Header, block *types.Bloc
Receipts: transition.Receipts(),
})

if builtBlock.Header.TxRoot != block.Header.TxRoot {
return nil, fmt.Errorf("incorrect tx root (expected: %s, actual: %s)",
builtBlock.Header.TxRoot, block.Header.TxRoot)
}

return &types.FullBlock{
Block: builtBlock,
Receipts: transition.Receipts(),
Expand Down
10 changes: 5 additions & 5 deletions consensus/polybft/fsm.go
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ func (f *fsm) createBridgeCommitmentTx() (*types.Transaction, error) {
return nil, fmt.Errorf("failed to encode input data for bridge commitment registration: %w", err)
}

return createStateTransactionWithData(contracts.StateReceiverContract, inputData), nil
return createStateTransactionWithData(f.Height(), contracts.StateReceiverContract, inputData), nil
}

// getValidatorsTransition applies delta to the current validators,
Expand All @@ -255,7 +255,7 @@ func (f *fsm) createCommitEpochTx() (*types.Transaction, error) {
return nil, err
}

return createStateTransactionWithData(contracts.ValidatorSetContract, input), nil
return createStateTransactionWithData(f.Height(), contracts.ValidatorSetContract, input), nil
}

// createDistributeRewardsTx create a StateTransaction, which invokes RewardPool smart contract
Expand All @@ -266,7 +266,7 @@ func (f *fsm) createDistributeRewardsTx() (*types.Transaction, error) {
return nil, err
}

return createStateTransactionWithData(contracts.RewardPoolContract, input), nil
return createStateTransactionWithData(f.Height(), contracts.RewardPoolContract, input), nil
}

// ValidateCommit is used to validate that a given commit is valid
Expand Down Expand Up @@ -701,7 +701,7 @@ func validateHeaderFields(parent *types.Header, header *types.Header, blockTimeD

// createStateTransactionWithData creates a state transaction
// with provided target address and inputData parameter which is ABI encoded byte array.
func createStateTransactionWithData(target types.Address, inputData []byte) *types.Transaction {
func createStateTransactionWithData(blockNumber uint64, target types.Address, inputData []byte) *types.Transaction {
tx := &types.Transaction{
From: contracts.SystemCaller,
To: &target,
Expand All @@ -711,7 +711,7 @@ func createStateTransactionWithData(target types.Address, inputData []byte) *typ
GasPrice: big.NewInt(0),
}

tx.ComputeHash()
tx.ComputeHash(blockNumber)

return tx
}
Loading

0 comments on commit 14ea06c

Please sign in to comment.