Commit b2202f6f authored by clabby's avatar clabby

Merge branch 'develop' into cl/ctb/deployment-checks

parents 8ada905b 0361bd89
...@@ -14,6 +14,7 @@ COPY ./indexer /app/indexer ...@@ -14,6 +14,7 @@ COPY ./indexer /app/indexer
COPY ./op-bindings /app/op-bindings COPY ./op-bindings /app/op-bindings
COPY ./op-service /app/op-service COPY ./op-service /app/op-service
COPY ./op-node /app/op-node COPY ./op-node /app/op-node
COPY ./op-chain-ops /app/op-chain-ops
WORKDIR /app/indexer WORKDIR /app/indexer
......
...@@ -39,6 +39,11 @@ type L2BridgeMessage struct { ...@@ -39,6 +39,11 @@ type L2BridgeMessage struct {
TransactionWithdrawalHash common.Hash `gorm:"serializer:bytes"` TransactionWithdrawalHash common.Hash `gorm:"serializer:bytes"`
} }
type L2BridgeMessageVersionedMessageHash struct {
MessageHash common.Hash `gorm:"primaryKey;serializer:bytes"`
V1MessageHash common.Hash `gorm:"serializer:bytes"`
}
type BridgeMessagesView interface { type BridgeMessagesView interface {
L1BridgeMessage(common.Hash) (*L1BridgeMessage, error) L1BridgeMessage(common.Hash) (*L1BridgeMessage, error)
L1BridgeMessageWithFilter(BridgeMessage) (*L1BridgeMessage, error) L1BridgeMessageWithFilter(BridgeMessage) (*L1BridgeMessage, error)
...@@ -55,6 +60,8 @@ type BridgeMessagesDB interface { ...@@ -55,6 +60,8 @@ type BridgeMessagesDB interface {
StoreL2BridgeMessages([]L2BridgeMessage) error StoreL2BridgeMessages([]L2BridgeMessage) error
MarkRelayedL2BridgeMessage(common.Hash, uuid.UUID) error MarkRelayedL2BridgeMessage(common.Hash, uuid.UUID) error
StoreL2BridgeMessageV1MessageHash(common.Hash, common.Hash) error
} }
/** /**
...@@ -134,8 +141,37 @@ func (db bridgeMessagesDB) StoreL2BridgeMessages(messages []L2BridgeMessage) err ...@@ -134,8 +141,37 @@ func (db bridgeMessagesDB) StoreL2BridgeMessages(messages []L2BridgeMessage) err
return result.Error return result.Error
} }
func (db bridgeMessagesDB) StoreL2BridgeMessageV1MessageHash(msgHash, v1MsgHash common.Hash) error {
if msgHash == v1MsgHash {
return fmt.Errorf("message hash is equal to the v1 message: %s", msgHash)
}
deduped := db.gorm.Clauses(clause.OnConflict{Columns: []clause.Column{{Name: "message_hash"}}, DoNothing: true})
result := deduped.Create(&L2BridgeMessageVersionedMessageHash{MessageHash: msgHash, V1MessageHash: v1MsgHash})
if result.Error == nil && int(result.RowsAffected) < 1 {
db.log.Warn("ignored L2 bridge v1 message hash duplicates")
}
return result.Error
}
func (db bridgeMessagesDB) L2BridgeMessage(msgHash common.Hash) (*L2BridgeMessage, error) { func (db bridgeMessagesDB) L2BridgeMessage(msgHash common.Hash) (*L2BridgeMessage, error) {
return db.L2BridgeMessageWithFilter(BridgeMessage{MessageHash: msgHash}) message, err := db.L2BridgeMessageWithFilter(BridgeMessage{MessageHash: msgHash})
if message != nil || err != nil {
return message, err
}
// check if this is a v1 hash of an older message
versioned := L2BridgeMessageVersionedMessageHash{V1MessageHash: msgHash}
result := db.gorm.Where(&versioned).Take(&versioned)
if result.Error != nil {
if errors.Is(result.Error, gorm.ErrRecordNotFound) {
return nil, nil
}
return nil, result.Error
}
return db.L2BridgeMessageWithFilter(BridgeMessage{MessageHash: versioned.MessageHash})
} }
func (db bridgeMessagesDB) L2BridgeMessageWithFilter(filter BridgeMessage) (*L2BridgeMessage, error) { func (db bridgeMessagesDB) L2BridgeMessageWithFilter(filter BridgeMessage) (*L2BridgeMessage, error) {
......
...@@ -4,12 +4,11 @@ import ( ...@@ -4,12 +4,11 @@ import (
"errors" "errors"
"math/big" "math/big"
"github.com/ethereum-optimism/optimism/indexer/processors/contracts"
"github.com/ethereum-optimism/optimism/op-bindings/bindings" "github.com/ethereum-optimism/optimism/op-bindings/bindings"
"github.com/ethereum-optimism/optimism/op-chain-ops/crossdomain"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
) )
type CrossDomainMessengerSentMessage struct { type CrossDomainMessengerSentMessage struct {
...@@ -40,7 +39,17 @@ func ParseCrossDomainMessage(sentMessageReceipt *types.Receipt) (CrossDomainMess ...@@ -40,7 +39,17 @@ func ParseCrossDomainMessage(sentMessageReceipt *types.Receipt) (CrossDomainMess
if err != nil { if err != nil {
return CrossDomainMessengerSentMessage{}, err return CrossDomainMessengerSentMessage{}, err
} }
msgHash, err := CrossDomainMessengerSentMessageHash(sentMessage, sentMessageExtension.Value)
msg := crossdomain.NewCrossDomainMessage(
sentMessage.MessageNonce,
sentMessage.Sender,
sentMessage.Target,
sentMessageExtension.Value,
sentMessage.GasLimit,
sentMessage.Message,
)
msgHash, err := msg.Hash()
if err != nil { if err != nil {
return CrossDomainMessengerSentMessage{}, err return CrossDomainMessengerSentMessage{}, err
} }
...@@ -51,17 +60,3 @@ func ParseCrossDomainMessage(sentMessageReceipt *types.Receipt) (CrossDomainMess ...@@ -51,17 +60,3 @@ func ParseCrossDomainMessage(sentMessageReceipt *types.Receipt) (CrossDomainMess
return CrossDomainMessengerSentMessage{}, errors.New("missing SentMessage receipts") return CrossDomainMessengerSentMessage{}, errors.New("missing SentMessage receipts")
} }
func CrossDomainMessengerSentMessageHash(sentMessage *bindings.CrossDomainMessengerSentMessage, value *big.Int) (common.Hash, error) {
abi, err := bindings.CrossDomainMessengerMetaData.GetAbi()
if err != nil {
return common.Hash{}, err
}
calldata, err := contracts.CrossDomainMessageCalldata(abi, sentMessage, value)
if err != nil {
return common.Hash{}, err
}
return crypto.Keccak256Hash(calldata), nil
}
...@@ -176,6 +176,22 @@ CREATE INDEX IF NOT EXISTS l2_bridge_messages_timestamp ON l2_bridge_messages(ti ...@@ -176,6 +176,22 @@ CREATE INDEX IF NOT EXISTS l2_bridge_messages_timestamp ON l2_bridge_messages(ti
CREATE INDEX IF NOT EXISTS l2_bridge_messages_transaction_withdrawal_hash ON l2_bridge_messages(transaction_withdrawal_hash); CREATE INDEX IF NOT EXISTS l2_bridge_messages_transaction_withdrawal_hash ON l2_bridge_messages(transaction_withdrawal_hash);
CREATE INDEX IF NOT EXISTS l2_bridge_messages_from_address ON l2_bridge_messages(from_address); CREATE INDEX IF NOT EXISTS l2_bridge_messages_from_address ON l2_bridge_messages(from_address);
/**
* Since the CDM uses the latest versioned message hash when emitting the `RelayedMessage` event, we need
* to keep track of all of the future versions of message hashes such that legacy messages can be queried
* queried for when relayed on L1
*
* As new the CDM is updated with new versions, we need to ensure that there's a better way to correlate message between
* chains (adding the message nonce to the RelayedMessage event) or continue to add columns to this table and migrate
* unrelayed messages such that finalization logic can handle switching between the varying versioned message hashes
*/
CREATE TABLE IF NOT EXISTS l2_bridge_message_versioned_message_hashes(
message_hash VARCHAR PRIMARY KEY NOT NULL UNIQUE REFERENCES l2_bridge_messages(message_hash),
-- only filled in if `message_hash` is for a v0 message
v1_message_hash VARCHAR UNIQUE
);
-- StandardBridge -- StandardBridge
CREATE TABLE IF NOT EXISTS l1_bridge_deposits ( CREATE TABLE IF NOT EXISTS l1_bridge_deposits (
transaction_source_hash VARCHAR PRIMARY KEY REFERENCES l1_transaction_deposits(source_hash) ON DELETE CASCADE, transaction_source_hash VARCHAR PRIMARY KEY REFERENCES l1_transaction_deposits(source_hash) ON DELETE CASCADE,
......
...@@ -256,7 +256,7 @@ func (b *BridgeProcessor) processInitiatedL2Events() error { ...@@ -256,7 +256,7 @@ func (b *BridgeProcessor) processInitiatedL2Events() error {
legacyBridgeLog := l2BridgeLog.New("mode", "legacy", "from_block_number", legacyFromL2Height, "to_block_number", legacyToL2Height) legacyBridgeLog := l2BridgeLog.New("mode", "legacy", "from_block_number", legacyFromL2Height, "to_block_number", legacyToL2Height)
legacyBridgeLog.Info("scanning for initiated bridge events") legacyBridgeLog.Info("scanning for initiated bridge events")
if err := bridge.LegacyL2ProcessInitiatedBridgeEvents(legacyBridgeLog, tx, b.metrics, b.chainConfig.L2Contracts, legacyFromL2Height, legacyToL2Height); err != nil { if err := bridge.LegacyL2ProcessInitiatedBridgeEvents(legacyBridgeLog, tx, b.metrics, b.chainConfig.Preset, b.chainConfig.L2Contracts, legacyFromL2Height, legacyToL2Height); err != nil {
return err return err
} else if legacyToL2Height.Cmp(toL2Height) == 0 { } else if legacyToL2Height.Cmp(toL2Height) == 0 {
return nil // a-ok! Entire range was legacy blocks return nil // a-ok! Entire range was legacy blocks
......
...@@ -12,6 +12,8 @@ import ( ...@@ -12,6 +12,8 @@ import (
"github.com/ethereum-optimism/optimism/indexer/database" "github.com/ethereum-optimism/optimism/indexer/database"
"github.com/ethereum-optimism/optimism/indexer/node" "github.com/ethereum-optimism/optimism/indexer/node"
"github.com/ethereum-optimism/optimism/indexer/processors/contracts" "github.com/ethereum-optimism/optimism/indexer/processors/contracts"
"github.com/ethereum-optimism/optimism/op-bindings/predeploys"
"github.com/ethereum-optimism/optimism/op-chain-ops/crossdomain"
) )
// Legacy Bridge Initiation // Legacy Bridge Initiation
...@@ -145,7 +147,7 @@ func LegacyL1ProcessInitiatedBridgeEvents(log log.Logger, db *database.DB, metri ...@@ -145,7 +147,7 @@ func LegacyL1ProcessInitiatedBridgeEvents(log log.Logger, db *database.DB, metri
// 1. L2CrossDomainMessenger - The LegacyMessagePasser contract cannot be used as entrypoint to bridge transactions from L2. The protocol // 1. L2CrossDomainMessenger - The LegacyMessagePasser contract cannot be used as entrypoint to bridge transactions from L2. The protocol
// only allows the L2CrossDomainMessenger as the sole sender when relaying a bridged message. // only allows the L2CrossDomainMessenger as the sole sender when relaying a bridged message.
// 2. L2StandardBridge // 2. L2StandardBridge
func LegacyL2ProcessInitiatedBridgeEvents(log log.Logger, db *database.DB, metrics L2Metricer, l2Contracts config.L2Contracts, fromHeight, toHeight *big.Int) error { func LegacyL2ProcessInitiatedBridgeEvents(log log.Logger, db *database.DB, metrics L2Metricer, preset int, l2Contracts config.L2Contracts, fromHeight, toHeight *big.Int) error {
// (1) L2CrossDomainMessenger // (1) L2CrossDomainMessenger
crossDomainSentMessages, err := contracts.CrossDomainMessengerSentMessageEvents("l2", l2Contracts.L2CrossDomainMessenger, db, fromHeight, toHeight) crossDomainSentMessages, err := contracts.CrossDomainMessengerSentMessageEvents("l2", l2Contracts.L2CrossDomainMessenger, db, fromHeight, toHeight)
if err != nil { if err != nil {
...@@ -168,22 +170,38 @@ func LegacyL2ProcessInitiatedBridgeEvents(log log.Logger, db *database.DB, metri ...@@ -168,22 +170,38 @@ func LegacyL2ProcessInitiatedBridgeEvents(log log.Logger, db *database.DB, metri
sentMessage := crossDomainSentMessages[i] sentMessage := crossDomainSentMessages[i]
withdrawnWEI = new(big.Int).Add(withdrawnWEI, sentMessage.BridgeMessage.Tx.Amount) withdrawnWEI = new(big.Int).Add(withdrawnWEI, sentMessage.BridgeMessage.Tx.Amount)
// We re-use the L2CrossDomainMessenger message hash as the withdrawal hash to remain consistent in the schema. // Since these message can be relayed in bedrock, we utilize the migrated withdrawal hash
// and also store the v1 version of the message hash such that the bedrock l1 finalization
// processor works as expected
v1MessageHash, err := legacyBridgeMessageV1MessageHash(&sentMessage.BridgeMessage)
if err != nil {
return fmt.Errorf("failed to compute versioned message hash: %w", err)
}
if err := db.BridgeMessages.StoreL2BridgeMessageV1MessageHash(sentMessage.BridgeMessage.MessageHash, v1MessageHash); err != nil {
return err
}
withdrawalHash, err := legacyBridgeMessageWithdrawalHash(preset, &sentMessage.BridgeMessage)
if err != nil {
return fmt.Errorf("failed to construct migrated withdrawal hash: %w", err)
}
transactionWithdrawals[i] = database.L2TransactionWithdrawal{ transactionWithdrawals[i] = database.L2TransactionWithdrawal{
WithdrawalHash: sentMessage.BridgeMessage.MessageHash, WithdrawalHash: withdrawalHash,
InitiatedL2EventGUID: sentMessage.Event.GUID, InitiatedL2EventGUID: sentMessage.Event.GUID,
Nonce: sentMessage.BridgeMessage.Nonce, Nonce: sentMessage.BridgeMessage.Nonce,
GasLimit: sentMessage.BridgeMessage.GasLimit, GasLimit: sentMessage.BridgeMessage.GasLimit,
Tx: database.Transaction{ Tx: database.Transaction{
FromAddress: sentMessage.BridgeMessage.Tx.FromAddress, FromAddress: sentMessage.BridgeMessage.Tx.FromAddress,
ToAddress: sentMessage.BridgeMessage.Tx.ToAddress, ToAddress: sentMessage.BridgeMessage.Tx.ToAddress,
Amount: big.NewInt(0), Amount: bigint.Zero,
Data: sentMessage.BridgeMessage.Tx.Data, Data: sentMessage.BridgeMessage.Tx.Data,
Timestamp: sentMessage.Event.Timestamp, Timestamp: sentMessage.Event.Timestamp,
}, },
} }
sentMessages[logKey{sentMessage.Event.BlockHash, sentMessage.Event.LogIndex}] = sentMessageEvent{&sentMessage, sentMessage.BridgeMessage.MessageHash} sentMessages[logKey{sentMessage.Event.BlockHash, sentMessage.Event.LogIndex}] = sentMessageEvent{&sentMessage, withdrawalHash}
bridgeMessages[i] = database.L2BridgeMessage{ bridgeMessages[i] = database.L2BridgeMessage{
TransactionWithdrawalHash: sentMessage.BridgeMessage.MessageHash, TransactionWithdrawalHash: sentMessage.BridgeMessage.MessageHash,
BridgeMessage: sentMessage.BridgeMessage, BridgeMessage: sentMessage.BridgeMessage,
...@@ -297,16 +315,17 @@ func LegacyL1ProcessFinalizedBridgeEvents(log log.Logger, db *database.DB, metri ...@@ -297,16 +315,17 @@ func LegacyL1ProcessFinalizedBridgeEvents(log log.Logger, db *database.DB, metri
} }
} }
// Mark the associated tx withdrawal as proven/finalized with the same event. The message hash is also the transaction withdrawal hash if err := db.BridgeMessages.MarkRelayedL2BridgeMessage(relayedMessage.MessageHash, relayedMessage.Event.GUID); err != nil {
if err := db.BridgeTransactions.MarkL2TransactionWithdrawalProvenEvent(relayedMessage.MessageHash, relayedMessage.Event.GUID); err != nil { return fmt.Errorf("failed to relay cross domain message. tx_hash = %s: %w", relayedMessage.Event.TransactionHash, err)
}
// Mark the associated tx withdrawal as proven/finalized with the same event.
if err := db.BridgeTransactions.MarkL2TransactionWithdrawalProvenEvent(message.TransactionWithdrawalHash, relayedMessage.Event.GUID); err != nil {
return fmt.Errorf("failed to mark withdrawal as proven. tx_hash = %s: %w", relayedMessage.Event.TransactionHash, err) return fmt.Errorf("failed to mark withdrawal as proven. tx_hash = %s: %w", relayedMessage.Event.TransactionHash, err)
} }
if err := db.BridgeTransactions.MarkL2TransactionWithdrawalFinalizedEvent(relayedMessage.MessageHash, relayedMessage.Event.GUID, true); err != nil { if err := db.BridgeTransactions.MarkL2TransactionWithdrawalFinalizedEvent(message.TransactionWithdrawalHash, relayedMessage.Event.GUID, true); err != nil {
return fmt.Errorf("failed to mark withdrawal as finalized. tx_hash = %s: %w", relayedMessage.Event.TransactionHash, err) return fmt.Errorf("failed to mark withdrawal as finalized. tx_hash = %s: %w", relayedMessage.Event.TransactionHash, err)
} }
if err := db.BridgeMessages.MarkRelayedL2BridgeMessage(relayedMessage.MessageHash, relayedMessage.Event.GUID); err != nil {
return fmt.Errorf("failed to relay cross domain message. tx_hash = %s: %w", relayedMessage.Event.TransactionHash, err)
}
} }
if len(crossDomainRelayedMessages) > 0 { if len(crossDomainRelayedMessages) > 0 {
metrics.RecordL1ProvenWithdrawals(len(crossDomainRelayedMessages)) metrics.RecordL1ProvenWithdrawals(len(crossDomainRelayedMessages))
...@@ -370,3 +389,27 @@ func LegacyL2ProcessFinalizedBridgeEvents(log log.Logger, db *database.DB, metri ...@@ -370,3 +389,27 @@ func LegacyL2ProcessFinalizedBridgeEvents(log log.Logger, db *database.DB, metri
// a-ok! // a-ok!
return nil return nil
} }
// Utils
func legacyBridgeMessageWithdrawalHash(preset int, msg *database.BridgeMessage) (common.Hash, error) {
l1Cdm := config.Presets[preset].ChainConfig.L1Contracts.L1CrossDomainMessengerProxy
legacyWithdrawal := crossdomain.NewLegacyWithdrawal(predeploys.L2CrossDomainMessengerAddr, msg.Tx.ToAddress, msg.Tx.FromAddress, msg.Tx.Data, msg.Nonce)
migratedWithdrawal, err := crossdomain.MigrateWithdrawal(legacyWithdrawal, &l1Cdm, big.NewInt(int64(preset)))
if err != nil {
return common.Hash{}, err
}
return migratedWithdrawal.Hash()
}
func legacyBridgeMessageV1MessageHash(msg *database.BridgeMessage) (common.Hash, error) {
legacyWithdrawal := crossdomain.NewLegacyWithdrawal(predeploys.L2CrossDomainMessengerAddr, msg.Tx.ToAddress, msg.Tx.FromAddress, msg.Tx.Data, msg.Nonce)
value, err := legacyWithdrawal.Value()
if err != nil {
return common.Hash{}, fmt.Errorf("failed to extract ETH value from legacy bridge message: %w", err)
}
// Note: GasLimit is always zero. Only the GasLimit for the withdrawal transaction was migrated
return crossdomain.HashCrossDomainMessageV1(msg.Nonce, msg.Tx.FromAddress, msg.Tx.ToAddress, value, new(big.Int), msg.Tx.Data)
}
package bridge
import (
"testing"
"github.com/ethereum-optimism/optimism/indexer/bigint"
"github.com/ethereum-optimism/optimism/indexer/database"
"github.com/ethereum-optimism/optimism/indexer/processors/contracts"
"github.com/ethereum-optimism/optimism/op-bindings/bindings"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/stretchr/testify/require"
)
func TestLegacyWithdrawalAndMessageHash(t *testing.T) {
// Pre-Bedrock OP-Goerli withdrawal that was proven post-bedrock
// - L1 proven withdrawal tx: 0xa8853a3532f40052385602c66512e438bc1e3736d3cb7abde359f5b9377441c7
value := bigint.Zero
expectedWithdrawalHash := common.HexToHash("0xae99d25df3e38730f6ee6588733417e20a131923b84870be6aedb4f863b6302d")
// Ensure the L2 Tx which correlates with the above proven withdrawal results in the same computed withdrawal hash
// - L2 withdrawal tx: 0x254d9c28add020404142f840ed794cea51f86c0f0a737e3e7bdd7e1e4550962e
abi, err := bindings.CrossDomainMessengerMetaData.GetAbi()
require.NoError(t, err)
var sentMessage bindings.CrossDomainMessengerSentMessage
sentMessageEvent := abi.Events["SentMessage"]
logData := common.FromHex("0x0000000000000000000000004200000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000186a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e4a9f9e67500000000000000000000000007865c6e87b9f70255377e024ace6630c1eaa37f0000000000000000000000003b8e53b3ab8e01fb57d0c9e893bc4d655aa67d84000000000000000000000000b91882244f7f82540f2941a759724523c7b9a166000000000000000000000000b91882244f7f82540f2941a759724523c7b9a166000000000000000000000000000000000000000000000000000000000000271000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")
require.NoError(t, contracts.UnpackLog(&sentMessage, &types.Log{Data: logData, Topics: []common.Hash{sentMessageEvent.ID, common.HexToHash("0x000000000000000000000000636af16bf2f682dd3109e60102b8e1a089fedaa8")}}, sentMessageEvent.Name, abi))
// timestamp and message hash are filled in fields. not core to the event
msg := database.BridgeMessage{
Nonce: sentMessage.MessageNonce,
GasLimit: sentMessage.GasLimit,
Tx: database.Transaction{FromAddress: sentMessage.Sender, ToAddress: sentMessage.Target, Amount: value, Data: sentMessage.Message},
}
hash, err := legacyBridgeMessageWithdrawalHash(420, &msg)
require.NoError(t, err)
require.Equal(t, expectedWithdrawalHash, hash)
// Ensure the relayed message hash (v1) matches
expectedMessageHash := common.HexToHash("0xcb16ecc1967f5d7aed909349a4351d28fbb396429ef7faf1c9d2a670e3ca906f")
v1MessageHash, err := legacyBridgeMessageV1MessageHash(&msg)
require.NoError(t, err)
require.Equal(t, expectedMessageHash, v1MessageHash)
}
...@@ -6,17 +6,18 @@ import ( ...@@ -6,17 +6,18 @@ import (
"github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum-optimism/optimism/indexer/bigint"
"github.com/ethereum-optimism/optimism/indexer/database" "github.com/ethereum-optimism/optimism/indexer/database"
"github.com/ethereum-optimism/optimism/op-bindings/bindings" "github.com/ethereum-optimism/optimism/op-bindings/bindings"
"github.com/ethereum-optimism/optimism/op-chain-ops/crossdomain"
) )
var ( var (
// Standard ABI types copied from golang ABI tests // Standard ABI types copied from golang ABI tests
uint256Type, _ = abi.NewType("uint256", "", nil)
bytesType, _ = abi.NewType("bytes", "", nil)
addressType, _ = abi.NewType("address", "", nil) addressType, _ = abi.NewType("address", "", nil)
bytesType, _ = abi.NewType("bytes", "", nil)
uint256Type, _ = abi.NewType("uint256", "", nil)
CrossDomainMessengerLegacyRelayMessageEncoding = abi.NewMethod( CrossDomainMessengerLegacyRelayMessageEncoding = abi.NewMethod(
"relayMessage", "relayMessage",
...@@ -38,9 +39,9 @@ var ( ...@@ -38,9 +39,9 @@ var (
) )
type CrossDomainMessengerSentMessageEvent struct { type CrossDomainMessengerSentMessageEvent struct {
Event *database.ContractEvent Event *database.ContractEvent
MessageCalldata []byte BridgeMessage database.BridgeMessage
BridgeMessage database.BridgeMessage Version uint16
} }
type CrossDomainMessengerRelayedMessageEvent struct { type CrossDomainMessengerRelayedMessageEvent struct {
...@@ -85,32 +86,46 @@ func CrossDomainMessengerSentMessageEvents(chainSelector string, contractAddress ...@@ -85,32 +86,46 @@ func CrossDomainMessengerSentMessageEvents(chainSelector string, contractAddress
return nil, err return nil, err
} }
version, _ := DecodeVersionedNonce(sentMessage.MessageNonce) _, versionBig := crossdomain.DecodeVersionedNonce(sentMessage.MessageNonce)
version := uint16(versionBig.Uint64())
if i < numVersionZeroMessages && version != 0 { if i < numVersionZeroMessages && version != 0 {
return nil, fmt.Errorf("expected version zero nonce. nonce %d tx_hash %s", sentMessage.MessageNonce, sentMessage.Raw.TxHash) return nil, fmt.Errorf("expected version zero nonce: nonce %d, tx_hash %s", sentMessage.MessageNonce, sentMessage.Raw.TxHash)
} }
// In version zero, to value is bridged through the cross domain messenger. value := bigint.Zero
value := big.NewInt(0) var messageHash common.Hash
if version > 0 { switch version {
case 0:
messageHash, err = crossdomain.HashCrossDomainMessageV0(sentMessage.Target, sentMessage.Sender, sentMessage.Message, sentMessage.MessageNonce)
if err != nil {
return nil, err
}
case 1:
sentMessageExtension := bindings.CrossDomainMessengerSentMessageExtension1{Raw: *sentMessageExtensionEvents[i].RLPLog} sentMessageExtension := bindings.CrossDomainMessengerSentMessageExtension1{Raw: *sentMessageExtensionEvents[i].RLPLog}
err = UnpackLog(&sentMessageExtension, sentMessageExtensionEvents[i].RLPLog, sentMessageExtensionEventAbi.Name, crossDomainMessengerAbi) err = UnpackLog(&sentMessageExtension, sentMessageExtensionEvents[i].RLPLog, sentMessageExtensionEventAbi.Name, crossDomainMessengerAbi)
if err != nil { if err != nil {
return nil, err return nil, err
} }
value = sentMessageExtension.Value value = sentMessageExtension.Value
} messageHash, err = crossdomain.HashCrossDomainMessageV1(sentMessage.MessageNonce, sentMessage.Sender, sentMessage.Target, value, sentMessage.GasLimit, sentMessage.Message)
if err != nil {
return nil, err
}
messageCalldata, err := CrossDomainMessageCalldata(crossDomainMessengerAbi, &sentMessage, value) default:
if err != nil { // NOTE: We explicitly fail here since the presence of a new version means finalization
return nil, err // logic needs to be updated to ensure L1 finalization can run from genesis and handle
// the changing version formats. This is meant to be a serving indicator of this.
return nil, fmt.Errorf("expected cross domain version 0 or version 1: %d", version)
} }
crossDomainSentMessages[i] = CrossDomainMessengerSentMessageEvent{ crossDomainSentMessages[i] = CrossDomainMessengerSentMessageEvent{
Event: &sentMessageEvents[i], Event: &sentMessageEvents[i],
MessageCalldata: messageCalldata, Version: version,
BridgeMessage: database.BridgeMessage{ BridgeMessage: database.BridgeMessage{
MessageHash: crypto.Keccak256Hash(messageCalldata), MessageHash: messageHash,
Nonce: sentMessage.MessageNonce, Nonce: sentMessage.MessageNonce,
SentMessageEventGUID: sentMessageEvents[i].GUID, SentMessageEventGUID: sentMessageEvents[i].GUID,
GasLimit: sentMessage.GasLimit, GasLimit: sentMessage.GasLimit,
...@@ -157,26 +172,3 @@ func CrossDomainMessengerRelayedMessageEvents(chainSelector string, contractAddr ...@@ -157,26 +172,3 @@ func CrossDomainMessengerRelayedMessageEvents(chainSelector string, contractAddr
return crossDomainRelayedMessages, nil return crossDomainRelayedMessages, nil
} }
// Replica of `Encoding.sol#encodeCrossDomainMessage` solidity implementation
func CrossDomainMessageCalldata(abi *abi.ABI, sentMsg *bindings.CrossDomainMessengerSentMessage, value *big.Int) ([]byte, error) {
version, _ := DecodeVersionedNonce(sentMsg.MessageNonce)
switch version {
case 0:
// Legacy Message
inputBytes, err := CrossDomainMessengerLegacyRelayMessageEncoding.Inputs.Pack(sentMsg.Target, sentMsg.Sender, sentMsg.Message, sentMsg.MessageNonce)
if err != nil {
return nil, err
}
return append(CrossDomainMessengerLegacyRelayMessageEncoding.ID, inputBytes...), nil
case 1:
// Current Message
msgBytes, err := abi.Pack("relayMessage", sentMsg.MessageNonce, sentMsg.Sender, sentMsg.Target, value, sentMsg.GasLimit, sentMsg.Message)
if err != nil {
return nil, err
}
return msgBytes, nil
}
return nil, fmt.Errorf("unsupported cross domain messenger version: %d", version)
}
package contracts package contracts
import ( import (
"encoding/binary"
"errors" "errors"
"fmt" "fmt"
"math/big"
"github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
) )
// DecodeVersionNonce is an re-implementation of Encoding.sol#decodeVersionedNonce.
// If the nonce is greater than 32 bytes (solidity uint256), bytes [32:] are ignored
func DecodeVersionedNonce(nonce *big.Int) (uint16, *big.Int) {
nonceBytes := nonce.Bytes()
nonceByteLen := len(nonceBytes)
if nonceByteLen < 30 {
// version is 0x0000
return 0, nonce
} else if nonceByteLen == 31 {
// version is 0x00[01..ff]
return uint16(nonceBytes[0]), new(big.Int).SetBytes(nonceBytes[1:])
} else {
// fully specified
version := binary.BigEndian.Uint16(nonceBytes[:2])
return version, new(big.Int).SetBytes(nonceBytes[2:])
}
}
func UnpackLog(out interface{}, log *types.Log, name string, contractAbi *abi.ABI) error { func UnpackLog(out interface{}, log *types.Log, name string, contractAbi *abi.ABI) error {
eventAbi, ok := contractAbi.Events[name] eventAbi, ok := contractAbi.Events[name]
if !ok { if !ok {
......
...@@ -312,6 +312,10 @@ func (bs *BatcherService) Stop(ctx context.Context) error { ...@@ -312,6 +312,10 @@ func (bs *BatcherService) Stop(ctx context.Context) error {
result = errors.Join(result, fmt.Errorf("failed to close balance metricer: %w", err)) result = errors.Join(result, fmt.Errorf("failed to close balance metricer: %w", err))
} }
} }
if bs.TxManager != nil {
bs.TxManager.Close()
}
if bs.metricsSrv != nil { if bs.metricsSrv != nil {
if err := bs.metricsSrv.Stop(ctx); err != nil { if err := bs.metricsSrv.Stop(ctx); err != nil {
result = errors.Join(result, fmt.Errorf("failed to stop metrics server: %w", err)) result = errors.Join(result, fmt.Errorf("failed to stop metrics server: %w", err))
......
...@@ -2,22 +2,19 @@ package op_challenger ...@@ -2,22 +2,19 @@ package op_challenger
import ( import (
"context" "context"
"fmt"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum-optimism/optimism/op-challenger/config" "github.com/ethereum-optimism/optimism/op-challenger/config"
"github.com/ethereum-optimism/optimism/op-challenger/game" "github.com/ethereum-optimism/optimism/op-challenger/game"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum-optimism/optimism/op-service/cliapp"
) )
// Main is the programmatic entry-point for running op-challenger // Main is the programmatic entry-point for running op-challenger with a given configuration.
func Main(ctx context.Context, logger log.Logger, cfg *config.Config) error { func Main(ctx context.Context, logger log.Logger, cfg *config.Config) (cliapp.Lifecycle, error) {
if err := cfg.Check(); err != nil { if err := cfg.Check(); err != nil {
return err return nil, err
} }
service, err := game.NewService(ctx, logger, cfg) srv, err := game.NewService(ctx, logger, cfg)
if err != nil { return srv, err
return fmt.Errorf("failed to create the fault service: %w", err)
}
return service.MonitorGame(ctx)
} }
...@@ -12,6 +12,7 @@ import ( ...@@ -12,6 +12,7 @@ import (
func TestMainShouldReturnErrorWhenConfigInvalid(t *testing.T) { func TestMainShouldReturnErrorWhenConfigInvalid(t *testing.T) {
cfg := &config.Config{} cfg := &config.Config{}
err := Main(context.Background(), testlog.Logger(t, log.LvlInfo), cfg) app, err := Main(context.Background(), testlog.Logger(t, log.LvlInfo), cfg)
require.ErrorIs(t, err, cfg.Check()) require.ErrorIs(t, err, cfg.Check())
require.Nil(t, app)
} }
...@@ -4,16 +4,18 @@ import ( ...@@ -4,16 +4,18 @@ import (
"context" "context"
"os" "os"
op_challenger "github.com/ethereum-optimism/optimism/op-challenger"
opservice "github.com/ethereum-optimism/optimism/op-service"
"github.com/ethereum/go-ethereum/log"
"github.com/urfave/cli/v2" "github.com/urfave/cli/v2"
"github.com/ethereum/go-ethereum/log"
challenger "github.com/ethereum-optimism/optimism/op-challenger"
"github.com/ethereum-optimism/optimism/op-challenger/config" "github.com/ethereum-optimism/optimism/op-challenger/config"
"github.com/ethereum-optimism/optimism/op-challenger/flags" "github.com/ethereum-optimism/optimism/op-challenger/flags"
"github.com/ethereum-optimism/optimism/op-challenger/version" "github.com/ethereum-optimism/optimism/op-challenger/version"
opservice "github.com/ethereum-optimism/optimism/op-service"
"github.com/ethereum-optimism/optimism/op-service/cliapp" "github.com/ethereum-optimism/optimism/op-service/cliapp"
oplog "github.com/ethereum-optimism/optimism/op-service/log" oplog "github.com/ethereum-optimism/optimism/op-service/log"
"github.com/ethereum-optimism/optimism/op-service/opio"
) )
var ( var (
...@@ -26,14 +28,15 @@ var VersionWithMeta = opservice.FormatVersion(version.Version, GitCommit, GitDat ...@@ -26,14 +28,15 @@ var VersionWithMeta = opservice.FormatVersion(version.Version, GitCommit, GitDat
func main() { func main() {
args := os.Args args := os.Args
if err := run(args, op_challenger.Main); err != nil { ctx := opio.WithInterruptBlocker(context.Background())
if err := run(ctx, args, challenger.Main); err != nil {
log.Crit("Application failed", "err", err) log.Crit("Application failed", "err", err)
} }
} }
type ConfigAction func(ctx context.Context, log log.Logger, config *config.Config) error type ConfiguredLifecycle func(ctx context.Context, log log.Logger, config *config.Config) (cliapp.Lifecycle, error)
func run(args []string, action ConfigAction) error { func run(ctx context.Context, args []string, action ConfiguredLifecycle) error {
oplog.SetupDefaults() oplog.SetupDefaults()
app := cli.NewApp() app := cli.NewApp()
...@@ -42,20 +45,20 @@ func run(args []string, action ConfigAction) error { ...@@ -42,20 +45,20 @@ func run(args []string, action ConfigAction) error {
app.Name = "op-challenger" app.Name = "op-challenger"
app.Usage = "Challenge outputs" app.Usage = "Challenge outputs"
app.Description = "Ensures that on chain outputs are correct." app.Description = "Ensures that on chain outputs are correct."
app.Action = func(ctx *cli.Context) error { app.Action = cliapp.LifecycleCmd(func(ctx *cli.Context, close context.CancelCauseFunc) (cliapp.Lifecycle, error) {
logger, err := setupLogging(ctx) logger, err := setupLogging(ctx)
if err != nil { if err != nil {
return err return nil, err
} }
logger.Info("Starting op-challenger", "version", VersionWithMeta) logger.Info("Starting op-challenger", "version", VersionWithMeta)
cfg, err := flags.NewConfigFromCLI(ctx) cfg, err := flags.NewConfigFromCLI(ctx)
if err != nil { if err != nil {
return err return nil, err
} }
return action(ctx.Context, logger, cfg) return action(ctx.Context, logger, cfg)
} })
return app.Run(args) return app.RunContext(ctx, args)
} }
func setupLogging(ctx *cli.Context) (log.Logger, error) { func setupLogging(ctx *cli.Context) (log.Logger, error) {
......
...@@ -2,15 +2,19 @@ package main ...@@ -2,15 +2,19 @@ package main
import ( import (
"context" "context"
"errors"
"fmt" "fmt"
"testing" "testing"
"time" "time"
"github.com/ethereum-optimism/optimism/op-challenger/config" "github.com/stretchr/testify/require"
"github.com/ethereum-optimism/optimism/op-service/txmgr"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
"github.com/stretchr/testify/require"
"github.com/ethereum-optimism/optimism/op-challenger/config"
"github.com/ethereum-optimism/optimism/op-service/cliapp"
"github.com/ethereum-optimism/optimism/op-service/txmgr"
) )
var ( var (
...@@ -36,7 +40,7 @@ func TestLogLevel(t *testing.T) { ...@@ -36,7 +40,7 @@ func TestLogLevel(t *testing.T) {
for _, lvl := range []string{"trace", "debug", "info", "error", "crit"} { for _, lvl := range []string{"trace", "debug", "info", "error", "crit"} {
lvl := lvl lvl := lvl
t.Run("AcceptValid_"+lvl, func(t *testing.T) { t.Run("AcceptValid_"+lvl, func(t *testing.T) {
logger, _, err := runWithArgs(addRequiredArgs(config.TraceTypeAlphabet, "--log.level", lvl)) logger, _, err := dryRunWithArgs(addRequiredArgs(config.TraceTypeAlphabet, "--log.level", lvl))
require.NoError(t, err) require.NoError(t, err)
require.NotNil(t, logger) require.NotNil(t, logger)
}) })
...@@ -431,25 +435,29 @@ func TestCannonL2Genesis(t *testing.T) { ...@@ -431,25 +435,29 @@ func TestCannonL2Genesis(t *testing.T) {
} }
func verifyArgsInvalid(t *testing.T, messageContains string, cliArgs []string) { func verifyArgsInvalid(t *testing.T, messageContains string, cliArgs []string) {
_, _, err := runWithArgs(cliArgs) _, _, err := dryRunWithArgs(cliArgs)
require.ErrorContains(t, err, messageContains) require.ErrorContains(t, err, messageContains)
} }
func configForArgs(t *testing.T, cliArgs []string) config.Config { func configForArgs(t *testing.T, cliArgs []string) config.Config {
_, cfg, err := runWithArgs(cliArgs) _, cfg, err := dryRunWithArgs(cliArgs)
require.NoError(t, err) require.NoError(t, err)
return cfg return cfg
} }
func runWithArgs(cliArgs []string) (log.Logger, config.Config, error) { func dryRunWithArgs(cliArgs []string) (log.Logger, config.Config, error) {
cfg := new(config.Config) cfg := new(config.Config)
var logger log.Logger var logger log.Logger
fullArgs := append([]string{"op-challenger"}, cliArgs...) fullArgs := append([]string{"op-challenger"}, cliArgs...)
err := run(fullArgs, func(ctx context.Context, log log.Logger, config *config.Config) error { testErr := errors.New("dry-run")
err := run(context.Background(), fullArgs, func(ctx context.Context, log log.Logger, config *config.Config) (cliapp.Lifecycle, error) {
logger = log logger = log
cfg = config cfg = config
return nil return nil, testErr
}) })
if errors.Is(err, testErr) { // expected error
err = nil
}
return logger, *cfg, err return logger, *cfg, err
} }
......
...@@ -65,7 +65,7 @@ func registerOutputCannon( ...@@ -65,7 +65,7 @@ func registerOutputCannon(
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
accessor, err := outputs.NewOutputCannonTraceAccessor(ctx, logger, cfg.RollupRpc, gameDepth, agreed.L2BlockNumber.Uint64(), disputed.L2BlockNumber.Uint64()) accessor, err := outputs.NewOutputCannonTraceAccessor(ctx, logger, m, cfg, contract, dir, gameDepth, agreed.L2BlockNumber.Uint64(), disputed.L2BlockNumber.Uint64())
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
......
...@@ -232,6 +232,9 @@ func (m *mockTxManager) From() common.Address { ...@@ -232,6 +232,9 @@ func (m *mockTxManager) From() common.Address {
return m.from return m.from
} }
func (m *mockTxManager) Close() {
}
type mockContract struct { type mockContract struct {
calls int calls int
callFails bool callFails bool
......
...@@ -23,21 +23,29 @@ type L2DataSource interface { ...@@ -23,21 +23,29 @@ type L2DataSource interface {
HeaderByNumber(context.Context, *big.Int) (*ethtypes.Header, error) HeaderByNumber(context.Context, *big.Int) (*ethtypes.Header, error)
} }
type GameInputsSource interface { type L1HeadSource interface {
GetL1Head(ctx context.Context) (common.Hash, error) GetL1Head(ctx context.Context) (common.Hash, error)
}
type GameInputsSource interface {
L1HeadSource
GetProposals(ctx context.Context) (agreed contracts.Proposal, disputed contracts.Proposal, err error) GetProposals(ctx context.Context) (agreed contracts.Proposal, disputed contracts.Proposal, err error)
} }
func fetchLocalInputs(ctx context.Context, caller GameInputsSource, l2Client L2DataSource) (LocalGameInputs, error) { func fetchLocalInputs(ctx context.Context, caller GameInputsSource, l2Client L2DataSource) (LocalGameInputs, error) {
l1Head, err := caller.GetL1Head(ctx) agreedOutput, claimedOutput, err := caller.GetProposals(ctx)
if err != nil { if err != nil {
return LocalGameInputs{}, fmt.Errorf("fetch L1 head: %w", err) return LocalGameInputs{}, fmt.Errorf("fetch proposals: %w", err)
} }
return fetchLocalInputsFromProposals(ctx, caller, l2Client, agreedOutput, claimedOutput)
}
agreedOutput, claimedOutput, err := caller.GetProposals(ctx) func fetchLocalInputsFromProposals(ctx context.Context, caller L1HeadSource, l2Client L2DataSource, agreedOutput contracts.Proposal, claimedOutput contracts.Proposal) (LocalGameInputs, error) {
l1Head, err := caller.GetL1Head(ctx)
if err != nil { if err != nil {
return LocalGameInputs{}, fmt.Errorf("fetch proposals: %w", err) return LocalGameInputs{}, fmt.Errorf("fetch L1 head: %w", err)
} }
agreedHeader, err := l2Client.HeaderByNumber(ctx, agreedOutput.L2BlockNumber) agreedHeader, err := l2Client.HeaderByNumber(ctx, agreedOutput.L2BlockNumber)
if err != nil { if err != nil {
return LocalGameInputs{}, fmt.Errorf("fetch L2 block header %v: %w", agreedOutput.L2BlockNumber, err) return LocalGameInputs{}, fmt.Errorf("fetch L2 block header %v: %w", agreedOutput.L2BlockNumber, err)
......
...@@ -42,6 +42,36 @@ func TestFetchLocalInputs(t *testing.T) { ...@@ -42,6 +42,36 @@ func TestFetchLocalInputs(t *testing.T) {
require.Equal(t, contract.disputed.L2BlockNumber, inputs.L2BlockNumber) require.Equal(t, contract.disputed.L2BlockNumber, inputs.L2BlockNumber)
} }
func TestFetchLocalInputsFromProposals(t *testing.T) {
ctx := context.Background()
agreed := contracts.Proposal{
L2BlockNumber: big.NewInt(2222),
OutputRoot: common.Hash{0xdd},
}
claimed := contracts.Proposal{
L2BlockNumber: big.NewInt(3333),
OutputRoot: common.Hash{0xee},
}
contract := &mockGameInputsSource{
l1Head: common.Hash{0xcc},
}
l2Client := &mockL2DataSource{
chainID: big.NewInt(88422),
header: ethtypes.Header{
Number: agreed.L2BlockNumber,
},
}
inputs, err := fetchLocalInputsFromProposals(ctx, contract, l2Client, agreed, claimed)
require.NoError(t, err)
require.Equal(t, contract.l1Head, inputs.L1Head)
require.Equal(t, l2Client.header.Hash(), inputs.L2Head)
require.EqualValues(t, agreed.OutputRoot, inputs.L2OutputRoot)
require.EqualValues(t, claimed.OutputRoot, inputs.L2Claim)
require.Equal(t, claimed.L2BlockNumber, inputs.L2BlockNumber)
}
type mockGameInputsSource struct { type mockGameInputsSource struct {
l1Head common.Hash l1Head common.Hash
starting contracts.Proposal starting contracts.Proposal
......
...@@ -69,6 +69,30 @@ func NewTraceProvider(ctx context.Context, logger log.Logger, m CannonMetricer, ...@@ -69,6 +69,30 @@ func NewTraceProvider(ctx context.Context, logger log.Logger, m CannonMetricer,
return NewTraceProviderFromInputs(logger, m, cfg, localContext, localInputs, dir, gameDepth), nil return NewTraceProviderFromInputs(logger, m, cfg, localContext, localInputs, dir, gameDepth), nil
} }
func NewTraceProviderFromProposals(
ctx context.Context,
logger log.Logger,
m CannonMetricer,
cfg *config.Config,
gameContract *contracts.FaultDisputeGameContract,
localContext common.Hash,
agreed contracts.Proposal,
claimed contracts.Proposal,
dir string,
gameDepth uint64,
) (*CannonTraceProvider, error) {
l2Client, err := ethclient.DialContext(ctx, cfg.CannonL2)
if err != nil {
return nil, fmt.Errorf("dial l2 client %v: %w", cfg.CannonL2, err)
}
defer l2Client.Close() // Not needed after fetching the inputs
localInputs, err := fetchLocalInputsFromProposals(ctx, gameContract, l2Client, agreed, claimed)
if err != nil {
return nil, fmt.Errorf("fetch local game inputs: %w", err)
}
return NewTraceProviderFromInputs(logger, m, cfg, localContext, localInputs, dir, gameDepth), nil
}
func NewTraceProviderFromInputs(logger log.Logger, m CannonMetricer, cfg *config.Config, localContext common.Hash, localInputs LocalGameInputs, dir string, gameDepth uint64) *CannonTraceProvider { func NewTraceProviderFromInputs(logger log.Logger, m CannonMetricer, cfg *config.Config, localContext common.Hash, localInputs LocalGameInputs, dir string, gameDepth uint64) *CannonTraceProvider {
return &CannonTraceProvider{ return &CannonTraceProvider{
logger: logger, logger: logger,
......
...@@ -2,28 +2,50 @@ package outputs ...@@ -2,28 +2,50 @@ package outputs
import ( import (
"context" "context"
"errors" "fmt"
"path/filepath"
"github.com/ethereum-optimism/optimism/op-challenger/config"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/cannon"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/split" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/split"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types"
"github.com/ethereum-optimism/optimism/op-challenger/metrics"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
) )
func NewOutputCannonTraceAccessor(ctx context.Context, logger log.Logger, rollupRpc string, gameDepth uint64, prestateBlock uint64, poststateBlock uint64) (*trace.Accessor, error) { func NewOutputCannonTraceAccessor(
topDepth := gameDepth / 2 // TODO(client-pod#43): Load this from the contract ctx context.Context,
outputProvider, err := NewTraceProvider(ctx, logger, rollupRpc, topDepth, prestateBlock, poststateBlock) logger log.Logger,
m metrics.Metricer,
cfg *config.Config,
contract *contracts.FaultDisputeGameContract,
dir string,
gameDepth uint64,
prestateBlock uint64,
poststateBlock uint64,
) (*trace.Accessor, error) {
// TODO(client-pod#43): Load depths from the contract
topDepth := gameDepth / 2
bottomDepth := gameDepth - topDepth
outputProvider, err := NewTraceProvider(ctx, logger, cfg.RollupRpc, topDepth, prestateBlock, poststateBlock)
if err != nil { if err != nil {
return nil, err return nil, err
} }
cannonCreator := func(ctx context.Context, localContext common.Hash, agreed contracts.Proposal, claimed contracts.Proposal) (types.TraceProvider, error) { cannonCreator := func(ctx context.Context, localContext common.Hash, agreed contracts.Proposal, claimed contracts.Proposal) (types.TraceProvider, error) {
// TODO(client-pod#43): Actually create the cannon trace provider for the trace between the given claims. logger := logger.New("pre", agreed.OutputRoot, "post", claimed.OutputRoot, "localContext", localContext)
return nil, errors.New("not implemented") subdir := filepath.Join(dir, localContext.Hex())
provider, err := cannon.NewTraceProviderFromProposals(ctx, logger, m, cfg, contract, localContext, agreed, claimed, subdir, bottomDepth)
if err != nil {
return nil, fmt.Errorf("failed to create cannon trace provider: %w", err)
}
return provider, nil
} }
selector := split.NewSplitProviderSelector(outputProvider, int(topDepth), OutputRootSplitAdapter(outputProvider, cannonCreator)) cache := NewProviderCache(m, "output_cannon_provider", cannonCreator)
selector := split.NewSplitProviderSelector(outputProvider, int(topDepth), OutputRootSplitAdapter(outputProvider, cache.GetOrCreate))
return trace.NewAccessor(selector), nil return trace.NewAccessor(selector), nil
} }
package outputs
import (
"context"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/types"
"github.com/ethereum-optimism/optimism/op-service/sources/caching"
"github.com/ethereum/go-ethereum/common"
)
type ProviderCache struct {
cache *caching.LRUCache[common.Hash, types.TraceProvider]
creator ProposalTraceProviderCreator
}
func (c *ProviderCache) GetOrCreate(ctx context.Context, localContext common.Hash, agreed contracts.Proposal, claimed contracts.Proposal) (types.TraceProvider, error) {
provider, ok := c.cache.Get(localContext)
if ok {
return provider, nil
}
provider, err := c.creator(ctx, localContext, agreed, claimed)
if err != nil {
return nil, err
}
c.cache.Add(localContext, provider)
return provider, nil
}
func NewProviderCache(m caching.Metrics, metricsLabel string, creator ProposalTraceProviderCreator) *ProviderCache {
cache := caching.NewLRUCache[common.Hash, types.TraceProvider](m, metricsLabel, 100)
return &ProviderCache{
cache: cache,
creator: creator,
}
}
package outputs
import (
"context"
"errors"
"math/big"
"testing"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/alphabet"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/types"
"github.com/ethereum-optimism/optimism/op-challenger/metrics"
"github.com/ethereum/go-ethereum/common"
"github.com/stretchr/testify/require"
)
func TestProviderCache(t *testing.T) {
agreed := contracts.Proposal{
L2BlockNumber: big.NewInt(34),
OutputRoot: common.Hash{0xaa},
}
claimed := contracts.Proposal{
L2BlockNumber: big.NewInt(35),
OutputRoot: common.Hash{0xcc},
}
var createdProvider types.TraceProvider
creator := func(ctx context.Context, localContext common.Hash, agreed contracts.Proposal, claimed contracts.Proposal) (types.TraceProvider, error) {
createdProvider = alphabet.NewTraceProvider("abcdef", 6)
return createdProvider, nil
}
localContext1 := common.Hash{0xdd}
localContext2 := common.Hash{0xee}
cache := NewProviderCache(metrics.NoopMetrics, "test", creator)
// Create on first call
provider1, err := cache.GetOrCreate(context.Background(), localContext1, agreed, claimed)
require.NoError(t, err)
require.Same(t, createdProvider, provider1, "should return created trace provider")
// Return the cached provider on subsequent calls.
createdProvider = nil
cached, err := cache.GetOrCreate(context.Background(), localContext1, agreed, claimed)
require.NoError(t, err)
require.Same(t, provider1, cached, "should return exactly the same instance from cache")
require.Nil(t, createdProvider)
// Create a new provider when the local context is different
createdProvider = nil
otherProvider, err := cache.GetOrCreate(context.Background(), localContext2, agreed, claimed)
require.NoError(t, err)
require.Same(t, otherProvider, createdProvider, "should return newly created trace provider")
require.NotSame(t, otherProvider, provider1, "should not use cached provider for different local context")
}
func TestProviderCache_DoNotCacheErrors(t *testing.T) {
callCount := 0
providerErr := errors.New("boom")
creator := func(ctx context.Context, localContext common.Hash, agreed contracts.Proposal, claimed contracts.Proposal) (types.TraceProvider, error) {
callCount++
return nil, providerErr
}
localContext1 := common.Hash{0xdd}
cache := NewProviderCache(metrics.NoopMetrics, "test", creator)
provider, err := cache.GetOrCreate(context.Background(), localContext1, contracts.Proposal{}, contracts.Proposal{})
require.Nil(t, provider)
require.ErrorIs(t, err, providerErr)
require.Equal(t, 1, callCount)
// Should call the creator again on the second attempt
provider, err = cache.GetOrCreate(context.Background(), localContext1, contracts.Proposal{}, contracts.Proposal{})
require.Nil(t, provider)
require.ErrorIs(t, err, providerErr)
require.Equal(t, 2, callCount)
}
...@@ -4,6 +4,7 @@ import ( ...@@ -4,6 +4,7 @@ import (
"context" "context"
"errors" "errors"
"fmt" "fmt"
"sync"
"time" "time"
"github.com/ethereum-optimism/optimism/op-challenger/game/scheduler" "github.com/ethereum-optimism/optimism/op-challenger/game/scheduler"
...@@ -39,6 +40,7 @@ type gameMonitor struct { ...@@ -39,6 +40,7 @@ type gameMonitor struct {
allowedGames []common.Address allowedGames []common.Address
l1HeadsSub ethereum.Subscription l1HeadsSub ethereum.Subscription
l1Source *headSource l1Source *headSource
runState sync.Mutex
} }
type MinimalSubscriber interface { type MinimalSubscriber interface {
...@@ -126,8 +128,10 @@ func (m *gameMonitor) onNewL1Head(ctx context.Context, sig eth.L1BlockRef) { ...@@ -126,8 +128,10 @@ func (m *gameMonitor) onNewL1Head(ctx context.Context, sig eth.L1BlockRef) {
} }
} }
func (m *gameMonitor) resubscribeFunction(ctx context.Context) event.ResubscribeErrFunc { func (m *gameMonitor) resubscribeFunction() event.ResubscribeErrFunc {
return func(innerCtx context.Context, err error) (event.Subscription, error) { // The ctx is cancelled as soon as the subscription is returned,
// but is only used to create the subscription, and does not affect the returned subscription.
return func(ctx context.Context, err error) (event.Subscription, error) {
if err != nil { if err != nil {
m.logger.Warn("resubscribing after failed L1 subscription", "err", err) m.logger.Warn("resubscribing after failed L1 subscription", "err", err)
} }
...@@ -135,18 +139,21 @@ func (m *gameMonitor) resubscribeFunction(ctx context.Context) event.Resubscribe ...@@ -135,18 +139,21 @@ func (m *gameMonitor) resubscribeFunction(ctx context.Context) event.Resubscribe
} }
} }
func (m *gameMonitor) MonitorGames(ctx context.Context) error { func (m *gameMonitor) StartMonitoring() {
m.l1HeadsSub = event.ResubscribeErr(time.Second*10, m.resubscribeFunction(ctx)) m.runState.Lock()
for { defer m.runState.Unlock()
select { if m.l1HeadsSub != nil {
case <-ctx.Done(): return // already started
m.l1HeadsSub.Unsubscribe() }
return nil m.l1HeadsSub = event.ResubscribeErr(time.Second*10, m.resubscribeFunction())
case err, ok := <-m.l1HeadsSub.Err(): }
if !ok {
return err func (m *gameMonitor) StopMonitoring() {
} m.runState.Lock()
m.logger.Error("L1 subscription error", "err", err) defer m.runState.Unlock()
} if m.l1HeadsSub == nil {
return // already stopped
} }
m.l1HeadsSub.Unsubscribe()
m.l1HeadsSub = nil
} }
...@@ -84,8 +84,9 @@ func TestMonitorGames(t *testing.T) { ...@@ -84,8 +84,9 @@ func TestMonitorGames(t *testing.T) {
cancel() cancel()
}() }()
err := monitor.MonitorGames(ctx) monitor.StartMonitoring()
require.NoError(t, err) <-ctx.Done()
monitor.StopMonitoring()
require.Len(t, sched.scheduled, 1) require.Len(t, sched.scheduled, 1)
require.Equal(t, []common.Address{addr1, addr2}, sched.scheduled[0]) require.Equal(t, []common.Address{addr1, addr2}, sched.scheduled[0])
}) })
...@@ -129,8 +130,9 @@ func TestMonitorGames(t *testing.T) { ...@@ -129,8 +130,9 @@ func TestMonitorGames(t *testing.T) {
cancel() cancel()
}() }()
err := monitor.MonitorGames(ctx) monitor.StartMonitoring()
require.NoError(t, err) <-ctx.Done()
monitor.StopMonitoring()
require.NotEmpty(t, sched.scheduled) // We might get more than one update scheduled. require.NotEmpty(t, sched.scheduled) // We might get more than one update scheduled.
require.Equal(t, []common.Address{addr1, addr2}, sched.scheduled[0]) require.Equal(t, []common.Address{addr1, addr2}, sched.scheduled[0])
}) })
......
...@@ -4,6 +4,11 @@ import ( ...@@ -4,6 +4,11 @@ import (
"context" "context"
"errors" "errors"
"fmt" "fmt"
"io"
"sync/atomic"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum-optimism/optimism/op-challenger/config" "github.com/ethereum-optimism/optimism/op-challenger/config"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault" "github.com/ethereum-optimism/optimism/op-challenger/game/fault"
...@@ -13,14 +18,14 @@ import ( ...@@ -13,14 +18,14 @@ import (
"github.com/ethereum-optimism/optimism/op-challenger/game/scheduler" "github.com/ethereum-optimism/optimism/op-challenger/game/scheduler"
"github.com/ethereum-optimism/optimism/op-challenger/metrics" "github.com/ethereum-optimism/optimism/op-challenger/metrics"
"github.com/ethereum-optimism/optimism/op-challenger/version" "github.com/ethereum-optimism/optimism/op-challenger/version"
opClient "github.com/ethereum-optimism/optimism/op-service/client" "github.com/ethereum-optimism/optimism/op-service/client"
"github.com/ethereum-optimism/optimism/op-service/clock" "github.com/ethereum-optimism/optimism/op-service/clock"
"github.com/ethereum-optimism/optimism/op-service/dial" "github.com/ethereum-optimism/optimism/op-service/dial"
"github.com/ethereum-optimism/optimism/op-service/httputil" "github.com/ethereum-optimism/optimism/op-service/httputil"
opmetrics "github.com/ethereum-optimism/optimism/op-service/metrics"
oppprof "github.com/ethereum-optimism/optimism/op-service/pprof" oppprof "github.com/ethereum-optimism/optimism/op-service/pprof"
"github.com/ethereum-optimism/optimism/op-service/sources/batching" "github.com/ethereum-optimism/optimism/op-service/sources/batching"
"github.com/ethereum-optimism/optimism/op-service/txmgr" "github.com/ethereum-optimism/optimism/op-service/txmgr"
"github.com/ethereum/go-ethereum/log"
) )
type Service struct { type Service struct {
...@@ -29,101 +34,196 @@ type Service struct { ...@@ -29,101 +34,196 @@ type Service struct {
monitor *gameMonitor monitor *gameMonitor
sched *scheduler.Scheduler sched *scheduler.Scheduler
txMgr *txmgr.SimpleTxManager
loader *loader.GameLoader
l1Client *ethclient.Client
pollClient client.RPC
pprofSrv *httputil.HTTPServer pprofSrv *httputil.HTTPServer
metricsSrv *httputil.HTTPServer metricsSrv *httputil.HTTPServer
balanceMetricer io.Closer
stopped atomic.Bool
} }
func (s *Service) Stop(ctx context.Context) error { // NewService creates a new Service.
var result error func NewService(ctx context.Context, logger log.Logger, cfg *config.Config) (*Service, error) {
if s.sched != nil { s := &Service{
result = errors.Join(result, s.sched.Close()) logger: logger,
metrics: metrics.NewMetrics(),
} }
if s.pprofSrv != nil {
result = errors.Join(result, s.pprofSrv.Stop(ctx)) if err := s.initFromConfig(ctx, cfg); err != nil {
// upon initialization error we can try to close any of the service components that may have started already.
return nil, errors.Join(fmt.Errorf("failed to init challenger game service: %w", err), s.Stop(ctx))
} }
if s.metricsSrv != nil {
result = errors.Join(result, s.metricsSrv.Stop(ctx)) return s, nil
}
func (s *Service) initFromConfig(ctx context.Context, cfg *config.Config) error {
if err := s.initTxManager(cfg); err != nil {
return err
} }
return result if err := s.initL1Client(ctx, cfg); err != nil {
return err
}
if err := s.initPollClient(ctx, cfg); err != nil {
return err
}
if err := s.initPProfServer(&cfg.PprofConfig); err != nil {
return err
}
if err := s.initMetricsServer(&cfg.MetricsConfig); err != nil {
return err
}
if err := s.initGameLoader(cfg); err != nil {
return err
}
s.initScheduler(ctx, cfg)
s.initMonitor(cfg)
s.metrics.RecordInfo(version.SimpleWithMeta)
s.metrics.RecordUp()
return nil
} }
// NewService creates a new Service. func (s *Service) initTxManager(cfg *config.Config) error {
func NewService(ctx context.Context, logger log.Logger, cfg *config.Config) (*Service, error) { txMgr, err := txmgr.NewSimpleTxManager("challenger", s.logger, s.metrics, cfg.TxMgrConfig)
cl := clock.SystemClock
m := metrics.NewMetrics()
txMgr, err := txmgr.NewSimpleTxManager("challenger", logger, &m.TxMetrics, cfg.TxMgrConfig)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to create the transaction manager: %w", err) return fmt.Errorf("failed to create the transaction manager: %w", err)
} }
s.txMgr = txMgr
return nil
}
l1Client, err := dial.DialEthClientWithTimeout(ctx, dial.DefaultDialTimeout, logger, cfg.L1EthRpc) func (s *Service) initL1Client(ctx context.Context, cfg *config.Config) error {
l1Client, err := dial.DialEthClientWithTimeout(ctx, dial.DefaultDialTimeout, s.logger, cfg.L1EthRpc)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to dial L1: %w", err) return fmt.Errorf("failed to dial L1: %w", err)
} }
s.l1Client = l1Client
return nil
}
s := &Service{ func (s *Service) initPollClient(ctx context.Context, cfg *config.Config) error {
logger: logger, pollClient, err := client.NewRPCWithClient(ctx, s.logger, cfg.L1EthRpc, client.NewBaseRPCClient(s.l1Client.Client()), cfg.PollInterval)
metrics: m, if err != nil {
return fmt.Errorf("failed to create RPC client: %w", err)
} }
s.pollClient = pollClient
return nil
}
pprofConfig := cfg.PprofConfig func (s *Service) initPProfServer(cfg *oppprof.CLIConfig) error {
if pprofConfig.Enabled { if !cfg.Enabled {
logger.Debug("starting pprof", "addr", pprofConfig.ListenAddr, "port", pprofConfig.ListenPort) return nil
pprofSrv, err := oppprof.StartServer(pprofConfig.ListenAddr, pprofConfig.ListenPort)
if err != nil {
return nil, errors.Join(fmt.Errorf("failed to start pprof server: %w", err), s.Stop(ctx))
}
s.pprofSrv = pprofSrv
logger.Info("started pprof server", "addr", pprofSrv.Addr())
} }
s.logger.Debug("starting pprof", "addr", cfg.ListenAddr, "port", cfg.ListenPort)
pprofSrv, err := oppprof.StartServer(cfg.ListenAddr, cfg.ListenPort)
if err != nil {
return fmt.Errorf("failed to start pprof server: %w", err)
}
s.pprofSrv = pprofSrv
s.logger.Info("started pprof server", "addr", pprofSrv.Addr())
return nil
}
metricsCfg := cfg.MetricsConfig func (s *Service) initMetricsServer(cfg *opmetrics.CLIConfig) error {
if metricsCfg.Enabled { if !cfg.Enabled {
logger.Debug("starting metrics server", "addr", metricsCfg.ListenAddr, "port", metricsCfg.ListenPort) return nil
metricsSrv, err := m.Start(metricsCfg.ListenAddr, metricsCfg.ListenPort) }
if err != nil { s.logger.Debug("starting metrics server", "addr", cfg.ListenAddr, "port", cfg.ListenPort)
return nil, errors.Join(fmt.Errorf("failed to start metrics server: %w", err), s.Stop(ctx)) m, ok := s.metrics.(opmetrics.RegistryMetricer)
} if !ok {
logger.Info("started metrics server", "addr", metricsSrv.Addr()) return fmt.Errorf("metrics were enabled, but metricer %T does not expose registry for metrics-server", s.metrics)
s.metricsSrv = metricsSrv
m.StartBalanceMetrics(ctx, logger, l1Client, txMgr.From())
} }
metricsSrv, err := opmetrics.StartServer(m.Registry(), cfg.ListenAddr, cfg.ListenPort)
if err != nil {
return fmt.Errorf("failed to start metrics server: %w", err)
}
s.logger.Info("started metrics server", "addr", metricsSrv.Addr())
s.metricsSrv = metricsSrv
s.balanceMetricer = s.metrics.StartBalanceMetrics(s.logger, s.l1Client, s.txMgr.From())
return nil
}
factoryContract, err := contracts.NewDisputeGameFactoryContract(cfg.GameFactoryAddress, batching.NewMultiCaller(l1Client.Client(), batching.DefaultBatchSize)) func (s *Service) initGameLoader(cfg *config.Config) error {
factoryContract, err := contracts.NewDisputeGameFactoryContract(cfg.GameFactoryAddress,
batching.NewMultiCaller(s.l1Client.Client(), batching.DefaultBatchSize))
if err != nil { if err != nil {
return nil, errors.Join(fmt.Errorf("failed to bind the fault dispute game factory contract: %w", err), s.Stop(ctx)) return fmt.Errorf("failed to bind the fault dispute game factory contract: %w", err)
} }
loader := loader.NewGameLoader(factoryContract) s.loader = loader.NewGameLoader(factoryContract)
return nil
}
func (s *Service) initScheduler(ctx context.Context, cfg *config.Config) {
gameTypeRegistry := registry.NewGameTypeRegistry() gameTypeRegistry := registry.NewGameTypeRegistry()
fault.RegisterGameTypes(gameTypeRegistry, ctx, logger, m, cfg, txMgr, l1Client) fault.RegisterGameTypes(gameTypeRegistry, ctx, s.logger, s.metrics, cfg, s.txMgr, s.l1Client)
disk := newDiskManager(cfg.Datadir) disk := newDiskManager(cfg.Datadir)
s.sched = scheduler.NewScheduler( s.sched = scheduler.NewScheduler(s.logger, s.metrics, disk, cfg.MaxConcurrency, gameTypeRegistry.CreatePlayer)
logger, }
m,
disk,
cfg.MaxConcurrency,
gameTypeRegistry.CreatePlayer)
pollClient, err := opClient.NewRPCWithClient(ctx, logger, cfg.L1EthRpc, opClient.NewBaseRPCClient(l1Client.Client()), cfg.PollInterval)
if err != nil {
return nil, errors.Join(fmt.Errorf("failed to create RPC client: %w", err), s.Stop(ctx))
}
s.monitor = newGameMonitor(logger, cl, loader, s.sched, cfg.GameWindow, l1Client.BlockNumber, cfg.GameAllowlist, pollClient)
m.RecordInfo(version.SimpleWithMeta)
m.RecordUp()
return s, nil func (s *Service) initMonitor(cfg *config.Config) {
cl := clock.SystemClock
s.monitor = newGameMonitor(s.logger, cl, s.loader, s.sched, cfg.GameWindow, s.l1Client.BlockNumber, cfg.GameAllowlist, s.pollClient)
} }
// MonitorGame monitors the fault dispute game and attempts to progress it. func (s *Service) Start(ctx context.Context) error {
func (s *Service) MonitorGame(ctx context.Context) error { s.logger.Info("starting scheduler")
s.sched.Start(ctx) s.sched.Start(ctx)
err := s.monitor.MonitorGames(ctx) s.logger.Info("starting monitoring")
// The other ctx is the close-trigger. s.monitor.StartMonitoring()
// We need to refactor Service more to allow for graceful/force-shutdown granularity. s.logger.Info("challenger game service start completed")
err = errors.Join(err, s.Stop(context.Background())) return nil
return err }
func (s *Service) Stopped() bool {
return s.stopped.Load()
}
func (s *Service) Stop(ctx context.Context) error {
s.logger.Info("stopping challenger game service")
var result error
if s.sched != nil {
if err := s.sched.Close(); err != nil {
result = errors.Join(result, fmt.Errorf("failed to close scheduler: %w", err))
}
}
if s.monitor != nil {
s.monitor.StopMonitoring()
}
if s.pprofSrv != nil {
if err := s.pprofSrv.Stop(ctx); err != nil {
result = errors.Join(result, fmt.Errorf("failed to close pprof server: %w", err))
}
}
if s.balanceMetricer != nil {
if err := s.balanceMetricer.Close(); err != nil {
result = errors.Join(result, fmt.Errorf("failed to close balance metricer: %w", err))
}
}
if s.txMgr != nil {
s.txMgr.Close()
}
if s.l1Client != nil {
s.l1Client.Close()
}
if s.metricsSrv != nil {
if err := s.metricsSrv.Stop(ctx); err != nil {
result = errors.Join(result, fmt.Errorf("failed to close metrics server: %w", err))
}
}
s.stopped.Store(true)
s.logger.Info("stopped challenger game service", "err", result)
return result
} }
package metrics package metrics
import ( import (
"context" "io"
"github.com/ethereum-optimism/optimism/op-service/sources/caching"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/ethclient" "github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
...@@ -19,9 +20,14 @@ type Metricer interface { ...@@ -19,9 +20,14 @@ type Metricer interface {
RecordInfo(version string) RecordInfo(version string)
RecordUp() RecordUp()
StartBalanceMetrics(l log.Logger, client *ethclient.Client, account common.Address) io.Closer
// Record Tx metrics // Record Tx metrics
txmetrics.TxMetricer txmetrics.TxMetricer
// Record cache metrics
caching.Metrics
RecordGameStep() RecordGameStep()
RecordGameMove() RecordGameMove()
RecordCannonExecutionTime(t float64) RecordCannonExecutionTime(t float64)
...@@ -44,6 +50,8 @@ type Metrics struct { ...@@ -44,6 +50,8 @@ type Metrics struct {
txmetrics.TxMetrics txmetrics.TxMetrics
*opmetrics.CacheMetrics
info prometheus.GaugeVec info prometheus.GaugeVec
up prometheus.Gauge up prometheus.Gauge
...@@ -71,6 +79,8 @@ func NewMetrics() *Metrics { ...@@ -71,6 +79,8 @@ func NewMetrics() *Metrics {
TxMetrics: txmetrics.MakeTxMetrics(Namespace, factory), TxMetrics: txmetrics.MakeTxMetrics(Namespace, factory),
CacheMetrics: opmetrics.NewCacheMetrics(factory, Namespace, "provider_cache", "Provider cache"),
info: *factory.NewGaugeVec(prometheus.GaugeOpts{ info: *factory.NewGaugeVec(prometheus.GaugeOpts{
Namespace: Namespace, Namespace: Namespace,
Name: "info", Name: "info",
...@@ -128,17 +138,11 @@ func (m *Metrics) Start(host string, port int) (*httputil.HTTPServer, error) { ...@@ -128,17 +138,11 @@ func (m *Metrics) Start(host string, port int) (*httputil.HTTPServer, error) {
} }
func (m *Metrics) StartBalanceMetrics( func (m *Metrics) StartBalanceMetrics(
ctx context.Context,
l log.Logger, l log.Logger,
client *ethclient.Client, client *ethclient.Client,
account common.Address, account common.Address,
) { ) io.Closer {
// TODO(7684): util was refactored to close, but ctx is still being used by caller for shutdown return opmetrics.LaunchBalanceMetrics(l, m.registry, m.ns, client, account)
balanceMetric := opmetrics.LaunchBalanceMetrics(l, m.registry, m.ns, client, account)
go func() {
<-ctx.Done()
_ = balanceMetric.Close()
}()
} }
// RecordInfo sets a pseudo-metric that contains versioning and // RecordInfo sets a pseudo-metric that contains versioning and
......
package metrics package metrics
import ( import (
"io"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/log"
txmetrics "github.com/ethereum-optimism/optimism/op-service/txmgr/metrics" txmetrics "github.com/ethereum-optimism/optimism/op-service/txmgr/metrics"
) )
...@@ -8,6 +14,10 @@ type NoopMetricsImpl struct { ...@@ -8,6 +14,10 @@ type NoopMetricsImpl struct {
txmetrics.NoopTxMetrics txmetrics.NoopTxMetrics
} }
func (i *NoopMetricsImpl) StartBalanceMetrics(l log.Logger, client *ethclient.Client, account common.Address) io.Closer {
return nil
}
var NoopMetrics Metricer = new(NoopMetricsImpl) var NoopMetrics Metricer = new(NoopMetricsImpl)
func (*NoopMetricsImpl) RecordInfo(version string) {} func (*NoopMetricsImpl) RecordInfo(version string) {}
...@@ -27,3 +37,6 @@ func (*NoopMetricsImpl) IncActiveExecutors() {} ...@@ -27,3 +37,6 @@ func (*NoopMetricsImpl) IncActiveExecutors() {}
func (*NoopMetricsImpl) DecActiveExecutors() {} func (*NoopMetricsImpl) DecActiveExecutors() {}
func (*NoopMetricsImpl) IncIdleExecutors() {} func (*NoopMetricsImpl) IncIdleExecutors() {}
func (*NoopMetricsImpl) DecIdleExecutors() {} func (*NoopMetricsImpl) DecIdleExecutors() {}
func (*NoopMetricsImpl) CacheAdd(_ string, _ int, _ bool) {}
func (*NoopMetricsImpl) CacheGet(_ string, _ bool) {}
...@@ -54,6 +54,8 @@ func (f fakeTxMgr) BlockNumber(_ context.Context) (uint64, error) { ...@@ -54,6 +54,8 @@ func (f fakeTxMgr) BlockNumber(_ context.Context) (uint64, error) {
func (f fakeTxMgr) Send(_ context.Context, _ txmgr.TxCandidate) (*types.Receipt, error) { func (f fakeTxMgr) Send(_ context.Context, _ txmgr.TxCandidate) (*types.Receipt, error) {
panic("unimplemented") panic("unimplemented")
} }
func (f fakeTxMgr) Close() {
}
func NewL2Proposer(t Testing, log log.Logger, cfg *ProposerCfg, l1 *ethclient.Client, rollupCl *sources.RollupClient) *L2Proposer { func NewL2Proposer(t Testing, log log.Logger, cfg *ProposerCfg, l1 *ethclient.Client, rollupCl *sources.RollupClient) *L2Proposer {
proposerConfig := proposer.ProposerConfig{ proposerConfig := proposer.ProposerConfig{
......
...@@ -11,16 +11,19 @@ import ( ...@@ -11,16 +11,19 @@ import (
"testing" "testing"
"time" "time"
op_challenger "github.com/ethereum-optimism/optimism/op-challenger" "github.com/stretchr/testify/require"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/log"
challenger "github.com/ethereum-optimism/optimism/op-challenger"
"github.com/ethereum-optimism/optimism/op-challenger/config" "github.com/ethereum-optimism/optimism/op-challenger/config"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait"
"github.com/ethereum-optimism/optimism/op-node/rollup" "github.com/ethereum-optimism/optimism/op-node/rollup"
"github.com/ethereum-optimism/optimism/op-service/cliapp"
"github.com/ethereum-optimism/optimism/op-service/testlog" "github.com/ethereum-optimism/optimism/op-service/testlog"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/log"
"github.com/stretchr/testify/require"
) )
type Helper struct { type Helper struct {
...@@ -28,8 +31,7 @@ type Helper struct { ...@@ -28,8 +31,7 @@ type Helper struct {
t *testing.T t *testing.T
require *require.Assertions require *require.Assertions
dir string dir string
cancel func() chl cliapp.Lifecycle
errors chan error
} }
type Option func(config2 *config.Config) type Option func(config2 *config.Config)
...@@ -127,20 +129,16 @@ func NewChallenger(t *testing.T, ctx context.Context, l1Endpoint string, name st ...@@ -127,20 +129,16 @@ func NewChallenger(t *testing.T, ctx context.Context, l1Endpoint string, name st
log := testlog.Logger(t, log.LvlDebug).New("role", name) log := testlog.Logger(t, log.LvlDebug).New("role", name)
log.Info("Creating challenger", "l1", l1Endpoint) log.Info("Creating challenger", "l1", l1Endpoint)
cfg := NewChallengerConfig(t, l1Endpoint, options...) cfg := NewChallengerConfig(t, l1Endpoint, options...)
chl, err := challenger.Main(ctx, log, cfg)
require.NoError(t, err, "must init challenger")
require.NoError(t, chl.Start(ctx), "must start challenger")
errCh := make(chan error, 1)
ctx, cancel := context.WithCancel(ctx)
go func() {
defer close(errCh)
errCh <- op_challenger.Main(ctx, log, cfg)
}()
return &Helper{ return &Helper{
log: log, log: log,
t: t, t: t,
require: require.New(t), require: require.New(t),
dir: cfg.Datadir, dir: cfg.Datadir,
cancel: cancel, chl: chl,
errors: errCh,
} }
} }
...@@ -179,16 +177,9 @@ func NewChallengerConfig(t *testing.T, l1Endpoint string, options ...Option) *co ...@@ -179,16 +177,9 @@ func NewChallengerConfig(t *testing.T, l1Endpoint string, options ...Option) *co
} }
func (h *Helper) Close() error { func (h *Helper) Close() error {
h.cancel() ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
select { defer cancel()
case <-time.After(1 * time.Minute): return h.chl.Stop(ctx)
return errors.New("timed out while stopping challenger")
case err := <-h.errors:
if !errors.Is(err, context.Canceled) {
return err
}
return nil
}
} }
type GameAddr interface { type GameAddr interface {
......
...@@ -12,6 +12,7 @@ import ( ...@@ -12,6 +12,7 @@ import (
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethclient" "github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/rpc"
) )
var ( var (
...@@ -80,7 +81,6 @@ func WaitForTransaction(hash common.Hash, client *ethclient.Client, timeout time ...@@ -80,7 +81,6 @@ func WaitForTransaction(hash common.Hash, client *ethclient.Client, timeout time
} }
func WaitForBlock(number *big.Int, client *ethclient.Client, timeout time.Duration) (*types.Block, error) { func WaitForBlock(number *big.Int, client *ethclient.Client, timeout time.Duration) (*types.Block, error) {
timeoutCh := time.After(timeout)
ctx, cancel := context.WithTimeout(context.Background(), timeout) ctx, cancel := context.WithTimeout(context.Background(), timeout)
defer cancel() defer cancel()
...@@ -99,8 +99,43 @@ func WaitForBlock(number *big.Int, client *ethclient.Client, timeout time.Durati ...@@ -99,8 +99,43 @@ func WaitForBlock(number *big.Int, client *ethclient.Client, timeout time.Durati
} }
case err := <-headSub.Err(): case err := <-headSub.Err():
return nil, fmt.Errorf("error in head subscription: %w", err) return nil, fmt.Errorf("error in head subscription: %w", err)
case <-timeoutCh: case <-ctx.Done():
return nil, errTimeout return nil, ctx.Err()
}
}
}
func WaitForBlockToBeFinalized(number *big.Int, client *ethclient.Client, timeout time.Duration) (*types.Block, error) {
return waitForBlockTag(number, client, timeout, rpc.FinalizedBlockNumber)
}
func WaitForBlockToBeSafe(number *big.Int, client *ethclient.Client, timeout time.Duration) (*types.Block, error) {
return waitForBlockTag(number, client, timeout, rpc.SafeBlockNumber)
}
// waitForBlockTag polls for a block number to reach the specified tag & then returns that block at the number.
func waitForBlockTag(number *big.Int, client *ethclient.Client, timeout time.Duration, tag rpc.BlockNumber) (*types.Block, error) {
ctx, cancel := context.WithTimeout(context.Background(), timeout)
defer cancel()
// Wait for it to be finalized. Poll every half second.
ticker := time.NewTicker(500 * time.Millisecond)
defer ticker.Stop()
tagBigInt := big.NewInt(tag.Int64())
for {
select {
case <-ticker.C:
block, err := client.BlockByNumber(ctx, tagBigInt)
if err != nil {
return nil, err
}
if block != nil && block.NumberU64() >= number.Uint64() {
return client.BlockByNumber(ctx, number)
}
case <-ctx.Done():
return nil, ctx.Err()
} }
} }
} }
...@@ -368,17 +368,8 @@ func TestFinalize(t *testing.T) { ...@@ -368,17 +368,8 @@ func TestFinalize(t *testing.T) {
l2Seq := sys.Clients["sequencer"] l2Seq := sys.Clients["sequencer"]
// as configured in the extra geth lifecycle in testing setup l2Finalized, err := geth.WaitForBlockToBeFinalized(big.NewInt(12), l2Seq, 1*time.Minute)
const finalizedDistance = 8 require.NoError(t, err, "must be able to fetch a finalized L2 block")
// Wait enough time for L1 to finalize and L2 to confirm its data in finalized L1 blocks
time.Sleep(time.Duration((finalizedDistance+6)*cfg.DeployConfig.L1BlockTime) * time.Second)
// fetch the finalizes head of geth
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
defer cancel()
l2Finalized, err := l2Seq.BlockByNumber(ctx, big.NewInt(int64(rpc.FinalizedBlockNumber)))
require.NoError(t, err)
require.NotZerof(t, l2Finalized.NumberU64(), "must have finalized L2 block") require.NotZerof(t, l2Finalized.NumberU64(), "must have finalized L2 block")
} }
......
...@@ -174,7 +174,7 @@ func (n *OpNode) initL1(ctx context.Context, cfg *Config) error { ...@@ -174,7 +174,7 @@ func (n *OpNode) initL1(ctx context.Context, cfg *Config) error {
if err != nil { if err != nil {
n.log.Warn("resubscribing after failed L1 subscription", "err", err) n.log.Warn("resubscribing after failed L1 subscription", "err", err)
} }
return eth.WatchHeadChanges(n.resourcesCtx, n.l1Source, n.OnNewL1Head) return eth.WatchHeadChanges(ctx, n.l1Source, n.OnNewL1Head)
}) })
go func() { go func() {
err, ok := <-n.l1HeadsSub.Err() err, ok := <-n.l1HeadsSub.Err()
...@@ -186,9 +186,9 @@ func (n *OpNode) initL1(ctx context.Context, cfg *Config) error { ...@@ -186,9 +186,9 @@ func (n *OpNode) initL1(ctx context.Context, cfg *Config) error {
// Poll for the safe L1 block and finalized block, // Poll for the safe L1 block and finalized block,
// which only change once per epoch at most and may be delayed. // which only change once per epoch at most and may be delayed.
n.l1SafeSub = eth.PollBlockChanges(n.resourcesCtx, n.log, n.l1Source, n.OnNewL1Safe, eth.Safe, n.l1SafeSub = eth.PollBlockChanges(n.log, n.l1Source, n.OnNewL1Safe, eth.Safe,
cfg.L1EpochPollInterval, time.Second*10) cfg.L1EpochPollInterval, time.Second*10)
n.l1FinalizedSub = eth.PollBlockChanges(n.resourcesCtx, n.log, n.l1Source, n.OnNewL1Finalized, eth.Finalized, n.l1FinalizedSub = eth.PollBlockChanges(n.log, n.l1Source, n.OnNewL1Finalized, eth.Finalized,
cfg.L1EpochPollInterval, time.Second*10) cfg.L1EpochPollInterval, time.Second*10)
return nil return nil
} }
...@@ -582,6 +582,14 @@ func (n *OpNode) Stop(ctx context.Context) error { ...@@ -582,6 +582,14 @@ func (n *OpNode) Stop(ctx context.Context) error {
if n.l1HeadsSub != nil { if n.l1HeadsSub != nil {
n.l1HeadsSub.Unsubscribe() n.l1HeadsSub.Unsubscribe()
} }
// stop polling for L1 safe-head changes
if n.l1SafeSub != nil {
n.l1SafeSub.Unsubscribe()
}
// stop polling for L1 finalized-head changes
if n.l1FinalizedSub != nil {
n.l1FinalizedSub.Unsubscribe()
}
// close L2 driver // close L2 driver
if n.l2Driver != nil { if n.l2Driver != nil {
......
...@@ -94,7 +94,7 @@ func (d *recordsBook[K, V]) dsKey(key K) ds.Key { ...@@ -94,7 +94,7 @@ func (d *recordsBook[K, V]) dsKey(key K) ds.Key {
func (d *recordsBook[K, V]) deleteRecord(key K) error { func (d *recordsBook[K, V]) deleteRecord(key K) error {
d.cache.Remove(key) d.cache.Remove(key)
err := d.store.Delete(d.ctx, d.dsKey(key)) err := d.store.Delete(d.ctx, d.dsKey(key))
if errors.Is(err, ds.ErrNotFound) { if err == nil || errors.Is(err, ds.ErrNotFound) {
return nil return nil
} }
return fmt.Errorf("failed to delete entry with key %v: %w", key, err) return fmt.Errorf("failed to delete entry with key %v: %w", key, err)
......
...@@ -279,6 +279,11 @@ func (ps *ProposerService) Stop(ctx context.Context) error { ...@@ -279,6 +279,11 @@ func (ps *ProposerService) Stop(ctx context.Context) error {
result = errors.Join(result, fmt.Errorf("failed to close balance metricer: %w", err)) result = errors.Join(result, fmt.Errorf("failed to close balance metricer: %w", err))
} }
} }
if ps.TxManager != nil {
ps.TxManager.Close()
}
if ps.metricsSrv != nil { if ps.metricsSrv != nil {
if err := ps.metricsSrv.Stop(ctx); err != nil { if err := ps.metricsSrv.Stop(ctx); err != nil {
result = errors.Join(result, fmt.Errorf("failed to stop metrics server: %w", err)) result = errors.Join(result, fmt.Errorf("failed to stop metrics server: %w", err))
......
...@@ -17,7 +17,8 @@ type NewHeadSource interface { ...@@ -17,7 +17,8 @@ type NewHeadSource interface {
SubscribeNewHead(ctx context.Context, ch chan<- *types.Header) (ethereum.Subscription, error) SubscribeNewHead(ctx context.Context, ch chan<- *types.Header) (ethereum.Subscription, error)
} }
// WatchHeadChanges wraps a new-head subscription from NewHeadSource to feed the given Tracker // WatchHeadChanges wraps a new-head subscription from NewHeadSource to feed the given Tracker.
// The ctx is only used to create the subscription, and does not affect the returned subscription.
func WatchHeadChanges(ctx context.Context, src NewHeadSource, fn HeadSignalFn) (ethereum.Subscription, error) { func WatchHeadChanges(ctx context.Context, src NewHeadSource, fn HeadSignalFn) (ethereum.Subscription, error) {
headChanges := make(chan *types.Header, 10) headChanges := make(chan *types.Header, 10)
sub, err := src.SubscribeNewHead(ctx, headChanges) sub, err := src.SubscribeNewHead(ctx, headChanges)
...@@ -25,22 +26,33 @@ func WatchHeadChanges(ctx context.Context, src NewHeadSource, fn HeadSignalFn) ( ...@@ -25,22 +26,33 @@ func WatchHeadChanges(ctx context.Context, src NewHeadSource, fn HeadSignalFn) (
return nil, err return nil, err
} }
return event.NewSubscription(func(quit <-chan struct{}) error { return event.NewSubscription(func(quit <-chan struct{}) error {
eventsCtx, eventsCancel := context.WithCancel(context.Background())
defer sub.Unsubscribe() defer sub.Unsubscribe()
defer eventsCancel()
// We can handle a quit signal while fn is running, by closing the ctx.
go func() {
select {
case <-quit:
eventsCancel()
case <-eventsCtx.Done(): // don't wait for quit signal if we closed for other reasons.
return
}
}()
for { for {
select { select {
case header := <-headChanges: case header := <-headChanges:
fn(ctx, L1BlockRef{ fn(eventsCtx, L1BlockRef{
Hash: header.Hash(), Hash: header.Hash(),
Number: header.Number.Uint64(), Number: header.Number.Uint64(),
ParentHash: header.ParentHash, ParentHash: header.ParentHash,
Time: header.Time, Time: header.Time,
}) })
case err := <-sub.Err(): case <-eventsCtx.Done():
return err
case <-ctx.Done():
return ctx.Err()
case <-quit:
return nil return nil
case err := <-sub.Err(): // if the underlying subscription fails, stop
return err
} }
} }
}), nil }), nil
...@@ -53,7 +65,7 @@ type L1BlockRefsSource interface { ...@@ -53,7 +65,7 @@ type L1BlockRefsSource interface {
// PollBlockChanges opens a polling loop to fetch the L1 block reference with the given label, // PollBlockChanges opens a polling loop to fetch the L1 block reference with the given label,
// on provided interval and with request timeout. Results are returned with provided callback fn, // on provided interval and with request timeout. Results are returned with provided callback fn,
// which may block to pause/back-pressure polling. // which may block to pause/back-pressure polling.
func PollBlockChanges(ctx context.Context, log log.Logger, src L1BlockRefsSource, fn HeadSignalFn, func PollBlockChanges(log log.Logger, src L1BlockRefsSource, fn HeadSignalFn,
label BlockLabel, interval time.Duration, timeout time.Duration) ethereum.Subscription { label BlockLabel, interval time.Duration, timeout time.Duration) ethereum.Subscription {
return event.NewSubscription(func(quit <-chan struct{}) error { return event.NewSubscription(func(quit <-chan struct{}) error {
if interval <= 0 { if interval <= 0 {
...@@ -61,22 +73,32 @@ func PollBlockChanges(ctx context.Context, log log.Logger, src L1BlockRefsSource ...@@ -61,22 +73,32 @@ func PollBlockChanges(ctx context.Context, log log.Logger, src L1BlockRefsSource
<-quit <-quit
return nil return nil
} }
eventsCtx, eventsCancel := context.WithCancel(context.Background())
defer eventsCancel()
// We can handle a quit signal while fn is running, by closing the ctx.
go func() {
select {
case <-quit:
eventsCancel()
case <-eventsCtx.Done(): // don't wait for quit signal if we closed for other reasons.
return
}
}()
ticker := time.NewTicker(interval) ticker := time.NewTicker(interval)
defer ticker.Stop() defer ticker.Stop()
for { for {
select { select {
case <-ticker.C: case <-ticker.C:
reqCtx, reqCancel := context.WithTimeout(ctx, timeout) reqCtx, reqCancel := context.WithTimeout(eventsCtx, timeout)
ref, err := src.L1BlockRefByLabel(reqCtx, label) ref, err := src.L1BlockRefByLabel(reqCtx, label)
reqCancel() reqCancel()
if err != nil { if err != nil {
log.Warn("failed to poll L1 block", "label", label, "err", err) log.Warn("failed to poll L1 block", "label", label, "err", err)
} else { } else {
fn(ctx, ref) fn(eventsCtx, ref)
} }
case <-ctx.Done(): case <-eventsCtx.Done():
return ctx.Err()
case <-quit:
return nil return nil
} }
} }
......
...@@ -43,6 +43,11 @@ func (_m *TxManager) BlockNumber(ctx context.Context) (uint64, error) { ...@@ -43,6 +43,11 @@ func (_m *TxManager) BlockNumber(ctx context.Context) (uint64, error) {
return r0, r1 return r0, r1
} }
// Close provides a mock function with given fields:
func (_m *TxManager) Close() {
_m.Called()
}
// From provides a mock function with given fields: // From provides a mock function with given fields:
func (_m *TxManager) From() common.Address { func (_m *TxManager) From() common.Address {
ret := _m.Called() ret := _m.Called()
......
...@@ -49,6 +49,9 @@ type TxManager interface { ...@@ -49,6 +49,9 @@ type TxManager interface {
// BlockNumber returns the most recent block number from the underlying network. // BlockNumber returns the most recent block number from the underlying network.
BlockNumber(ctx context.Context) (uint64, error) BlockNumber(ctx context.Context) (uint64, error)
// Close the underlying connection
Close()
} }
// ETHBackend is the set of methods that the transaction manager uses to resubmit gas & determine // ETHBackend is the set of methods that the transaction manager uses to resubmit gas & determine
...@@ -80,6 +83,8 @@ type ETHBackend interface { ...@@ -80,6 +83,8 @@ type ETHBackend interface {
// EstimateGas returns an estimate of the amount of gas needed to execute the given // EstimateGas returns an estimate of the amount of gas needed to execute the given
// transaction against the current pending block. // transaction against the current pending block.
EstimateGas(ctx context.Context, msg ethereum.CallMsg) (uint64, error) EstimateGas(ctx context.Context, msg ethereum.CallMsg) (uint64, error)
// Close the underlying eth connection
Close()
} }
// SimpleTxManager is a implementation of TxManager that performs linear fee // SimpleTxManager is a implementation of TxManager that performs linear fee
...@@ -131,6 +136,10 @@ func (m *SimpleTxManager) BlockNumber(ctx context.Context) (uint64, error) { ...@@ -131,6 +136,10 @@ func (m *SimpleTxManager) BlockNumber(ctx context.Context) (uint64, error) {
return m.backend.BlockNumber(ctx) return m.backend.BlockNumber(ctx)
} }
func (m *SimpleTxManager) Close() {
m.backend.Close()
}
// TxCandidate is a transaction candidate that can be submitted to ask the // TxCandidate is a transaction candidate that can be submitted to ask the
// [TxManager] to construct a transaction with gas price bounds. // [TxManager] to construct a transaction with gas price bounds.
type TxCandidate struct { type TxCandidate struct {
......
...@@ -261,6 +261,9 @@ func (b *mockBackend) TransactionReceipt(ctx context.Context, txHash common.Hash ...@@ -261,6 +261,9 @@ func (b *mockBackend) TransactionReceipt(ctx context.Context, txHash common.Hash
}, nil }, nil
} }
func (b *mockBackend) Close() {
}
// TestTxMgrConfirmAtMinGasPrice asserts that Send returns the min gas price tx // TestTxMgrConfirmAtMinGasPrice asserts that Send returns the min gas price tx
// if the tx is mined instantly. // if the tx is mined instantly.
func TestTxMgrConfirmAtMinGasPrice(t *testing.T) { func TestTxMgrConfirmAtMinGasPrice(t *testing.T) {
...@@ -755,6 +758,9 @@ func (b *failingBackend) ChainID(ctx context.Context) (*big.Int, error) { ...@@ -755,6 +758,9 @@ func (b *failingBackend) ChainID(ctx context.Context) (*big.Int, error) {
return nil, errors.New("unimplemented") return nil, errors.New("unimplemented")
} }
func (b *failingBackend) Close() {
}
// TestWaitMinedReturnsReceiptAfterFailure asserts that WaitMined is able to // TestWaitMinedReturnsReceiptAfterFailure asserts that WaitMined is able to
// recover from failed calls to the backend. It uses the failedBackend to // recover from failed calls to the backend. It uses the failedBackend to
// simulate an rpc call failure, followed by the successful return of a receipt. // simulate an rpc call failure, followed by the successful return of a receipt.
......
# @eth-optimism/drippie-mon # @eth-optimism/drippie-mon
## 0.5.4
### Patch Changes
- Updated dependencies [[`dd0e46986`](https://github.com/ethereum-optimism/optimism/commit/dd0e46986f19dcceb304fc48f2bd410685ecd179)]:
- @eth-optimism/sdk@3.1.6
## 0.5.3 ## 0.5.3
### Patch Changes ### Patch Changes
......
{ {
"private": true, "private": true,
"name": "@eth-optimism/chain-mon", "name": "@eth-optimism/chain-mon",
"version": "0.5.3", "version": "0.5.4",
"description": "[Optimism] Chain monitoring services", "description": "[Optimism] Chain monitoring services",
"main": "dist/index", "main": "dist/index",
"types": "dist/index", "types": "dist/index",
...@@ -63,6 +63,6 @@ ...@@ -63,6 +63,6 @@
"@nomiclabs/hardhat-waffle": "^2.0.6", "@nomiclabs/hardhat-waffle": "^2.0.6",
"hardhat": "^2.19.0", "hardhat": "^2.19.0",
"ts-node": "^10.9.1", "ts-node": "^10.9.1",
"tsx": "^4.1.1" "tsx": "^4.2.0"
} }
} }
...@@ -26,24 +26,24 @@ Bytes_toNibbles_Test:test_toNibbles_expectedResult128Bytes_works() (gas: 78882) ...@@ -26,24 +26,24 @@ Bytes_toNibbles_Test:test_toNibbles_expectedResult128Bytes_works() (gas: 78882)
Bytes_toNibbles_Test:test_toNibbles_expectedResult5Bytes_works() (gas: 3992) Bytes_toNibbles_Test:test_toNibbles_expectedResult5Bytes_works() (gas: 3992)
Bytes_toNibbles_Test:test_toNibbles_zeroLengthInput_works() (gas: 845) Bytes_toNibbles_Test:test_toNibbles_zeroLengthInput_works() (gas: 845)
Constants_Test:test_eip1967Constants_succeeds() (gas: 453) Constants_Test:test_eip1967Constants_succeeds() (gas: 453)
CrossDomainMessenger_BaseGas_Test:test_baseGas_succeeds() (gas: 20458) CrossDomainMessenger_BaseGas_Test:test_baseGas_succeeds() (gas: 20480)
CrossDomainOwnable2_Test:test_onlyOwner_notMessenger_reverts() (gas: 8539) CrossDomainOwnable2_Test:test_onlyOwner_notMessenger_reverts() (gas: 8517)
CrossDomainOwnable2_Test:test_onlyOwner_notOwner2_reverts() (gas: 57518) CrossDomainOwnable2_Test:test_onlyOwner_notOwner2_reverts() (gas: 57583)
CrossDomainOwnable2_Test:test_onlyOwner_notOwner_reverts() (gas: 16655) CrossDomainOwnable2_Test:test_onlyOwner_notOwner_reverts() (gas: 16699)
CrossDomainOwnable2_Test:test_onlyOwner_succeeds() (gas: 73619) CrossDomainOwnable2_Test:test_onlyOwner_succeeds() (gas: 73662)
CrossDomainOwnable3_Test:test_constructor_succeeds() (gas: 10627) CrossDomainOwnable3_Test:test_constructor_succeeds() (gas: 10628)
CrossDomainOwnable3_Test:test_crossDomainOnlyOwner_notMessenger_reverts() (gas: 28363) CrossDomainOwnable3_Test:test_crossDomainOnlyOwner_notMessenger_reverts() (gas: 28341)
CrossDomainOwnable3_Test:test_crossDomainOnlyOwner_notOwner2_reverts() (gas: 74002) CrossDomainOwnable3_Test:test_crossDomainOnlyOwner_notOwner2_reverts() (gas: 74021)
CrossDomainOwnable3_Test:test_crossDomainOnlyOwner_notOwner_reverts() (gas: 32118) CrossDomainOwnable3_Test:test_crossDomainOnlyOwner_notOwner_reverts() (gas: 32096)
CrossDomainOwnable3_Test:test_crossDomainTransferOwnership_succeeds() (gas: 91600) CrossDomainOwnable3_Test:test_crossDomainTransferOwnership_succeeds() (gas: 91578)
CrossDomainOwnable3_Test:test_localOnlyOwner_notOwner_reverts() (gas: 13260) CrossDomainOwnable3_Test:test_localOnlyOwner_notOwner_reverts() (gas: 13238)
CrossDomainOwnable3_Test:test_localOnlyOwner_succeeds() (gas: 35271) CrossDomainOwnable3_Test:test_localOnlyOwner_succeeds() (gas: 35294)
CrossDomainOwnable3_Test:test_localTransferOwnership_succeeds() (gas: 52158) CrossDomainOwnable3_Test:test_localTransferOwnership_succeeds() (gas: 52202)
CrossDomainOwnable3_Test:test_transferOwnershipNoLocal_succeeds() (gas: 48662) CrossDomainOwnable3_Test:test_transferOwnershipNoLocal_succeeds() (gas: 48706)
CrossDomainOwnable3_Test:test_transferOwnership_noLocalZeroAddress_reverts() (gas: 12090) CrossDomainOwnable3_Test:test_transferOwnership_noLocalZeroAddress_reverts() (gas: 12090)
CrossDomainOwnable3_Test:test_transferOwnership_notOwner_reverts() (gas: 13460) CrossDomainOwnable3_Test:test_transferOwnership_notOwner_reverts() (gas: 13460)
CrossDomainOwnable3_Test:test_transferOwnership_zeroAddress_reverts() (gas: 12177) CrossDomainOwnable3_Test:test_transferOwnership_zeroAddress_reverts() (gas: 12155)
CrossDomainOwnableThroughPortal_Test:test_depositTransaction_crossDomainOwner_succeeds() (gas: 81570) CrossDomainOwnableThroughPortal_Test:test_depositTransaction_crossDomainOwner_succeeds() (gas: 81526)
CrossDomainOwnable_Test:test_onlyOwner_notOwner_reverts() (gas: 10597) CrossDomainOwnable_Test:test_onlyOwner_notOwner_reverts() (gas: 10597)
CrossDomainOwnable_Test:test_onlyOwner_succeeds() (gas: 34905) CrossDomainOwnable_Test:test_onlyOwner_succeeds() (gas: 34905)
DelayedVetoable_Getters_Test:test_getters() (gas: 24400) DelayedVetoable_Getters_Test:test_getters() (gas: 24400)
...@@ -51,11 +51,11 @@ DelayedVetoable_Getters_TestFail:test_getters_notZeroAddress_reverts() (gas: 360 ...@@ -51,11 +51,11 @@ DelayedVetoable_Getters_TestFail:test_getters_notZeroAddress_reverts() (gas: 360
DelayedVetoable_HandleCall_TestFail:test_handleCall_unauthorizedInitiation_reverts() (gas: 15172) DelayedVetoable_HandleCall_TestFail:test_handleCall_unauthorizedInitiation_reverts() (gas: 15172)
DeployerWhitelist_Test:test_owner_succeeds() (gas: 7582) DeployerWhitelist_Test:test_owner_succeeds() (gas: 7582)
DeployerWhitelist_Test:test_storageSlots_succeeds() (gas: 33417) DeployerWhitelist_Test:test_storageSlots_succeeds() (gas: 33417)
DisputeGameFactory_Owner_Test:test_owner_succeeds() (gas: 12611) DisputeGameFactory_Owner_Test:test_owner_succeeds() (gas: 12677)
DisputeGameFactory_SetImplementation_Test:test_setImplementation_notOwner_reverts() (gas: 16078) DisputeGameFactory_SetImplementation_Test:test_setImplementation_notOwner_reverts() (gas: 16121)
DisputeGameFactory_SetImplementation_Test:test_setImplementation_succeeds() (gas: 44323) DisputeGameFactory_SetImplementation_Test:test_setImplementation_succeeds() (gas: 44368)
DisputeGameFactory_TransferOwnership_Test:test_transferOwnership_notOwner_reverts() (gas: 15974) DisputeGameFactory_TransferOwnership_Test:test_transferOwnership_notOwner_reverts() (gas: 15996)
DisputeGameFactory_TransferOwnership_Test:test_transferOwnership_succeeds() (gas: 18738) DisputeGameFactory_TransferOwnership_Test:test_transferOwnership_succeeds() (gas: 18716)
Drippie_Test:test_create_calledTwice_reverts() (gas: 168887) Drippie_Test:test_create_calledTwice_reverts() (gas: 168887)
Drippie_Test:test_create_succeeds() (gas: 183459) Drippie_Test:test_create_succeeds() (gas: 183459)
Drippie_Test:test_drip_amount_succeeds() (gas: 285433) Drippie_Test:test_drip_amount_succeeds() (gas: 285433)
...@@ -134,173 +134,173 @@ GasBenchMark_L1CrossDomainMessenger:test_sendMessage_benchmark_0() (gas: 352336) ...@@ -134,173 +134,173 @@ GasBenchMark_L1CrossDomainMessenger:test_sendMessage_benchmark_0() (gas: 352336)
GasBenchMark_L1CrossDomainMessenger:test_sendMessage_benchmark_1() (gas: 2950586) GasBenchMark_L1CrossDomainMessenger:test_sendMessage_benchmark_1() (gas: 2950586)
GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_0() (gas: 540752) GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_0() (gas: 540752)
GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_1() (gas: 4052922) GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_1() (gas: 4052922)
GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_0() (gas: 442107) GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_0() (gas: 442085)
GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_1() (gas: 3487834) GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_1() (gas: 3487812)
GasBenchMark_L1StandardBridge_Finalize:test_finalizeETHWithdrawal_benchmark() (gas: 43032) GasBenchMark_L1StandardBridge_Finalize:test_finalizeETHWithdrawal_benchmark() (gas: 43010)
GasBenchMark_L2OutputOracle:test_proposeL2Output_benchmark() (gas: 86675) GasBenchMark_L2OutputOracle:test_proposeL2Output_benchmark() (gas: 86653)
GasBenchMark_OptimismPortal:test_depositTransaction_benchmark() (gas: 68485) GasBenchMark_OptimismPortal:test_depositTransaction_benchmark() (gas: 68485)
GasBenchMark_OptimismPortal:test_depositTransaction_benchmark_1() (gas: 68966) GasBenchMark_OptimismPortal:test_depositTransaction_benchmark_1() (gas: 68988)
GasBenchMark_OptimismPortal:test_proveWithdrawalTransaction_benchmark() (gas: 143233) GasBenchMark_OptimismPortal:test_proveWithdrawalTransaction_benchmark() (gas: 143255)
GasPriceOracle_Test:test_baseFee_succeeds() (gas: 8348) GasPriceOracle_Test:test_baseFee_succeeds() (gas: 8392)
GasPriceOracle_Test:test_decimals_succeeds() (gas: 6234) GasPriceOracle_Test:test_decimals_succeeds() (gas: 6212)
GasPriceOracle_Test:test_gasPrice_succeeds() (gas: 8340) GasPriceOracle_Test:test_gasPrice_succeeds() (gas: 8340)
GasPriceOracle_Test:test_l1BaseFee_succeeds() (gas: 10680) GasPriceOracle_Test:test_l1BaseFee_succeeds() (gas: 10702)
GasPriceOracle_Test:test_overhead_succeeds() (gas: 10637) GasPriceOracle_Test:test_overhead_succeeds() (gas: 10681)
GasPriceOracle_Test:test_scalar_succeeds() (gas: 10700) GasPriceOracle_Test:test_scalar_succeeds() (gas: 10678)
GasPriceOracle_Test:test_setGasPrice_doesNotExist_reverts() (gas: 5956) GasPriceOracle_Test:test_setGasPrice_doesNotExist_reverts() (gas: 5999)
GasPriceOracle_Test:test_setL1BaseFee_doesNotExist_reverts() (gas: 5976) GasPriceOracle_Test:test_setL1BaseFee_doesNotExist_reverts() (gas: 5977)
GovernanceToken_Test:test_approve_succeeds() (gas: 138023) GovernanceToken_Test:test_approve_succeeds() (gas: 138023)
GovernanceToken_Test:test_burnFrom_succeeds() (gas: 127582) GovernanceToken_Test:test_burnFrom_succeeds() (gas: 127560)
GovernanceToken_Test:test_burn_succeeds() (gas: 119092) GovernanceToken_Test:test_burn_succeeds() (gas: 119070)
GovernanceToken_Test:test_constructor_succeeds() (gas: 23693) GovernanceToken_Test:test_constructor_succeeds() (gas: 23735)
GovernanceToken_Test:test_decreaseAllowance_succeeds() (gas: 141912) GovernanceToken_Test:test_decreaseAllowance_succeeds() (gas: 141889)
GovernanceToken_Test:test_increaseAllowance_succeeds() (gas: 142022) GovernanceToken_Test:test_increaseAllowance_succeeds() (gas: 142066)
GovernanceToken_Test:test_mint_fromNotOwner_reverts() (gas: 21378) GovernanceToken_Test:test_mint_fromNotOwner_reverts() (gas: 21421)
GovernanceToken_Test:test_mint_fromOwner_succeeds() (gas: 110940) GovernanceToken_Test:test_mint_fromOwner_succeeds() (gas: 110960)
GovernanceToken_Test:test_transferFrom_succeeds() (gas: 151340) GovernanceToken_Test:test_transferFrom_succeeds() (gas: 151296)
GovernanceToken_Test:test_transfer_succeeds() (gas: 142867) GovernanceToken_Test:test_transfer_succeeds() (gas: 142823)
Hashing_hashDepositSource_Test:test_hashDepositSource_succeeds() (gas: 700) Hashing_hashDepositSource_Test:test_hashDepositSource_succeeds() (gas: 656)
L1BlockNumberTest:test_fallback_succeeds() (gas: 18677) L1BlockNumberTest:test_fallback_succeeds() (gas: 18677)
L1BlockNumberTest:test_getL1BlockNumber_succeeds() (gas: 10647) L1BlockNumberTest:test_getL1BlockNumber_succeeds() (gas: 10647)
L1BlockNumberTest:test_receive_succeeds() (gas: 25384) L1BlockNumberTest:test_receive_succeeds() (gas: 25384)
L1BlockTest:test_basefee_succeeds() (gas: 7576) L1BlockTest:test_basefee_succeeds() (gas: 7599)
L1BlockTest:test_hash_succeeds() (gas: 7694) L1BlockTest:test_hash_succeeds() (gas: 7716)
L1BlockTest:test_number_succeeds() (gas: 7674) L1BlockTest:test_number_succeeds() (gas: 7696)
L1BlockTest:test_sequenceNumber_succeeds() (gas: 7676) L1BlockTest:test_sequenceNumber_succeeds() (gas: 7676)
L1BlockTest:test_timestamp_succeeds() (gas: 7663) L1BlockTest:test_timestamp_succeeds() (gas: 7685)
L1BlockTest:test_updateValues_succeeds() (gas: 63327) L1BlockTest:test_updateValues_succeeds() (gas: 63305)
L1CrossDomainMessenger_Test:test_messageVersion_succeeds() (gas: 24803) L1CrossDomainMessenger_Test:test_messageVersion_succeeds() (gas: 24759)
L1CrossDomainMessenger_Test:test_relayMessage_legacyOldReplay_reverts() (gas: 49385) L1CrossDomainMessenger_Test:test_relayMessage_legacyOldReplay_reverts() (gas: 49408)
L1CrossDomainMessenger_Test:test_relayMessage_legacyRetryAfterFailureThenSuccess_reverts() (gas: 237022) L1CrossDomainMessenger_Test:test_relayMessage_legacyRetryAfterFailureThenSuccess_reverts() (gas: 237000)
L1CrossDomainMessenger_Test:test_relayMessage_legacyRetryAfterFailure_succeeds() (gas: 230978) L1CrossDomainMessenger_Test:test_relayMessage_legacyRetryAfterFailure_succeeds() (gas: 230956)
L1CrossDomainMessenger_Test:test_relayMessage_legacyRetryAfterSuccess_reverts() (gas: 123950) L1CrossDomainMessenger_Test:test_relayMessage_legacyRetryAfterSuccess_reverts() (gas: 123973)
L1CrossDomainMessenger_Test:test_relayMessage_legacy_succeeds() (gas: 77309) L1CrossDomainMessenger_Test:test_relayMessage_legacy_succeeds() (gas: 77331)
L1CrossDomainMessenger_Test:test_relayMessage_retryAfterFailure_succeeds() (gas: 224938) L1CrossDomainMessenger_Test:test_relayMessage_retryAfterFailure_succeeds() (gas: 224981)
L1CrossDomainMessenger_Test:test_relayMessage_succeeds() (gas: 74345) L1CrossDomainMessenger_Test:test_relayMessage_succeeds() (gas: 74322)
L1CrossDomainMessenger_Test:test_relayMessage_toSystemContract_reverts() (gas: 56475) L1CrossDomainMessenger_Test:test_relayMessage_toSystemContract_reverts() (gas: 56453)
L1CrossDomainMessenger_Test:test_relayMessage_v2_reverts() (gas: 12410) L1CrossDomainMessenger_Test:test_relayMessage_v2_reverts() (gas: 12366)
L1CrossDomainMessenger_Test:test_replayMessage_withValue_reverts() (gas: 31031) L1CrossDomainMessenger_Test:test_replayMessage_withValue_reverts() (gas: 31075)
L1CrossDomainMessenger_Test:test_sendMessage_succeeds() (gas: 390952) L1CrossDomainMessenger_Test:test_sendMessage_succeeds() (gas: 390974)
L1CrossDomainMessenger_Test:test_sendMessage_twice_succeeds() (gas: 1666956) L1CrossDomainMessenger_Test:test_sendMessage_twice_succeeds() (gas: 1666975)
L1CrossDomainMessenger_Test:test_xDomainMessageSender_reset_succeeds() (gas: 85630) L1CrossDomainMessenger_Test:test_xDomainMessageSender_reset_succeeds() (gas: 85607)
L1CrossDomainMessenger_Test:test_xDomainSender_notSet_reverts() (gas: 24282) L1CrossDomainMessenger_Test:test_xDomainSender_notSet_reverts() (gas: 24282)
L1ERC721Bridge_Test:test_bridgeERC721To_localTokenZeroAddress_reverts() (gas: 62788) L1ERC721Bridge_Test:test_bridgeERC721To_localTokenZeroAddress_reverts() (gas: 62789)
L1ERC721Bridge_Test:test_bridgeERC721To_remoteTokenZeroAddress_reverts() (gas: 37362) L1ERC721Bridge_Test:test_bridgeERC721To_remoteTokenZeroAddress_reverts() (gas: 37383)
L1ERC721Bridge_Test:test_bridgeERC721To_succeeds() (gas: 451075) L1ERC721Bridge_Test:test_bridgeERC721To_succeeds() (gas: 451097)
L1ERC721Bridge_Test:test_bridgeERC721To_wrongOwner_reverts() (gas: 71051) L1ERC721Bridge_Test:test_bridgeERC721To_wrongOwner_reverts() (gas: 71007)
L1ERC721Bridge_Test:test_bridgeERC721_fromContract_reverts() (gas: 35736) L1ERC721Bridge_Test:test_bridgeERC721_fromContract_reverts() (gas: 35757)
L1ERC721Bridge_Test:test_bridgeERC721_localTokenZeroAddress_reverts() (gas: 60595) L1ERC721Bridge_Test:test_bridgeERC721_localTokenZeroAddress_reverts() (gas: 60596)
L1ERC721Bridge_Test:test_bridgeERC721_remoteTokenZeroAddress_reverts() (gas: 35172) L1ERC721Bridge_Test:test_bridgeERC721_remoteTokenZeroAddress_reverts() (gas: 35191)
L1ERC721Bridge_Test:test_bridgeERC721_succeeds() (gas: 450770) L1ERC721Bridge_Test:test_bridgeERC721_succeeds() (gas: 450771)
L1ERC721Bridge_Test:test_bridgeERC721_wrongOwner_reverts() (gas: 70854) L1ERC721Bridge_Test:test_bridgeERC721_wrongOwner_reverts() (gas: 70810)
L1ERC721Bridge_Test:test_constructor_succeeds() (gas: 16611) L1ERC721Bridge_Test:test_constructor_succeeds() (gas: 16611)
L1ERC721Bridge_Test:test_finalizeBridgeERC721_notEscrowed_reverts() (gas: 27154) L1ERC721Bridge_Test:test_finalizeBridgeERC721_notEscrowed_reverts() (gas: 27198)
L1ERC721Bridge_Test:test_finalizeBridgeERC721_notFromRemoteMessenger_reverts() (gas: 24920) L1ERC721Bridge_Test:test_finalizeBridgeERC721_notFromRemoteMessenger_reverts() (gas: 24920)
L1ERC721Bridge_Test:test_finalizeBridgeERC721_notViaLocalMessenger_reverts() (gas: 21150) L1ERC721Bridge_Test:test_finalizeBridgeERC721_notViaLocalMessenger_reverts() (gas: 21128)
L1ERC721Bridge_Test:test_finalizeBridgeERC721_selfToken_reverts() (gas: 22694) L1ERC721Bridge_Test:test_finalizeBridgeERC721_selfToken_reverts() (gas: 22672)
L1ERC721Bridge_Test:test_finalizeBridgeERC721_succeeds() (gas: 420728) L1ERC721Bridge_Test:test_finalizeBridgeERC721_succeeds() (gas: 420684)
L1StandardBridge_BridgeETHTo_Test:test_bridgeETHTo_succeeds() (gas: 513135) L1StandardBridge_BridgeETHTo_Test:test_bridgeETHTo_succeeds() (gas: 513177)
L1StandardBridge_BridgeETH_Test:test_bridgeETH_succeeds() (gas: 500344) L1StandardBridge_BridgeETH_Test:test_bridgeETH_succeeds() (gas: 500366)
L1StandardBridge_DepositERC20To_Test:test_depositERC20To_succeeds() (gas: 719145) L1StandardBridge_DepositERC20To_Test:test_depositERC20To_succeeds() (gas: 719101)
L1StandardBridge_DepositERC20_Test:test_depositERC20_succeeds() (gas: 716764) L1StandardBridge_DepositERC20_Test:test_depositERC20_succeeds() (gas: 716742)
L1StandardBridge_DepositERC20_TestFail:test_depositERC20_notEoa_reverts() (gas: 24977) L1StandardBridge_DepositERC20_TestFail:test_depositERC20_notEoa_reverts() (gas: 24933)
L1StandardBridge_DepositETHTo_Test:test_depositETHTo_succeeds() (gas: 513188) L1StandardBridge_DepositETHTo_Test:test_depositETHTo_succeeds() (gas: 513144)
L1StandardBridge_DepositETH_Test:test_depositETH_succeeds() (gas: 500483) L1StandardBridge_DepositETH_Test:test_depositETH_succeeds() (gas: 500461)
L1StandardBridge_DepositETH_TestFail:test_depositETH_notEoa_reverts() (gas: 43404) L1StandardBridge_DepositETH_TestFail:test_depositETH_notEoa_reverts() (gas: 43360)
L1StandardBridge_FinalizeBridgeETH_Test:test_finalizeBridgeETH_succeeds() (gas: 55399) L1StandardBridge_FinalizeBridgeETH_Test:test_finalizeBridgeETH_succeeds() (gas: 55355)
L1StandardBridge_FinalizeBridgeETH_TestFail:test_finalizeBridgeETH_incorrectValue_reverts() (gas: 37976) L1StandardBridge_FinalizeBridgeETH_TestFail:test_finalizeBridgeETH_incorrectValue_reverts() (gas: 37932)
L1StandardBridge_FinalizeBridgeETH_TestFail:test_finalizeBridgeETH_sendToMessenger_reverts() (gas: 38011) L1StandardBridge_FinalizeBridgeETH_TestFail:test_finalizeBridgeETH_sendToMessenger_reverts() (gas: 37967)
L1StandardBridge_FinalizeBridgeETH_TestFail:test_finalizeBridgeETH_sendToSelf_reverts() (gas: 38003) L1StandardBridge_FinalizeBridgeETH_TestFail:test_finalizeBridgeETH_sendToSelf_reverts() (gas: 37959)
L1StandardBridge_FinalizeERC20Withdrawal_Test:test_finalizeERC20Withdrawal_succeeds() (gas: 476244) L1StandardBridge_FinalizeERC20Withdrawal_Test:test_finalizeERC20Withdrawal_succeeds() (gas: 476279)
L1StandardBridge_FinalizeERC20Withdrawal_TestFail:test_finalizeERC20Withdrawal_notMessenger_reverts() (gas: 34965) L1StandardBridge_FinalizeERC20Withdrawal_TestFail:test_finalizeERC20Withdrawal_notMessenger_reverts() (gas: 34921)
L1StandardBridge_FinalizeERC20Withdrawal_TestFail:test_finalizeERC20Withdrawal_notOtherBridge_reverts() (gas: 35344) L1StandardBridge_FinalizeERC20Withdrawal_TestFail:test_finalizeERC20Withdrawal_notOtherBridge_reverts() (gas: 35322)
L1StandardBridge_FinalizeETHWithdrawal_Test:test_finalizeETHWithdrawal_succeeds() (gas: 67111) L1StandardBridge_FinalizeETHWithdrawal_Test:test_finalizeETHWithdrawal_succeeds() (gas: 67089)
L1StandardBridge_Getter_Test:test_getters_succeeds() (gas: 30489) L1StandardBridge_Getter_Test:test_getters_succeeds() (gas: 30467)
L1StandardBridge_Initialize_Test:test_initialize_succeeds() (gas: 25183) L1StandardBridge_Initialize_Test:test_initialize_succeeds() (gas: 25227)
L1StandardBridge_Receive_Test:test_receive_succeeds() (gas: 613466) L1StandardBridge_Receive_Test:test_receive_succeeds() (gas: 613466)
L2CrossDomainMessenger_Test:test_messageVersion_succeeds() (gas: 8521) L2CrossDomainMessenger_Test:test_messageVersion_succeeds() (gas: 8477)
L2CrossDomainMessenger_Test:test_relayMessage_retry_succeeds() (gas: 191101) L2CrossDomainMessenger_Test:test_relayMessage_retry_succeeds() (gas: 191079)
L2CrossDomainMessenger_Test:test_relayMessage_succeeds() (gas: 48936) L2CrossDomainMessenger_Test:test_relayMessage_succeeds() (gas: 48936)
L2CrossDomainMessenger_Test:test_relayMessage_toSystemContract_reverts() (gas: 29056) L2CrossDomainMessenger_Test:test_relayMessage_toSystemContract_reverts() (gas: 29034)
L2CrossDomainMessenger_Test:test_relayMessage_v2_reverts() (gas: 11756) L2CrossDomainMessenger_Test:test_relayMessage_v2_reverts() (gas: 11734)
L2CrossDomainMessenger_Test:test_sendMessage_succeeds() (gas: 124025) L2CrossDomainMessenger_Test:test_sendMessage_succeeds() (gas: 124025)
L2CrossDomainMessenger_Test:test_sendMessage_twice_succeeds() (gas: 135857) L2CrossDomainMessenger_Test:test_sendMessage_twice_succeeds() (gas: 135899)
L2CrossDomainMessenger_Test:test_xDomainMessageSender_reset_succeeds() (gas: 49311) L2CrossDomainMessenger_Test:test_xDomainMessageSender_reset_succeeds() (gas: 49311)
L2CrossDomainMessenger_Test:test_xDomainSender_senderNotSet_reverts() (gas: 10686) L2CrossDomainMessenger_Test:test_xDomainSender_senderNotSet_reverts() (gas: 10664)
L2ERC721Bridge_Test:test_bridgeERC721To_localTokenZeroAddress_reverts() (gas: 26498) L2ERC721Bridge_Test:test_bridgeERC721To_localTokenZeroAddress_reverts() (gas: 26499)
L2ERC721Bridge_Test:test_bridgeERC721To_remoteTokenZeroAddress_reverts() (gas: 21814) L2ERC721Bridge_Test:test_bridgeERC721To_remoteTokenZeroAddress_reverts() (gas: 21815)
L2ERC721Bridge_Test:test_bridgeERC721To_succeeds() (gas: 150000) L2ERC721Bridge_Test:test_bridgeERC721To_succeeds() (gas: 150022)
L2ERC721Bridge_Test:test_bridgeERC721To_wrongOwner_reverts() (gas: 29494) L2ERC721Bridge_Test:test_bridgeERC721To_wrongOwner_reverts() (gas: 29515)
L2ERC721Bridge_Test:test_bridgeERC721_fromContract_reverts() (gas: 22193) L2ERC721Bridge_Test:test_bridgeERC721_fromContract_reverts() (gas: 22194)
L2ERC721Bridge_Test:test_bridgeERC721_localTokenZeroAddress_reverts() (gas: 24354) L2ERC721Bridge_Test:test_bridgeERC721_localTokenZeroAddress_reverts() (gas: 24310)
L2ERC721Bridge_Test:test_bridgeERC721_remoteTokenZeroAddress_reverts() (gas: 19651) L2ERC721Bridge_Test:test_bridgeERC721_remoteTokenZeroAddress_reverts() (gas: 19629)
L2ERC721Bridge_Test:test_bridgeERC721_succeeds() (gas: 147663) L2ERC721Bridge_Test:test_bridgeERC721_succeeds() (gas: 147619)
L2ERC721Bridge_Test:test_bridgeERC721_wrongOwner_reverts() (gas: 29326) L2ERC721Bridge_Test:test_bridgeERC721_wrongOwner_reverts() (gas: 29345)
L2ERC721Bridge_Test:test_constructor_succeeds() (gas: 12411) L2ERC721Bridge_Test:test_constructor_succeeds() (gas: 12411)
L2ERC721Bridge_Test:test_finalizeBridgeERC721_alreadyExists_reverts() (gas: 31353) L2ERC721Bridge_Test:test_finalizeBridgeERC721_alreadyExists_reverts() (gas: 31375)
L2ERC721Bridge_Test:test_finalizeBridgeERC721_interfaceNotCompliant_reverts() (gas: 238955) L2ERC721Bridge_Test:test_finalizeBridgeERC721_interfaceNotCompliant_reverts() (gas: 238978)
L2ERC721Bridge_Test:test_finalizeBridgeERC721_notFromRemoteMessenger_reverts() (gas: 19918) L2ERC721Bridge_Test:test_finalizeBridgeERC721_notFromRemoteMessenger_reverts() (gas: 19919)
L2ERC721Bridge_Test:test_finalizeBridgeERC721_notViaLocalMessenger_reverts() (gas: 16171) L2ERC721Bridge_Test:test_finalizeBridgeERC721_notViaLocalMessenger_reverts() (gas: 16149)
L2ERC721Bridge_Test:test_finalizeBridgeERC721_selfToken_reverts() (gas: 19816) L2ERC721Bridge_Test:test_finalizeBridgeERC721_selfToken_reverts() (gas: 19794)
L2ERC721Bridge_Test:test_finalizeBridgeERC721_succeeds() (gas: 172094) L2ERC721Bridge_Test:test_finalizeBridgeERC721_succeeds() (gas: 172050)
L2OutputOracleUpgradeable_Test:test_initValuesOnImpl_succeeds() (gas: 43714) L2OutputOracleUpgradeable_Test:test_initValuesOnImpl_succeeds() (gas: 43691)
L2OutputOracleUpgradeable_Test:test_initValuesOnProxy_succeeds() (gas: 53427) L2OutputOracleUpgradeable_Test:test_initValuesOnProxy_succeeds() (gas: 53471)
L2OutputOracleUpgradeable_Test:test_initializeImpl_alreadyInitialized_reverts() (gas: 24715) L2OutputOracleUpgradeable_Test:test_initializeImpl_alreadyInitialized_reverts() (gas: 24693)
L2OutputOracleUpgradeable_Test:test_initializeProxy_alreadyInitialized_reverts() (gas: 26328) L2OutputOracleUpgradeable_Test:test_initializeProxy_alreadyInitialized_reverts() (gas: 26350)
L2OutputOracleUpgradeable_Test:test_upgrading_succeeds() (gas: 191094) L2OutputOracleUpgradeable_Test:test_upgrading_succeeds() (gas: 191094)
L2OutputOracle_constructor_Test:test_constructor_l2BlockTimeZero_reverts() (gas: 53454) L2OutputOracle_constructor_Test:test_constructor_l2BlockTimeZero_reverts() (gas: 53454)
L2OutputOracle_constructor_Test:test_constructor_submissionInterval_reverts() (gas: 53486) L2OutputOracle_constructor_Test:test_constructor_submissionInterval_reverts() (gas: 53530)
L2OutputOracle_constructor_Test:test_constructor_succeeds() (gas: 56916) L2OutputOracle_constructor_Test:test_constructor_succeeds() (gas: 56872)
L2OutputOracle_constructor_Test:test_initialize_badTimestamp_reverts() (gas: 15270) L2OutputOracle_constructor_Test:test_initialize_badTimestamp_reverts() (gas: 15292)
L2OutputOracle_deleteOutputs_Test:test_deleteL2Outputs_afterLatest_reverts() (gas: 225293) L2OutputOracle_deleteOutputs_Test:test_deleteL2Outputs_afterLatest_reverts() (gas: 225293)
L2OutputOracle_deleteOutputs_Test:test_deleteL2Outputs_finalized_reverts() (gas: 115915) L2OutputOracle_deleteOutputs_Test:test_deleteL2Outputs_finalized_reverts() (gas: 115959)
L2OutputOracle_deleteOutputs_Test:test_deleteL2Outputs_ifNotChallenger_reverts() (gas: 18974) L2OutputOracle_deleteOutputs_Test:test_deleteL2Outputs_ifNotChallenger_reverts() (gas: 18951)
L2OutputOracle_deleteOutputs_Test:test_deleteL2Outputs_nonExistent_reverts() (gas: 114320) L2OutputOracle_deleteOutputs_Test:test_deleteL2Outputs_nonExistent_reverts() (gas: 114298)
L2OutputOracle_deleteOutputs_Test:test_deleteOutputs_multipleOutputs_succeeds() (gas: 315178) L2OutputOracle_deleteOutputs_Test:test_deleteOutputs_multipleOutputs_succeeds() (gas: 315221)
L2OutputOracle_deleteOutputs_Test:test_deleteOutputs_singleOutput_succeeds() (gas: 190566) L2OutputOracle_deleteOutputs_Test:test_deleteOutputs_singleOutput_succeeds() (gas: 190544)
L2OutputOracle_getter_Test:test_computeL2Timestamp_succeeds() (gas: 44465) L2OutputOracle_getter_Test:test_computeL2Timestamp_succeeds() (gas: 44443)
L2OutputOracle_getter_Test:test_getL2OutputIndexAfter_multipleOutputsExist_succeeds() (gas: 274992) L2OutputOracle_getter_Test:test_getL2OutputIndexAfter_multipleOutputsExist_succeeds() (gas: 274993)
L2OutputOracle_getter_Test:test_getL2OutputIndexAfter_noOutputsExis_reverts() (gas: 17915) L2OutputOracle_getter_Test:test_getL2OutputIndexAfter_noOutputsExis_reverts() (gas: 17893)
L2OutputOracle_getter_Test:test_getL2OutputIndexAfter_previousBlock_succeeds() (gas: 101420) L2OutputOracle_getter_Test:test_getL2OutputIndexAfter_previousBlock_succeeds() (gas: 101376)
L2OutputOracle_getter_Test:test_getL2OutputIndexAfter_sameBlock_succeeds() (gas: 101328) L2OutputOracle_getter_Test:test_getL2OutputIndexAfter_sameBlock_succeeds() (gas: 101370)
L2OutputOracle_getter_Test:test_getL2Output_succeeds() (gas: 107900) L2OutputOracle_getter_Test:test_getL2Output_succeeds() (gas: 107901)
L2OutputOracle_getter_Test:test_latestBlockNumber_succeeds() (gas: 102405) L2OutputOracle_getter_Test:test_latestBlockNumber_succeeds() (gas: 102383)
L2OutputOracle_getter_Test:test_nextBlockNumber_succeeds() (gas: 17560) L2OutputOracle_getter_Test:test_nextBlockNumber_succeeds() (gas: 17604)
L2OutputOracle_proposeL2Output_Test:test_proposeL2Output_emptyOutput_reverts() (gas: 32089) L2OutputOracle_proposeL2Output_Test:test_proposeL2Output_emptyOutput_reverts() (gas: 32044)
L2OutputOracle_proposeL2Output_Test:test_proposeL2Output_futureTimetamp_reverts() (gas: 32118) L2OutputOracle_proposeL2Output_Test:test_proposeL2Output_futureTimetamp_reverts() (gas: 32096)
L2OutputOracle_proposeL2Output_Test:test_proposeL2Output_notProposer_reverts() (gas: 23999) L2OutputOracle_proposeL2Output_Test:test_proposeL2Output_notProposer_reverts() (gas: 23977)
L2OutputOracle_proposeL2Output_Test:test_proposeL2Output_proposeAnotherOutput_succeeds() (gas: 107202) L2OutputOracle_proposeL2Output_Test:test_proposeL2Output_proposeAnotherOutput_succeeds() (gas: 107244)
L2OutputOracle_proposeL2Output_Test:test_proposeL2Output_unexpectedBlockNumber_reverts() (gas: 31846) L2OutputOracle_proposeL2Output_Test:test_proposeL2Output_unexpectedBlockNumber_reverts() (gas: 31846)
L2OutputOracle_proposeL2Output_Test:test_proposeL2Output_unmatchedBlockhash_reverts() (gas: 32869) L2OutputOracle_proposeL2Output_Test:test_proposeL2Output_unmatchedBlockhash_reverts() (gas: 32912)
L2OutputOracle_proposeL2Output_Test:test_proposeL2Output_wrongFork_reverts() (gas: 32367) L2OutputOracle_proposeL2Output_Test:test_proposeL2Output_wrongFork_reverts() (gas: 32367)
L2OutputOracle_proposeL2Output_Test:test_proposeWithBlockhashAndHeight_succeeds() (gas: 98746) L2OutputOracle_proposeL2Output_Test:test_proposeWithBlockhashAndHeight_succeeds() (gas: 98724)
L2StandardBridge_BridgeERC20To_Test:test_bridgeERC20To_succeeds() (gas: 390647) L2StandardBridge_BridgeERC20To_Test:test_bridgeERC20To_succeeds() (gas: 390612)
L2StandardBridge_BridgeERC20To_Test:test_withdrawTo_withdrawingERC20_succeeds() (gas: 390895) L2StandardBridge_BridgeERC20To_Test:test_withdrawTo_withdrawingERC20_succeeds() (gas: 390877)
L2StandardBridge_BridgeERC20_Test:test_bridgeERC20_succeeds() (gas: 386260) L2StandardBridge_BridgeERC20_Test:test_bridgeERC20_succeeds() (gas: 386242)
L2StandardBridge_BridgeERC20_Test:test_bridgeLegacyERC20_succeeds() (gas: 394528) L2StandardBridge_BridgeERC20_Test:test_bridgeLegacyERC20_succeeds() (gas: 394510)
L2StandardBridge_BridgeERC20_Test:test_withdrawLegacyERC20_succeeds() (gas: 394890) L2StandardBridge_BridgeERC20_Test:test_withdrawLegacyERC20_succeeds() (gas: 394855)
L2StandardBridge_BridgeERC20_Test:test_withdraw_notEOA_reverts() (gas: 251904) L2StandardBridge_BridgeERC20_Test:test_withdraw_notEOA_reverts() (gas: 251886)
L2StandardBridge_BridgeERC20_Test:test_withdraw_withdrawingERC20_succeeds() (gas: 386556) L2StandardBridge_BridgeERC20_Test:test_withdraw_withdrawingERC20_succeeds() (gas: 386539)
L2StandardBridge_Bridge_Test:test_finalizeBridgeETH_incorrectValue_reverts() (gas: 23867) L2StandardBridge_Bridge_Test:test_finalizeBridgeETH_incorrectValue_reverts() (gas: 23845)
L2StandardBridge_Bridge_Test:test_finalizeBridgeETH_sendToMessenger_reverts() (gas: 23983) L2StandardBridge_Bridge_Test:test_finalizeBridgeETH_sendToMessenger_reverts() (gas: 23984)
L2StandardBridge_Bridge_Test:test_finalizeBridgeETH_sendToSelf_reverts() (gas: 23894) L2StandardBridge_Bridge_Test:test_finalizeBridgeETH_sendToSelf_reverts() (gas: 23872)
L2StandardBridge_Bridge_Test:test_finalizeDeposit_depositingERC20_succeeds() (gas: 93814) L2StandardBridge_Bridge_Test:test_finalizeDeposit_depositingERC20_succeeds() (gas: 93879)
L2StandardBridge_Bridge_Test:test_finalizeDeposit_depositingETH_succeeds() (gas: 92711) L2StandardBridge_Bridge_Test:test_finalizeDeposit_depositingETH_succeeds() (gas: 92667)
L2StandardBridge_FinalizeBridgeETH_Test:test_finalizeBridgeETH_succeeds() (gas: 43171) L2StandardBridge_FinalizeBridgeETH_Test:test_finalizeBridgeETH_succeeds() (gas: 43127)
L2StandardBridge_Test:test_initialize_succeeds() (gas: 26804) L2StandardBridge_Test:test_initialize_succeeds() (gas: 26826)
L2StandardBridge_Test:test_receive_succeeds() (gas: 175032) L2StandardBridge_Test:test_receive_succeeds() (gas: 175032)
L2StandardBridge_Test:test_withdraw_ether_succeeds() (gas: 141296) L2StandardBridge_Test:test_withdraw_ether_succeeds() (gas: 141340)
L2StandardBridge_Test:test_withdraw_insufficientValue_reverts() (gas: 16586) L2StandardBridge_Test:test_withdraw_insufficientValue_reverts() (gas: 16609)
LegacyERC20ETH_Test:test_approve_doesNotExist_reverts() (gas: 10745) LegacyERC20ETH_Test:test_approve_doesNotExist_reverts() (gas: 10746)
LegacyERC20ETH_Test:test_burn_doesNotExist_reverts() (gas: 10705) LegacyERC20ETH_Test:test_burn_doesNotExist_reverts() (gas: 10661)
LegacyERC20ETH_Test:test_crossDomain_succeeds() (gas: 6400) LegacyERC20ETH_Test:test_crossDomain_succeeds() (gas: 6442)
LegacyERC20ETH_Test:test_decreaseAllowance_doesNotExist_reverts() (gas: 10747) LegacyERC20ETH_Test:test_decreaseAllowance_doesNotExist_reverts() (gas: 10724)
LegacyERC20ETH_Test:test_increaseAllowance_doesNotExist_reverts() (gas: 10757) LegacyERC20ETH_Test:test_increaseAllowance_doesNotExist_reverts() (gas: 10757)
LegacyERC20ETH_Test:test_metadata_succeeds() (gas: 15795) LegacyERC20ETH_Test:test_metadata_succeeds() (gas: 15773)
LegacyERC20ETH_Test:test_mint_doesNotExist_reverts() (gas: 10672) LegacyERC20ETH_Test:test_mint_doesNotExist_reverts() (gas: 10694)
LegacyERC20ETH_Test:test_transferFrom_doesNotExist_reverts() (gas: 13002) LegacyERC20ETH_Test:test_transferFrom_doesNotExist_reverts() (gas: 13002)
LegacyERC20ETH_Test:test_transfer_doesNotExist_reverts() (gas: 10801) LegacyERC20ETH_Test:test_transfer_doesNotExist_reverts() (gas: 10779)
LegacyMessagePasser_Test:test_passMessageToL1_succeeds() (gas: 34629) LegacyMessagePasser_Test:test_passMessageToL1_succeeds() (gas: 34607)
LibPosition_Test:test_pos_correctness_succeeds() (gas: 38711) LibPosition_Test:test_pos_correctness_succeeds() (gas: 38711)
LivenessGuard_CheckAfterExecution_TestFails:test_checkAfterExecution_callerIsNotSafe_revert() (gas: 8576) LivenessGuard_CheckAfterExecution_TestFails:test_checkAfterExecution_callerIsNotSafe_revert() (gas: 8576)
LivenessGuard_CheckTx_Test:test_checkTransaction_succeeds() (gas: 233535) LivenessGuard_CheckTx_Test:test_checkTransaction_succeeds() (gas: 233535)
...@@ -329,81 +329,81 @@ LivenessModule_RemoveOwners_TestFail:test_removeOwners_ownerHasShownLivenessRece ...@@ -329,81 +329,81 @@ LivenessModule_RemoveOwners_TestFail:test_removeOwners_ownerHasShownLivenessRece
LivenessModule_RemoveOwners_TestFail:test_removeOwners_ownerHasSignedRecently_reverts() (gas: 615047) LivenessModule_RemoveOwners_TestFail:test_removeOwners_ownerHasSignedRecently_reverts() (gas: 615047)
LivenessModule_RemoveOwners_TestFail:test_removeOwners_swapToFallbackOwner_reverts() (gas: 1278252) LivenessModule_RemoveOwners_TestFail:test_removeOwners_swapToFallbackOwner_reverts() (gas: 1278252)
LivenessModule_RemoveOwners_TestFail:test_removeOwners_wrongPreviousOwner_reverts() (gas: 73954) LivenessModule_RemoveOwners_TestFail:test_removeOwners_wrongPreviousOwner_reverts() (gas: 73954)
MIPS_Test:test_add_succeeds() (gas: 123021) MIPS_Test:test_add_succeeds() (gas: 122999)
MIPS_Test:test_addiSign_succeeds() (gas: 122946) MIPS_Test:test_addiSign_succeeds() (gas: 122946)
MIPS_Test:test_addi_succeeds() (gas: 123166) MIPS_Test:test_addi_succeeds() (gas: 123144)
MIPS_Test:test_addu_succeeds() (gas: 122975) MIPS_Test:test_addu_succeeds() (gas: 123041)
MIPS_Test:test_addui_succeeds() (gas: 123162) MIPS_Test:test_addui_succeeds() (gas: 123228)
MIPS_Test:test_and_succeeds() (gas: 123017) MIPS_Test:test_and_succeeds() (gas: 122995)
MIPS_Test:test_andi_succeeds() (gas: 122994) MIPS_Test:test_andi_succeeds() (gas: 123016)
MIPS_Test:test_beq_succeeds() (gas: 203427) MIPS_Test:test_beq_succeeds() (gas: 203405)
MIPS_Test:test_bgez_succeeds() (gas: 122265) MIPS_Test:test_bgez_succeeds() (gas: 122243)
MIPS_Test:test_bgtz_succeeds() (gas: 122205) MIPS_Test:test_bgtz_succeeds() (gas: 122206)
MIPS_Test:test_blez_succeeds() (gas: 122142) MIPS_Test:test_blez_succeeds() (gas: 122120)
MIPS_Test:test_bltz_succeeds() (gas: 122262) MIPS_Test:test_bltz_succeeds() (gas: 122284)
MIPS_Test:test_bne_succeeds() (gas: 122351) MIPS_Test:test_bne_succeeds() (gas: 122329)
MIPS_Test:test_branch_inDelaySlot_fails() (gas: 86536) MIPS_Test:test_branch_inDelaySlot_fails() (gas: 86558)
MIPS_Test:test_brk_succeeds() (gas: 122655) MIPS_Test:test_brk_succeeds() (gas: 122611)
MIPS_Test:test_clo_succeeds() (gas: 122707) MIPS_Test:test_clo_succeeds() (gas: 122685)
MIPS_Test:test_clone_succeeds() (gas: 122563) MIPS_Test:test_clone_succeeds() (gas: 122541)
MIPS_Test:test_clz_succeeds() (gas: 123177) MIPS_Test:test_clz_succeeds() (gas: 123133)
MIPS_Test:test_div_succeeds() (gas: 123134) MIPS_Test:test_div_succeeds() (gas: 123112)
MIPS_Test:test_divu_succeeds() (gas: 123142) MIPS_Test:test_divu_succeeds() (gas: 123185)
MIPS_Test:test_exit_succeeds() (gas: 122657) MIPS_Test:test_exit_succeeds() (gas: 122679)
MIPS_Test:test_fcntl_succeeds() (gas: 204864) MIPS_Test:test_fcntl_succeeds() (gas: 204906)
MIPS_Test:test_illegal_instruction_fails() (gas: 92045) MIPS_Test:test_illegal_instruction_fails() (gas: 92023)
MIPS_Test:test_invalid_root_fails() (gas: 436238) MIPS_Test:test_invalid_root_fails() (gas: 436194)
MIPS_Test:test_jal_nonzeroRegion_succeeds() (gas: 121250) MIPS_Test:test_jal_nonzeroRegion_succeeds() (gas: 121228)
MIPS_Test:test_jal_succeeds() (gas: 121217) MIPS_Test:test_jal_succeeds() (gas: 121283)
MIPS_Test:test_jalr_succeeds() (gas: 122425) MIPS_Test:test_jalr_succeeds() (gas: 122425)
MIPS_Test:test_jr_succeeds() (gas: 122096) MIPS_Test:test_jr_succeeds() (gas: 122074)
MIPS_Test:test_jump_inDelaySlot_fails() (gas: 85884) MIPS_Test:test_jump_inDelaySlot_fails() (gas: 85906)
MIPS_Test:test_jump_nonzeroRegion_succeeds() (gas: 120994) MIPS_Test:test_jump_nonzeroRegion_succeeds() (gas: 120972)
MIPS_Test:test_jump_succeeds() (gas: 120969) MIPS_Test:test_jump_succeeds() (gas: 120925)
MIPS_Test:test_lb_succeeds() (gas: 128187) MIPS_Test:test_lb_succeeds() (gas: 128210)
MIPS_Test:test_lbu_succeeds() (gas: 128085) MIPS_Test:test_lbu_succeeds() (gas: 128063)
MIPS_Test:test_lh_succeeds() (gas: 128229) MIPS_Test:test_lh_succeeds() (gas: 128230)
MIPS_Test:test_lhu_succeeds() (gas: 128103) MIPS_Test:test_lhu_succeeds() (gas: 128168)
MIPS_Test:test_ll_succeeds() (gas: 128303) MIPS_Test:test_ll_succeeds() (gas: 128369)
MIPS_Test:test_lui_succeeds() (gas: 122293) MIPS_Test:test_lui_succeeds() (gas: 122271)
MIPS_Test:test_lw_succeeds() (gas: 127976) MIPS_Test:test_lw_succeeds() (gas: 127976)
MIPS_Test:test_lwl_succeeds() (gas: 243161) MIPS_Test:test_lwl_succeeds() (gas: 243183)
MIPS_Test:test_lwr_succeeds() (gas: 243428) MIPS_Test:test_lwr_succeeds() (gas: 243450)
MIPS_Test:test_mfhi_succeeds() (gas: 122634) MIPS_Test:test_mfhi_succeeds() (gas: 122634)
MIPS_Test:test_mflo_succeeds() (gas: 122718) MIPS_Test:test_mflo_succeeds() (gas: 122718)
MIPS_Test:test_mmap_succeeds() (gas: 119637) MIPS_Test:test_mmap_succeeds() (gas: 119681)
MIPS_Test:test_movn_succeeds() (gas: 204054) MIPS_Test:test_movn_succeeds() (gas: 204032)
MIPS_Test:test_movz_succeeds() (gas: 203945) MIPS_Test:test_movz_succeeds() (gas: 203967)
MIPS_Test:test_mthi_succeeds() (gas: 122678) MIPS_Test:test_mthi_succeeds() (gas: 122656)
MIPS_Test:test_mtlo_succeeds() (gas: 122741) MIPS_Test:test_mtlo_succeeds() (gas: 122784)
MIPS_Test:test_mul_succeeds() (gas: 122278) MIPS_Test:test_mul_succeeds() (gas: 122234)
MIPS_Test:test_mult_succeeds() (gas: 122959) MIPS_Test:test_mult_succeeds() (gas: 122937)
MIPS_Test:test_multu_succeeds() (gas: 123018) MIPS_Test:test_multu_succeeds() (gas: 123040)
MIPS_Test:test_nor_succeeds() (gas: 123109) MIPS_Test:test_nor_succeeds() (gas: 123065)
MIPS_Test:test_or_succeeds() (gas: 123024) MIPS_Test:test_or_succeeds() (gas: 123068)
MIPS_Test:test_ori_succeeds() (gas: 123026) MIPS_Test:test_ori_succeeds() (gas: 123026)
MIPS_Test:test_preimage_read_succeeds() (gas: 235502) MIPS_Test:test_preimage_read_succeeds() (gas: 235480)
MIPS_Test:test_preimage_write_succeeds() (gas: 127574) MIPS_Test:test_preimage_write_succeeds() (gas: 127574)
MIPS_Test:test_prestate_exited_succeeds() (gas: 113835) MIPS_Test:test_prestate_exited_succeeds() (gas: 113813)
MIPS_Test:test_sb_succeeds() (gas: 161547) MIPS_Test:test_sb_succeeds() (gas: 161547)
MIPS_Test:test_sc_succeeds() (gas: 161752) MIPS_Test:test_sc_succeeds() (gas: 161752)
MIPS_Test:test_sh_succeeds() (gas: 161606) MIPS_Test:test_sh_succeeds() (gas: 161651)
MIPS_Test:test_sll_succeeds() (gas: 122260) MIPS_Test:test_sll_succeeds() (gas: 122238)
MIPS_Test:test_sllv_succeeds() (gas: 122402) MIPS_Test:test_sllv_succeeds() (gas: 122446)
MIPS_Test:test_slt_succeeds() (gas: 205250) MIPS_Test:test_slt_succeeds() (gas: 205206)
MIPS_Test:test_sltu_succeeds() (gas: 123285) MIPS_Test:test_sltu_succeeds() (gas: 123263)
MIPS_Test:test_sra_succeeds() (gas: 122490) MIPS_Test:test_sra_succeeds() (gas: 122468)
MIPS_Test:test_srav_succeeds() (gas: 122758) MIPS_Test:test_srav_succeeds() (gas: 122714)
MIPS_Test:test_srl_succeeds() (gas: 122276) MIPS_Test:test_srl_succeeds() (gas: 122254)
MIPS_Test:test_srlv_succeeds() (gas: 122506) MIPS_Test:test_srlv_succeeds() (gas: 122462)
MIPS_Test:test_step_abi_succeeds() (gas: 58532) MIPS_Test:test_step_abi_succeeds() (gas: 58510)
MIPS_Test:test_sub_succeeds() (gas: 123007) MIPS_Test:test_sub_succeeds() (gas: 123050)
MIPS_Test:test_subu_succeeds() (gas: 123092) MIPS_Test:test_subu_succeeds() (gas: 123048)
MIPS_Test:test_sw_succeeds() (gas: 161604) MIPS_Test:test_sw_succeeds() (gas: 161582)
MIPS_Test:test_swl_succeeds() (gas: 161621) MIPS_Test:test_swl_succeeds() (gas: 161662)
MIPS_Test:test_swr_succeeds() (gas: 161696) MIPS_Test:test_swr_succeeds() (gas: 161652)
MIPS_Test:test_xor_succeeds() (gas: 123029) MIPS_Test:test_xor_succeeds() (gas: 123095)
MIPS_Test:test_xori_succeeds() (gas: 123147) MIPS_Test:test_xori_succeeds() (gas: 123103)
MerkleTrie_get_Test:test_get_corruptedProof_reverts() (gas: 5710) MerkleTrie_get_Test:test_get_corruptedProof_reverts() (gas: 5710)
MerkleTrie_get_Test:test_get_extraProofElements_reverts() (gas: 58889) MerkleTrie_get_Test:test_get_extraProofElements_reverts() (gas: 58889)
MerkleTrie_get_Test:test_get_invalidDataRemainder_reverts() (gas: 35867) MerkleTrie_get_Test:test_get_invalidDataRemainder_reverts() (gas: 35867)
...@@ -425,47 +425,47 @@ MerkleTrie_get_Test:test_get_validProof9_succeeds() (gas: 48802) ...@@ -425,47 +425,47 @@ MerkleTrie_get_Test:test_get_validProof9_succeeds() (gas: 48802)
MerkleTrie_get_Test:test_get_wrongKeyProof_reverts() (gas: 50752) MerkleTrie_get_Test:test_get_wrongKeyProof_reverts() (gas: 50752)
MerkleTrie_get_Test:test_get_zeroBranchValueLength_reverts() (gas: 41706) MerkleTrie_get_Test:test_get_zeroBranchValueLength_reverts() (gas: 41706)
MerkleTrie_get_Test:test_get_zeroLengthKey_reverts() (gas: 3632) MerkleTrie_get_Test:test_get_zeroLengthKey_reverts() (gas: 3632)
MintManager_constructor_Test:test_constructor_succeeds() (gas: 10623) MintManager_constructor_Test:test_constructor_succeeds() (gas: 10579)
MintManager_mint_Test:test_mint_afterPeriodElapsed_succeeds() (gas: 148184) MintManager_mint_Test:test_mint_afterPeriodElapsed_succeeds() (gas: 148184)
MintManager_mint_Test:test_mint_beforePeriodElapsed_reverts() (gas: 140479) MintManager_mint_Test:test_mint_beforePeriodElapsed_reverts() (gas: 140523)
MintManager_mint_Test:test_mint_fromNotOwner_reverts() (gas: 11054) MintManager_mint_Test:test_mint_fromNotOwner_reverts() (gas: 11054)
MintManager_mint_Test:test_mint_fromOwner_succeeds() (gas: 137330) MintManager_mint_Test:test_mint_fromOwner_succeeds() (gas: 137308)
MintManager_mint_Test:test_mint_moreThanCap_reverts() (gas: 142590) MintManager_mint_Test:test_mint_moreThanCap_reverts() (gas: 142568)
MintManager_upgrade_Test:test_upgrade_fromNotOwner_reverts() (gas: 11041) MintManager_upgrade_Test:test_upgrade_fromNotOwner_reverts() (gas: 10975)
MintManager_upgrade_Test:test_upgrade_fromOwner_succeeds() (gas: 23509) MintManager_upgrade_Test:test_upgrade_fromOwner_succeeds() (gas: 23509)
MintManager_upgrade_Test:test_upgrade_toZeroAddress_reverts() (gas: 11070) MintManager_upgrade_Test:test_upgrade_toZeroAddress_reverts() (gas: 11092)
OptimismMintableERC20_Test:test_bridge_succeeds() (gas: 7732) OptimismMintableERC20_Test:test_bridge_succeeds() (gas: 7710)
OptimismMintableERC20_Test:test_burn_notBridge_reverts() (gas: 11168) OptimismMintableERC20_Test:test_burn_notBridge_reverts() (gas: 11190)
OptimismMintableERC20_Test:test_burn_succeeds() (gas: 51057) OptimismMintableERC20_Test:test_burn_succeeds() (gas: 51040)
OptimismMintableERC20_Test:test_erc165_supportsInterface_succeeds() (gas: 7863) OptimismMintableERC20_Test:test_erc165_supportsInterface_succeeds() (gas: 7819)
OptimismMintableERC20_Test:test_l1Token_succeeds() (gas: 7732) OptimismMintableERC20_Test:test_l1Token_succeeds() (gas: 7710)
OptimismMintableERC20_Test:test_l2Bridge_succeeds() (gas: 7687) OptimismMintableERC20_Test:test_l2Bridge_succeeds() (gas: 7710)
OptimismMintableERC20_Test:test_legacy_succeeds() (gas: 14630) OptimismMintableERC20_Test:test_legacy_succeeds() (gas: 14631)
OptimismMintableERC20_Test:test_mint_notBridge_reverts() (gas: 11212) OptimismMintableERC20_Test:test_mint_notBridge_reverts() (gas: 11190)
OptimismMintableERC20_Test:test_mint_succeeds() (gas: 63595) OptimismMintableERC20_Test:test_mint_succeeds() (gas: 63639)
OptimismMintableERC20_Test:test_remoteToken_succeeds() (gas: 7755) OptimismMintableERC20_Test:test_remoteToken_succeeds() (gas: 7733)
OptimismMintableERC721Factory_Test:test_constructor_succeeds() (gas: 8424) OptimismMintableERC721Factory_Test:test_constructor_succeeds() (gas: 8380)
OptimismMintableERC721Factory_Test:test_createOptimismMintableERC721_sameTwice_reverts() (gas: 8937393460516800078) OptimismMintableERC721Factory_Test:test_createOptimismMintableERC721_sameTwice_reverts() (gas: 8937393460516800076)
OptimismMintableERC721Factory_Test:test_createOptimismMintableERC721_succeeds() (gas: 2316545) OptimismMintableERC721Factory_Test:test_createOptimismMintableERC721_succeeds() (gas: 2316523)
OptimismMintableERC721Factory_Test:test_createOptimismMintableERC721_zeroRemoteToken_reverts() (gas: 9542) OptimismMintableERC721Factory_Test:test_createOptimismMintableERC721_zeroRemoteToken_reverts() (gas: 9542)
OptimismMintableERC721_Test:test_burn_notBridge_reverts() (gas: 136967) OptimismMintableERC721_Test:test_burn_notBridge_reverts() (gas: 136989)
OptimismMintableERC721_Test:test_burn_succeeds() (gas: 118874) OptimismMintableERC721_Test:test_burn_succeeds() (gas: 118892)
OptimismMintableERC721_Test:test_constructor_succeeds() (gas: 24516) OptimismMintableERC721_Test:test_constructor_succeeds() (gas: 24517)
OptimismMintableERC721_Test:test_safeMint_notBridge_reverts() (gas: 11209) OptimismMintableERC721_Test:test_safeMint_notBridge_reverts() (gas: 11165)
OptimismMintableERC721_Test:test_safeMint_succeeds() (gas: 140599) OptimismMintableERC721_Test:test_safeMint_succeeds() (gas: 140599)
OptimismMintableERC721_Test:test_supportsInterfaces_succeeds() (gas: 9050) OptimismMintableERC721_Test:test_supportsInterfaces_succeeds() (gas: 9093)
OptimismMintableERC721_Test:test_tokenURI_succeeds() (gas: 163605) OptimismMintableERC721_Test:test_tokenURI_succeeds() (gas: 163583)
OptimismMintableTokenFactory_Test:test_bridge_succeeds() (gas: 7720) OptimismMintableTokenFactory_Test:test_bridge_succeeds() (gas: 7698)
OptimismMintableTokenFactory_Test:test_createStandardL2TokenWithDecimals_succeeds() (gas: 1140441) OptimismMintableTokenFactory_Test:test_createStandardL2TokenWithDecimals_succeeds() (gas: 1140419)
OptimismMintableTokenFactory_Test:test_createStandardL2Token_remoteIsZero_reverts() (gas: 9620) OptimismMintableTokenFactory_Test:test_createStandardL2Token_remoteIsZero_reverts() (gas: 9643)
OptimismMintableTokenFactory_Test:test_createStandardL2Token_sameTwice_reverts() (gas: 8937393460516764345) OptimismMintableTokenFactory_Test:test_createStandardL2Token_sameTwice_reverts() (gas: 8937393460516764344)
OptimismMintableTokenFactory_Test:test_createStandardL2Token_succeeds() (gas: 1140433) OptimismMintableTokenFactory_Test:test_createStandardL2Token_succeeds() (gas: 1140410)
OptimismPortalUpgradeable_Test:test_initialize_cannotInitImpl_reverts() (gas: 14453) OptimismPortalUpgradeable_Test:test_initialize_cannotInitImpl_reverts() (gas: 14409)
OptimismPortalUpgradeable_Test:test_initialize_cannotInitProxy_reverts() (gas: 16051) OptimismPortalUpgradeable_Test:test_initialize_cannotInitProxy_reverts() (gas: 16007)
OptimismPortalUpgradeable_Test:test_params_initValuesOnProxy_succeeds() (gas: 26689) OptimismPortalUpgradeable_Test:test_params_initValuesOnProxy_succeeds() (gas: 26711)
OptimismPortalUpgradeable_Test:test_upgradeToAndCall_upgrading_succeeds() (gas: 185977) OptimismPortalUpgradeable_Test:test_upgradeToAndCall_upgrading_succeeds() (gas: 185999)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_ifOutputRootChanges_reverts() (gas: 178074) OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_ifOutputRootChanges_reverts() (gas: 178052)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_ifOutputTimestampIsNotFinalized_reverts() (gas: 181439) OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_ifOutputTimestampIsNotFinalized_reverts() (gas: 181461)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_ifWithdrawalNotProven_reverts() (gas: 41777) OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_ifWithdrawalNotProven_reverts() (gas: 41777)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_ifWithdrawalProofNotOldEnough_reverts() (gas: 173449) OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_ifWithdrawalProofNotOldEnough_reverts() (gas: 173449)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_onInsufficientGas_reverts() (gas: 180336) OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_onInsufficientGas_reverts() (gas: 180336)
...@@ -476,25 +476,25 @@ OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_paused ...@@ -476,25 +476,25 @@ OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_paused
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_provenWithdrawalHash_succeeds() (gas: 208960) OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_provenWithdrawalHash_succeeds() (gas: 208960)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_targetFails_fails() (gas: 8797746687696162666) OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_targetFails_fails() (gas: 8797746687696162666)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_timestampLessThanL2OracleStart_reverts() (gas: 170961) OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_timestampLessThanL2OracleStart_reverts() (gas: 170961)
OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_onInvalidOutputRootProof_reverts() (gas: 85758) OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_onInvalidOutputRootProof_reverts() (gas: 85714)
OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_onInvalidWithdrawalProof_reverts() (gas: 111248) OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_onInvalidWithdrawalProof_reverts() (gas: 111248)
OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_onSelfCall_reverts() (gas: 52989) OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_onSelfCall_reverts() (gas: 52944)
OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_paused_reverts() (gas: 73807) OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_paused_reverts() (gas: 73785)
OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_replayProveChangedOutputRootAndOutputIndex_succeeds() (gas: 294672) OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_replayProveChangedOutputRootAndOutputIndex_succeeds() (gas: 294694)
OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_replayProveChangedOutputRoot_succeeds() (gas: 227343) OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_replayProveChangedOutputRoot_succeeds() (gas: 227365)
OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_replayProve_reverts() (gas: 166490) OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_replayProve_reverts() (gas: 166513)
OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_validWithdrawalProof_succeeds() (gas: 154361) OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_validWithdrawalProof_succeeds() (gas: 154405)
OptimismPortal_Test:test_constructor_succeeds() (gas: 31035) OptimismPortal_Test:test_constructor_succeeds() (gas: 31014)
OptimismPortal_Test:test_depositTransaction_contractCreation_reverts() (gas: 14322) OptimismPortal_Test:test_depositTransaction_contractCreation_reverts() (gas: 14300)
OptimismPortal_Test:test_depositTransaction_largeData_reverts() (gas: 512252) OptimismPortal_Test:test_depositTransaction_largeData_reverts() (gas: 512272)
OptimismPortal_Test:test_depositTransaction_smallGasLimit_reverts() (gas: 14578) OptimismPortal_Test:test_depositTransaction_smallGasLimit_reverts() (gas: 14578)
OptimismPortal_Test:test_isOutputFinalized_succeeds() (gas: 122745) OptimismPortal_Test:test_isOutputFinalized_succeeds() (gas: 122745)
OptimismPortal_Test:test_minimumGasLimit_succeeds() (gas: 17643) OptimismPortal_Test:test_minimumGasLimit_succeeds() (gas: 17663)
OptimismPortal_Test:test_pause_onlyGuardian_reverts() (gas: 22284) OptimismPortal_Test:test_pause_onlyGuardian_reverts() (gas: 22284)
OptimismPortal_Test:test_pause_succeeds() (gas: 42226) OptimismPortal_Test:test_pause_succeeds() (gas: 42182)
OptimismPortal_Test:test_simple_isOutputFinalized_succeeds() (gas: 38180) OptimismPortal_Test:test_simple_isOutputFinalized_succeeds() (gas: 38181)
OptimismPortal_Test:test_unpause_onlyGuardian_reverts() (gas: 46274) OptimismPortal_Test:test_unpause_onlyGuardian_reverts() (gas: 46252)
OptimismPortal_Test:test_unpause_succeeds() (gas: 31744) OptimismPortal_Test:test_unpause_succeeds() (gas: 31727)
OptimistAllowlistTest:test_constructor_succeeds() (gas: 16362) OptimistAllowlistTest:test_constructor_succeeds() (gas: 16362)
OptimistAllowlistTest:test_isAllowedToMint_fromAllowlistAttestorWithFalsyValue_fails() (gas: 49652) OptimistAllowlistTest:test_isAllowedToMint_fromAllowlistAttestorWithFalsyValue_fails() (gas: 49652)
OptimistAllowlistTest:test_isAllowedToMint_fromAllowlistAttestor_succeeds() (gas: 49276) OptimistAllowlistTest:test_isAllowedToMint_fromAllowlistAttestor_succeeds() (gas: 49276)
...@@ -549,9 +549,9 @@ PreimageOracle_Test:test_loadLocalData_multipleContexts_succeeds() (gas: 147718) ...@@ -549,9 +549,9 @@ PreimageOracle_Test:test_loadLocalData_multipleContexts_succeeds() (gas: 147718)
PreimageOracle_Test:test_loadLocalData_onePart_succeeds() (gas: 75905) PreimageOracle_Test:test_loadLocalData_onePart_succeeds() (gas: 75905)
PreimageOracle_Test:test_loadLocalData_outOfBoundsOffset_reverts() (gas: 8882) PreimageOracle_Test:test_loadLocalData_outOfBoundsOffset_reverts() (gas: 8882)
ProtocolVersions_Initialize_Test:test_initialize_events_succeeds() (gas: 59548) ProtocolVersions_Initialize_Test:test_initialize_events_succeeds() (gas: 59548)
ProtocolVersions_Initialize_Test:test_initialize_values_succeeds() (gas: 45046) ProtocolVersions_Initialize_Test:test_initialize_values_succeeds() (gas: 45091)
ProtocolVersions_Setters_TestFail:test_setRecommended_notOwner_reverts() (gas: 15553) ProtocolVersions_Setters_TestFail:test_setRecommended_notOwner_reverts() (gas: 15597)
ProtocolVersions_Setters_TestFail:test_setRequired_notOwner_reverts() (gas: 15587) ProtocolVersions_Setters_TestFail:test_setRequired_notOwner_reverts() (gas: 15543)
ProxyAdmin_Test:test_chugsplashChangeProxyAdmin_succeeds() (gas: 36440) ProxyAdmin_Test:test_chugsplashChangeProxyAdmin_succeeds() (gas: 36440)
ProxyAdmin_Test:test_chugsplashGetProxyAdmin_succeeds() (gas: 15610) ProxyAdmin_Test:test_chugsplashGetProxyAdmin_succeeds() (gas: 15610)
ProxyAdmin_Test:test_chugsplashGetProxyImplementation_succeeds() (gas: 51040) ProxyAdmin_Test:test_chugsplashGetProxyImplementation_succeeds() (gas: 51040)
...@@ -660,34 +660,33 @@ ResourceMetering_Test:test_meter_useMax_succeeds() (gas: 20020816) ...@@ -660,34 +660,33 @@ ResourceMetering_Test:test_meter_useMax_succeeds() (gas: 20020816)
ResourceMetering_Test:test_meter_useMoreThanMax_reverts() (gas: 19549) ResourceMetering_Test:test_meter_useMoreThanMax_reverts() (gas: 19549)
SafeCall_Test:test_callWithMinGas_noLeakageHigh_succeeds() (gas: 1020805932) SafeCall_Test:test_callWithMinGas_noLeakageHigh_succeeds() (gas: 1020805932)
SafeCall_Test:test_callWithMinGas_noLeakageLow_succeeds() (gas: 1094905711) SafeCall_Test:test_callWithMinGas_noLeakageLow_succeeds() (gas: 1094905711)
SequencerFeeVault_L2Withdrawal_Test:test_withdraw_toL2_succeeds() (gas: 80502) SequencerFeeVault_L2Withdrawal_Test:test_withdraw_toL2_succeeds() (gas: 80524)
SequencerFeeVault_L2Withdrawal_Test:test_withdraw_toL2recipientReverts_fails() (gas: 48948) SequencerFeeVault_L2Withdrawal_Test:test_withdraw_toL2recipientReverts_fails() (gas: 48904)
SequencerFeeVault_Test:test_constructor_succeeds() (gas: 7705) SequencerFeeVault_Test:test_constructor_succeeds() (gas: 7706)
SequencerFeeVault_Test:test_minWithdrawalAmount_succeeds() (gas: 12794) SequencerFeeVault_Test:test_minWithdrawalAmount_succeeds() (gas: 12860)
SequencerFeeVault_Test:test_receive_succeeds() (gas: 17395) SequencerFeeVault_Test:test_receive_succeeds() (gas: 17395)
SequencerFeeVault_Test:test_withdraw_notEnough_reverts() (gas: 9399) SequencerFeeVault_Test:test_withdraw_notEnough_reverts() (gas: 9421)
SequencerFeeVault_Test:test_withdraw_toL1_succeeds() (gas: 616090) SequencerFeeVault_Test:test_withdraw_toL1_succeeds() (gas: 616068)
SetPrevBaseFee_Test:test_setPrevBaseFee_succeeds() (gas: 11595) SetPrevBaseFee_Test:test_setPrevBaseFee_succeeds() (gas: 11617)
StandardBridge_Stateless_Test:test_isCorrectTokenPair_succeeds() (gas: 50149) StandardBridge_Stateless_Test:test_isCorrectTokenPair_succeeds() (gas: 50171)
StandardBridge_Stateless_Test:test_isOptimismMintableERC20_succeeds() (gas: 33142) StandardBridge_Stateless_Test:test_isOptimismMintableERC20_succeeds() (gas: 33098)
Storage_Roundtrip_Test:test_setGetAddress_succeeds(bytes32,address) (runs: 64, μ: 31221, ~: 31843) Storage_Roundtrip_Test:test_setGetAddress_succeeds(bytes32,address) (runs: 64, μ: 31221, ~: 31843)
Storage_Roundtrip_Test:test_setGetBytes32_succeeds(bytes32,bytes32) (runs: 64, μ: 31654, ~: 31654) Storage_Roundtrip_Test:test_setGetBytes32_succeeds(bytes32,bytes32) (runs: 64, μ: 31654, ~: 31654)
Storage_Roundtrip_Test:test_setGetUint_succeeds(bytes32,uint256) (runs: 64, μ: 30731, ~: 31664) Storage_Roundtrip_Test:test_setGetUint_succeeds(bytes32,uint256) (runs: 64, μ: 30731, ~: 31664)
SystemConfig_Initialize_Test:test_initialize_values_succeeds() (gas: 45459) SystemConfig_Initialize_Test:test_initialize_values_succeeds() (gas: 45504)
SystemConfig_Initialize_TestFail:test_initialize_lowGasLimit_reverts() (gas: 61167) SystemConfig_Initialize_TestFail:test_initialize_lowGasLimit_reverts() (gas: 61167)
SystemConfig_Setters_TestFail:test_setBatcherHash_notOwner_reverts() (gas: 15609) SystemConfig_Setters_TestFail:test_setBatcherHash_notOwner_reverts() (gas: 15631)
SystemConfig_Setters_TestFail:test_setGasConfig_notOwner_reverts() (gas: 15687) SystemConfig_Setters_TestFail:test_setGasConfig_notOwner_reverts() (gas: 15687)
SystemConfig_Setters_TestFail:test_setGasLimit_notOwner_reverts() (gas: 15677) SystemConfig_Setters_TestFail:test_setGasLimit_notOwner_reverts() (gas: 15655)
SystemConfig_Setters_TestFail:test_setResourceConfig_badMinMax_reverts() (gas: 18558) SystemConfig_Setters_TestFail:test_setResourceConfig_badMinMax_reverts() (gas: 18559)
SystemConfig_Setters_TestFail:test_setResourceConfig_badPrecision_reverts() (gas: 21182) SystemConfig_Setters_TestFail:test_setResourceConfig_badPrecision_reverts() (gas: 21160)
SystemConfig_Setters_TestFail:test_setResourceConfig_lowGasLimit_reverts() (gas: 22185) SystemConfig_Setters_TestFail:test_setResourceConfig_lowGasLimit_reverts() (gas: 22163)
SystemConfig_Setters_TestFail:test_setResourceConfig_notOwner_reverts() (gas: 16877) SystemConfig_Setters_TestFail:test_setResourceConfig_notOwner_reverts() (gas: 16854)
SystemConfig_Setters_TestFail:test_setResourceConfig_zeroDenominator_reverts() (gas: 18595) SystemConfig_Setters_TestFail:test_setResourceConfig_zeroDenominator_reverts() (gas: 18573)
SystemConfig_Setters_TestFail:test_setUnsafeBlockSigner_notOwner_reverts() (gas: 15658) SystemConfig_Setters_TestFail:test_setUnsafeBlockSigner_notOwner_reverts() (gas: 15679)
TransactorTest:test_call_succeeds() (gas: 26754) TransactorTest:test_call_succeeds() (gas: 26754)
TransactorTest:test_call_unauthorized_reverts() (gas: 18139) TransactorTest:test_call_unauthorized_reverts() (gas: 18139)
TransactorTest:test_constructor_succeeds() (gas: 9673) TransactorTest:test_constructor_succeeds() (gas: 9673)
TransactorTest:test_delegateCall_succeeds() (gas: 20931) TransactorTest:test_delegateCall_succeeds() (gas: 20931)
TransactorTest:test_delegateCall_unauthorized_reverts() (gas: 18124) TransactorTest:test_delegateCall_unauthorized_reverts() (gas: 18124)
TransferOnionTest:test_constructor_succeeds() (gas: 564789) TransferOnionTest:test_constructor_succeeds() (gas: 564789)
TransferOnionTest:test_unwrap_succeeds() (gas: 724955)
\ No newline at end of file
...@@ -86,26 +86,11 @@ To deploy the smart contracts on a local devnet, run `make devnet-up` in the mon ...@@ -86,26 +86,11 @@ To deploy the smart contracts on a local devnet, run `make devnet-up` in the mon
### Tools ### Tools
#### Layout Locking #### Validate Spacing
We use a system called "layout locking" as a safety mechanism to prevent certain contract variables from being moved to different storage slots accidentally. In order to make sure that we don't accidentally overwrite storage slots, contract storage layouts are checked to make sure spacing is correct.
To lock a contract variable, add it to the `layout-lock.json` file which has the following format:
This uses the `.storage-layout` file to check contract spacing. Run `pnpm validate-spacers` to check the spacing of all contracts.
```json
{
"MyContractName": {
"myVariableName": {
"slot": 1,
"offset": 0,
"length": 32
}
}
}
```
With the above config, the `validate-spacers` script will check that we have a contract called `MyContractName`, that the contract has a variable named `myVariableName`, and that the variable is in the correct position as defined in the lock file.
You should add things to the `layout-lock.json` file when you want those variables to **never** change.
Layout locking should be used in combination with diffing the `.storage-layout` file in CI.
#### Gas Snapshots #### Gas Snapshots
......
{
"L1CrossDomainMessenger": {
"spacer_0_0_20": {
"slot": 0,
"offset": 0,
"length": 20
},
"spacer_1_0_1600": {
"slot": 1,
"offset": 0,
"length": 1600
},
"spacer_51_0_20": {
"slot": 51,
"offset": 0,
"length": 20
},
"spacer_52_0_1568": {
"slot": 52,
"offset": 0,
"length": 1568
},
"spacer_101_0_1": {
"slot": 101,
"offset": 0,
"length": 1
},
"spacer_102_0_1568": {
"slot": 102,
"offset": 0,
"length": 1568
},
"spacer_151_0_32": {
"slot": 151,
"offset": 0,
"length": 32
},
"spacer_201_0_32": {
"slot": 201,
"offset": 0,
"length": 32
},
"spacer_202_0_32": {
"slot": 202,
"offset": 0,
"length": 32
}
},
"L2CrossDomainMessenger": {
"spacer_0_0_20": {
"slot": 0,
"offset": 0,
"length": 20
},
"spacer_1_0_1600": {
"slot": 1,
"offset": 0,
"length": 1600
},
"spacer_51_0_20": {
"slot": 51,
"offset": 0,
"length": 20
},
"spacer_52_0_1568": {
"slot": 52,
"offset": 0,
"length": 1568
},
"spacer_101_0_1": {
"slot": 101,
"offset": 0,
"length": 1
},
"spacer_102_0_1568": {
"slot": 102,
"offset": 0,
"length": 1568
},
"spacer_151_0_32": {
"slot": 151,
"offset": 0,
"length": 32
},
"spacer_201_0_32": {
"slot": 201,
"offset": 0,
"length": 32
},
"spacer_202_0_32": {
"slot": 202,
"offset": 0,
"length": 32
}
},
"L1StandardBridge": {
"spacer_0_2_20": {
"slot": 0,
"offset": 2,
"length": 20
},
"spacer_1_0_20": {
"slot": 1,
"offset": 0,
"length": 20
}
}
}
...@@ -45,9 +45,9 @@ ...@@ -45,9 +45,9 @@
"lint": "pnpm lint:fix && pnpm lint:check" "lint": "pnpm lint:fix && pnpm lint:check"
}, },
"devDependencies": { "devDependencies": {
"@typescript-eslint/eslint-plugin": "^6.11.0", "@typescript-eslint/eslint-plugin": "^6.12.0",
"@typescript-eslint/parser": "^6.11.0", "@typescript-eslint/parser": "^6.11.0",
"tsx": "^4.1.1", "tsx": "^4.2.0",
"typescript": "^5.2.2" "typescript": "^5.2.2"
} }
} }
...@@ -55,11 +55,149 @@ import { Types } from "scripts/Types.sol"; ...@@ -55,11 +55,149 @@ import { Types } from "scripts/Types.sol";
contract Deploy is Deployer { contract Deploy is Deployer {
DeployConfig cfg; DeployConfig cfg;
////////////////////////////////////////////////////////////////
// Modifiers //
////////////////////////////////////////////////////////////////
/// @notice Modifier that wraps a function in broadcasting.
modifier broadcast() {
vm.startBroadcast();
_;
vm.stopBroadcast();
}
/// @notice Modifier that will only allow a function to be called on devnet.
modifier onlyDevnet() {
uint256 chainid = block.chainid;
if (chainid == Chains.LocalDevnet || chainid == Chains.GethDevnet) {
_;
}
}
/// @notice Modifier that will only allow a function to be called on a public
/// testnet or devnet.
modifier onlyTestnetOrDevnet() {
uint256 chainid = block.chainid;
if (
chainid == Chains.Goerli || chainid == Chains.Sepolia || chainid == Chains.LocalDevnet
|| chainid == Chains.GethDevnet
) {
_;
}
}
////////////////////////////////////////////////////////////////
// Accessors //
////////////////////////////////////////////////////////////////
/// @inheritdoc Deployer /// @inheritdoc Deployer
function name() public pure override returns (string memory name_) { function name() public pure override returns (string memory name_) {
name_ = "Deploy"; name_ = "Deploy";
} }
/// @notice The create2 salt used for deployment of the contract implementations.
/// Using this helps to reduce config across networks as the implementation
/// addresses will be the same across networks when deployed with create2.
function _implSalt() internal returns (bytes32) {
return keccak256(bytes(vm.envOr("IMPL_SALT", string("ethers phoenix"))));
}
/// @notice Returns the proxy addresses
function _proxies() private view returns (Types.ContractSet memory proxies_) {
proxies_ = Types.ContractSet({
L1CrossDomainMessenger: mustGetAddress("L1CrossDomainMessengerProxy"),
L1StandardBridge: mustGetAddress("L1StandardBridgeProxy"),
L2OutputOracle: mustGetAddress("L2OutputOracleProxy"),
OptimismMintableERC20Factory: mustGetAddress("OptimismMintableERC20FactoryProxy"),
OptimismPortal: mustGetAddress("OptimismPortalProxy"),
SystemConfig: mustGetAddress("SystemConfigProxy"),
L1ERC721Bridge: mustGetAddress("L1ERC721BridgeProxy"),
ProtocolVersions: mustGetAddress("ProtocolVersionsProxy")
});
}
/// @notice Returns the proxy addresses, not reverting if any are unset.
function _proxiesUnstrict() private view returns (Types.ContractSet memory proxies_) {
proxies_ = Types.ContractSet({
L1CrossDomainMessenger: getAddress("L1CrossDomainMessengerProxy"),
L1StandardBridge: getAddress("L1StandardBridgeProxy"),
L2OutputOracle: getAddress("L2OutputOracleProxy"),
OptimismMintableERC20Factory: getAddress("OptimismMintableERC20FactoryProxy"),
OptimismPortal: getAddress("OptimismPortalProxy"),
SystemConfig: getAddress("SystemConfigProxy"),
L1ERC721Bridge: getAddress("L1ERC721BridgeProxy"),
ProtocolVersions: getAddress("ProtocolVersionsProxy")
});
}
////////////////////////////////////////////////////////////////
// State Changing Helper Functions //
////////////////////////////////////////////////////////////////
/// @notice Gets the address of the SafeProxyFactory and Safe singleton for use in deploying a new GnosisSafe.
function _getSafeFactory() internal returns (SafeProxyFactory safeProxyFactory_, Safe safeSingleton_) {
// These are they standard create2 deployed contracts. First we'll check if they are deployed,
// if not we'll deploy new ones, though not at these addresses.
address safeProxyFactory = 0xa6B71E26C5e0845f74c812102Ca7114b6a896AB2;
address safeSingleton = 0xd9Db270c1B5E3Bd161E8c8503c55cEABeE709552;
safeProxyFactory.code.length == 0
? safeProxyFactory_ = new SafeProxyFactory()
: safeProxyFactory_ = SafeProxyFactory(safeProxyFactory);
safeSingleton.code.length == 0 ? safeSingleton_ = new Safe() : safeSingleton_ = Safe(payable(safeSingleton));
save("SafeProxyFactory", address(safeProxyFactory_));
save("SafeSingleton", address(safeSingleton_));
}
/// @notice Make a call from the Safe contract to an arbitrary address with arbitrary data
function _callViaSafe(address _target, bytes memory _data) internal {
Safe safe = Safe(mustGetAddress("SystemOwnerSafe"));
// This is the signature format used the caller is also the signer.
bytes memory signature = abi.encodePacked(uint256(uint160(msg.sender)), bytes32(0), uint8(1));
safe.execTransaction({
to: _target,
value: 0,
data: _data,
operation: SafeOps.Operation.Call,
safeTxGas: 0,
baseGas: 0,
gasPrice: 0,
gasToken: address(0),
refundReceiver: payable(address(0)),
signatures: signature
});
}
/// @notice Call from the Safe contract to the Proxy Admin's upgrade and call method
function _upgradeAndCallViaSafe(address _proxy, address _implementation, bytes memory _innerCallData) internal {
address proxyAdmin = mustGetAddress("ProxyAdmin");
bytes memory data =
abi.encodeCall(ProxyAdmin.upgradeAndCall, (payable(_proxy), _implementation, _innerCallData));
_callViaSafe({ _target: proxyAdmin, _data: data });
}
/// @notice Transfer ownership of the ProxyAdmin contract to the final system owner
function transferProxyAdminOwnership() public broadcast {
ProxyAdmin proxyAdmin = ProxyAdmin(mustGetAddress("ProxyAdmin"));
address owner = proxyAdmin.owner();
address safe = mustGetAddress("SystemOwnerSafe");
if (owner != safe) {
proxyAdmin.transferOwnership(safe);
console.log("ProxyAdmin ownership transferred to Safe at: %s", safe);
}
}
////////////////////////////////////////////////////////////////
// SetUp and Run //
////////////////////////////////////////////////////////////////
function setUp() public virtual override { function setUp() public virtual override {
super.setUp(); super.setUp();
...@@ -96,54 +234,24 @@ contract Deploy is Deployer { ...@@ -96,54 +234,24 @@ contract Deploy is Deployer {
transferDisputeGameFactoryOwnership(); transferDisputeGameFactoryOwnership();
} }
/// @notice The create2 salt used for deployment of the contract implementations. ////////////////////////////////////////////////////////////////
/// Using this helps to reduce config across networks as the implementation // High Level Deployment Functions //
/// addresses will be the same across networks when deployed with create2. ////////////////////////////////////////////////////////////////
function implSalt() internal returns (bytes32) {
return keccak256(bytes(vm.envOr("IMPL_SALT", string("ethers phoenix"))));
}
/// @notice Modifier that wraps a function in broadcasting.
modifier broadcast() {
vm.startBroadcast();
_;
vm.stopBroadcast();
}
/// @notice Modifier that will only allow a function to be called on devnet.
modifier onlyDevnet() {
uint256 chainid = block.chainid;
if (chainid == Chains.LocalDevnet || chainid == Chains.GethDevnet) {
_;
}
}
/// @notice Modifier that will only allow a function to be called on a public
/// testnet or devnet.
modifier onlyTestnetOrDevnet() {
uint256 chainid = block.chainid;
if (
chainid == Chains.Goerli || chainid == Chains.Sepolia || chainid == Chains.LocalDevnet
|| chainid == Chains.GethDevnet
) {
_;
}
}
/// @notice Deploy all of the proxies /// @notice Deploy all of the proxies
function deployProxies() public { function deployProxies() public {
deployAddressManager(); deployAddressManager();
deployProxyAdmin(); deployProxyAdmin();
deployOptimismPortalProxy(); deployERC1967Proxy("OptimismPortalProxy");
deployL2OutputOracleProxy(); deployERC1967Proxy("L2OutputOracleProxy");
deploySystemConfigProxy(); deployERC1967Proxy("SystemConfigProxy");
deployL1StandardBridgeProxy(); deployL1StandardBridgeProxy();
deployL1CrossDomainMessengerProxy(); deployL1CrossDomainMessengerProxy();
deployOptimismMintableERC20FactoryProxy(); deployERC1967Proxy("OptimismMintableERC20FactoryProxy");
deployL1ERC721BridgeProxy(); deployERC1967Proxy("L1ERC721BridgeProxy");
deployDisputeGameFactoryProxy(); deployERC1967Proxy("DisputeGameFactoryProxy");
deployProtocolVersionsProxy(); deployERC1967Proxy("ProtocolVersionsProxy");
transferAddressManagerOwnership(); // to the ProxyAdmin transferAddressManagerOwnership(); // to the ProxyAdmin
} }
...@@ -164,22 +272,9 @@ contract Deploy is Deployer { ...@@ -164,22 +272,9 @@ contract Deploy is Deployer {
deployProtocolVersions(); deployProtocolVersions();
} }
// @notice Gets the address of the SafeProxyFactory and Safe singleton for use in deploying a new GnosisSafe. ////////////////////////////////////////////////////////////////
function _getSafeFactory() internal returns (SafeProxyFactory safeProxyFactory_, Safe safeSingleton_) { // Non-Proxied Deployment Functions //
// These are they standard create2 deployed contracts. First we'll check if they are deployed, ////////////////////////////////////////////////////////////////
// if not we'll deploy new ones, though not at these addresses.
address safeProxyFactory = 0xa6B71E26C5e0845f74c812102Ca7114b6a896AB2;
address safeSingleton = 0xd9Db270c1B5E3Bd161E8c8503c55cEABeE709552;
safeProxyFactory.code.length == 0
? safeProxyFactory_ = new SafeProxyFactory()
: safeProxyFactory_ = SafeProxyFactory(safeProxyFactory);
safeSingleton.code.length == 0 ? safeSingleton_ = new Safe() : safeSingleton_ = Safe(payable(safeSingleton));
save("SafeProxyFactory", address(safeProxyFactory_));
save("SafeSingleton", address(safeSingleton_));
}
/// @notice Deploy the Safe /// @notice Deploy the Safe
function deploySafe() public broadcast returns (address addr_) { function deploySafe() public broadcast returns (address addr_) {
...@@ -227,7 +322,20 @@ contract Deploy is Deployer { ...@@ -227,7 +322,20 @@ contract Deploy is Deployer {
addr_ = address(admin); addr_ = address(admin);
} }
/// @notice Deploy the L1StandardBridgeProxy /// @notice Deploy the StorageSetter contract, used for upgrades.
function deployStorageSetter() public broadcast returns (address addr_) {
StorageSetter setter = new StorageSetter{ salt: _implSalt() }();
console.log("StorageSetter deployed at: %s", address(setter));
string memory version = setter.version();
console.log("StorageSetter version: %s", version);
addr_ = address(setter);
}
////////////////////////////////////////////////////////////////
// Proxy Deployment Functions //
////////////////////////////////////////////////////////////////
/// @notice Deploy the L1StandardBridgeProxy using a ChugSplashProxy
function deployL1StandardBridgeProxy() public broadcast returns (address addr_) { function deployL1StandardBridgeProxy() public broadcast returns (address addr_) {
address proxyAdmin = mustGetAddress("ProxyAdmin"); address proxyAdmin = mustGetAddress("ProxyAdmin");
L1ChugSplashProxy proxy = new L1ChugSplashProxy(proxyAdmin); L1ChugSplashProxy proxy = new L1ChugSplashProxy(proxyAdmin);
...@@ -240,22 +348,7 @@ contract Deploy is Deployer { ...@@ -240,22 +348,7 @@ contract Deploy is Deployer {
addr_ = address(proxy); addr_ = address(proxy);
} }
/// @notice Deploy the L2OutputOracleProxy /// @notice Deploy the L1CrossDomainMessengerProxy using a ResolvedDelegateProxy
function deployL2OutputOracleProxy() public broadcast returns (address addr_) {
address proxyAdmin = mustGetAddress("ProxyAdmin");
Proxy proxy = new Proxy({
_admin: proxyAdmin
});
address admin = address(uint160(uint256(vm.load(address(proxy), OWNER_KEY))));
require(admin == proxyAdmin);
save("L2OutputOracleProxy", address(proxy));
console.log("L2OutputOracleProxy deployed at %s", address(proxy));
addr_ = address(proxy);
}
/// @notice Deploy the L1CrossDomainMessengerProxy
function deployL1CrossDomainMessengerProxy() public broadcast returns (address addr_) { function deployL1CrossDomainMessengerProxy() public broadcast returns (address addr_) {
AddressManager addressManager = AddressManager(mustGetAddress("AddressManager")); AddressManager addressManager = AddressManager(mustGetAddress("AddressManager"));
string memory contractName = "OVM_L1CrossDomainMessenger"; string memory contractName = "OVM_L1CrossDomainMessenger";
...@@ -274,40 +367,8 @@ contract Deploy is Deployer { ...@@ -274,40 +367,8 @@ contract Deploy is Deployer {
addr_ = address(proxy); addr_ = address(proxy);
} }
/// @notice Deploy the OptimismPortalProxy function deployERC1967Proxy(string memory _name) public broadcast returns (address addr_) {
function deployOptimismPortalProxy() public broadcast returns (address addr_) { console.log(string.concat("Deploying ", _name));
address proxyAdmin = mustGetAddress("ProxyAdmin");
Proxy proxy = new Proxy({
_admin: proxyAdmin
});
address admin = address(uint160(uint256(vm.load(address(proxy), OWNER_KEY))));
require(admin == proxyAdmin);
save("OptimismPortalProxy", address(proxy));
console.log("OptimismPortalProxy deployed at %s", address(proxy));
addr_ = address(proxy);
}
/// @notice Deploy the OptimismMintableERC20FactoryProxy
function deployOptimismMintableERC20FactoryProxy() public broadcast returns (address addr_) {
address proxyAdmin = mustGetAddress("ProxyAdmin");
Proxy proxy = new Proxy({
_admin: proxyAdmin
});
address admin = address(uint160(uint256(vm.load(address(proxy), OWNER_KEY))));
require(admin == proxyAdmin);
save("OptimismMintableERC20FactoryProxy", address(proxy));
console.log("OptimismMintableERC20FactoryProxy deployed at %s", address(proxy));
addr_ = address(proxy);
}
/// @notice Deploy the L1ERC721BridgeProxy
function deployL1ERC721BridgeProxy() public broadcast returns (address addr_) {
address proxyAdmin = mustGetAddress("ProxyAdmin"); address proxyAdmin = mustGetAddress("ProxyAdmin");
Proxy proxy = new Proxy({ Proxy proxy = new Proxy({
_admin: proxyAdmin _admin: proxyAdmin
...@@ -316,64 +377,19 @@ contract Deploy is Deployer { ...@@ -316,64 +377,19 @@ contract Deploy is Deployer {
address admin = address(uint160(uint256(vm.load(address(proxy), OWNER_KEY)))); address admin = address(uint160(uint256(vm.load(address(proxy), OWNER_KEY))));
require(admin == proxyAdmin); require(admin == proxyAdmin);
save("L1ERC721BridgeProxy", address(proxy)); save(_name, address(proxy));
console.log("L1ERC721BridgeProxy deployed at %s", address(proxy)); console.log(" at %s", address(proxy));
addr_ = address(proxy); addr_ = address(proxy);
} }
/// @notice Deploy the SystemConfigProxy ////////////////////////////////////////////////////////////////
function deploySystemConfigProxy() public broadcast returns (address addr_) { // Implementation Deployment Functions //
address proxyAdmin = mustGetAddress("ProxyAdmin"); ////////////////////////////////////////////////////////////////
Proxy proxy = new Proxy({
_admin: proxyAdmin
});
address admin = address(uint160(uint256(vm.load(address(proxy), OWNER_KEY))));
require(admin == proxyAdmin);
save("SystemConfigProxy", address(proxy));
console.log("SystemConfigProxy deployed at %s", address(proxy));
addr_ = address(proxy);
}
/// @notice Deploy the DisputeGameFactoryProxy
function deployDisputeGameFactoryProxy() public onlyDevnet broadcast returns (address addr_) {
address proxyAdmin = mustGetAddress("ProxyAdmin");
Proxy proxy = new Proxy({
_admin: proxyAdmin
});
address admin = address(uint160(uint256(vm.load(address(proxy), OWNER_KEY))));
require(admin == proxyAdmin);
save("DisputeGameFactoryProxy", address(proxy));
console.log("DisputeGameFactoryProxy deployed at %s", address(proxy));
addr_ = address(proxy);
}
/// @notice Deploy the ProtocolVersionsProxy
function deployProtocolVersionsProxy() public broadcast returns (address addr_) {
address proxyAdmin = mustGetAddress("ProxyAdmin");
Proxy proxy = new Proxy({
_admin: proxyAdmin
});
address admin = address(uint160(uint256(vm.load(address(proxy), OWNER_KEY))));
require(admin == proxyAdmin);
save("ProtocolVersionsProxy", address(proxy));
console.log("ProtocolVersionsProxy deployed at %s", address(proxy));
addr_ = address(proxy);
}
/// @notice Deploy the L1CrossDomainMessenger /// @notice Deploy the L1CrossDomainMessenger
function deployL1CrossDomainMessenger() public broadcast returns (address addr_) { function deployL1CrossDomainMessenger() public broadcast returns (address addr_) {
address portal = mustGetAddress("OptimismPortalProxy"); address portal = mustGetAddress("OptimismPortalProxy");
L1CrossDomainMessenger messenger = new L1CrossDomainMessenger{ salt: implSalt() }({ L1CrossDomainMessenger messenger = new L1CrossDomainMessenger{ salt: _implSalt() }({
_portal: OptimismPortal(payable(portal)) _portal: OptimismPortal(payable(portal))
}); });
...@@ -399,7 +415,7 @@ contract Deploy is Deployer { ...@@ -399,7 +415,7 @@ contract Deploy is Deployer {
L2OutputOracle l2OutputOracle = L2OutputOracle(mustGetAddress("L2OutputOracleProxy")); L2OutputOracle l2OutputOracle = L2OutputOracle(mustGetAddress("L2OutputOracleProxy"));
SystemConfig systemConfig = SystemConfig(mustGetAddress("SystemConfigProxy")); SystemConfig systemConfig = SystemConfig(mustGetAddress("SystemConfigProxy"));
OptimismPortal portal = new OptimismPortal{ salt: implSalt() }({ OptimismPortal portal = new OptimismPortal{ salt: _implSalt() }({
_l2Oracle: l2OutputOracle, _l2Oracle: l2OutputOracle,
_guardian: guardian, _guardian: guardian,
_paused: true, _paused: true,
...@@ -420,7 +436,7 @@ contract Deploy is Deployer { ...@@ -420,7 +436,7 @@ contract Deploy is Deployer {
/// @notice Deploy the L2OutputOracle /// @notice Deploy the L2OutputOracle
function deployL2OutputOracle() public broadcast returns (address addr_) { function deployL2OutputOracle() public broadcast returns (address addr_) {
L2OutputOracle oracle = new L2OutputOracle{ salt: implSalt() }({ L2OutputOracle oracle = new L2OutputOracle{ salt: _implSalt() }({
_submissionInterval: cfg.l2OutputOracleSubmissionInterval(), _submissionInterval: cfg.l2OutputOracleSubmissionInterval(),
_l2BlockTime: cfg.l2BlockTime(), _l2BlockTime: cfg.l2BlockTime(),
_startingBlockNumber: 0, _startingBlockNumber: 0,
...@@ -446,7 +462,7 @@ contract Deploy is Deployer { ...@@ -446,7 +462,7 @@ contract Deploy is Deployer {
function deployOptimismMintableERC20Factory() public broadcast returns (address addr_) { function deployOptimismMintableERC20Factory() public broadcast returns (address addr_) {
address l1standardBridgeProxy = mustGetAddress("L1StandardBridgeProxy"); address l1standardBridgeProxy = mustGetAddress("L1StandardBridgeProxy");
OptimismMintableERC20Factory factory = OptimismMintableERC20Factory factory =
new OptimismMintableERC20Factory{ salt: implSalt() }({_bridge: l1standardBridgeProxy}); new OptimismMintableERC20Factory{ salt: _implSalt() }({_bridge: l1standardBridgeProxy});
save("OptimismMintableERC20Factory", address(factory)); save("OptimismMintableERC20Factory", address(factory));
console.log("OptimismMintableERC20Factory deployed at %s", address(factory)); console.log("OptimismMintableERC20Factory deployed at %s", address(factory));
...@@ -460,7 +476,7 @@ contract Deploy is Deployer { ...@@ -460,7 +476,7 @@ contract Deploy is Deployer {
/// @notice Deploy the DisputeGameFactory /// @notice Deploy the DisputeGameFactory
function deployDisputeGameFactory() public onlyDevnet broadcast returns (address addr_) { function deployDisputeGameFactory() public onlyDevnet broadcast returns (address addr_) {
DisputeGameFactory factory = new DisputeGameFactory{ salt: implSalt() }(); DisputeGameFactory factory = new DisputeGameFactory{ salt: _implSalt() }();
save("DisputeGameFactory", address(factory)); save("DisputeGameFactory", address(factory));
console.log("DisputeGameFactory deployed at %s", address(factory)); console.log("DisputeGameFactory deployed at %s", address(factory));
...@@ -469,7 +485,7 @@ contract Deploy is Deployer { ...@@ -469,7 +485,7 @@ contract Deploy is Deployer {
/// @notice Deploy the BlockOracle /// @notice Deploy the BlockOracle
function deployBlockOracle() public onlyDevnet broadcast returns (address addr_) { function deployBlockOracle() public onlyDevnet broadcast returns (address addr_) {
BlockOracle oracle = new BlockOracle{ salt: implSalt() }(); BlockOracle oracle = new BlockOracle{ salt: _implSalt() }();
save("BlockOracle", address(oracle)); save("BlockOracle", address(oracle));
console.log("BlockOracle deployed at %s", address(oracle)); console.log("BlockOracle deployed at %s", address(oracle));
...@@ -478,7 +494,7 @@ contract Deploy is Deployer { ...@@ -478,7 +494,7 @@ contract Deploy is Deployer {
/// @notice Deploy the ProtocolVersions /// @notice Deploy the ProtocolVersions
function deployProtocolVersions() public broadcast returns (address addr_) { function deployProtocolVersions() public broadcast returns (address addr_) {
ProtocolVersions versions = new ProtocolVersions{ salt: implSalt() }(); ProtocolVersions versions = new ProtocolVersions{ salt: _implSalt() }();
save("ProtocolVersions", address(versions)); save("ProtocolVersions", address(versions));
console.log("ProtocolVersions deployed at %s", address(versions)); console.log("ProtocolVersions deployed at %s", address(versions));
...@@ -493,7 +509,7 @@ contract Deploy is Deployer { ...@@ -493,7 +509,7 @@ contract Deploy is Deployer {
/// @notice Deploy the PreimageOracle /// @notice Deploy the PreimageOracle
function deployPreimageOracle() public onlyDevnet broadcast returns (address addr_) { function deployPreimageOracle() public onlyDevnet broadcast returns (address addr_) {
PreimageOracle preimageOracle = new PreimageOracle{ salt: implSalt() }(); PreimageOracle preimageOracle = new PreimageOracle{ salt: _implSalt() }();
save("PreimageOracle", address(preimageOracle)); save("PreimageOracle", address(preimageOracle));
console.log("PreimageOracle deployed at %s", address(preimageOracle)); console.log("PreimageOracle deployed at %s", address(preimageOracle));
...@@ -502,7 +518,7 @@ contract Deploy is Deployer { ...@@ -502,7 +518,7 @@ contract Deploy is Deployer {
/// @notice Deploy Mips /// @notice Deploy Mips
function deployMips() public onlyDevnet broadcast returns (address addr_) { function deployMips() public onlyDevnet broadcast returns (address addr_) {
MIPS mips = new MIPS{ salt: implSalt() }(IPreimageOracle(mustGetAddress("PreimageOracle"))); MIPS mips = new MIPS{ salt: _implSalt() }(IPreimageOracle(mustGetAddress("PreimageOracle")));
save("Mips", address(mips)); save("Mips", address(mips));
console.log("MIPS deployed at %s", address(mips)); console.log("MIPS deployed at %s", address(mips));
...@@ -539,7 +555,7 @@ contract Deploy is Deployer { ...@@ -539,7 +555,7 @@ contract Deploy is Deployer {
function deployL1StandardBridge() public broadcast returns (address addr_) { function deployL1StandardBridge() public broadcast returns (address addr_) {
address l1CrossDomainMessengerProxy = mustGetAddress("L1CrossDomainMessengerProxy"); address l1CrossDomainMessengerProxy = mustGetAddress("L1CrossDomainMessengerProxy");
L1StandardBridge bridge = new L1StandardBridge{ salt: implSalt() }({ L1StandardBridge bridge = new L1StandardBridge{ salt: _implSalt() }({
_messenger: payable(l1CrossDomainMessengerProxy) _messenger: payable(l1CrossDomainMessengerProxy)
}); });
...@@ -556,7 +572,7 @@ contract Deploy is Deployer { ...@@ -556,7 +572,7 @@ contract Deploy is Deployer {
/// @notice Deploy the L1ERC721Bridge /// @notice Deploy the L1ERC721Bridge
function deployL1ERC721Bridge() public broadcast returns (address addr_) { function deployL1ERC721Bridge() public broadcast returns (address addr_) {
address l1CrossDomainMessengerProxy = mustGetAddress("L1CrossDomainMessengerProxy"); address l1CrossDomainMessengerProxy = mustGetAddress("L1CrossDomainMessengerProxy");
L1ERC721Bridge bridge = new L1ERC721Bridge{ salt: implSalt() }({ L1ERC721Bridge bridge = new L1ERC721Bridge{ salt: _implSalt() }({
_messenger: l1CrossDomainMessengerProxy, _messenger: l1CrossDomainMessengerProxy,
_otherBridge: Predeploys.L2_ERC721_BRIDGE _otherBridge: Predeploys.L2_ERC721_BRIDGE
}); });
...@@ -584,36 +600,9 @@ contract Deploy is Deployer { ...@@ -584,36 +600,9 @@ contract Deploy is Deployer {
require(addressManager.owner() == proxyAdmin); require(addressManager.owner() == proxyAdmin);
} }
/// @notice Make a call from the Safe contract to an arbitrary address with arbitrary data ////////////////////////////////////////////////////////////////
function _callViaSafe(address _target, bytes memory _data) internal { // Initialize Functions //
Safe safe = Safe(mustGetAddress("SystemOwnerSafe")); ////////////////////////////////////////////////////////////////
// This is the signature format used the caller is also the signer.
bytes memory signature = abi.encodePacked(uint256(uint160(msg.sender)), bytes32(0), uint8(1));
safe.execTransaction({
to: _target,
value: 0,
data: _data,
operation: SafeOps.Operation.Call,
safeTxGas: 0,
baseGas: 0,
gasPrice: 0,
gasToken: address(0),
refundReceiver: payable(address(0)),
signatures: signature
});
}
/// @notice Call from the Safe contract to the Proxy Admin's upgrade and call method
function _upgradeAndCallViaSafe(address _proxy, address _implementation, bytes memory _innerCallData) internal {
address proxyAdmin = mustGetAddress("ProxyAdmin");
bytes memory data =
abi.encodeCall(ProxyAdmin.upgradeAndCall, (payable(_proxy), _implementation, _innerCallData));
_callViaSafe({ _target: proxyAdmin, _data: data });
}
/// @notice Initialize the DisputeGameFactory /// @notice Initialize the DisputeGameFactory
function initializeDisputeGameFactory() public onlyDevnet broadcast { function initializeDisputeGameFactory() public onlyDevnet broadcast {
...@@ -846,17 +835,6 @@ contract Deploy is Deployer { ...@@ -846,17 +835,6 @@ contract Deploy is Deployer {
require(loadInitializedSlot("ProtocolVersions", true) == 1, "ProtocolVersionsProxy is not initialized"); require(loadInitializedSlot("ProtocolVersions", true) == 1, "ProtocolVersionsProxy is not initialized");
} }
/// @notice Transfer ownership of the ProxyAdmin contract to the final system owner
function transferProxyAdminOwnership() public broadcast {
ProxyAdmin proxyAdmin = ProxyAdmin(mustGetAddress("ProxyAdmin"));
address owner = proxyAdmin.owner();
address safe = mustGetAddress("SystemOwnerSafe");
if (owner != safe) {
proxyAdmin.transferOwnership(safe);
console.log("ProxyAdmin ownership transferred to Safe at: %s", safe);
}
}
/// @notice Transfer ownership of the DisputeGameFactory contract to the final system owner /// @notice Transfer ownership of the DisputeGameFactory contract to the final system owner
function transferDisputeGameFactoryOwnership() public onlyDevnet broadcast { function transferDisputeGameFactoryOwnership() public onlyDevnet broadcast {
DisputeGameFactory disputeGameFactory = DisputeGameFactory(mustGetAddress("DisputeGameFactoryProxy")); DisputeGameFactory disputeGameFactory = DisputeGameFactory(mustGetAddress("DisputeGameFactoryProxy"));
...@@ -955,41 +933,4 @@ contract Deploy is Deployer { ...@@ -955,41 +933,4 @@ contract Deploy is Deployer {
); );
} }
} }
/// @notice Deploy the StorageSetter contract, used for upgrades.
function deployStorageSetter() public broadcast returns (address addr_) {
StorageSetter setter = new StorageSetter{ salt: implSalt() }();
console.log("StorageSetter deployed at: %s", address(setter));
string memory version = setter.version();
console.log("StorageSetter version: %s", version);
addr_ = address(setter);
}
/// @notice Returns the proxy addresses
function _proxies() private view returns (Types.ContractSet memory proxies_) {
proxies_ = Types.ContractSet({
L1CrossDomainMessenger: mustGetAddress("L1CrossDomainMessengerProxy"),
L1StandardBridge: mustGetAddress("L1StandardBridgeProxy"),
L2OutputOracle: mustGetAddress("L2OutputOracleProxy"),
OptimismMintableERC20Factory: mustGetAddress("OptimismMintableERC20FactoryProxy"),
OptimismPortal: mustGetAddress("OptimismPortalProxy"),
SystemConfig: mustGetAddress("SystemConfigProxy"),
L1ERC721Bridge: mustGetAddress("L1ERC721BridgeProxy"),
ProtocolVersions: mustGetAddress("ProtocolVersionsProxy")
});
}
/// @notice Returns the proxy addresses, not reverting if any are unset.
function _proxiesUnstrict() private view returns (Types.ContractSet memory proxies_) {
proxies_ = Types.ContractSet({
L1CrossDomainMessenger: getAddress("L1CrossDomainMessengerProxy"),
L1StandardBridge: getAddress("L1StandardBridgeProxy"),
L2OutputOracle: getAddress("L2OutputOracleProxy"),
OptimismMintableERC20Factory: getAddress("OptimismMintableERC20FactoryProxy"),
OptimismPortal: getAddress("OptimismPortalProxy"),
SystemConfig: getAddress("SystemConfigProxy"),
L1ERC721Bridge: getAddress("L1ERC721BridgeProxy"),
ProtocolVersions: getAddress("ProtocolVersionsProxy")
});
}
} }
import fs from 'fs' import fs from 'fs'
import path from 'path' import path from 'path'
import layoutLock from '../layout-lock.json'
/** /**
* Directory path to the artifacts. * Directory path to the artifacts.
* Can be configured as the first argument to the script or * Can be configured as the first argument to the script or
...@@ -22,15 +20,6 @@ const skipped = (contractName: string): boolean => { ...@@ -22,15 +20,6 @@ const skipped = (contractName: string): boolean => {
return contractName.includes('CrossDomainMessengerLegacySpacer') return contractName.includes('CrossDomainMessengerLegacySpacer')
} }
/**
* Parses the fully qualified name of a contract into the name of the contract.
* For example `contracts/Foo.sol:Foo` becomes `Foo`.
*/
const parseFqn = (name: string): string => {
const parts = name.split(':')
return parts[parts.length - 1]
}
/** /**
* Parses out variable info from the variable structure in standard compiler json output. * Parses out variable info from the variable structure in standard compiler json output.
* *
...@@ -89,7 +78,6 @@ const parseVariableInfo = ( ...@@ -89,7 +78,6 @@ const parseVariableInfo = (
/** /**
* Main logic of the script * Main logic of the script
* - Ensures that all of the spacer variables are named correctly * - Ensures that all of the spacer variables are named correctly
* - Ensures that storage slots in the layout lock file do not change
*/ */
const main = async () => { const main = async () => {
const paths = [] const paths = []
...@@ -128,24 +116,6 @@ const main = async () => { ...@@ -128,24 +116,6 @@ const main = async () => {
continue continue
} }
const contractName = parseFqn(fqn)
// Check that the layout lock has not changed
const lock = layoutLock[contractName] || {}
if (lock[variable.label]) {
const variableInfo = parseVariableInfo(variable)
const expectedInfo = lock[variable.label]
if (variableInfo.slot !== expectedInfo.slot) {
throw new Error(`${fqn}.${variable.label} slot has changed`)
}
if (variableInfo.offset !== expectedInfo.offset) {
throw new Error(`${fqn}.${variable.label} offset has changed`)
}
if (variableInfo.length !== expectedInfo.length) {
throw new Error(`${fqn}.${variable.label} length has changed`)
}
}
// Check that the spacers are all named correctly // Check that the spacers are all named correctly
if (variable.label.startsWith('spacer_')) { if (variable.label.startsWith('spacer_')) {
const [, slot, offset, length] = variable.label.split('_') const [, slot, offset, length] = variable.label.split('_')
......
...@@ -49,7 +49,7 @@ ...@@ -49,7 +49,7 @@
"node-fetch": "^2.6.7" "node-fetch": "^2.6.7"
}, },
"devDependencies": { "devDependencies": {
"@types/node": "^20.9.0", "@types/node": "^20.9.3",
"mocha": "^10.2.0" "mocha": "^10.2.0"
} }
} }
# @eth-optimism/sdk # @eth-optimism/sdk
## 3.1.6
### Patch Changes
- [#8212](https://github.com/ethereum-optimism/optimism/pull/8212) [`dd0e46986`](https://github.com/ethereum-optimism/optimism/commit/dd0e46986f19dcceb304fc48f2bd410685ecd179) Thanks [@smartcontracts](https://github.com/smartcontracts)! - Simplifies getMessageStatus to use an O(1) lookup instead of an event query
## 3.1.5 ## 3.1.5
### Patch Changes ### Patch Changes
......
{ {
"name": "@eth-optimism/sdk", "name": "@eth-optimism/sdk",
"version": "3.1.5", "version": "3.1.6",
"description": "[Optimism] Tools for working with Optimism", "description": "[Optimism] Tools for working with Optimism",
"main": "dist/index", "main": "dist/index",
"types": "dist/index", "types": "dist/index",
...@@ -43,8 +43,8 @@ ...@@ -43,8 +43,8 @@
"@nomiclabs/hardhat-waffle": "^2.0.1", "@nomiclabs/hardhat-waffle": "^2.0.1",
"@types/chai": "^4.3.10", "@types/chai": "^4.3.10",
"@types/chai-as-promised": "^7.1.8", "@types/chai-as-promised": "^7.1.8",
"@types/mocha": "^10.0.4", "@types/mocha": "^10.0.6",
"@types/node": "^20.9.0", "@types/node": "^20.9.3",
"chai-as-promised": "^7.1.1", "chai-as-promised": "^7.1.1",
"ethereum-waffle": "^4.0.10", "ethereum-waffle": "^4.0.10",
"ethers": "^5.7.2", "ethers": "^5.7.2",
......
...@@ -667,25 +667,54 @@ export class CrossChainMessenger { ...@@ -667,25 +667,54 @@ export class CrossChainMessenger {
toBlockOrBlockHash?: BlockTag toBlockOrBlockHash?: BlockTag
): Promise<MessageStatus> { ): Promise<MessageStatus> {
const resolved = await this.toCrossChainMessage(message, messageIndex) const resolved = await this.toCrossChainMessage(message, messageIndex)
const receipt = await this.getMessageReceipt( // legacy withdrawals relayed prebedrock are v1
resolved, const messageHashV0 = hashCrossDomainMessagev0(
messageIndex, resolved.target,
fromBlockOrBlockHash, resolved.sender,
toBlockOrBlockHash resolved.message,
resolved.messageNonce
) )
// bedrock withdrawals are v1
// legacy withdrawals relayed postbedrock are v1
// there is no good way to differentiate between the two types of legacy
// so what we will check for both
const messageHashV1 = hashCrossDomainMessagev1(
resolved.messageNonce,
resolved.sender,
resolved.target,
resolved.value,
resolved.minGasLimit,
resolved.message
)
// Here we want the messenger that will receive the message, not the one that sent it.
const messenger =
resolved.direction === MessageDirection.L1_TO_L2
? this.contracts.l2.L2CrossDomainMessenger
: this.contracts.l1.L1CrossDomainMessenger
const success =
(await messenger.successfulMessages(messageHashV0)) ||
(await messenger.successfulMessages(messageHashV1))
const failure =
(await messenger.failedMessages(messageHashV0)) ||
(await messenger.failedMessages(messageHashV1))
if (resolved.direction === MessageDirection.L1_TO_L2) { if (resolved.direction === MessageDirection.L1_TO_L2) {
if (receipt === null) { if (success) {
return MessageStatus.UNCONFIRMED_L1_TO_L2_MESSAGE return MessageStatus.RELAYED
} else if (failure) {
return MessageStatus.FAILED_L1_TO_L2_MESSAGE
} else { } else {
if (receipt.receiptStatus === MessageReceiptStatus.RELAYED_SUCCEEDED) { return MessageStatus.UNCONFIRMED_L1_TO_L2_MESSAGE
return MessageStatus.RELAYED
} else {
return MessageStatus.FAILED_L1_TO_L2_MESSAGE
}
} }
} else { } else {
if (receipt === null) { if (success) {
return MessageStatus.RELAYED
} else if (failure) {
return MessageStatus.READY_FOR_RELAY
} else {
let timestamp: number let timestamp: number
if (this.bedrock) { if (this.bedrock) {
const output = await this.getMessageBedrockOutput( const output = await this.getMessageBedrockOutput(
...@@ -737,12 +766,6 @@ export class CrossChainMessenger { ...@@ -737,12 +766,6 @@ export class CrossChainMessenger {
} else { } else {
return MessageStatus.READY_FOR_RELAY return MessageStatus.READY_FOR_RELAY
} }
} else {
if (receipt.receiptStatus === MessageReceiptStatus.RELAYED_SUCCEEDED) {
return MessageStatus.RELAYED
} else {
return MessageStatus.READY_FOR_RELAY
}
} }
} }
} }
......
...@@ -8,6 +8,8 @@ contract MockMessenger is ICrossDomainMessenger { ...@@ -8,6 +8,8 @@ contract MockMessenger is ICrossDomainMessenger {
} }
uint256 public nonce; uint256 public nonce;
mapping (bytes32 => bool) public successfulMessages;
mapping (bytes32 => bool) public failedMessages;
// Empty function to satisfy the interface. // Empty function to satisfy the interface.
function sendMessage( function sendMessage(
...@@ -81,6 +83,7 @@ contract MockMessenger is ICrossDomainMessenger { ...@@ -81,6 +83,7 @@ contract MockMessenger is ICrossDomainMessenger {
) public { ) public {
for (uint256 i = 0; i < _params.length; i++) { for (uint256 i = 0; i < _params.length; i++) {
emit RelayedMessage(_params[i]); emit RelayedMessage(_params[i]);
successfulMessages[_params[i]] = true;
} }
} }
...@@ -89,6 +92,7 @@ contract MockMessenger is ICrossDomainMessenger { ...@@ -89,6 +92,7 @@ contract MockMessenger is ICrossDomainMessenger {
) public { ) public {
for (uint256 i = 0; i < _params.length; i++) { for (uint256 i = 0; i < _params.length; i++) {
emit FailedRelayedMessage(_params[i]); emit FailedRelayedMessage(_params[i]);
failedMessages[_params[i]] = true;
} }
} }
} }
...@@ -33,7 +33,7 @@ ...@@ -33,7 +33,7 @@
}, },
"devDependencies": { "devDependencies": {
"@eth-optimism/contracts-ts": "workspace:^", "@eth-optimism/contracts-ts": "workspace:^",
"@swc/core": "^1.3.95", "@swc/core": "^1.3.99",
"@vitest/coverage-istanbul": "^0.34.6", "@vitest/coverage-istanbul": "^0.34.6",
"tsup": "^7.2.0", "tsup": "^7.2.0",
"typescript": "^5.2.2", "typescript": "^5.2.2",
......
...@@ -28,14 +28,14 @@ importers: ...@@ -28,14 +28,14 @@ importers:
specifier: ^7.1.8 specifier: ^7.1.8
version: 7.1.8 version: 7.1.8
'@types/mocha': '@types/mocha':
specifier: ^10.0.4 specifier: ^10.0.6
version: 10.0.4 version: 10.0.6
'@types/node': '@types/node':
specifier: ^20.9.0 specifier: ^20.9.3
version: 20.9.0 version: 20.9.3
'@typescript-eslint/eslint-plugin': '@typescript-eslint/eslint-plugin':
specifier: ^6.11.0 specifier: ^6.12.0
version: 6.11.0(@typescript-eslint/parser@6.11.0)(eslint@8.54.0)(typescript@5.2.2) version: 6.12.0(@typescript-eslint/parser@6.11.0)(eslint@8.54.0)(typescript@5.2.2)
'@typescript-eslint/parser': '@typescript-eslint/parser':
specifier: ^6.11.0 specifier: ^6.11.0
version: 6.11.0(eslint@8.54.0)(typescript@5.2.2) version: 6.11.0(eslint@8.54.0)(typescript@5.2.2)
...@@ -127,7 +127,7 @@ importers: ...@@ -127,7 +127,7 @@ importers:
devDependencies: devDependencies:
tsup: tsup:
specifier: ^7.2.0 specifier: ^7.2.0
version: 7.2.0(@swc/core@1.3.95)(typescript@5.2.2) version: 7.2.0(@swc/core@1.3.99)(typescript@5.2.2)
vitest: vitest:
specifier: ^0.34.4 specifier: ^0.34.4
version: 0.34.4 version: 0.34.4
...@@ -181,10 +181,10 @@ importers: ...@@ -181,10 +181,10 @@ importers:
version: 2.19.0(ts-node@10.9.1)(typescript@5.2.2) version: 2.19.0(ts-node@10.9.1)(typescript@5.2.2)
ts-node: ts-node:
specifier: ^10.9.1 specifier: ^10.9.1
version: 10.9.1(@types/node@20.9.0)(typescript@5.2.2) version: 10.9.1(@types/node@20.9.3)(typescript@5.2.2)
tsx: tsx:
specifier: ^4.1.1 specifier: ^4.2.0
version: 4.1.1 version: 4.2.0
packages/common-ts: packages/common-ts:
dependencies: dependencies:
...@@ -265,14 +265,14 @@ importers: ...@@ -265,14 +265,14 @@ importers:
packages/contracts-bedrock: packages/contracts-bedrock:
devDependencies: devDependencies:
'@typescript-eslint/eslint-plugin': '@typescript-eslint/eslint-plugin':
specifier: ^6.11.0 specifier: ^6.12.0
version: 6.11.0(@typescript-eslint/parser@6.11.0)(eslint@8.53.0)(typescript@5.2.2) version: 6.12.0(@typescript-eslint/parser@6.11.0)(eslint@8.54.0)(typescript@5.2.2)
'@typescript-eslint/parser': '@typescript-eslint/parser':
specifier: ^6.11.0 specifier: ^6.11.0
version: 6.11.0(eslint@8.53.0)(typescript@5.2.2) version: 6.11.0(eslint@8.54.0)(typescript@5.2.2)
tsx: tsx:
specifier: ^4.1.1 specifier: ^4.2.0
version: 4.1.1 version: 4.2.0
typescript: typescript:
specifier: ^5.2.2 specifier: ^5.2.2
version: 5.2.2 version: 5.2.2
...@@ -339,13 +339,13 @@ importers: ...@@ -339,13 +339,13 @@ importers:
version: 22.1.0 version: 22.1.0
tsup: tsup:
specifier: ^7.2.0 specifier: ^7.2.0
version: 7.2.0(@swc/core@1.3.95)(typescript@5.2.2) version: 7.2.0(@swc/core@1.3.99)(typescript@5.2.2)
typescript: typescript:
specifier: ^5.2.2 specifier: ^5.2.2
version: 5.2.2 version: 5.2.2
vite: vite:
specifier: ^4.5.0 specifier: ^4.5.0
version: 4.5.0(@types/node@20.9.0) version: 4.5.0(@types/node@20.9.3)
vitest: vitest:
specifier: ^0.34.2 specifier: ^0.34.2
version: 0.34.2(jsdom@22.1.0) version: 0.34.2(jsdom@22.1.0)
...@@ -396,8 +396,8 @@ importers: ...@@ -396,8 +396,8 @@ importers:
version: 2.6.7 version: 2.6.7
devDependencies: devDependencies:
'@types/node': '@types/node':
specifier: ^20.9.0 specifier: ^20.9.3
version: 20.9.0 version: 20.9.3
mocha: mocha:
specifier: ^10.2.0 specifier: ^10.2.0
version: 10.2.0 version: 10.2.0
...@@ -430,7 +430,7 @@ importers: ...@@ -430,7 +430,7 @@ importers:
version: 22.1.0 version: 22.1.0
tsup: tsup:
specifier: ^7.2.0 specifier: ^7.2.0
version: 7.2.0(@swc/core@1.3.95)(typescript@5.2.2) version: 7.2.0(@swc/core@1.3.99)(typescript@5.2.2)
typescript: typescript:
specifier: ^5.2.2 specifier: ^5.2.2
version: 5.2.2 version: 5.2.2
...@@ -439,7 +439,7 @@ importers: ...@@ -439,7 +439,7 @@ importers:
version: 1.19.4(typescript@5.2.2)(zod@3.22.4) version: 1.19.4(typescript@5.2.2)(zod@3.22.4)
vite: vite:
specifier: ^4.5.0 specifier: ^4.5.0
version: 4.5.0(@types/node@20.9.0) version: 4.5.0(@types/node@20.9.3)
vitest: vitest:
specifier: ^0.34.2 specifier: ^0.34.2
version: 0.34.2(jsdom@22.1.0) version: 0.34.2(jsdom@22.1.0)
...@@ -487,11 +487,11 @@ importers: ...@@ -487,11 +487,11 @@ importers:
specifier: ^7.1.8 specifier: ^7.1.8
version: 7.1.8 version: 7.1.8
'@types/mocha': '@types/mocha':
specifier: ^10.0.4 specifier: ^10.0.6
version: 10.0.4 version: 10.0.6
'@types/node': '@types/node':
specifier: ^20.9.0 specifier: ^20.9.3
version: 20.9.0 version: 20.9.3
chai-as-promised: chai-as-promised:
specifier: ^7.1.1 specifier: ^7.1.1
version: 7.1.1(chai@4.3.10) version: 7.1.1(chai@4.3.10)
...@@ -518,7 +518,7 @@ importers: ...@@ -518,7 +518,7 @@ importers:
version: 15.1.0 version: 15.1.0
ts-node: ts-node:
specifier: ^10.9.1 specifier: ^10.9.1
version: 10.9.1(@types/node@20.9.0)(typescript@5.2.2) version: 10.9.1(@types/node@20.9.3)(typescript@5.2.2)
typedoc: typedoc:
specifier: ^0.25.3 specifier: ^0.25.3
version: 0.25.3(typescript@5.2.2) version: 0.25.3(typescript@5.2.2)
...@@ -554,14 +554,14 @@ importers: ...@@ -554,14 +554,14 @@ importers:
specifier: workspace:^ specifier: workspace:^
version: link:../contracts-ts version: link:../contracts-ts
'@swc/core': '@swc/core':
specifier: ^1.3.95 specifier: ^1.3.99
version: 1.3.95 version: 1.3.99
'@vitest/coverage-istanbul': '@vitest/coverage-istanbul':
specifier: ^0.34.6 specifier: ^0.34.6
version: 0.34.6(vitest@0.34.1) version: 0.34.6(vitest@0.34.1)
tsup: tsup:
specifier: ^7.2.0 specifier: ^7.2.0
version: 7.2.0(@swc/core@1.3.95)(typescript@5.2.2) version: 7.2.0(@swc/core@1.3.99)(typescript@5.2.2)
typescript: typescript:
specifier: ^5.2.2 specifier: ^5.2.2
version: 5.2.2 version: 5.2.2
...@@ -570,7 +570,7 @@ importers: ...@@ -570,7 +570,7 @@ importers:
version: 1.19.4(typescript@5.2.2)(zod@3.22.4) version: 1.19.4(typescript@5.2.2)(zod@3.22.4)
vite: vite:
specifier: ^4.5.0 specifier: ^4.5.0
version: 4.5.0(@types/node@20.9.0) version: 4.5.0(@types/node@20.9.3)
vitest: vitest:
specifier: ^0.34.1 specifier: ^0.34.1
version: 0.34.1 version: 0.34.1
...@@ -1798,16 +1798,6 @@ packages: ...@@ -1798,16 +1798,6 @@ packages:
dev: true dev: true
optional: true optional: true
/@eslint-community/eslint-utils@4.4.0(eslint@8.53.0):
resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
peerDependencies:
eslint: ^6.0.0 || ^7.0.0 || >=8.0.0
dependencies:
eslint: 8.53.0
eslint-visitor-keys: 3.4.3
dev: true
/@eslint-community/eslint-utils@4.4.0(eslint@8.54.0): /@eslint-community/eslint-utils@4.4.0(eslint@8.54.0):
resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
...@@ -1840,11 +1830,6 @@ packages: ...@@ -1840,11 +1830,6 @@ packages:
- supports-color - supports-color
dev: true dev: true
/@eslint/js@8.53.0:
resolution: {integrity: sha512-Kn7K8dx/5U6+cT1yEhpX1w4PCSg0M+XyRILPgvwcEBjerFWCwQj5sbr3/VmxqV0JGHCBCzyd6LxypEuehypY1w==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
dev: true
/@eslint/js@8.54.0: /@eslint/js@8.54.0:
resolution: {integrity: sha512-ut5V+D+fOoWPgGGNj83GGjnntO39xDy6DWxO0wb7Jp3DcMX0TfIqdzHF85VTQkerdyGmuuMD9AKAo5KiNlf/AQ==} resolution: {integrity: sha512-ut5V+D+fOoWPgGGNj83GGjnntO39xDy6DWxO0wb7Jp3DcMX0TfIqdzHF85VTQkerdyGmuuMD9AKAo5KiNlf/AQ==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
...@@ -3519,8 +3504,8 @@ packages: ...@@ -3519,8 +3504,8 @@ packages:
'@stablelib/random': 1.0.2 '@stablelib/random': 1.0.2
'@stablelib/wipe': 1.0.1 '@stablelib/wipe': 1.0.1
/@swc/core-darwin-arm64@1.3.95: /@swc/core-darwin-arm64@1.3.99:
resolution: {integrity: sha512-VAuBAP3MNetO/yBIBzvorUXq7lUBwhfpJxYViSxyluMwtoQDhE/XWN598TWMwMl1ZuImb56d7eUsuFdjgY7pJw==} resolution: {integrity: sha512-Qj7Jct68q3ZKeuJrjPx7k8SxzWN6PqLh+VFxzA+KwLDpQDPzOlKRZwkIMzuFjLhITO4RHgSnXoDk/Syz0ZeN+Q==}
engines: {node: '>=10'} engines: {node: '>=10'}
cpu: [arm64] cpu: [arm64]
os: [darwin] os: [darwin]
...@@ -3528,8 +3513,8 @@ packages: ...@@ -3528,8 +3513,8 @@ packages:
dev: true dev: true
optional: true optional: true
/@swc/core-darwin-x64@1.3.95: /@swc/core-darwin-x64@1.3.99:
resolution: {integrity: sha512-20vF2rvUsN98zGLZc+dsEdHvLoCuiYq/1B+TDeE4oolgTFDmI1jKO+m44PzWjYtKGU9QR95sZ6r/uec0QC5O4Q==} resolution: {integrity: sha512-wR7m9QVJjgiBu1PSOHy7s66uJPa45Kf9bZExXUL+JAa9OQxt5y+XVzr+n+F045VXQOwdGWplgPnWjgbUUHEVyw==}
engines: {node: '>=10'} engines: {node: '>=10'}
cpu: [x64] cpu: [x64]
os: [darwin] os: [darwin]
...@@ -3537,17 +3522,8 @@ packages: ...@@ -3537,17 +3522,8 @@ packages:
dev: true dev: true
optional: true optional: true
/@swc/core-linux-arm-gnueabihf@1.3.95: /@swc/core-linux-arm64-gnu@1.3.99:
resolution: {integrity: sha512-oEudEM8PST1MRNGs+zu0cx5i9uP8TsLE4/L9HHrS07Ck0RJ3DCj3O2fU832nmLe2QxnAGPwBpSO9FntLfOiWEQ==} resolution: {integrity: sha512-gcGv1l5t0DScEONmw5OhdVmEI/o49HCe9Ik38zzH0NtDkc+PDYaCcXU5rvfZP2qJFaAAr8cua8iJcOunOSLmnA==}
engines: {node: '>=10'}
cpu: [arm]
os: [linux]
requiresBuild: true
dev: true
optional: true
/@swc/core-linux-arm64-gnu@1.3.95:
resolution: {integrity: sha512-pIhFI+cuC1aYg+0NAPxwT/VRb32f2ia8oGxUjQR6aJg65gLkUYQzdwuUmpMtFR2WVf7WVFYxUnjo4UyMuyh3ng==}
engines: {node: '>=10'} engines: {node: '>=10'}
cpu: [arm64] cpu: [arm64]
os: [linux] os: [linux]
...@@ -3555,8 +3531,8 @@ packages: ...@@ -3555,8 +3531,8 @@ packages:
dev: true dev: true
optional: true optional: true
/@swc/core-linux-arm64-musl@1.3.95: /@swc/core-linux-arm64-musl@1.3.99:
resolution: {integrity: sha512-ZpbTr+QZDT4OPJfjPAmScqdKKaT+wGurvMU5AhxLaf85DuL8HwUwwlL0n1oLieLc47DwIJEMuKQkYhXMqmJHlg==} resolution: {integrity: sha512-XL1/eUsTO8BiKsWq9i3iWh7H99iPO61+9HYiWVKhSavknfj4Plbn+XyajDpxsauln5o8t+BRGitymtnAWJM4UQ==}
engines: {node: '>=10'} engines: {node: '>=10'}
cpu: [arm64] cpu: [arm64]
os: [linux] os: [linux]
...@@ -3564,8 +3540,8 @@ packages: ...@@ -3564,8 +3540,8 @@ packages:
dev: true dev: true
optional: true optional: true
/@swc/core-linux-x64-gnu@1.3.95: /@swc/core-linux-x64-gnu@1.3.99:
resolution: {integrity: sha512-n9SuHEFtdfSJ+sHdNXNRuIOVprB8nbsz+08apKfdo4lEKq6IIPBBAk5kVhPhkjmg2dFVHVo4Tr/OHXM1tzWCCw==} resolution: {integrity: sha512-fGrXYE6DbTfGNIGQmBefYxSk3rp/1lgbD0nVg4rl4mfFRQPi7CgGhrrqSuqZ/ezXInUIgoCyvYGWFSwjLXt/Qg==}
engines: {node: '>=10'} engines: {node: '>=10'}
cpu: [x64] cpu: [x64]
os: [linux] os: [linux]
...@@ -3573,8 +3549,8 @@ packages: ...@@ -3573,8 +3549,8 @@ packages:
dev: true dev: true
optional: true optional: true
/@swc/core-linux-x64-musl@1.3.95: /@swc/core-linux-x64-musl@1.3.99:
resolution: {integrity: sha512-L1JrVlsXU3LC0WwmVnMK9HrOT2uhHahAoPNMJnZQpc18a0paO9fqifPG8M/HjNRffMUXR199G/phJsf326UvVg==} resolution: {integrity: sha512-kvgZp/mqf3IJ806gUOL6gN6VU15+DfzM1Zv4Udn8GqgXiUAvbQehrtruid4Snn5pZTLj4PEpSCBbxgxK1jbssA==}
engines: {node: '>=10'} engines: {node: '>=10'}
cpu: [x64] cpu: [x64]
os: [linux] os: [linux]
...@@ -3582,8 +3558,8 @@ packages: ...@@ -3582,8 +3558,8 @@ packages:
dev: true dev: true
optional: true optional: true
/@swc/core-win32-arm64-msvc@1.3.95: /@swc/core-win32-arm64-msvc@1.3.99:
resolution: {integrity: sha512-YaP4x/aZbUyNdqCBpC2zL8b8n58MEpOUpmOIZK6G1SxGi+2ENht7gs7+iXpWPc0sy7X3YPKmSWMAuui0h8lgAA==} resolution: {integrity: sha512-yt8RtZ4W/QgFF+JUemOUQAkVW58cCST7mbfKFZ1v16w3pl3NcWd9OrtppFIXpbjU1rrUX2zp2R7HZZzZ2Zk/aQ==}
engines: {node: '>=10'} engines: {node: '>=10'}
cpu: [arm64] cpu: [arm64]
os: [win32] os: [win32]
...@@ -3591,8 +3567,8 @@ packages: ...@@ -3591,8 +3567,8 @@ packages:
dev: true dev: true
optional: true optional: true
/@swc/core-win32-ia32-msvc@1.3.95: /@swc/core-win32-ia32-msvc@1.3.99:
resolution: {integrity: sha512-w0u3HI916zT4BC/57gOd+AwAEjXeUlQbGJ9H4p/gzs1zkSHtoDQghVUNy3n/ZKp9KFod/95cA8mbVF9t1+6epQ==} resolution: {integrity: sha512-62p5fWnOJR/rlbmbUIpQEVRconICy5KDScWVuJg1v3GPLBrmacjphyHiJC1mp6dYvvoEWCk/77c/jcQwlXrDXw==}
engines: {node: '>=10'} engines: {node: '>=10'}
cpu: [ia32] cpu: [ia32]
os: [win32] os: [win32]
...@@ -3600,8 +3576,8 @@ packages: ...@@ -3600,8 +3576,8 @@ packages:
dev: true dev: true
optional: true optional: true
/@swc/core-win32-x64-msvc@1.3.95: /@swc/core-win32-x64-msvc@1.3.99:
resolution: {integrity: sha512-5RGnMt0S6gg4Gc6QtPUJ3Qs9Un4sKqccEzgH/tj7V/DVTJwKdnBKxFZfgQ34OR2Zpz7zGOn889xwsFVXspVWNA==} resolution: {integrity: sha512-PdppWhkoS45VGdMBxvClVgF1hVjqamtvYd82Gab1i4IV45OSym2KinoDCKE1b6j3LwBLOn2J9fvChGSgGfDCHQ==}
engines: {node: '>=10'} engines: {node: '>=10'}
cpu: [x64] cpu: [x64]
os: [win32] os: [win32]
...@@ -3609,8 +3585,8 @@ packages: ...@@ -3609,8 +3585,8 @@ packages:
dev: true dev: true
optional: true optional: true
/@swc/core@1.3.95: /@swc/core@1.3.99:
resolution: {integrity: sha512-PMrNeuqIusq9DPDooV3FfNEbZuTu5jKAc04N3Hm6Uk2Fl49cqElLFQ4xvl4qDmVDz97n3n/C1RE0/f6WyGPEiA==} resolution: {integrity: sha512-8O996RfuPC4ieb4zbYMfbyCU9k4gSOpyCNnr7qBQ+o7IEmh8JCV6B8wwu+fT/Om/6Lp34KJe1IpJ/24axKS6TQ==}
engines: {node: '>=10'} engines: {node: '>=10'}
requiresBuild: true requiresBuild: true
peerDependencies: peerDependencies:
...@@ -3622,16 +3598,15 @@ packages: ...@@ -3622,16 +3598,15 @@ packages:
'@swc/counter': 0.1.1 '@swc/counter': 0.1.1
'@swc/types': 0.1.5 '@swc/types': 0.1.5
optionalDependencies: optionalDependencies:
'@swc/core-darwin-arm64': 1.3.95 '@swc/core-darwin-arm64': 1.3.99
'@swc/core-darwin-x64': 1.3.95 '@swc/core-darwin-x64': 1.3.99
'@swc/core-linux-arm-gnueabihf': 1.3.95 '@swc/core-linux-arm64-gnu': 1.3.99
'@swc/core-linux-arm64-gnu': 1.3.95 '@swc/core-linux-arm64-musl': 1.3.99
'@swc/core-linux-arm64-musl': 1.3.95 '@swc/core-linux-x64-gnu': 1.3.99
'@swc/core-linux-x64-gnu': 1.3.95 '@swc/core-linux-x64-musl': 1.3.99
'@swc/core-linux-x64-musl': 1.3.95 '@swc/core-win32-arm64-msvc': 1.3.99
'@swc/core-win32-arm64-msvc': 1.3.95 '@swc/core-win32-ia32-msvc': 1.3.99
'@swc/core-win32-ia32-msvc': 1.3.95 '@swc/core-win32-x64-msvc': 1.3.99
'@swc/core-win32-x64-msvc': 1.3.95
dev: true dev: true
/@swc/counter@0.1.1: /@swc/counter@0.1.1:
...@@ -3866,20 +3841,20 @@ packages: ...@@ -3866,20 +3841,20 @@ packages:
/@types/bn.js@4.11.6: /@types/bn.js@4.11.6:
resolution: {integrity: sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==} resolution: {integrity: sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==}
dependencies: dependencies:
'@types/node': 20.9.0 '@types/node': 20.9.3
dev: true dev: true
/@types/bn.js@5.1.0: /@types/bn.js@5.1.0:
resolution: {integrity: sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA==} resolution: {integrity: sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA==}
dependencies: dependencies:
'@types/node': 20.9.0 '@types/node': 20.9.3
dev: true dev: true
/@types/body-parser@1.19.1: /@types/body-parser@1.19.1:
resolution: {integrity: sha512-a6bTJ21vFOGIkwM0kzh9Yr89ziVxq4vYH2fQ6N8AeipEzai/cFK6aGMArIkUeIdRIgpwQa+2bXiLuUJCpSf2Cg==} resolution: {integrity: sha512-a6bTJ21vFOGIkwM0kzh9Yr89ziVxq4vYH2fQ6N8AeipEzai/cFK6aGMArIkUeIdRIgpwQa+2bXiLuUJCpSf2Cg==}
dependencies: dependencies:
'@types/connect': 3.4.35 '@types/connect': 3.4.35
'@types/node': 20.9.0 '@types/node': 20.9.3
dev: true dev: true
/@types/chai-as-promised@7.1.8: /@types/chai-as-promised@7.1.8:
...@@ -3912,7 +3887,7 @@ packages: ...@@ -3912,7 +3887,7 @@ packages:
/@types/connect@3.4.35: /@types/connect@3.4.35:
resolution: {integrity: sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==} resolution: {integrity: sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==}
dependencies: dependencies:
'@types/node': 20.9.0 '@types/node': 20.9.3
/@types/dateformat@5.0.0: /@types/dateformat@5.0.0:
resolution: {integrity: sha512-SZg4JdHIWHQGEokbYGZSDvo5wA4TLYPXaqhigs/wH+REDOejcJzgH+qyY+HtEUtWOZxEUkbhbdYPqQDiEgrXeA==} resolution: {integrity: sha512-SZg4JdHIWHQGEokbYGZSDvo5wA4TLYPXaqhigs/wH+REDOejcJzgH+qyY+HtEUtWOZxEUkbhbdYPqQDiEgrXeA==}
...@@ -3926,7 +3901,7 @@ packages: ...@@ -3926,7 +3901,7 @@ packages:
/@types/express-serve-static-core@4.17.35: /@types/express-serve-static-core@4.17.35:
resolution: {integrity: sha512-wALWQwrgiB2AWTT91CB62b6Yt0sNHpznUXeZEcnPU3DRdlDIz74x8Qg1UUYKSVFi+va5vKOLYRBI1bRKiLLKIg==} resolution: {integrity: sha512-wALWQwrgiB2AWTT91CB62b6Yt0sNHpznUXeZEcnPU3DRdlDIz74x8Qg1UUYKSVFi+va5vKOLYRBI1bRKiLLKIg==}
dependencies: dependencies:
'@types/node': 20.9.0 '@types/node': 20.9.3
'@types/qs': 6.9.7 '@types/qs': 6.9.7
'@types/range-parser': 1.2.4 '@types/range-parser': 1.2.4
'@types/send': 0.17.1 '@types/send': 0.17.1
...@@ -3945,7 +3920,7 @@ packages: ...@@ -3945,7 +3920,7 @@ packages:
resolution: {integrity: sha512-IO+MJPVhoqz+28h1qLAcBEH2+xHMK6MTyHJc7MTnnYb6wsoLR29POVGJ7LycmVXIqyy/4/2ShP5sUwTXuOwb/w==} resolution: {integrity: sha512-IO+MJPVhoqz+28h1qLAcBEH2+xHMK6MTyHJc7MTnnYb6wsoLR29POVGJ7LycmVXIqyy/4/2ShP5sUwTXuOwb/w==}
dependencies: dependencies:
'@types/minimatch': 5.1.2 '@types/minimatch': 5.1.2
'@types/node': 20.8.9 '@types/node': 20.9.0
dev: true dev: true
/@types/is-ci@3.0.0: /@types/is-ci@3.0.0:
...@@ -3972,7 +3947,7 @@ packages: ...@@ -3972,7 +3947,7 @@ packages:
dependencies: dependencies:
'@types/abstract-leveldown': 5.0.2 '@types/abstract-leveldown': 5.0.2
'@types/level-errors': 3.0.0 '@types/level-errors': 3.0.0
'@types/node': 20.9.0 '@types/node': 20.9.3
dev: true dev: true
/@types/lru-cache@5.1.1: /@types/lru-cache@5.1.1:
...@@ -4004,11 +3979,11 @@ packages: ...@@ -4004,11 +3979,11 @@ packages:
/@types/mkdirp@0.5.2: /@types/mkdirp@0.5.2:
resolution: {integrity: sha512-U5icWpv7YnZYGsN4/cmh3WD2onMY0aJIiTE6+51TwJCttdHvtCYmkBNOobHlXwrJRL0nkH9jH4kD+1FAdMN4Tg==} resolution: {integrity: sha512-U5icWpv7YnZYGsN4/cmh3WD2onMY0aJIiTE6+51TwJCttdHvtCYmkBNOobHlXwrJRL0nkH9jH4kD+1FAdMN4Tg==}
dependencies: dependencies:
'@types/node': 20.9.0 '@types/node': 20.9.3
dev: true dev: true
/@types/mocha@10.0.4: /@types/mocha@10.0.6:
resolution: {integrity: sha512-xKU7bUjiFTIttpWaIZ9qvgg+22O1nmbA+HRxdlR+u6TWsGfmFdXrheJoK4fFxrHNVIOBDvDNKZG+LYBpMHpX3w==} resolution: {integrity: sha512-dJvrYWxP/UcXm36Qn36fxhUKu8A/xMRXVT2cliFF1Z7UA9liG5Psj3ezNSZw+5puH2czDXRLcXQxf8JbJt0ejg==}
dev: true dev: true
/@types/morgan@1.9.9: /@types/morgan@1.9.9:
...@@ -4023,7 +3998,7 @@ packages: ...@@ -4023,7 +3998,7 @@ packages:
/@types/node-fetch@2.6.4: /@types/node-fetch@2.6.4:
resolution: {integrity: sha512-1ZX9fcN4Rvkvgv4E6PAY5WXUFWFcRWxZa3EW83UjycOB9ljJCedb2CupIP4RZMEwF/M3eTcCihbBRgwtGbg5Rg==} resolution: {integrity: sha512-1ZX9fcN4Rvkvgv4E6PAY5WXUFWFcRWxZa3EW83UjycOB9ljJCedb2CupIP4RZMEwF/M3eTcCihbBRgwtGbg5Rg==}
dependencies: dependencies:
'@types/node': 20.9.0 '@types/node': 20.9.3
form-data: 3.0.1 form-data: 3.0.1
dev: true dev: true
...@@ -4034,14 +4009,14 @@ packages: ...@@ -4034,14 +4009,14 @@ packages:
/@types/node@12.20.55: /@types/node@12.20.55:
resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==}
/@types/node@20.8.9: /@types/node@20.9.0:
resolution: {integrity: sha512-UzykFsT3FhHb1h7yD4CA4YhBHq545JC0YnEz41xkipN88eKQtL6rSgocL5tbAP6Ola9Izm/Aw4Ora8He4x0BHg==} resolution: {integrity: sha512-nekiGu2NDb1BcVofVcEKMIwzlx4NjHlcjhoxxKBNLtz15Y1z7MYf549DFvkHSId02Ax6kGwWntIBPC3l/JZcmw==}
dependencies: dependencies:
undici-types: 5.26.5 undici-types: 5.26.5
dev: true dev: true
/@types/node@20.9.0: /@types/node@20.9.3:
resolution: {integrity: sha512-nekiGu2NDb1BcVofVcEKMIwzlx4NjHlcjhoxxKBNLtz15Y1z7MYf549DFvkHSId02Ax6kGwWntIBPC3l/JZcmw==} resolution: {integrity: sha512-nk5wXLAXGBKfrhLB0cyHGbSqopS+nz0BUgZkUQqSHSSgdee0kssp1IAqlQOu333bW+gMNs2QREx7iynm19Abxw==}
dependencies: dependencies:
undici-types: 5.26.5 undici-types: 5.26.5
...@@ -4055,7 +4030,7 @@ packages: ...@@ -4055,7 +4030,7 @@ packages:
/@types/pbkdf2@3.1.0: /@types/pbkdf2@3.1.0:
resolution: {integrity: sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ==} resolution: {integrity: sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ==}
dependencies: dependencies:
'@types/node': 20.9.0 '@types/node': 20.9.3
dev: true dev: true
/@types/pino-multi-stream@5.1.5: /@types/pino-multi-stream@5.1.5:
...@@ -4073,13 +4048,13 @@ packages: ...@@ -4073,13 +4048,13 @@ packages:
/@types/pino-std-serializers@2.4.1: /@types/pino-std-serializers@2.4.1:
resolution: {integrity: sha512-17XcksO47M24IVTVKPeAByWUd3Oez7EbIjXpSbzMPhXVzgjGtrOa49gKBwxH9hb8dKv58OelsWQ+A1G1l9S3wQ==} resolution: {integrity: sha512-17XcksO47M24IVTVKPeAByWUd3Oez7EbIjXpSbzMPhXVzgjGtrOa49gKBwxH9hb8dKv58OelsWQ+A1G1l9S3wQ==}
dependencies: dependencies:
'@types/node': 20.9.0 '@types/node': 20.9.3
dev: true dev: true
/@types/pino@6.3.11: /@types/pino@6.3.11:
resolution: {integrity: sha512-S7+fLONqSpHeW9d7TApUqO6VN47KYgOXhCNKwGBVLHObq8HhaAYlVqUNdfnvoXjCMiwE5xcPm/5R2ZUh8bgaXQ==} resolution: {integrity: sha512-S7+fLONqSpHeW9d7TApUqO6VN47KYgOXhCNKwGBVLHObq8HhaAYlVqUNdfnvoXjCMiwE5xcPm/5R2ZUh8bgaXQ==}
dependencies: dependencies:
'@types/node': 20.9.0 '@types/node': 20.9.3
'@types/pino-pretty': 4.7.1 '@types/pino-pretty': 4.7.1
'@types/pino-std-serializers': 2.4.1 '@types/pino-std-serializers': 2.4.1
sonic-boom: 2.8.0 sonic-boom: 2.8.0
...@@ -4125,7 +4100,7 @@ packages: ...@@ -4125,7 +4100,7 @@ packages:
/@types/readable-stream@2.3.15: /@types/readable-stream@2.3.15:
resolution: {integrity: sha512-oM5JSKQCcICF1wvGgmecmHldZ48OZamtMxcGGVICOJA8o8cahXC1zEVAif8iwoc5j8etxFaRFnf095+CDsuoFQ==} resolution: {integrity: sha512-oM5JSKQCcICF1wvGgmecmHldZ48OZamtMxcGGVICOJA8o8cahXC1zEVAif8iwoc5j8etxFaRFnf095+CDsuoFQ==}
dependencies: dependencies:
'@types/node': 20.9.0 '@types/node': 20.9.3
safe-buffer: 5.1.2 safe-buffer: 5.1.2
dev: true dev: true
...@@ -4136,7 +4111,7 @@ packages: ...@@ -4136,7 +4111,7 @@ packages:
/@types/secp256k1@4.0.3: /@types/secp256k1@4.0.3:
resolution: {integrity: sha512-Da66lEIFeIz9ltsdMZcpQvmrmmoqrfju8pm1BH8WbYjZSwUgCwXLb9C+9XYogwBITnbsSaMdVPb2ekf7TV+03w==} resolution: {integrity: sha512-Da66lEIFeIz9ltsdMZcpQvmrmmoqrfju8pm1BH8WbYjZSwUgCwXLb9C+9XYogwBITnbsSaMdVPb2ekf7TV+03w==}
dependencies: dependencies:
'@types/node': 20.9.0 '@types/node': 20.9.3
dev: true dev: true
/@types/seedrandom@3.0.1: /@types/seedrandom@3.0.1:
...@@ -4155,14 +4130,14 @@ packages: ...@@ -4155,14 +4130,14 @@ packages:
resolution: {integrity: sha512-Cwo8LE/0rnvX7kIIa3QHCkcuF21c05Ayb0ZfxPiv0W8VRiZiNW/WuRupHKpqqGVGf7SUA44QSOUKaEd9lIrd/Q==} resolution: {integrity: sha512-Cwo8LE/0rnvX7kIIa3QHCkcuF21c05Ayb0ZfxPiv0W8VRiZiNW/WuRupHKpqqGVGf7SUA44QSOUKaEd9lIrd/Q==}
dependencies: dependencies:
'@types/mime': 1.3.2 '@types/mime': 1.3.2
'@types/node': 20.9.0 '@types/node': 20.9.3
dev: true dev: true
/@types/serve-static@1.13.10: /@types/serve-static@1.13.10:
resolution: {integrity: sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ==} resolution: {integrity: sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ==}
dependencies: dependencies:
'@types/mime': 1.3.2 '@types/mime': 1.3.2
'@types/node': 20.9.0 '@types/node': 20.9.3
dev: true dev: true
/@types/sinon-chai@3.2.5: /@types/sinon-chai@3.2.5:
...@@ -4199,45 +4174,16 @@ packages: ...@@ -4199,45 +4174,16 @@ packages:
/@types/ws@7.4.7: /@types/ws@7.4.7:
resolution: {integrity: sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==} resolution: {integrity: sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==}
dependencies: dependencies:
'@types/node': 20.9.0 '@types/node': 20.9.3
/@types/ws@8.5.3: /@types/ws@8.5.3:
resolution: {integrity: sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w==} resolution: {integrity: sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w==}
dependencies: dependencies:
'@types/node': 20.9.0 '@types/node': 20.9.3
dev: false dev: false
/@typescript-eslint/eslint-plugin@6.11.0(@typescript-eslint/parser@6.11.0)(eslint@8.53.0)(typescript@5.2.2): /@typescript-eslint/eslint-plugin@6.12.0(@typescript-eslint/parser@6.11.0)(eslint@8.54.0)(typescript@5.2.2):
resolution: {integrity: sha512-uXnpZDc4VRjY4iuypDBKzW1rz9T5YBBK0snMn8MaTSNd2kMlj50LnLBABELjJiOL5YHk7ZD8hbSpI9ubzqYI0w==} resolution: {integrity: sha512-XOpZ3IyJUIV1b15M7HVOpgQxPPF7lGXgsfcEIu3yDxFPaf/xZKt7s9QO/pbk7vpWQyVulpJbu4E5LwpZiQo4kA==}
engines: {node: ^16.0.0 || >=18.0.0}
peerDependencies:
'@typescript-eslint/parser': ^6.0.0 || ^6.0.0-alpha
eslint: ^7.0.0 || ^8.0.0
typescript: '*'
peerDependenciesMeta:
typescript:
optional: true
dependencies:
'@eslint-community/regexpp': 4.6.2
'@typescript-eslint/parser': 6.11.0(eslint@8.53.0)(typescript@5.2.2)
'@typescript-eslint/scope-manager': 6.11.0
'@typescript-eslint/type-utils': 6.11.0(eslint@8.53.0)(typescript@5.2.2)
'@typescript-eslint/utils': 6.11.0(eslint@8.53.0)(typescript@5.2.2)
'@typescript-eslint/visitor-keys': 6.11.0
debug: 4.3.4(supports-color@8.1.1)
eslint: 8.53.0
graphemer: 1.4.0
ignore: 5.2.4
natural-compare: 1.4.0
semver: 7.5.4
ts-api-utils: 1.0.1(typescript@5.2.2)
typescript: 5.2.2
transitivePeerDependencies:
- supports-color
dev: true
/@typescript-eslint/eslint-plugin@6.11.0(@typescript-eslint/parser@6.11.0)(eslint@8.54.0)(typescript@5.2.2):
resolution: {integrity: sha512-uXnpZDc4VRjY4iuypDBKzW1rz9T5YBBK0snMn8MaTSNd2kMlj50LnLBABELjJiOL5YHk7ZD8hbSpI9ubzqYI0w==}
engines: {node: ^16.0.0 || >=18.0.0} engines: {node: ^16.0.0 || >=18.0.0}
peerDependencies: peerDependencies:
'@typescript-eslint/parser': ^6.0.0 || ^6.0.0-alpha '@typescript-eslint/parser': ^6.0.0 || ^6.0.0-alpha
...@@ -4249,10 +4195,10 @@ packages: ...@@ -4249,10 +4195,10 @@ packages:
dependencies: dependencies:
'@eslint-community/regexpp': 4.6.2 '@eslint-community/regexpp': 4.6.2
'@typescript-eslint/parser': 6.11.0(eslint@8.54.0)(typescript@5.2.2) '@typescript-eslint/parser': 6.11.0(eslint@8.54.0)(typescript@5.2.2)
'@typescript-eslint/scope-manager': 6.11.0 '@typescript-eslint/scope-manager': 6.12.0
'@typescript-eslint/type-utils': 6.11.0(eslint@8.54.0)(typescript@5.2.2) '@typescript-eslint/type-utils': 6.12.0(eslint@8.54.0)(typescript@5.2.2)
'@typescript-eslint/utils': 6.11.0(eslint@8.54.0)(typescript@5.2.2) '@typescript-eslint/utils': 6.12.0(eslint@8.54.0)(typescript@5.2.2)
'@typescript-eslint/visitor-keys': 6.11.0 '@typescript-eslint/visitor-keys': 6.12.0
debug: 4.3.4(supports-color@8.1.1) debug: 4.3.4(supports-color@8.1.1)
eslint: 8.54.0 eslint: 8.54.0
graphemer: 1.4.0 graphemer: 1.4.0
...@@ -4265,27 +4211,6 @@ packages: ...@@ -4265,27 +4211,6 @@ packages:
- supports-color - supports-color
dev: true dev: true
/@typescript-eslint/parser@6.11.0(eslint@8.53.0)(typescript@5.2.2):
resolution: {integrity: sha512-+whEdjk+d5do5nxfxx73oanLL9ghKO3EwM9kBCkUtWMRwWuPaFv9ScuqlYfQ6pAD6ZiJhky7TZ2ZYhrMsfMxVQ==}
engines: {node: ^16.0.0 || >=18.0.0}
peerDependencies:
eslint: ^7.0.0 || ^8.0.0
typescript: '*'
peerDependenciesMeta:
typescript:
optional: true
dependencies:
'@typescript-eslint/scope-manager': 6.11.0
'@typescript-eslint/types': 6.11.0
'@typescript-eslint/typescript-estree': 6.11.0(typescript@5.2.2)
'@typescript-eslint/visitor-keys': 6.11.0
debug: 4.3.4(supports-color@8.1.1)
eslint: 8.53.0
typescript: 5.2.2
transitivePeerDependencies:
- supports-color
dev: true
/@typescript-eslint/parser@6.11.0(eslint@8.54.0)(typescript@5.2.2): /@typescript-eslint/parser@6.11.0(eslint@8.54.0)(typescript@5.2.2):
resolution: {integrity: sha512-+whEdjk+d5do5nxfxx73oanLL9ghKO3EwM9kBCkUtWMRwWuPaFv9ScuqlYfQ6pAD6ZiJhky7TZ2ZYhrMsfMxVQ==} resolution: {integrity: sha512-+whEdjk+d5do5nxfxx73oanLL9ghKO3EwM9kBCkUtWMRwWuPaFv9ScuqlYfQ6pAD6ZiJhky7TZ2ZYhrMsfMxVQ==}
engines: {node: ^16.0.0 || >=18.0.0} engines: {node: ^16.0.0 || >=18.0.0}
...@@ -4315,28 +4240,16 @@ packages: ...@@ -4315,28 +4240,16 @@ packages:
'@typescript-eslint/visitor-keys': 6.11.0 '@typescript-eslint/visitor-keys': 6.11.0
dev: true dev: true
/@typescript-eslint/type-utils@6.11.0(eslint@8.53.0)(typescript@5.2.2): /@typescript-eslint/scope-manager@6.12.0:
resolution: {integrity: sha512-nA4IOXwZtqBjIoYrJcYxLRO+F9ri+leVGoJcMW1uqr4r1Hq7vW5cyWrA43lFbpRvQ9XgNrnfLpIkO3i1emDBIA==} resolution: {integrity: sha512-5gUvjg+XdSj8pcetdL9eXJzQNTl3RD7LgUiYTl8Aabdi8hFkaGSYnaS6BLc0BGNaDH+tVzVwmKtWvu0jLgWVbw==}
engines: {node: ^16.0.0 || >=18.0.0} engines: {node: ^16.0.0 || >=18.0.0}
peerDependencies:
eslint: ^7.0.0 || ^8.0.0
typescript: '*'
peerDependenciesMeta:
typescript:
optional: true
dependencies: dependencies:
'@typescript-eslint/typescript-estree': 6.11.0(typescript@5.2.2) '@typescript-eslint/types': 6.12.0
'@typescript-eslint/utils': 6.11.0(eslint@8.53.0)(typescript@5.2.2) '@typescript-eslint/visitor-keys': 6.12.0
debug: 4.3.4(supports-color@8.1.1)
eslint: 8.53.0
ts-api-utils: 1.0.1(typescript@5.2.2)
typescript: 5.2.2
transitivePeerDependencies:
- supports-color
dev: true dev: true
/@typescript-eslint/type-utils@6.11.0(eslint@8.54.0)(typescript@5.2.2): /@typescript-eslint/type-utils@6.12.0(eslint@8.54.0)(typescript@5.2.2):
resolution: {integrity: sha512-nA4IOXwZtqBjIoYrJcYxLRO+F9ri+leVGoJcMW1uqr4r1Hq7vW5cyWrA43lFbpRvQ9XgNrnfLpIkO3i1emDBIA==} resolution: {integrity: sha512-WWmRXxhm1X8Wlquj+MhsAG4dU/Blvf1xDgGaYCzfvStP2NwPQh6KBvCDbiOEvaE0filhranjIlK/2fSTVwtBng==}
engines: {node: ^16.0.0 || >=18.0.0} engines: {node: ^16.0.0 || >=18.0.0}
peerDependencies: peerDependencies:
eslint: ^7.0.0 || ^8.0.0 eslint: ^7.0.0 || ^8.0.0
...@@ -4345,8 +4258,8 @@ packages: ...@@ -4345,8 +4258,8 @@ packages:
typescript: typescript:
optional: true optional: true
dependencies: dependencies:
'@typescript-eslint/typescript-estree': 6.11.0(typescript@5.2.2) '@typescript-eslint/typescript-estree': 6.12.0(typescript@5.2.2)
'@typescript-eslint/utils': 6.11.0(eslint@8.54.0)(typescript@5.2.2) '@typescript-eslint/utils': 6.12.0(eslint@8.54.0)(typescript@5.2.2)
debug: 4.3.4(supports-color@8.1.1) debug: 4.3.4(supports-color@8.1.1)
eslint: 8.54.0 eslint: 8.54.0
ts-api-utils: 1.0.1(typescript@5.2.2) ts-api-utils: 1.0.1(typescript@5.2.2)
...@@ -4360,6 +4273,11 @@ packages: ...@@ -4360,6 +4273,11 @@ packages:
engines: {node: ^16.0.0 || >=18.0.0} engines: {node: ^16.0.0 || >=18.0.0}
dev: true dev: true
/@typescript-eslint/types@6.12.0:
resolution: {integrity: sha512-MA16p/+WxM5JG/F3RTpRIcuOghWO30//VEOvzubM8zuOOBYXsP+IfjoCXXiIfy2Ta8FRh9+IO9QLlaFQUU+10Q==}
engines: {node: ^16.0.0 || >=18.0.0}
dev: true
/@typescript-eslint/typescript-estree@6.11.0(typescript@5.2.2): /@typescript-eslint/typescript-estree@6.11.0(typescript@5.2.2):
resolution: {integrity: sha512-Aezzv1o2tWJwvZhedzvD5Yv7+Lpu1by/U1LZ5gLc4tCx8jUmuSCMioPFRjliN/6SJIvY6HpTtJIWubKuYYYesQ==} resolution: {integrity: sha512-Aezzv1o2tWJwvZhedzvD5Yv7+Lpu1by/U1LZ5gLc4tCx8jUmuSCMioPFRjliN/6SJIvY6HpTtJIWubKuYYYesQ==}
engines: {node: ^16.0.0 || >=18.0.0} engines: {node: ^16.0.0 || >=18.0.0}
...@@ -4381,27 +4299,29 @@ packages: ...@@ -4381,27 +4299,29 @@ packages:
- supports-color - supports-color
dev: true dev: true
/@typescript-eslint/utils@6.11.0(eslint@8.53.0)(typescript@5.2.2): /@typescript-eslint/typescript-estree@6.12.0(typescript@5.2.2):
resolution: {integrity: sha512-p23ibf68fxoZy605dc0dQAEoUsoiNoP3MD9WQGiHLDuTSOuqoTsa4oAy+h3KDkTcxbbfOtUjb9h3Ta0gT4ug2g==} resolution: {integrity: sha512-vw9E2P9+3UUWzhgjyyVczLWxZ3GuQNT7QpnIY3o5OMeLO/c8oHljGc8ZpryBMIyympiAAaKgw9e5Hl9dCWFOYw==}
engines: {node: ^16.0.0 || >=18.0.0} engines: {node: ^16.0.0 || >=18.0.0}
peerDependencies: peerDependencies:
eslint: ^7.0.0 || ^8.0.0 typescript: '*'
peerDependenciesMeta:
typescript:
optional: true
dependencies: dependencies:
'@eslint-community/eslint-utils': 4.4.0(eslint@8.53.0) '@typescript-eslint/types': 6.12.0
'@types/json-schema': 7.0.12 '@typescript-eslint/visitor-keys': 6.12.0
'@types/semver': 7.5.0 debug: 4.3.4(supports-color@8.1.1)
'@typescript-eslint/scope-manager': 6.11.0 globby: 11.1.0
'@typescript-eslint/types': 6.11.0 is-glob: 4.0.3
'@typescript-eslint/typescript-estree': 6.11.0(typescript@5.2.2)
eslint: 8.53.0
semver: 7.5.4 semver: 7.5.4
ts-api-utils: 1.0.1(typescript@5.2.2)
typescript: 5.2.2
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
- typescript
dev: true dev: true
/@typescript-eslint/utils@6.11.0(eslint@8.54.0)(typescript@5.2.2): /@typescript-eslint/utils@6.12.0(eslint@8.54.0)(typescript@5.2.2):
resolution: {integrity: sha512-p23ibf68fxoZy605dc0dQAEoUsoiNoP3MD9WQGiHLDuTSOuqoTsa4oAy+h3KDkTcxbbfOtUjb9h3Ta0gT4ug2g==} resolution: {integrity: sha512-LywPm8h3tGEbgfyjYnu3dauZ0U7R60m+miXgKcZS8c7QALO9uWJdvNoP+duKTk2XMWc7/Q3d/QiCuLN9X6SWyQ==}
engines: {node: ^16.0.0 || >=18.0.0} engines: {node: ^16.0.0 || >=18.0.0}
peerDependencies: peerDependencies:
eslint: ^7.0.0 || ^8.0.0 eslint: ^7.0.0 || ^8.0.0
...@@ -4409,9 +4329,9 @@ packages: ...@@ -4409,9 +4329,9 @@ packages:
'@eslint-community/eslint-utils': 4.4.0(eslint@8.54.0) '@eslint-community/eslint-utils': 4.4.0(eslint@8.54.0)
'@types/json-schema': 7.0.12 '@types/json-schema': 7.0.12
'@types/semver': 7.5.0 '@types/semver': 7.5.0
'@typescript-eslint/scope-manager': 6.11.0 '@typescript-eslint/scope-manager': 6.12.0
'@typescript-eslint/types': 6.11.0 '@typescript-eslint/types': 6.12.0
'@typescript-eslint/typescript-estree': 6.11.0(typescript@5.2.2) '@typescript-eslint/typescript-estree': 6.12.0(typescript@5.2.2)
eslint: 8.54.0 eslint: 8.54.0
semver: 7.5.4 semver: 7.5.4
transitivePeerDependencies: transitivePeerDependencies:
...@@ -4427,6 +4347,14 @@ packages: ...@@ -4427,6 +4347,14 @@ packages:
eslint-visitor-keys: 3.4.3 eslint-visitor-keys: 3.4.3
dev: true dev: true
/@typescript-eslint/visitor-keys@6.12.0:
resolution: {integrity: sha512-rg3BizTZHF1k3ipn8gfrzDXXSFKyOEB5zxYXInQ6z0hUvmQlhaZQzK+YmHmNViMA9HzW5Q9+bPPt90bU6GQwyw==}
engines: {node: ^16.0.0 || >=18.0.0}
dependencies:
'@typescript-eslint/types': 6.12.0
eslint-visitor-keys: 3.4.3
dev: true
/@ungap/structured-clone@1.2.0: /@ungap/structured-clone@1.2.0:
resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==}
dev: true dev: true
...@@ -7811,53 +7739,6 @@ packages: ...@@ -7811,53 +7739,6 @@ packages:
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
dev: true dev: true
/eslint@8.53.0:
resolution: {integrity: sha512-N4VuiPjXDUa4xVeV/GC/RV3hQW9Nw+Y463lkWaKKXKYMvmRiRDAtfpuPFLN+E1/6ZhyR8J2ig+eVREnYgUsiag==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
hasBin: true
dependencies:
'@eslint-community/eslint-utils': 4.4.0(eslint@8.53.0)
'@eslint-community/regexpp': 4.6.2
'@eslint/eslintrc': 2.1.3
'@eslint/js': 8.53.0
'@humanwhocodes/config-array': 0.11.13
'@humanwhocodes/module-importer': 1.0.1
'@nodelib/fs.walk': 1.2.8
'@ungap/structured-clone': 1.2.0
ajv: 6.12.6
chalk: 4.1.2
cross-spawn: 7.0.3
debug: 4.3.4(supports-color@8.1.1)
doctrine: 3.0.0
escape-string-regexp: 4.0.0
eslint-scope: 7.2.2
eslint-visitor-keys: 3.4.3
espree: 9.6.1
esquery: 1.5.0
esutils: 2.0.3
fast-deep-equal: 3.1.3
file-entry-cache: 6.0.1
find-up: 5.0.0
glob-parent: 6.0.2
globals: 13.21.0
graphemer: 1.4.0
ignore: 5.2.4
imurmurhash: 0.1.4
is-glob: 4.0.3
is-path-inside: 3.0.3
js-yaml: 4.1.0
json-stable-stringify-without-jsonify: 1.0.1
levn: 0.4.1
lodash.merge: 4.6.2
minimatch: 3.1.2
natural-compare: 1.4.0
optionator: 0.9.3
strip-ansi: 6.0.1
text-table: 0.2.0
transitivePeerDependencies:
- supports-color
dev: true
/eslint@8.54.0: /eslint@8.54.0:
resolution: {integrity: sha512-NY0DfAkM8BIZDVl6PgSa1ttZbx3xHgJzSNJKYcQglem6CppHyMhRIQkBVSSMaSRnLhig3jsDbEzOjwCVt4AmmA==} resolution: {integrity: sha512-NY0DfAkM8BIZDVl6PgSa1ttZbx3xHgJzSNJKYcQglem6CppHyMhRIQkBVSSMaSRnLhig3jsDbEzOjwCVt4AmmA==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
...@@ -9097,7 +8978,7 @@ packages: ...@@ -9097,7 +8978,7 @@ packages:
solc: 0.7.3(debug@4.3.4) solc: 0.7.3(debug@4.3.4)
source-map-support: 0.5.21 source-map-support: 0.5.21
stacktrace-parser: 0.1.10 stacktrace-parser: 0.1.10
ts-node: 10.9.1(@types/node@20.9.0)(typescript@5.2.2) ts-node: 10.9.1(@types/node@20.9.3)(typescript@5.2.2)
tsort: 0.0.1 tsort: 0.0.1
typescript: 5.2.2 typescript: 5.2.2
undici: 5.24.0 undici: 5.24.0
...@@ -13832,7 +13713,7 @@ packages: ...@@ -13832,7 +13713,7 @@ packages:
tsconfig-paths: 3.14.2 tsconfig-paths: 3.14.2
dev: true dev: true
/ts-node@10.9.1(@types/node@20.9.0)(typescript@5.2.2): /ts-node@10.9.1(@types/node@20.9.3)(typescript@5.2.2):
resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==}
hasBin: true hasBin: true
peerDependencies: peerDependencies:
...@@ -13851,7 +13732,7 @@ packages: ...@@ -13851,7 +13732,7 @@ packages:
'@tsconfig/node12': 1.0.11 '@tsconfig/node12': 1.0.11
'@tsconfig/node14': 1.0.3 '@tsconfig/node14': 1.0.3
'@tsconfig/node16': 1.0.4 '@tsconfig/node16': 1.0.4
'@types/node': 20.9.0 '@types/node': 20.9.3
acorn: 8.10.0 acorn: 8.10.0
acorn-walk: 8.2.0 acorn-walk: 8.2.0
arg: 4.1.3 arg: 4.1.3
...@@ -13922,7 +13803,7 @@ packages: ...@@ -13922,7 +13803,7 @@ packages:
resolution: {integrity: sha512-Tyrf5mxF8Ofs1tNoxA13lFeZ2Zrbd6cKbuH3V+MQ5sb6DtBj5FjrXVsRWT8YvNAQTqNoz66dz1WsbigI22aEnw==} resolution: {integrity: sha512-Tyrf5mxF8Ofs1tNoxA13lFeZ2Zrbd6cKbuH3V+MQ5sb6DtBj5FjrXVsRWT8YvNAQTqNoz66dz1WsbigI22aEnw==}
dev: true dev: true
/tsup@7.2.0(@swc/core@1.3.95)(typescript@5.2.2): /tsup@7.2.0(@swc/core@1.3.99)(typescript@5.2.2):
resolution: {integrity: sha512-vDHlczXbgUvY3rWvqFEbSqmC1L7woozbzngMqTtL2PGBODTtWlRwGDDawhvWzr5c1QjKe4OAKqJGfE1xeXUvtQ==} resolution: {integrity: sha512-vDHlczXbgUvY3rWvqFEbSqmC1L7woozbzngMqTtL2PGBODTtWlRwGDDawhvWzr5c1QjKe4OAKqJGfE1xeXUvtQ==}
engines: {node: '>=16.14'} engines: {node: '>=16.14'}
hasBin: true hasBin: true
...@@ -13938,7 +13819,7 @@ packages: ...@@ -13938,7 +13819,7 @@ packages:
typescript: typescript:
optional: true optional: true
dependencies: dependencies:
'@swc/core': 1.3.95 '@swc/core': 1.3.99
bundle-require: 4.0.1(esbuild@0.18.15) bundle-require: 4.0.1(esbuild@0.18.15)
cac: 6.7.14 cac: 6.7.14
chokidar: 3.5.3 chokidar: 3.5.3
...@@ -13959,8 +13840,8 @@ packages: ...@@ -13959,8 +13840,8 @@ packages:
- ts-node - ts-node
dev: true dev: true
/tsx@4.1.1: /tsx@4.2.0:
resolution: {integrity: sha512-zyPn5BFMB0TB5kMLbYPNx4x/oL/oSlaecdKCv6WeJ0TeSEfx8RTJWjuB5TZ2dSewktgfBsBO/HNA9mrMWqLXMA==} resolution: {integrity: sha512-hvAXAz4KUYNyjXOjJJgyjT7YOGFUNLC8jnODI6Omc/wGKaZ7z0FvW5d2haqg1GLfX49H3nZOpLYRlHMYGI8Wbw==}
engines: {node: '>=18.0.0'} engines: {node: '>=18.0.0'}
hasBin: true hasBin: true
dependencies: dependencies:
...@@ -14453,7 +14334,7 @@ packages: ...@@ -14453,7 +14334,7 @@ packages:
- utf-8-validate - utf-8-validate
- zod - zod
/vite-node@0.34.1(@types/node@20.9.0): /vite-node@0.34.1(@types/node@20.9.3):
resolution: {integrity: sha512-odAZAL9xFMuAg8aWd7nSPT+hU8u2r9gU3LRm9QKjxBEF2rRdWpMuqkrkjvyVQEdNFiBctqr2Gg4uJYizm5Le6w==} resolution: {integrity: sha512-odAZAL9xFMuAg8aWd7nSPT+hU8u2r9gU3LRm9QKjxBEF2rRdWpMuqkrkjvyVQEdNFiBctqr2Gg4uJYizm5Le6w==}
engines: {node: '>=v14.18.0'} engines: {node: '>=v14.18.0'}
hasBin: true hasBin: true
...@@ -14463,7 +14344,7 @@ packages: ...@@ -14463,7 +14344,7 @@ packages:
mlly: 1.4.0 mlly: 1.4.0
pathe: 1.1.1 pathe: 1.1.1
picocolors: 1.0.0 picocolors: 1.0.0
vite: 4.5.0(@types/node@20.9.0) vite: 4.5.0(@types/node@20.9.3)
transitivePeerDependencies: transitivePeerDependencies:
- '@types/node' - '@types/node'
- less - less
...@@ -14475,7 +14356,7 @@ packages: ...@@ -14475,7 +14356,7 @@ packages:
- terser - terser
dev: true dev: true
/vite-node@0.34.2(@types/node@20.8.9): /vite-node@0.34.2(@types/node@20.9.0):
resolution: {integrity: sha512-JtW249Zm3FB+F7pQfH56uWSdlltCo1IOkZW5oHBzeQo0iX4jtC7o1t9aILMGd9kVekXBP2lfJBEQt9rBh07ebA==} resolution: {integrity: sha512-JtW249Zm3FB+F7pQfH56uWSdlltCo1IOkZW5oHBzeQo0iX4jtC7o1t9aILMGd9kVekXBP2lfJBEQt9rBh07ebA==}
engines: {node: '>=v14.18.0'} engines: {node: '>=v14.18.0'}
hasBin: true hasBin: true
...@@ -14485,7 +14366,7 @@ packages: ...@@ -14485,7 +14366,7 @@ packages:
mlly: 1.4.0 mlly: 1.4.0
pathe: 1.1.1 pathe: 1.1.1
picocolors: 1.0.0 picocolors: 1.0.0
vite: 4.5.0(@types/node@20.8.9) vite: 4.5.0(@types/node@20.9.0)
transitivePeerDependencies: transitivePeerDependencies:
- '@types/node' - '@types/node'
- less - less
...@@ -14497,7 +14378,7 @@ packages: ...@@ -14497,7 +14378,7 @@ packages:
- terser - terser
dev: true dev: true
/vite-node@0.34.2(@types/node@20.9.0): /vite-node@0.34.2(@types/node@20.9.3):
resolution: {integrity: sha512-JtW249Zm3FB+F7pQfH56uWSdlltCo1IOkZW5oHBzeQo0iX4jtC7o1t9aILMGd9kVekXBP2lfJBEQt9rBh07ebA==} resolution: {integrity: sha512-JtW249Zm3FB+F7pQfH56uWSdlltCo1IOkZW5oHBzeQo0iX4jtC7o1t9aILMGd9kVekXBP2lfJBEQt9rBh07ebA==}
engines: {node: '>=v14.18.0'} engines: {node: '>=v14.18.0'}
hasBin: true hasBin: true
...@@ -14507,7 +14388,7 @@ packages: ...@@ -14507,7 +14388,7 @@ packages:
mlly: 1.4.0 mlly: 1.4.0
pathe: 1.1.1 pathe: 1.1.1
picocolors: 1.0.0 picocolors: 1.0.0
vite: 4.5.0(@types/node@20.9.0) vite: 4.5.0(@types/node@20.9.3)
transitivePeerDependencies: transitivePeerDependencies:
- '@types/node' - '@types/node'
- less - less
...@@ -14519,7 +14400,7 @@ packages: ...@@ -14519,7 +14400,7 @@ packages:
- terser - terser
dev: true dev: true
/vite-node@0.34.4(@types/node@20.8.9): /vite-node@0.34.4(@types/node@20.9.0):
resolution: {integrity: sha512-ho8HtiLc+nsmbwZMw8SlghESEE3KxJNp04F/jPUCLVvaURwt0d+r9LxEqCX5hvrrOQ0GSyxbYr5ZfRYhQ0yVKQ==} resolution: {integrity: sha512-ho8HtiLc+nsmbwZMw8SlghESEE3KxJNp04F/jPUCLVvaURwt0d+r9LxEqCX5hvrrOQ0GSyxbYr5ZfRYhQ0yVKQ==}
engines: {node: '>=v14.18.0'} engines: {node: '>=v14.18.0'}
hasBin: true hasBin: true
...@@ -14529,7 +14410,7 @@ packages: ...@@ -14529,7 +14410,7 @@ packages:
mlly: 1.4.0 mlly: 1.4.0
pathe: 1.1.1 pathe: 1.1.1
picocolors: 1.0.0 picocolors: 1.0.0
vite: 4.5.0(@types/node@20.8.9) vite: 4.5.0(@types/node@20.9.0)
transitivePeerDependencies: transitivePeerDependencies:
- '@types/node' - '@types/node'
- less - less
...@@ -14541,7 +14422,7 @@ packages: ...@@ -14541,7 +14422,7 @@ packages:
- terser - terser
dev: true dev: true
/vite@4.4.10(@types/node@20.8.9): /vite@4.4.10(@types/node@20.9.0):
resolution: {integrity: sha512-TzIjiqx9BEXF8yzYdF2NTf1kFFbjMjUSV0LFZ3HyHoI3SGSPLnnFUKiIQtL3gl2AjHvMrprOvQ3amzaHgQlAxw==} resolution: {integrity: sha512-TzIjiqx9BEXF8yzYdF2NTf1kFFbjMjUSV0LFZ3HyHoI3SGSPLnnFUKiIQtL3gl2AjHvMrprOvQ3amzaHgQlAxw==}
engines: {node: ^14.18.0 || >=16.0.0} engines: {node: ^14.18.0 || >=16.0.0}
hasBin: true hasBin: true
...@@ -14569,7 +14450,7 @@ packages: ...@@ -14569,7 +14450,7 @@ packages:
terser: terser:
optional: true optional: true
dependencies: dependencies:
'@types/node': 20.8.9 '@types/node': 20.9.0
esbuild: 0.18.20 esbuild: 0.18.20
postcss: 8.4.27 postcss: 8.4.27
rollup: 3.28.0 rollup: 3.28.0
...@@ -14577,7 +14458,7 @@ packages: ...@@ -14577,7 +14458,7 @@ packages:
fsevents: 2.3.3 fsevents: 2.3.3
dev: true dev: true
/vite@4.5.0(@types/node@20.8.9): /vite@4.5.0(@types/node@20.9.0):
resolution: {integrity: sha512-ulr8rNLA6rkyFAlVWw2q5YJ91v098AFQ2R0PRFwPzREXOUJQPtFUG0t+/ZikhaOCDqFoDhN6/v8Sq0o4araFAw==} resolution: {integrity: sha512-ulr8rNLA6rkyFAlVWw2q5YJ91v098AFQ2R0PRFwPzREXOUJQPtFUG0t+/ZikhaOCDqFoDhN6/v8Sq0o4araFAw==}
engines: {node: ^14.18.0 || >=16.0.0} engines: {node: ^14.18.0 || >=16.0.0}
hasBin: true hasBin: true
...@@ -14605,7 +14486,7 @@ packages: ...@@ -14605,7 +14486,7 @@ packages:
terser: terser:
optional: true optional: true
dependencies: dependencies:
'@types/node': 20.8.9 '@types/node': 20.9.0
esbuild: 0.18.20 esbuild: 0.18.20
postcss: 8.4.27 postcss: 8.4.27
rollup: 3.28.0 rollup: 3.28.0
...@@ -14613,7 +14494,7 @@ packages: ...@@ -14613,7 +14494,7 @@ packages:
fsevents: 2.3.3 fsevents: 2.3.3
dev: true dev: true
/vite@4.5.0(@types/node@20.9.0): /vite@4.5.0(@types/node@20.9.3):
resolution: {integrity: sha512-ulr8rNLA6rkyFAlVWw2q5YJ91v098AFQ2R0PRFwPzREXOUJQPtFUG0t+/ZikhaOCDqFoDhN6/v8Sq0o4araFAw==} resolution: {integrity: sha512-ulr8rNLA6rkyFAlVWw2q5YJ91v098AFQ2R0PRFwPzREXOUJQPtFUG0t+/ZikhaOCDqFoDhN6/v8Sq0o4araFAw==}
engines: {node: ^14.18.0 || >=16.0.0} engines: {node: ^14.18.0 || >=16.0.0}
hasBin: true hasBin: true
...@@ -14641,7 +14522,7 @@ packages: ...@@ -14641,7 +14522,7 @@ packages:
terser: terser:
optional: true optional: true
dependencies: dependencies:
'@types/node': 20.9.0 '@types/node': 20.9.3
esbuild: 0.18.20 esbuild: 0.18.20
postcss: 8.4.27 postcss: 8.4.27
rollup: 3.28.0 rollup: 3.28.0
...@@ -14682,7 +14563,7 @@ packages: ...@@ -14682,7 +14563,7 @@ packages:
dependencies: dependencies:
'@types/chai': 4.3.10 '@types/chai': 4.3.10
'@types/chai-subset': 1.3.3 '@types/chai-subset': 1.3.3
'@types/node': 20.9.0 '@types/node': 20.9.3
'@vitest/expect': 0.34.1 '@vitest/expect': 0.34.1
'@vitest/runner': 0.34.1 '@vitest/runner': 0.34.1
'@vitest/snapshot': 0.34.1 '@vitest/snapshot': 0.34.1
...@@ -14701,8 +14582,8 @@ packages: ...@@ -14701,8 +14582,8 @@ packages:
strip-literal: 1.0.1 strip-literal: 1.0.1
tinybench: 2.5.0 tinybench: 2.5.0
tinypool: 0.7.0 tinypool: 0.7.0
vite: 4.5.0(@types/node@20.9.0) vite: 4.5.0(@types/node@20.9.3)
vite-node: 0.34.1(@types/node@20.9.0) vite-node: 0.34.1(@types/node@20.9.3)
why-is-node-running: 2.2.2 why-is-node-running: 2.2.2
transitivePeerDependencies: transitivePeerDependencies:
- less - less
...@@ -14747,7 +14628,7 @@ packages: ...@@ -14747,7 +14628,7 @@ packages:
dependencies: dependencies:
'@types/chai': 4.3.10 '@types/chai': 4.3.10
'@types/chai-subset': 1.3.3 '@types/chai-subset': 1.3.3
'@types/node': 20.9.0 '@types/node': 20.9.3
'@vitest/expect': 0.34.2 '@vitest/expect': 0.34.2
'@vitest/runner': 0.34.2 '@vitest/runner': 0.34.2
'@vitest/snapshot': 0.34.2 '@vitest/snapshot': 0.34.2
...@@ -14766,8 +14647,8 @@ packages: ...@@ -14766,8 +14647,8 @@ packages:
strip-literal: 1.0.1 strip-literal: 1.0.1
tinybench: 2.5.0 tinybench: 2.5.0
tinypool: 0.7.0 tinypool: 0.7.0
vite: 4.5.0(@types/node@20.9.0) vite: 4.5.0(@types/node@20.9.3)
vite-node: 0.34.2(@types/node@20.9.0) vite-node: 0.34.2(@types/node@20.9.3)
why-is-node-running: 2.2.2 why-is-node-running: 2.2.2
transitivePeerDependencies: transitivePeerDependencies:
- less - less
...@@ -14812,7 +14693,7 @@ packages: ...@@ -14812,7 +14693,7 @@ packages:
dependencies: dependencies:
'@types/chai': 4.3.8 '@types/chai': 4.3.8
'@types/chai-subset': 1.3.3 '@types/chai-subset': 1.3.3
'@types/node': 20.8.9 '@types/node': 20.9.0
'@vitest/expect': 0.34.2 '@vitest/expect': 0.34.2
'@vitest/runner': 0.34.2 '@vitest/runner': 0.34.2
'@vitest/snapshot': 0.34.2 '@vitest/snapshot': 0.34.2
...@@ -14832,8 +14713,8 @@ packages: ...@@ -14832,8 +14713,8 @@ packages:
strip-literal: 1.0.1 strip-literal: 1.0.1
tinybench: 2.5.0 tinybench: 2.5.0
tinypool: 0.7.0 tinypool: 0.7.0
vite: 4.5.0(@types/node@20.8.9) vite: 4.5.0(@types/node@20.9.0)
vite-node: 0.34.2(@types/node@20.8.9) vite-node: 0.34.2(@types/node@20.9.0)
why-is-node-running: 2.2.2 why-is-node-running: 2.2.2
transitivePeerDependencies: transitivePeerDependencies:
- less - less
...@@ -14878,7 +14759,7 @@ packages: ...@@ -14878,7 +14759,7 @@ packages:
dependencies: dependencies:
'@types/chai': 4.3.8 '@types/chai': 4.3.8
'@types/chai-subset': 1.3.3 '@types/chai-subset': 1.3.3
'@types/node': 20.8.9 '@types/node': 20.9.0
'@vitest/expect': 0.34.4 '@vitest/expect': 0.34.4
'@vitest/runner': 0.34.4 '@vitest/runner': 0.34.4
'@vitest/snapshot': 0.34.4 '@vitest/snapshot': 0.34.4
...@@ -14897,8 +14778,8 @@ packages: ...@@ -14897,8 +14778,8 @@ packages:
strip-literal: 1.0.1 strip-literal: 1.0.1
tinybench: 2.5.0 tinybench: 2.5.0
tinypool: 0.7.0 tinypool: 0.7.0
vite: 4.4.10(@types/node@20.8.9) vite: 4.4.10(@types/node@20.9.0)
vite-node: 0.34.4(@types/node@20.8.9) vite-node: 0.34.4(@types/node@20.9.0)
why-is-node-running: 2.2.2 why-is-node-running: 2.2.2
transitivePeerDependencies: transitivePeerDependencies:
- less - less
......
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