generated from ethereum-optimism/.github
-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'main' into faultproof_withdrawals-improvements
- Loading branch information
Showing
14 changed files
with
710 additions
and
281 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
FAULTPROOF_WITHDRAWAL_MON_L1_GETH_URL="<geth-url>" | ||
FAULTPROOF_WITHDRAWAL_MON_L2_OP_NODE_URL="<op-geth-node>" | ||
FAULTPROOF_WITHDRAWAL_MON_L2_OP_GETH_URL="<op-geth-url>" | ||
FAULTPROOF_WITHDRAWAL_MON_OPTIMISM_PORTAL="0xbEb5Fc579115071764c7423A4f12eDde41f106Ed" # This is the address of the Optimism portal contract, this should be for the chain you are monitoring | ||
FAULTPROOF_WITHDRAWAL_MON_START_BLOCK_HEIGHT=20872390 # This is the block height from which the monitoring will start, decide at which block height you want to start monitoring | ||
FAULTPROOF_WITHDRAWAL_MON_EVENT_BLOCK_RANGE=1000 # This is the range of blocks to be monitored | ||
MONITORISM_LOOP_INTERVAL_MSEC=100 # This is the interval in milliseconds for the monitoring loop | ||
MONITORISM_METRICS_PORT=7300 # This is the port on which the metrics server will run | ||
MONITORISM_METRICS_ENABLED=true # This is the flag to enable/disable the metrics server |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
173 changes: 173 additions & 0 deletions
173
op-monitorism/faultproof_withdrawals/monitor_live_mainnet_test.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,173 @@ | ||
//go:build live | ||
// +build live | ||
|
||
package faultproof_withdrawals | ||
|
||
import ( | ||
"context" | ||
"io" | ||
"math/big" | ||
"testing" | ||
|
||
oplog "github.com/ethereum-optimism/optimism/op-service/log" | ||
opmetrics "github.com/ethereum-optimism/optimism/op-service/metrics" | ||
"github.com/ethereum/go-ethereum/common" | ||
"github.com/joho/godotenv" | ||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
// NewTestMonitorMainnet initializes and returns a new Monitor instance for testing. | ||
// It sets up the necessary environment variables and configurations required for the monitor. | ||
func NewTestMonitorMainnet() *Monitor { | ||
envmap, err := godotenv.Read(".env.op.mainnet") | ||
if err != nil { | ||
panic("error") | ||
} | ||
|
||
ctx := context.Background() | ||
L1GethURL := envmap["FAULTPROOF_WITHDRAWAL_MON_L1_GETH_URL"] | ||
L2OpNodeURL := envmap["FAULTPROOF_WITHDRAWAL_MON_L2_OP_NODE_URL"] | ||
L2OpGethURL := envmap["FAULTPROOF_WITHDRAWAL_MON_L2_OP_GETH_URL"] | ||
|
||
FAULTPROOF_WITHDRAWAL_MON_OPTIMISM_PORTAL := "0xbEb5Fc579115071764c7423A4f12eDde41f106Ed" | ||
FAULTPROOF_WITHDRAWAL_MON_EVENT_BLOCK_RANGE := uint64(1000) | ||
FAULTPROOF_WITHDRAWAL_MON_START_BLOCK_HEIGHT := int64(6789100) | ||
|
||
cfg := CLIConfig{ | ||
L1GethURL: L1GethURL, | ||
L2OpGethURL: L2OpGethURL, | ||
L2OpNodeURL: L2OpNodeURL, | ||
EventBlockRange: FAULTPROOF_WITHDRAWAL_MON_EVENT_BLOCK_RANGE, | ||
StartingL1BlockHeight: FAULTPROOF_WITHDRAWAL_MON_START_BLOCK_HEIGHT, | ||
OptimismPortalAddress: common.HexToAddress(FAULTPROOF_WITHDRAWAL_MON_OPTIMISM_PORTAL), | ||
} | ||
|
||
clicfg := oplog.DefaultCLIConfig() | ||
output_writer := io.Discard // discard log output during tests to avoid pollution of the standard output | ||
log := oplog.NewLogger(output_writer, clicfg) | ||
|
||
metricsRegistry := opmetrics.NewRegistry() | ||
monitor, err := NewMonitor(ctx, log, opmetrics.With(metricsRegistry), cfg) | ||
if err != nil { | ||
panic(err) | ||
} | ||
return monitor | ||
} | ||
|
||
// TestSingleRunMainnet tests a single execution of the monitor's Run method. | ||
// It verifies that the state updates correctly after running. | ||
func TestSingleRunMainnet(t *testing.T) { | ||
test_monitor := NewTestMonitorMainnet() | ||
|
||
initialBlock := test_monitor.state.nextL1Height | ||
blockIncrement := test_monitor.maxBlockRange | ||
finalBlock := initialBlock + blockIncrement | ||
|
||
test_monitor.Run(test_monitor.ctx) | ||
|
||
require.Equal(t, finalBlock, test_monitor.state.nextL1Height) | ||
require.Equal(t, uint64(0), test_monitor.state.withdrawalsProcessed) | ||
require.Equal(t, uint64(0), test_monitor.state.eventsProcessed) | ||
require.Equal(t, uint64(0), test_monitor.state.numberOfPotentialAttackOnInProgressGames) | ||
require.Equal(t, uint64(0), test_monitor.state.numberOfPotentialAttacksOnDefenderWinsGames) | ||
require.Equal(t, uint64(0), test_monitor.state.numberOfSuspiciousEventsOnChallengerWinsGames) | ||
|
||
require.Equal(t, test_monitor.state.numberOfPotentialAttackOnInProgressGames, uint64(len(test_monitor.state.potentialAttackOnInProgressGames))) | ||
require.Equal(t, test_monitor.state.numberOfPotentialAttacksOnDefenderWinsGames, uint64(len(test_monitor.state.potentialAttackOnDefenderWinsGames))) | ||
require.Equal(t, test_monitor.state.numberOfSuspiciousEventsOnChallengerWinsGames, uint64(test_monitor.state.suspiciousEventsOnChallengerWinsGames.Len())) | ||
|
||
} | ||
|
||
// TestRun5Cycle1000BlocksMainnet tests multiple executions of the monitor's Run method over several cycles. | ||
// It verifies that the state updates correctly after each cycle. | ||
func TestRun5Cycle1000BlocksMainnet(t *testing.T) { | ||
test_monitor := NewTestMonitorMainnet() | ||
|
||
maxCycle := uint64(5) | ||
initialBlock := test_monitor.state.nextL1Height | ||
blockIncrement := test_monitor.maxBlockRange | ||
|
||
for cycle := uint64(1); cycle <= maxCycle; cycle++ { | ||
test_monitor.Run(test_monitor.ctx) | ||
} | ||
|
||
initialL1HeightGaugeValue, _ := GetGaugeValue(test_monitor.metrics.InitialL1HeightGauge) | ||
nextL1HeightGaugeValue, _ := GetGaugeValue(test_monitor.metrics.NextL1HeightGauge) | ||
|
||
withdrawalsProcessedCounterValue, _ := GetCounterValue(test_monitor.metrics.WithdrawalsProcessedCounter) | ||
eventsProcessedCounterValue, _ := GetCounterValue(test_monitor.metrics.EventsProcessedCounter) | ||
|
||
nodeConnectionFailuresCounterValue, _ := GetCounterValue(test_monitor.metrics.NodeConnectionFailuresCounter) | ||
|
||
expected_end_block := blockIncrement*maxCycle + initialBlock | ||
require.Equal(t, uint64(initialBlock), uint64(initialL1HeightGaugeValue)) | ||
require.Equal(t, uint64(expected_end_block), uint64(nextL1HeightGaugeValue)) | ||
|
||
require.Equal(t, uint64(0), uint64(eventsProcessedCounterValue)) | ||
require.Equal(t, uint64(0), uint64(withdrawalsProcessedCounterValue)) | ||
require.Equal(t, uint64(0), uint64(nodeConnectionFailuresCounterValue)) | ||
|
||
require.Equal(t, uint64(0), test_monitor.metrics.previousEventsProcessed) | ||
require.Equal(t, uint64(0), test_monitor.metrics.previousWithdrawalsProcessed) | ||
|
||
} | ||
|
||
func TestRunSingleBlocksMainnet(t *testing.T) { | ||
test_monitor := NewTestMonitorMainnet() | ||
|
||
maxCycle := 1 | ||
initialBlock := test_monitor.state.nextL1Height | ||
blockIncrement := test_monitor.maxBlockRange | ||
finalBlock := initialBlock + blockIncrement | ||
|
||
for cycle := 1; cycle <= maxCycle; cycle++ { | ||
test_monitor.Run(test_monitor.ctx) | ||
} | ||
|
||
require.Equal(t, test_monitor.state.nextL1Height, finalBlock) | ||
require.Equal(t, uint64(0), test_monitor.state.withdrawalsProcessed) | ||
require.Equal(t, uint64(0), test_monitor.state.eventsProcessed) | ||
require.Equal(t, 0, len(test_monitor.state.potentialAttackOnDefenderWinsGames)) | ||
require.Equal(t, 0, len(test_monitor.state.potentialAttackOnInProgressGames)) | ||
require.Equal(t, 0, test_monitor.state.suspiciousEventsOnChallengerWinsGames.Len()) | ||
} | ||
|
||
func TestInvalidWithdrawalsOnMainnet(t *testing.T) { | ||
test_monitor := NewTestMonitorMainnet() | ||
|
||
// On mainnet for OP OptimismPortal, the block number 20873192 is known to have only 1 event | ||
start := uint64(20873192) | ||
stop := uint64(20873193) | ||
newEvents, err := test_monitor.withdrawalValidator.GetEnrichedWithdrawalsEvents(start, &stop) | ||
require.NoError(t, err) | ||
require.Equal(t, len(newEvents), 1) | ||
|
||
event := newEvents[0] | ||
require.NotNil(t, event) | ||
|
||
// Expected event: | ||
//{WithdrawalHash: 0x45fd4bbcf3386b1fdf75929345b9243c05cd7431a707e84c293b710d40220ebd, ProofSubmitter: 0x394400571C825Da37ca4D6780417DFB514141b1f} | ||
require.Equal(t, event.Event.WithdrawalHash, [32]byte(common.HexToHash("0x45fd4bbcf3386b1fdf75929345b9243c05cd7431a707e84c293b710d40220ebd"))) | ||
require.Equal(t, event.Event.ProofSubmitter, common.HexToAddress("0x394400571C825Da37ca4D6780417DFB514141b1f")) | ||
|
||
//Expected DisputeGameData: | ||
// Game address: 0x52cE243d552369b11D6445Cd187F6393d3B42D4a | ||
require.Equal(t, event.DisputeGame.DisputeGameData.ProxyAddress, common.HexToAddress("0x52cE243d552369b11D6445Cd187F6393d3B42D4a")) | ||
|
||
// Expected Game root claim | ||
// 0xbc1c5ba13b936c6c23b7c51d425f25a8c9444771e851b6790f817a6002a14a33 | ||
require.Equal(t, event.DisputeGame.DisputeGameData.RootClaim, [32]byte(common.HexToHash("0xbc1c5ba13b936c6c23b7c51d425f25a8c9444771e851b6790f817a6002a14a33"))) | ||
|
||
// Expected L2 block number 1276288764 | ||
require.Equal(t, event.DisputeGame.DisputeGameData.L2blockNumber, big.NewInt(1276288764)) | ||
|
||
isValid, err := test_monitor.withdrawalValidator.IsWithdrawalEventValid(&event) | ||
require.EqualError(t, err, "game not enriched") | ||
require.False(t, isValid) | ||
err = test_monitor.withdrawalValidator.UpdateEnrichedWithdrawalEvent(&event) | ||
require.NoError(t, err) | ||
isValid, err = test_monitor.withdrawalValidator.IsWithdrawalEventValid(&event) | ||
require.NoError(t, err) | ||
require.False(t, isValid) | ||
|
||
} |
Oops, something went wrong.