@@ -3,9 +3,10 @@ package chain
3
3
import (
4
4
"errors"
5
5
"fmt"
6
+ "math/big"
7
+
6
8
"github.com/crytic/medusa/chain/state"
7
9
"golang.org/x/net/context"
8
- "math/big"
9
10
10
11
"github.com/crytic/medusa/chain/config"
11
12
"github.com/ethereum/go-ethereum/core/rawdb"
@@ -211,7 +212,6 @@ func newTestChainWithStateFactory(
211
212
212
213
// Convert our genesis block (go-ethereum type) to a test chain block.
213
214
testChainGenesisBlock := types .NewBlock (genesisBlock .Header ())
214
-
215
215
// Create our state database over-top our database.
216
216
stateDatabase := gethState .NewDatabaseWithConfig (db , dbConfig )
217
217
@@ -288,8 +288,9 @@ func (t *TestChain) Clone(onCreateFunc func(chain *TestChain) error) (*TestChain
288
288
// did originally.
289
289
for i := 1 ; i < len (t .blocks ); i ++ {
290
290
// First create a new pending block to commit
291
- blockHeader := t .blocks [i ].Header
292
- _ , err = targetChain .PendingBlockCreateWithParameters (blockHeader .Number .Uint64 (), blockHeader .Time , & blockHeader .GasLimit )
291
+ block := t .blocks [i ]
292
+ blockHeader := block .Header
293
+ _ , err = targetChain .PendingBlockCreateWithBaseBlockContext (block .BaseContext , & blockHeader .GasLimit )
293
294
if err != nil {
294
295
return nil , err
295
296
}
@@ -578,11 +579,10 @@ func (t *TestChain) PendingBlockCreate() (*types.Block, error) {
578
579
return t .PendingBlockCreateWithParameters (blockNumber , timestamp , nil )
579
580
}
580
581
581
- // PendingBlockCreateWithParameters constructs an empty block which is pending addition to the chain, using the block
582
- // properties provided. Note that there are no constraints on the next block number or timestamp. Because of cheatcode
583
- // usage, the next block can go back in time.
584
- // Returns the constructed block, or an error if one occurred.
585
- func (t * TestChain ) PendingBlockCreateWithParameters (blockNumber uint64 , blockTime uint64 , blockGasLimit * uint64 ) (* types.Block , error ) {
582
+ // PendingBlockCreateWithBaseBlockContext constructs an empty block which is pending addition to the chain, using the
583
+ // provided base block context. The base block context holds information such as the block number, timestamp, and base fee
584
+ // that should be used to initialize the block.
585
+ func (t * TestChain ) PendingBlockCreateWithBaseBlockContext (baseBlockContext * types.BaseBlockContext , blockGasLimit * uint64 ) (* types.Block , error ) {
586
586
// If we already have a pending block, return an error.
587
587
if t .pendingBlock != nil {
588
588
return nil , fmt .Errorf ("could not create a new pending block for chain, as a block is already pending" )
@@ -593,41 +593,43 @@ func (t *TestChain) PendingBlockCreateWithParameters(blockNumber uint64, blockTi
593
593
blockGasLimit = & t .BlockGasLimit
594
594
}
595
595
596
- // Obtain our parent block hash to reference in our new block.
597
- parentBlockHash := t .Head ().Hash
598
-
599
596
// Note we do not perform any block number or timestamp validation since cheatcodes can permanently update the
600
597
// block number or timestamp which could violate the invariants of a blockchain (e.g. block.number is strictly
601
598
// increasing)
602
599
600
+ // Obtain our parent block hash to reference in our new block.
601
+ parentBlockHash := t .Head ().Hash
602
+
603
603
// Create a block header for this block:
604
604
// - State root hash reflects the state after applying block updates (no transactions, so unchanged from last block)
605
+ // - Other hashes will populate as we apply transactions
605
606
// - Bloom is aggregated for each transaction in the block (for now empty).
606
- // - TODO: Difficulty should be revisited/checked.
607
607
// - GasUsed is aggregated for each transaction in the block (for now zero).
608
- // - Mix digest is only useful for randomness, so we just fake randomness by using the previous block hash.
609
- // - TODO: BaseFee should be revisited/checked.
608
+ // - We don't care too much about difficulty and mix digest so setting them to random things
610
609
header := & gethTypes.Header {
611
610
ParentHash : parentBlockHash ,
612
611
UncleHash : gethTypes .EmptyUncleHash ,
613
- Coinbase : t .Head ().Header .Coinbase ,
614
612
Root : t .Head ().Header .Root ,
615
613
TxHash : gethTypes .EmptyRootHash ,
616
614
ReceiptHash : gethTypes .EmptyRootHash ,
617
615
Bloom : gethTypes.Bloom {},
618
- Difficulty : common .Big0 ,
619
- Number : big .NewInt (int64 (blockNumber )),
620
616
GasLimit : * blockGasLimit ,
621
617
GasUsed : 0 ,
622
- Time : blockTime ,
623
618
Extra : []byte {},
624
- MixDigest : parentBlockHash ,
625
619
Nonce : gethTypes.BlockNonce {},
626
- BaseFee : new (big.Int ).Set (t .Head ().Header .BaseFee ),
620
+ Coinbase : baseBlockContext .Coinbase ,
621
+ Difficulty : common .Big0 ,
622
+ Number : new (big.Int ).Set (baseBlockContext .Number ),
623
+ Time : baseBlockContext .Time ,
624
+ MixDigest : parentBlockHash ,
625
+ BaseFee : new (big.Int ).Set (baseBlockContext .BaseFee ),
627
626
}
628
627
629
- // Create a new block for our test node
628
+ // Create a new block for our test chain
630
629
t .pendingBlock = types .NewBlock (header )
630
+
631
+ // Set the block hash
632
+ // Note that this block hash may change if cheatcodes that update the block header are used (e.g. warp)
631
633
t .pendingBlock .Hash = t .pendingBlock .Header .Hash ()
632
634
633
635
// Emit our event for the pending block being created
@@ -643,6 +645,21 @@ func (t *TestChain) PendingBlockCreateWithParameters(blockNumber uint64, blockTi
643
645
return t .pendingBlock , nil
644
646
}
645
647
648
+ // PendingBlockCreateWithParameters constructs an empty block which is pending addition to the chain, using the block number
649
+ // and timestamp provided. Returns the constructed block, or an error if one occurred.
650
+ func (t * TestChain ) PendingBlockCreateWithParameters (blockNumber uint64 , blockTime uint64 , blockGasLimit * uint64 ) (* types.Block , error ) {
651
+ // We will create a base block context with the provided parameters in addition to using the current head block.
652
+ // All values that are not the block number and timestamp are taken from the current head block.
653
+ baseBlockContext := types .NewBaseBlockContext (
654
+ blockNumber ,
655
+ blockTime ,
656
+ t .Head ().Header .BaseFee ,
657
+ t .Head ().Header .Coinbase ,
658
+ )
659
+
660
+ return t .PendingBlockCreateWithBaseBlockContext (baseBlockContext , blockGasLimit )
661
+ }
662
+
646
663
// PendingBlockAddTx takes a message (internal txs) and adds it to the current pending block, updating the header
647
664
// with relevant execution information. If a pending block was not created, an error is returned.
648
665
// Returns an error if one occurred.
0 commit comments