Skip to content

Commit 1443adb

Browse files
authored
Merge branch 'develop' into c/lower-integration-tests-memory
2 parents 6963912 + 27feb17 commit 1443adb

File tree

2 files changed

+108
-41
lines changed

2 files changed

+108
-41
lines changed

gossip/c_block_callbacks.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ func consensusCallbackBeginBlockFn(
230230
maxBlockGas := es.Rules.Blocks.MaxBlockGas
231231
blockDuration := time.Duration(blockCtx.Time - bs.LastBlock.Time)
232232
blockBuilder := inter.NewBlockBuilder().
233-
WithEpoch(es.Epoch).
233+
WithEpoch(blockCtx.Atropos.Epoch()).
234234
WithNumber(number).
235235
WithParentHash(lastBlockHeader.Hash).
236236
WithTime(blockCtx.Time).

tests/block_header_test.go

+107-40
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package tests
22

33
import (
44
"context"
5+
"fmt"
56
"math/big"
67
"testing"
78
"time"
@@ -10,7 +11,9 @@ import (
1011
"github.com/Fantom-foundation/go-opera/gossip/gasprice"
1112
"github.com/Fantom-foundation/go-opera/inter"
1213
"github.com/Fantom-foundation/go-opera/opera"
14+
"github.com/Fantom-foundation/go-opera/opera/contracts/driver"
1315
"github.com/ethereum/go-ethereum/common"
16+
"github.com/ethereum/go-ethereum/common/hexutil"
1417
"github.com/ethereum/go-ethereum/core/types"
1518
"github.com/ethereum/go-ethereum/ethclient"
1619
"github.com/ethereum/go-ethereum/rpc"
@@ -19,7 +22,7 @@ import (
1922
)
2023

2124
func TestBlockHeader_SatisfiesInvariants(t *testing.T) {
22-
const numBlocks = 5
25+
const numBlocks = 10
2326
require := require.New(t)
2427

2528
net, err := StartIntegrationTestNet(t.TempDir())
@@ -47,57 +50,66 @@ func TestBlockHeader_SatisfiesInvariants(t *testing.T) {
4750
headers = append(headers, header)
4851
}
4952

50-
t.Run("BlockNumberEqualsPositionInChain", func(t *testing.T) {
51-
testHeaders_BlockNumberEqualsPositionInChain(t, headers)
52-
})
53+
// Run twice - once before and once after a node restart.
54+
for range 2 {
55+
t.Run("BlockNumberEqualsPositionInChain", func(t *testing.T) {
56+
testHeaders_BlockNumberEqualsPositionInChain(t, headers)
57+
})
5358

54-
t.Run("ParentHashCoversParentContent", func(t *testing.T) {
55-
testHeaders_ParentHashCoversParentContent(t, headers)
56-
})
59+
t.Run("ParentHashCoversParentContent", func(t *testing.T) {
60+
testHeaders_ParentHashCoversParentContent(t, headers)
61+
})
5762

58-
t.Run("GasUsedIsBelowGasLimit", func(t *testing.T) {
59-
testHeaders_GasUsedIsBelowGasLimit(t, headers)
60-
})
63+
t.Run("GasUsedIsBelowGasLimit", func(t *testing.T) {
64+
testHeaders_GasUsedIsBelowGasLimit(t, headers)
65+
})
6166

62-
t.Run("EncodesDurationAndNanoTimeInExtraData", func(t *testing.T) {
63-
testHeaders_EncodesDurationAndNanoTimeInExtraData(t, headers)
64-
})
67+
t.Run("EncodesDurationAndNanoTimeInExtraData", func(t *testing.T) {
68+
testHeaders_EncodesDurationAndNanoTimeInExtraData(t, headers)
69+
})
6570

66-
t.Run("BaseFeeEvolutionFollowsPricingRules", func(t *testing.T) {
67-
testHeaders_BaseFeeEvolutionFollowsPricingRules(t, headers)
68-
})
71+
t.Run("BaseFeeEvolutionFollowsPricingRules", func(t *testing.T) {
72+
testHeaders_BaseFeeEvolutionFollowsPricingRules(t, headers)
73+
})
6974

70-
t.Run("TransactionRootMatchesHashOfBlockTxs", func(t *testing.T) {
71-
testHeaders_TransactionRootMatchesBlockTxsHash(t, headers, client)
72-
})
75+
t.Run("TransactionRootMatchesHashOfBlockTxs", func(t *testing.T) {
76+
testHeaders_TransactionRootMatchesBlockTxsHash(t, headers, client)
77+
})
7378

74-
t.Run("ReceiptRootMatchesBlockReceipts", func(t *testing.T) {
75-
testHeaders_ReceiptRootMatchesBlockReceipts(t, headers, client)
76-
})
79+
t.Run("ReceiptRootMatchesBlockReceipts", func(t *testing.T) {
80+
testHeaders_ReceiptRootMatchesBlockReceipts(t, headers, client)
81+
})
7782

78-
t.Run("LogsBloomMatchesLogsInReceipts", func(t *testing.T) {
79-
testHeaders_LogsBloomMatchesLogsInReceipts(t, headers, client)
80-
})
83+
t.Run("LogsBloomMatchesLogsInReceipts", func(t *testing.T) {
84+
testHeaders_LogsBloomMatchesLogsInReceipts(t, headers, client)
85+
})
8186

82-
t.Run("CoinbaseIsZeroForAllBlocks", func(t *testing.T) {
83-
testHeaders_CoinbaseIsZeroForAllBlocks(t, headers)
84-
})
87+
t.Run("CoinbaseIsZeroForAllBlocks", func(t *testing.T) {
88+
testHeaders_CoinbaseIsZeroForAllBlocks(t, headers)
89+
})
8590

86-
t.Run("DifficultyIsZeroForAllBlocks", func(t *testing.T) {
87-
testHeaders_DifficultyIsZeroForAllBlocks(t, headers)
88-
})
91+
t.Run("DifficultyIsZeroForAllBlocks", func(t *testing.T) {
92+
testHeaders_DifficultyIsZeroForAllBlocks(t, headers)
93+
})
8994

90-
t.Run("NonceIsZeroForAllBlocks", func(t *testing.T) {
91-
testHeaders_NonceIsZeroForAllBlocks(t, headers)
92-
})
95+
t.Run("NonceIsZeroForAllBlocks", func(t *testing.T) {
96+
testHeaders_NonceIsZeroForAllBlocks(t, headers)
97+
})
9398

94-
t.Run("TimeProgressesMonotonically", func(t *testing.T) {
95-
testHeaders_TimeProgressesMonotonically(t, headers)
96-
})
99+
t.Run("TimeProgressesMonotonically", func(t *testing.T) {
100+
testHeaders_TimeProgressesMonotonically(t, headers)
101+
})
97102

98-
t.Run("MixDigestDiffersForAllBlocks", func(t *testing.T) {
99-
testHeaders_MixDigestDiffersForAllBlocks(t, headers)
100-
})
103+
t.Run("MixDigestDiffersForAllBlocks", func(t *testing.T) {
104+
testHeaders_MixDigestDiffersForAllBlocks(t, headers)
105+
})
106+
107+
t.Run("LastBlockOfEpochContainsSealingTransaction", func(t *testing.T) {
108+
testHeaders_LastBlockOfEpochContainsSealingTransaction(t, headers, client)
109+
})
110+
111+
require.NoError(net.Restart())
112+
}
101113
}
102114

103115
func testHeaders_BlockNumberEqualsPositionInChain(t *testing.T, headers []*types.Header) {
@@ -272,3 +284,58 @@ func testHeaders_MixDigestDiffersForAllBlocks(t *testing.T, headers []*types.Hea
272284
seen[headers[i].MixDigest] = struct{}{}
273285
}
274286
}
287+
288+
func testHeaders_LastBlockOfEpochContainsSealingTransaction(t *testing.T, headers []*types.Header, client *ethclient.Client) {
289+
require := require.New(t)
290+
291+
maxEpoch := 0
292+
for i := 0; i < len(headers)-1; i++ {
293+
294+
block, err := client.BlockByNumber(context.Background(), big.NewInt(int64(i)))
295+
require.NoError(err, "failed to get block body")
296+
297+
currentBlockEpoch, err := getEpochOfBlock(client, i)
298+
require.NoError(err, "failed to get epoch of block %d", i)
299+
300+
nextBlockEpoch, err := getEpochOfBlock(client, i+1)
301+
require.NoError(err, "failed to get epoch of block %d", i+1)
302+
303+
shouldContainSealingTx := currentBlockEpoch != nextBlockEpoch
304+
305+
containsSealingTx := false
306+
for _, tx := range block.Transactions() {
307+
// Any call to the driver is considered a sealing transaction.
308+
if tx.To() != nil && *tx.To() == driver.ContractAddress {
309+
containsSealingTx = true
310+
break
311+
}
312+
}
313+
314+
require.Equal(
315+
shouldContainSealingTx,
316+
containsSealingTx,
317+
"block %d, current epoch %d, next epoch %d",
318+
i, currentBlockEpoch, nextBlockEpoch,
319+
)
320+
321+
if currentBlockEpoch > maxEpoch {
322+
maxEpoch = currentBlockEpoch
323+
}
324+
}
325+
}
326+
327+
func getEpochOfBlock(client *ethclient.Client, blockNumber int) (int, error) {
328+
var result struct {
329+
Epoch hexutil.Uint64
330+
}
331+
err := client.Client().Call(
332+
&result,
333+
"eth_getBlockByNumber",
334+
fmt.Sprintf("0x%x", blockNumber),
335+
false,
336+
)
337+
if err != nil {
338+
return 0, err
339+
}
340+
return int(result.Epoch), nil
341+
}

0 commit comments

Comments
 (0)