Commit beb131f3 authored by mergify[bot]'s avatar mergify[bot] Committed by GitHub

Merge branch 'develop' into cleanup-logging-service-utils

parents b74ae89a 55c6ac8f
......@@ -121,4 +121,52 @@ var Presets = map[int]Preset{
L1StartingHeight: 8942381,
},
},
11155420: {
Name: "OP Sepolia",
ChainConfig: ChainConfig{
Preset: 11155420,
L1Contracts: L1Contracts{
AddressManager: common.HexToAddress("0x9bFE9c5609311DF1c011c47642253B78a4f33F4B"),
SystemConfigProxy: common.HexToAddress("0x034edD2A225f7f429A63E0f1D2084B9E0A93b538"),
OptimismPortalProxy: common.HexToAddress("0x16Fc5058F25648194471939df75CF27A2fdC48BC"),
L2OutputOracleProxy: common.HexToAddress("0x90E9c4f8a994a250F6aEfd61CAFb4F2e895D458F"),
L1CrossDomainMessengerProxy: common.HexToAddress("0x58Cc85b8D04EA49cC6DBd3CbFFd00B4B8D6cb3ef"),
L1StandardBridgeProxy: common.HexToAddress("0xFBb0621E0B23b5478B630BD55a5f21f67730B0F1"),
L1ERC721BridgeProxy: common.HexToAddress("0xd83e03D576d23C9AEab8cC44Fa98d058D2176D1f"),
},
L1StartingHeight: 4071408,
},
},
424: {
Name: "PGN",
ChainConfig: ChainConfig{
Preset: 424,
L1Contracts: L1Contracts{
AddressManager: common.HexToAddress("0x09d5DbA52F0ee2C4A5E94FD5C802bD74Ca9cAD3e"),
SystemConfigProxy: common.HexToAddress("0x7Df716EAD1d83a2BF35B416B7BC84bd0700357C9"),
OptimismPortalProxy: common.HexToAddress("0xb26Fd985c5959bBB382BAFdD0b879E149e48116c"),
L2OutputOracleProxy: common.HexToAddress("0xA38d0c4E6319F9045F20318BA5f04CDe94208608"),
L1CrossDomainMessengerProxy: common.HexToAddress("0x97BAf688E5d0465E149d1d5B497Ca99392a6760e"),
L1StandardBridgeProxy: common.HexToAddress("0xD0204B9527C1bA7bD765Fa5CCD9355d38338272b"),
L1ERC721BridgeProxy: common.HexToAddress("0xaFF0F8aaB6Cc9108D34b3B8423C76d2AF434d115"),
},
L1StartingHeight: 17672702,
},
},
58008: {
Name: "PGN Sepolia",
ChainConfig: ChainConfig{
Preset: 58008,
L1Contracts: L1Contracts{
AddressManager: common.HexToAddress("0x0Ad91488288BBe60ff38258785568A6D1EB3B983"),
SystemConfigProxy: common.HexToAddress("0x4BCCC52151f0ad7C62D45Ce0aA77d9d8ffCE534e"),
OptimismPortalProxy: common.HexToAddress("0xF04BdD5353Bb0EFF6CA60CfcC78594278eBfE179"),
L2OutputOracleProxy: common.HexToAddress("0xD5bAc3152ffC25318F848B3DD5dA6C85171BaEEe"),
L1CrossDomainMessengerProxy: common.HexToAddress("0x97f3558Ce48FE71B8CeFA5497708A49531D5A8E1"),
L1StandardBridgeProxy: common.HexToAddress("0xFaE6abCAF30D23e233AC7faF747F2fC3a5a6Bfa3"),
L1ERC721BridgeProxy: common.HexToAddress("0xBA8397B6f255618D5985d0fB427D8c0496F3a5FA"),
},
L1StartingHeight: 17672702,
},
},
}
......@@ -35,7 +35,7 @@ func (g *AlphabetGameHelper) StartChallenger(ctx context.Context, l1Endpoint str
return c
}
func (g *AlphabetGameHelper) CreateHonestActor(ctx context.Context, alphabetTrace string, depth uint64) *HonestHelper {
func (g *AlphabetGameHelper) CreateHonestActor(alphabetTrace string, depth uint64) *HonestHelper {
return &HonestHelper{
t: g.t,
require: g.require,
......@@ -43,3 +43,7 @@ func (g *AlphabetGameHelper) CreateHonestActor(ctx context.Context, alphabetTrac
correctTrace: alphabet.NewTraceProvider(alphabetTrace, depth),
}
}
func (g *AlphabetGameHelper) CreateDishonestHelper(alphabetTrace string, depth uint64, defender bool) *DishonestHelper {
return newDishonestHelper(&g.FaultGameHelper, g.CreateHonestActor(alphabetTrace, depth), defender)
}
package disputegame
import (
"context"
"errors"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/types"
"github.com/ethereum/go-ethereum/common"
)
type dishonestClaim struct {
ParentIndex int64
IsAttack bool
Valid bool
}
type DishonestHelper struct {
*FaultGameHelper
*HonestHelper
claims map[dishonestClaim]bool
defender bool
}
func newDishonestHelper(g *FaultGameHelper, correctTrace *HonestHelper, defender bool) *DishonestHelper {
return &DishonestHelper{g, correctTrace, make(map[dishonestClaim]bool), defender}
}
func (t *DishonestHelper) Attack(ctx context.Context, claimIndex int64) {
c := dishonestClaim{claimIndex, true, false}
if t.claims[c] {
return
}
t.claims[c] = true
t.FaultGameHelper.Attack(ctx, claimIndex, common.Hash{byte(claimIndex)})
}
func (t *DishonestHelper) Defend(ctx context.Context, claimIndex int64) {
c := dishonestClaim{claimIndex, false, false}
if t.claims[c] {
return
}
t.claims[c] = true
t.FaultGameHelper.Defend(ctx, claimIndex, common.Hash{byte(claimIndex)})
}
func (t *DishonestHelper) AttackCorrect(ctx context.Context, claimIndex int64) {
c := dishonestClaim{claimIndex, true, true}
if t.claims[c] {
return
}
t.claims[c] = true
t.HonestHelper.Attack(ctx, claimIndex)
}
func (t *DishonestHelper) DefendCorrect(ctx context.Context, claimIndex int64) {
c := dishonestClaim{claimIndex, false, true}
if t.claims[c] {
return
}
t.claims[c] = true
t.HonestHelper.Defend(ctx, claimIndex)
}
// ExhaustDishonestClaims makes all possible significant moves (mod honest challenger's) in a game.
// It is very inefficient and should NOT be used on games with large depths
func (d *DishonestHelper) ExhaustDishonestClaims(ctx context.Context) {
depth := d.MaxDepth(ctx)
move := func(claimIndex int64, claimData ContractClaim) {
// dishonest level, valid attack
// dishonest level, invalid attack
// dishonest level, valid defense
// dishonest level, invalid defense
// honest level, invalid attack
// honest level, invalid defense
pos := types.NewPositionFromGIndex(claimData.Position.Uint64())
if int64(pos.Depth()) == depth {
return
}
d.LogGameData(ctx)
d.FaultGameHelper.t.Logf("Dishonest moves against claimIndex %d", claimIndex)
agreeWithLevel := d.defender == (pos.Depth()%2 == 0)
if !agreeWithLevel {
d.AttackCorrect(ctx, claimIndex)
if claimIndex != 0 {
d.DefendCorrect(ctx, claimIndex)
}
}
d.Attack(ctx, claimIndex)
if claimIndex != 0 {
d.Defend(ctx, claimIndex)
}
}
var numClaimsSeen int64
for {
newCount, err := d.WaitForNewClaim(ctx, numClaimsSeen)
if errors.Is(err, context.DeadlineExceeded) {
// we assume that the honest challenger has stopped responding
// There's nothing to respond to.
break
}
d.FaultGameHelper.require.NoError(err)
for i := numClaimsSeen; i < newCount; i++ {
claimData := d.getClaim(ctx, numClaimsSeen)
move(numClaimsSeen, claimData)
numClaimsSeen++
}
}
}
......@@ -2,7 +2,6 @@ package disputegame
import (
"context"
"errors"
"fmt"
"math/big"
"testing"
......@@ -39,6 +38,9 @@ func (g *FaultGameHelper) GameDuration(ctx context.Context) time.Duration {
return time.Duration(duration) * time.Second
}
// WaitForClaimCount waits until there are at least count claims in the game.
// This does not check that the number of claims is exactly the specified count to avoid intermittent failures
// where a challenger posts an additional claim before this method sees the number of claims it was waiting for.
func (g *FaultGameHelper) WaitForClaimCount(ctx context.Context, count int64) {
ctx, cancel := context.WithTimeout(ctx, 2*time.Minute)
defer cancel()
......@@ -48,7 +50,7 @@ func (g *FaultGameHelper) WaitForClaimCount(ctx context.Context, count int64) {
return false, err
}
g.t.Log("Waiting for claim count", "current", actual, "expected", count, "game", g.addr)
return actual.Cmp(big.NewInt(count)) == 0, nil
return actual.Cmp(big.NewInt(count)) >= 0, nil
})
g.require.NoErrorf(err, "Did not find expected claim count %v", count)
}
......@@ -123,6 +125,12 @@ func (g *FaultGameHelper) GetClaimValue(ctx context.Context, claimIdx int64) com
return claim.Claim
}
func (g *FaultGameHelper) GetClaimPosition(ctx context.Context, claimIdx int64) types.Position {
g.WaitForClaimCount(ctx, claimIdx+1)
claim := g.getClaim(ctx, claimIdx)
return types.NewPositionFromGIndex(claim.Position.Uint64())
}
// getClaim retrieves the claim data for a specific index.
// Note that it is deliberately not exported as tests should use WaitForClaim to avoid race conditions.
func (g *FaultGameHelper) getClaim(ctx context.Context, claimIdx int64) ContractClaim {
......@@ -133,10 +141,6 @@ func (g *FaultGameHelper) getClaim(ctx context.Context, claimIdx int64) Contract
return claimData
}
func (g *FaultGameHelper) GetClaimUnsafe(ctx context.Context, claimIdx int64) ContractClaim {
return g.getClaim(ctx, claimIdx)
}
func (g *FaultGameHelper) WaitForClaimAtDepth(ctx context.Context, depth int) {
g.waitForClaim(
ctx,
......@@ -383,106 +387,3 @@ func (g *FaultGameHelper) gameData(ctx context.Context) string {
func (g *FaultGameHelper) LogGameData(ctx context.Context) {
g.t.Log(g.gameData(ctx))
}
type dishonestClaim struct {
ParentIndex int64
IsAttack bool
Valid bool
}
type DishonestHelper struct {
*FaultGameHelper
*HonestHelper
claims map[dishonestClaim]bool
defender bool
}
func NewDishonestHelper(g *FaultGameHelper, correctTrace *HonestHelper, defender bool) *DishonestHelper {
return &DishonestHelper{g, correctTrace, make(map[dishonestClaim]bool), defender}
}
func (t *DishonestHelper) Attack(ctx context.Context, claimIndex int64) {
c := dishonestClaim{claimIndex, true, false}
if t.claims[c] {
return
}
t.claims[c] = true
t.FaultGameHelper.Attack(ctx, claimIndex, common.Hash{byte(claimIndex)})
}
func (t *DishonestHelper) Defend(ctx context.Context, claimIndex int64) {
c := dishonestClaim{claimIndex, false, false}
if t.claims[c] {
return
}
t.claims[c] = true
t.FaultGameHelper.Defend(ctx, claimIndex, common.Hash{byte(claimIndex)})
}
func (t *DishonestHelper) AttackCorrect(ctx context.Context, claimIndex int64) {
c := dishonestClaim{claimIndex, true, true}
if t.claims[c] {
return
}
t.claims[c] = true
t.HonestHelper.Attack(ctx, claimIndex)
}
func (t *DishonestHelper) DefendCorrect(ctx context.Context, claimIndex int64) {
c := dishonestClaim{claimIndex, false, true}
if t.claims[c] {
return
}
t.claims[c] = true
t.HonestHelper.Defend(ctx, claimIndex)
}
// ExhaustDishonestClaims makes all possible significant moves (mod honest challenger's) in a game.
// It is very inefficient and should NOT be used on games with large depths
func (d *DishonestHelper) ExhaustDishonestClaims(ctx context.Context) {
depth := d.MaxDepth(ctx)
move := func(claimIndex int64, claimData ContractClaim) {
// dishonest level, valid attack
// dishonest level, invalid attack
// dishonest level, valid defense
// dishonest level, invalid defense
// honest level, invalid attack
// honest level, invalid defense
pos := types.NewPositionFromGIndex(claimData.Position.Uint64())
if int64(pos.Depth()) == depth {
return
}
d.LogGameData(ctx)
d.FaultGameHelper.t.Logf("Dishonest moves against claimIndex %d", claimIndex)
agreeWithLevel := d.defender == (pos.Depth()%2 == 0)
if !agreeWithLevel {
d.AttackCorrect(ctx, claimIndex)
if claimIndex != 0 {
d.DefendCorrect(ctx, claimIndex)
}
}
d.Attack(ctx, claimIndex)
if claimIndex != 0 {
d.Defend(ctx, claimIndex)
}
}
var numClaimsSeen int64
for {
newCount, err := d.WaitForNewClaim(ctx, numClaimsSeen)
if errors.Is(err, context.DeadlineExceeded) {
// we assume that the honest challenger has stopped responding
// There's nothing to respond to.
break
}
d.FaultGameHelper.require.NoError(err)
for i := numClaimsSeen; i < newCount; i++ {
claimData := d.getClaim(ctx, numClaimsSeen)
move(numClaimsSeen, claimData)
numClaimsSeen++
}
}
}
......@@ -5,7 +5,6 @@ import (
"testing"
"time"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/types"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/challenger"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/disputegame"
l2oo2 "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/l2oo"
......@@ -208,8 +207,7 @@ func TestChallengerCompleteExhaustiveDisputeGame(t *testing.T) {
)
// Start dishonest challenger
correctTrace := game.CreateHonestActor(ctx, disputegame.CorrectAlphabet, 4)
dishonestHelper := disputegame.NewDishonestHelper(&game.FaultGameHelper, correctTrace, !isRootCorrect)
dishonestHelper := game.CreateDishonestHelper(disputegame.CorrectAlphabet, 4, !isRootCorrect)
dishonestHelper.ExhaustDishonestClaims(ctx)
// Wait until we've reached max depth before checking for inactivity
......@@ -464,8 +462,7 @@ func TestCannonPoisonedPostState(t *testing.T) {
game.WaitForClaimCount(ctx, claimCount)
// Defender moves last. If we're at max depth, then we're done
dishonestClaim := game.GetClaimUnsafe(ctx, claimCount-1)
pos := types.NewPositionFromGIndex(dishonestClaim.Position.Uint64())
pos := game.GetClaimPosition(ctx, claimCount-1)
if int64(pos.Depth()) == depth {
break
}
......
package metrics
import (
"fmt"
"time"
"github.com/ethereum-optimism/optimism/op-service/metrics"
"github.com/prometheus/client_golang/prometheus"
)
type EventMetrics struct {
Total prometheus.Counter
LastTime prometheus.Gauge
}
func (e *EventMetrics) RecordEvent() {
e.Total.Inc()
e.LastTime.Set(float64(time.Now().Unix()))
}
func NewEventMetrics(factory metrics.Factory, ns string, name string, displayName string) *EventMetrics {
return &EventMetrics{
Total: factory.NewCounter(prometheus.CounterOpts{
Namespace: ns,
Name: fmt.Sprintf("%s_total", name),
Help: fmt.Sprintf("Count of %s events", displayName),
}),
LastTime: factory.NewGauge(prometheus.GaugeOpts{
Namespace: ns,
Name: fmt.Sprintf("last_%s_unix", name),
Help: fmt.Sprintf("Timestamp of last %s event", displayName),
}),
}
}
This diff is collapsed.
......@@ -16,8 +16,8 @@ func (e *Event) Record() {
e.LastTime.SetToCurrentTime()
}
func NewEvent(factory Factory, ns string, subsystem string, name string, displayName string) Event {
return Event{
func NewEvent(factory Factory, ns string, subsystem string, name string, displayName string) *Event {
return &Event{
Total: factory.NewCounter(prometheus.CounterOpts{
Namespace: ns,
Name: fmt.Sprintf("%s_total", name),
......
......@@ -27,7 +27,7 @@ type TxMetrics struct {
currentNonce prometheus.Gauge
pendingTxs prometheus.Gauge
txPublishError *prometheus.CounterVec
publishEvent metrics.Event
publishEvent *metrics.Event
confirmEvent metrics.EventVec
rpcError prometheus.Counter
}
......
......@@ -58,7 +58,7 @@
"@types/morgan": "^1.9.4",
"@types/pino": "^7.0.5",
"@types/pino-multi-stream": "^5.1.3",
"chai": "^4.3.7",
"chai": "^4.3.9",
"supertest": "^6.3.3"
}
}
......@@ -44,6 +44,6 @@
"@typescript-eslint/eslint-plugin": "^6.7.0",
"@typescript-eslint/parser": "^6.4.0",
"tsx": "^3.12.7",
"typescript": "^5.1.6"
"typescript": "^5.2.2"
}
}
......@@ -60,7 +60,7 @@
"jest-dom": "link:@types/@testing-library/jest-dom",
"jsdom": "^22.1.0",
"tsup": "^7.1.0",
"typescript": "^5.1.6",
"typescript": "^5.2.2",
"vite": "^4.4.6",
"vitest": "^0.34.2"
},
......
......@@ -44,7 +44,7 @@
"@ethersproject/properties": "^5.7.0",
"@ethersproject/rlp": "^5.7.0",
"@ethersproject/web": "^5.7.1",
"chai": "^4.3.7",
"chai": "^4.3.9",
"ethers": "^5.7.2",
"node-fetch": "^2.6.7"
},
......
......@@ -43,7 +43,7 @@
"jest-dom": "link:@types/@testing-library/jest-dom",
"jsdom": "^22.1.0",
"tsup": "^7.1.0",
"typescript": "^5.1.6",
"typescript": "^5.2.2",
"viem": "^1.3.1",
"vite": "^4.4.6",
"vitest": "^0.34.2"
......
......@@ -41,7 +41,7 @@
"@ethersproject/transactions": "^5.7.0",
"@nomiclabs/hardhat-ethers": "^2.2.3",
"@nomiclabs/hardhat-waffle": "^2.0.1",
"@types/chai": "^4.3.5",
"@types/chai": "^4.3.6",
"@types/chai-as-promised": "^7.1.5",
"@types/mocha": "^10.0.1",
"@types/node": "^20.5.0",
......@@ -55,7 +55,7 @@
"nyc": "^15.1.0",
"ts-node": "^10.9.1",
"typedoc": "^0.25.1",
"typescript": "^5.1.6",
"typescript": "^5.2.2",
"viem": "^1.6.0",
"vitest": "^0.34.2",
"zod": "^3.22.1"
......
......@@ -36,7 +36,7 @@
"@swc/core": "^1.3.76",
"@vitest/coverage-istanbul": "^0.34.1",
"tsup": "^7.2.0",
"typescript": "^5.1.6",
"typescript": "^5.2.2",
"viem": "^1.6.0",
"vite": "^4.4.9",
"vitest": "^0.34.1",
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment