1645c32997
Increase the chances of having multiple blocks at the same height by aligning block times across test miners. Also, make the block hash test faster.
86 lines
2.6 KiB
Go
86 lines
2.6 KiB
Go
package itests
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/filecoin-project/go-state-types/abi"
|
|
|
|
"github.com/filecoin-project/lotus/build"
|
|
"github.com/filecoin-project/lotus/chain/types/ethtypes"
|
|
"github.com/filecoin-project/lotus/itests/kit"
|
|
)
|
|
|
|
// TestEthBlockHashesCorrect_MultiBlockTipset validates that blocks retrieved through
|
|
// EthGetBlockByNumber are identical to blocks retrieved through
|
|
// EthGetBlockByHash, when using the block hash returned by the former.
|
|
//
|
|
// Specifically, it checks the system behaves correctly with multiblock tipsets.
|
|
//
|
|
// Catches regressions around https://github.com/filecoin-project/lotus/issues/10061.
|
|
func TestEthBlockHashesCorrect_MultiBlockTipset(t *testing.T) {
|
|
// miner is connected to the first node, and we want to observe the chain
|
|
// from the second node.
|
|
blocktime := 100 * time.Millisecond
|
|
n1, m1, m2, ens := kit.EnsembleOneTwo(t,
|
|
kit.MockProofs(),
|
|
kit.ThroughRPC(),
|
|
)
|
|
ens.InterconnectAll().BeginMining(blocktime)
|
|
|
|
{
|
|
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
|
n1.WaitTillChain(ctx, kit.HeightAtLeast(abi.ChainEpoch(5)))
|
|
cancel()
|
|
}
|
|
|
|
var n2 kit.TestFullNode
|
|
ens.FullNode(&n2, kit.ThroughRPC()).Start().Connect(n2, n1)
|
|
|
|
{
|
|
// find the first tipset where all miners mined a block.
|
|
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
|
|
n2.WaitTillChain(ctx, kit.BlocksMinedByAll(m1.ActorAddr, m2.ActorAddr))
|
|
cancel()
|
|
}
|
|
|
|
head, err := n2.ChainHead(context.Background())
|
|
require.NoError(t, err)
|
|
|
|
ctx := context.Background()
|
|
|
|
// let the chain run a little bit longer to minimise the chance of reorgs
|
|
n2.WaitTillChain(ctx, kit.HeightAtLeast(head.Height()+10))
|
|
|
|
tsk := head.Key()
|
|
for i := 1; i <= int(head.Height()); i++ {
|
|
hex := fmt.Sprintf("0x%x", i)
|
|
|
|
ts, err := n2.ChainGetTipSetByHeight(ctx, abi.ChainEpoch(i), tsk)
|
|
require.NoError(t, err)
|
|
|
|
ethBlockA, err := n2.EthGetBlockByNumber(ctx, hex, true)
|
|
// Cannot use static ErrFullRound error for comparison since it gets reserialized as a JSON RPC error.
|
|
if err != nil && strings.Contains(err.Error(), "null round") {
|
|
require.Less(t, ts.Height(), abi.ChainEpoch(i), "did not expect a tipset at epoch %d", i)
|
|
continue
|
|
}
|
|
require.NoError(t, err)
|
|
require.Equal(t, ts.Height(), abi.ChainEpoch(i), "expected a tipset at epoch %i", i)
|
|
|
|
ethBlockB, err := n2.EthGetBlockByHash(ctx, ethBlockA.Hash, true)
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, ethBlockA, ethBlockB)
|
|
|
|
numBlocks := len(ts.Blocks())
|
|
expGasLimit := ethtypes.EthUint64(int64(numBlocks) * build.BlockGasLimit)
|
|
require.Equal(t, expGasLimit, ethBlockB.GasLimit)
|
|
}
|
|
}
|