Skip to content

core/blockchain_mess_test.go — Version Comparison

v1.16.8 v1.17.3
Branch etc/v1.16.8-full-node etc/v1.17.3-full-node
Delta +620 -0 +700 -0

Diff between branches

diff --git a/core/blockchain_mess_test.go b/core/blockchain_mess_test.go
index d589906e3..3e2fb0455 100644
--- a/core/blockchain_mess_test.go
+++ b/core/blockchain_mess_test.go
@@ -524,6 +524,86 @@ func TestMESSKnownBlock(t *testing.T) {
    }
 }

+// TestMESSFailClosed verifies that MESS rejects (fail-closed) a reorg whose common
+// ancestor cannot be found, instead of silently allowing it. Regression test for the
+// previous fail-open behaviour where findCommonAncestor errors returned nil (allow).
+func TestMESSFailClosed(t *testing.T) {
+   engine := ethash.NewFaker()
+   db := rawdb.NewMemoryDatabase()
+   genesis := messTestGenesis() // ECBP1100 active from block 11
+   genesisB := genesis.MustCommit(db, triedb.NewDatabase(db, nil))
+
+   chain, err := NewBlockChain(db, genesis, engine, DefaultConfig())
+   if err != nil {
+       t.Fatal(err)
+   }
+   defer chain.Stop()
+   chain.EnableMESS(true, "test")
+
+   blocks, _ := GenerateChain(genesis.Config, genesisB, engine, db, 20, func(i int, gen *BlockGen) {})
+   if _, err := chain.InsertChain(blocks); err != nil {
+       t.Fatal(err)
+   }
+
+   current := chain.CurrentHeader() // block 20 → ECBP1100 active
+   if !chain.chainConfig.IsECBP1100(current.Number) {
+       t.Fatal("ECBP1100 should be active at the test height")
+   }
+
+   // An "extern" header that is not part of the chain: its parent (and itself) are
+   // unknown, so findCommonAncestor cannot resolve a common ancestor.
+   orphan := &types.Header{
+       ParentHash: common.HexToHash("0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef"),
+       Number:     new(big.Int).Add(current.Number, big.NewInt(1)),
+       Difficulty: big.NewInt(1),
+       GasLimit:   current.GasLimit,
+       Time:       current.Time + 1,
+   }
+
+   fc := NewForkChoiceWithMESS(chain, nil)
+   if err := fc.reorgFilter(current, orphan); err == nil {
+       t.Error("MESS allowed a reorg whose common ancestor could not be found (fail-open); expected rejection")
+   }
+}
+
+// TestMESSPerChainIsolation verifies that MESS runtime state is per-BlockChain, not global:
+// enabling MESS on one chain must not affect another chain in the same process.
+func TestMESSPerChainIsolation(t *testing.T) {
+   newChain := func() *BlockChain {
+       engine := ethash.NewFaker()
+       db := rawdb.NewMemoryDatabase()
+       genesis := messTestGenesis()
+       genesis.MustCommit(db, triedb.NewDatabase(db, nil))
+       bc, err := NewBlockChain(db, genesis, engine, DefaultConfig())
+       if err != nil {
+           t.Fatal(err)
+       }
+       return bc
+   }
+
+   chainA := newChain()
+   defer chainA.Stop()
+   chainB := newChain()
+   defer chainB.Stop()
+
+   if chainA.IsMESSEnabled() || chainB.IsMESSEnabled() {
+       t.Fatal("MESS should start disabled on both chains")
+   }
+
+   chainA.EnableMESS(true, "test")
+   if !chainA.IsMESSEnabled() {
+       t.Error("chainA: MESS should be enabled after EnableMESS(true)")
+   }
+   if chainB.IsMESSEnabled() {
+       t.Error("chainB: MESS leaked from chainA — runtime state is not per-chain")
+   }
+
+   chainA.EnableMESS(false, "test")
+   if chainA.IsMESSEnabled() {
+       t.Error("chainA: MESS should be disabled after EnableMESS(false)")
+   }
+}
+
 // TestEcbp1100ConfigActivation tests the IsECBP1100 config method.
 func TestEcbp1100ConfigActivation(t *testing.T) {
    tests := []struct {
← Back to Version Comparison