Skip to content

Commit

Permalink
Updating all sources of block.Transactions and do the corresponding w…
Browse files Browse the repository at this point in the history
…ork for block staking txns (#2655)

* Updating all sources of block.Transactions and do the corresponding work for block staking txns

* remove usages of uncle in accessors_chain_test

* fix bug in core/blockchain.go where incorrect receipt data was generated in SetReceiptsData
  • Loading branch information
denniswon authored Apr 10, 2020
1 parent f4edd53 commit a37074c
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 12 deletions.
1 change: 1 addition & 0 deletions consensus/consensus_v2.go
Original file line number Diff line number Diff line change
Expand Up @@ -473,6 +473,7 @@ func (consensus *Consensus) Start(

consensus.getLogger().Debug().
Int("numTxs", len(newBlock.Transactions())).
Int("numStakingTxs", len(newBlock.StakingTransactions())).
Time("startTime", startTime).
Int64("publicKeys", consensus.Decider.ParticipantsCount()).
Msg("[ConsensusMainLoop] STARTING CONSENSUS")
Expand Down
41 changes: 30 additions & 11 deletions core/blockchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -885,27 +885,25 @@ func (bc *BlockChain) Rollback(chain []common.Hash) {
func SetReceiptsData(config *params.ChainConfig, block *types.Block, receipts types.Receipts) error {
signer := types.MakeSigner(config, block.Epoch())

transactions, logIndex := block.Transactions(), uint(0)
if len(transactions) != len(receipts) {
return errors.New("transaction and receipt count mismatch")
transactions, stakingTransactions, logIndex := block.Transactions(), block.StakingTransactions(), uint(0)
if len(transactions)+len(stakingTransactions) != len(receipts) {
return errors.New("transaction+stakingTransactions and receipt count mismatch")
}

for j := 0; j < len(receipts); j++ {
// The used gas can be calculated based on previous receipts
if len(receipts) > 0 && len(transactions) > 0 {
receipts[0].GasUsed = receipts[0].CumulativeGasUsed
}
for j := 1; j < len(transactions); j++ {
// The transaction hash can be retrieved from the transaction itself
receipts[j].TxHash = transactions[j].Hash()

receipts[j].GasUsed = receipts[j].CumulativeGasUsed - receipts[j-1].CumulativeGasUsed
// The contract address can be derived from the transaction itself
if transactions[j].To() == nil {
// Deriving the signer is expensive, only do if it's actually needed
from, _ := types.Sender(signer, transactions[j])
receipts[j].ContractAddress = crypto.CreateAddress(from, transactions[j].Nonce())
}
// The used gas can be calculated based on previous receipts
if j == 0 {
receipts[j].GasUsed = receipts[j].CumulativeGasUsed
} else {
receipts[j].GasUsed = receipts[j].CumulativeGasUsed - receipts[j-1].CumulativeGasUsed
}
// The derived log fields can simply be set from the block and transaction
for k := 0; k < len(receipts[j].Logs); k++ {
receipts[j].Logs[k].BlockNumber = block.NumberU64()
Expand All @@ -916,6 +914,26 @@ func SetReceiptsData(config *params.ChainConfig, block *types.Block, receipts ty
logIndex++
}
}

// The used gas can be calculated based on previous receipts
if len(receipts) > len(transactions) && len(stakingTransactions) > 0 {
receipts[len(transactions)].GasUsed = receipts[len(transactions)].CumulativeGasUsed
}
// in a block, txns are processed before staking txns
for j := len(transactions) + 1; j < len(transactions)+len(stakingTransactions); j++ {
// The transaction hash can be retrieved from the staking transaction itself
receipts[j].TxHash = stakingTransactions[j].Hash()
receipts[j].GasUsed = receipts[j].CumulativeGasUsed - receipts[j-1].CumulativeGasUsed
// The derived log fields can simply be set from the block and transaction
for k := 0; k < len(receipts[j].Logs); k++ {
receipts[j].Logs[k].BlockNumber = block.NumberU64()
receipts[j].Logs[k].BlockHash = block.Hash()
receipts[j].Logs[k].TxHash = receipts[j].TxHash
receipts[j].Logs[k].TxIndex = uint(j) + uint(len(transactions))
receipts[j].Logs[k].Index = logIndex
logIndex++
}
}
return nil
}

Expand Down Expand Up @@ -1334,6 +1352,7 @@ func (bc *BlockChain) insertChain(chain types.Blocks, verifyHeaders bool) (int,
Str("hash", block.Hash().Hex()).
Int("uncles", len(block.Uncles())).
Int("txs", len(block.Transactions())).
Int("stakingTxs", len(block.StakingTransactions())).
Uint64("gas", block.GasUsed()).
Str("elapsed", common.PrettyDuration(time.Since(bstart)).String()).
Logger()
Expand Down
4 changes: 3 additions & 1 deletion core/rawdb/accessors_chain_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
"github.com/harmony-one/harmony/block"
blockfactory "github.com/harmony-one/harmony/block/factory"
"github.com/harmony-one/harmony/core/types"
staking "github.com/harmony-one/harmony/staking/types"
"golang.org/x/crypto/sha3"
)

Expand Down Expand Up @@ -136,7 +137,8 @@ func TestBlockStorage(t *testing.T) {
}
if entry := ReadBody(db, block.Hash(), block.NumberU64()); entry == nil {
t.Fatalf("Stored body not found")
} else if types.DeriveSha(types.Transactions(entry.Transactions())) != types.DeriveSha(block.Transactions()) || types.CalcUncleHash(entry.Uncles()) != types.CalcUncleHash(block.Uncles()) {
} else if types.DeriveSha(types.Transactions(entry.Transactions())) != types.DeriveSha(block.Transactions()) ||
types.DeriveSha(staking.StakingTransactions(entry.StakingTransactions())) != types.DeriveSha(block.StakingTransactions()) {
t.Fatalf("Retrieved body mismatch: have %v, want %v", entry, block.Body())
}
//if actual, err := ReadEpochBlockNumber(db, big.NewInt(0)); err != nil {
Expand Down

0 comments on commit a37074c

Please sign in to comment.