Skip to content
This repository has been archived by the owner on May 29, 2024. It is now read-only.

Commit

Permalink
[epociask/large-withdrawal-poc] Indexer integration
Browse files Browse the repository at this point in the history
  • Loading branch information
Ethen Pociask committed Oct 25, 2023
1 parent 89c1897 commit d36e3af
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 40 deletions.
21 changes: 17 additions & 4 deletions internal/engine/engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"github.com/base-org/pessimism/internal/engine/heuristic"
"github.com/base-org/pessimism/internal/logging"
"github.com/base-org/pessimism/internal/metrics"
"github.com/ethereum-optimism/optimism/op-service/retry"

"go.uber.org/zap"
)
Expand Down Expand Up @@ -95,11 +96,23 @@ func (hce *hardCodedEngine) EventLoop(ctx context.Context) {
logger.Debug("Heuristic input received",
zap.String(logging.SUUIDKey, execInput.h.SUUID().String()))

// (1) Execute heuristic
// (1) Execute heuristic with retry strategy
start := time.Now()
outcome, activated := hce.Execute(ctx, execInput.hi.Input, execInput.h)
metrics.WithContext(ctx).RecordHeuristicRun(execInput.h)
metrics.WithContext(ctx).RecordInvExecutionTime(execInput.h, float64(time.Since(start).Nanoseconds()))

var outcome *core.Activation
var activated bool

retryStrategy := &retry.ExponentialStrategy{Min: 1000, Max: 20_000, MaxJitter: 250}

Check failure on line 105 in internal/engine/engine.go

View workflow job for this annotation

GitHub Actions / lint

mnd: Magic number: 1000, in <assign> detected (gomnd)
if _, err := retry.Do[interface{}](ctx, 10, retryStrategy, func() (interface{}, error) {

Check failure on line 106 in internal/engine/engine.go

View workflow job for this annotation

GitHub Actions / lint

mnd: Magic number: 10, in <argument> detected (gomnd)
outcome, activated = hce.Execute(ctx, execInput.hi.Input, execInput.h)
metrics.WithContext(ctx).RecordHeuristicRun(execInput.h)
metrics.WithContext(ctx).RecordInvExecutionTime(execInput.h, float64(time.Since(start).Nanoseconds()))
// a-ok!
return nil, nil

Check failure on line 111 in internal/engine/engine.go

View workflow job for this annotation

GitHub Actions / lint

return both the `nil` error and invalid value: use a sentinel error instead (nilnil)
}); err != nil {
logger.Error("Failed to execute heuristic", zap.Error(err))
metrics.WithContext(ctx).RecordAssessmentError(execInput.h)
}

// (2) Send alert if activated
if activated {
Expand Down
9 changes: 9 additions & 0 deletions internal/engine/registry/constants.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
package registry

import (
"github.com/ethereum/go-ethereum/crypto"
)

const (
// Error constant strings
invalidAddrErr = "invalid address provided for heuristic. expected %s, got %s"
Expand All @@ -10,4 +14,9 @@ const (
// Event declaration strings
OutputProposedEvent = "OutputProposed(bytes32,uint256,uint256,uint256)"
WithdrawalProvenEvent = "WithdrawalProven(bytes32,address,address)"
MessagePassed = "MessagePassed(uint256,address,address,uint256,uint256,bytes,bytes32)"
)

var (
MessagePassedSig = crypto.Keccak256Hash([]byte(MessagePassed))
)
63 changes: 27 additions & 36 deletions internal/engine/registry/large_withdrawal.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"encoding/json"
"fmt"
"math/big"
"strconv"
"time"

"github.com/base-org/pessimism/internal/client"
Expand Down Expand Up @@ -40,10 +41,10 @@ type LargeWithdrawalCfg struct {

// LargeWithdrawHeuristic ... LargeWithdrawal heuristic implementation
type LargeWithdrawHeuristic struct {
eventHash common.Hash
cfg *LargeWithdrawalCfg
l2tol1MessagePasser *bindings.L2ToL1MessagePasserFilterer
l1PortalFilter *bindings.OptimismPortalFilterer
eventHash common.Hash
cfg *LargeWithdrawalCfg
indexerClient client.IndexerClient
l1PortalFilter *bindings.OptimismPortalFilterer

heuristic.Heuristic
}
Expand All @@ -55,36 +56,25 @@ func (cfg *LargeWithdrawalCfg) Unmarshal(isp *core.SessionParams) error {

// NewLargeWithdrawHeuristic ... Initializer
func NewLargeWithdrawHeuristic(ctx context.Context, cfg *LargeWithdrawalCfg) (heuristic.Heuristic, error) {
l2Client, err := client.FromContext(ctx, core.Layer2)
if err != nil {
return nil, err
}

l1Client, err := client.FromContext(ctx, core.Layer1)
clients, err := client.FromContext(ctx)
if err != nil {
return nil, err
}

withdrawalHash := crypto.Keccak256Hash([]byte(WithdrawalProvenEvent))
portalAddr := common.HexToAddress(cfg.L1PortalAddress)

addr := common.HexToAddress(cfg.L2ToL1Address)
addr2 := common.HexToAddress(cfg.L1PortalAddress)
l2MessagePasser, err := bindings.NewL2ToL1MessagePasserFilterer(addr, l2Client)
if err != nil {
return nil, err
}

filter, err := bindings.NewOptimismPortalFilterer(addr2, l1Client)
filter, err := bindings.NewOptimismPortalFilterer(portalAddr, clients.L1Client)
if err != nil {
return nil, err
}

return &LargeWithdrawHeuristic{
cfg: cfg,

eventHash: withdrawalHash,
l1PortalFilter: filter,
l2tol1MessagePasser: l2MessagePasser,
eventHash: withdrawalHash,
l1PortalFilter: filter,
indexerClient: clients.IndexerClient,

Heuristic: heuristic.NewBaseHeuristic(core.EventLog),
}, nil
Expand Down Expand Up @@ -116,25 +106,26 @@ func (wi *LargeWithdrawHeuristic) Assess(td core.TransitData) (*core.Activation,
return nil, false, err
}

// 3. Check if the withdrawal exists in the message outbox of the L2ToL1MessagePasser contract
iterator, err := wi.l2tol1MessagePasser.FilterMessagePassed(nil,
[]*big.Int{}, []common.Address{provenWithdrawal.From}, []common.Address{provenWithdrawal.To})
// 3. Get withdrawal metadata from OP Indexer API
withdrawals, err := wi.indexerClient.GetAllWithdrawalsByAddress(provenWithdrawal.From)
if err != nil {
return nil, false, err
}

for iterator.Next() {
if iterator.Event.WithdrawalHash == provenWithdrawal.WithdrawalHash { // Found the associated withdrawal on L2
// 4. Check if the withdrawal amount is greater than the threshold
if iterator.Event.Value.Cmp(wi.cfg.Threshold) == 1 {
return &core.Activation{
TimeStamp: time.Now(),
Message: fmt.Sprintf(largeWithdrawalMsg,
wi.cfg.L1PortalAddress, wi.cfg.L2ToL1Address,
wi.SUUID(), log.TxHash.Hex(), iterator.Event.Raw.TxHash,
iterator.Event.Value),
}, true, nil
}
for _, withdrawal := range withdrawals {
asInt, err := strconv.Atoi(withdrawal.Amount)
if err != nil {
return nil, false, err
}

if asInt > int(wi.cfg.Threshold.Int64()) {
return &core.Activation{
TimeStamp: time.Now(),
Message: fmt.Sprintf(largeWithdrawalMsg,

Check failure on line 124 in internal/engine/registry/large_withdrawal.go

View workflow job for this annotation

GitHub Actions / go-test

fmt.Sprintf format %d has arg withdrawal.Amount of wrong type string

Check failure on line 124 in internal/engine/registry/large_withdrawal.go

View workflow job for this annotation

GitHub Actions / lint

SA5009: Printf format %d has arg #6 of wrong type string (staticcheck)
wi.cfg.L1PortalAddress, wi.cfg.L2ToL1Address,
wi.SUUID(), log.TxHash.Hex(), withdrawal.TransactionHash,
withdrawal.Amount),
}, true, nil
}
}

Expand Down

0 comments on commit d36e3af

Please sign in to comment.