Commit 630d4edc authored by Karl Floersch's avatar Karl Floersch

Merge remote-tracking branch 'origin' into regenesis/0.4.0

parents e04de624 cc742715
--- ---
'@eth-optimism/l2geth': patch '@eth-optimism/l2geth': patch
'@eth-optimism/data-transport-layer': patch
--- ---
Fix gasLimit overflow Optimize main polling loops
---
'@eth-optimism/l2geth': patch
---
Fixes incorrect type parsing in the RollupClient. The gasLimit became greater than the largest safe JS number so it needs to be represented as a string
---
'@eth-optimism/integration-tests': patch
---
Reduce test timeout from 100 to 20 seconds
---
'@eth-optimism/smock': patch
---
Fixes a bug that would break call assertions for overloaded smocked functions
---
'@eth-optimism/data-transport-layer': patch
---
Represent gaslimit as a string to avoid an overflow
---
'@eth-optimism/l2geth': patch
'@eth-optimism/core-utils': patch
---
Implement the next fee spec in both geth and in core-utils
---
'@eth-optimism/message-relayer': patch
---
Adds a README and cleans up the interface for generating messages and proofs
---
'@eth-optimism/contracts': patch
---
Update contracts README to add deploy instructions.
---
'@eth-optimism/smock': patch
---
Fix a bug where overloaded functions would not be handled correctly
---
"@eth-optimism/l2geth": patch
---
Refactor the SyncService to more closely implement the specification. This includes using query params to select the backend from the DTL, trailing syncing of batches for the sequencer, syncing by batches as the verifier as well as unified code paths for transaction ingestion to prevent double ingestion or missed ingestion
--- ---
'@eth-optimism/batch-submitter': patch '@eth-optimism/batch-submitter': patch
'@eth-optimism/data-transport-layer': patch
--- ---
Remove dead imports from core-utils Fix typo in USE_HARDHAT config
---
'@eth-optimism/contracts': patch
---
Introduces the congestion price oracle contract
---
'@eth-optimism/message-relayer': patch
---
Adds a new set of tools for generating messages to be relayed and their proofs
---
'@eth-optimism/core-utils': patch
---
Delete dead transaction coders. These are no longer used now that RLP encoded transactions are used
---
'@eth-optimism/data-transport-layer': patch
---
Logs the error stacktrace for a failed HTTP request
---
'@eth-optimism/integration-tests': patch
'@eth-optimism/l2geth': patch
'@eth-optimism/core-utils': patch
---
Implement the latest fee spec such that the L2 gas limit is scaled and the tx.gasPrice/tx.gasLimit show correctly in metamask
---
'@eth-optimism/message-relayer': patch
---
Removes spreadsheet mode from the message relayer
---
'@eth-optimism/contracts': patch
---
Minor change to how deploy.ts is invoked
---
'@eth-optimism/integration-tests': patch
---
Add verifier sync test and extra docker-compose functions
...@@ -93,3 +93,21 @@ jobs: ...@@ -93,3 +93,21 @@ jobs:
yarn compile yarn compile
yarn compile:ovm yarn compile:ovm
yarn test:integration:ovm yarn test:integration:ovm
- name: Collect docker logs on failure
if: failure()
uses: jwalton/gh-docker-logs@v1
with:
images: 'ethereumoptimism/builder,ethereumoptimism/hardhat,ethereumoptimism/deployer,ethereumoptimism/data-transport-layer,ethereumoptimism/l2geth,ethereumoptimism/message-relayer,ethereumoptimism/batch-submitter,ethereumoptimism/l2geth,ethereumoptimism/integration-tests'
dest: './logs'
- name: Tar logs
if: failure()
run: tar cvzf ./logs.tgz ./logs
- name: Upload logs to GitHub
if: failure()
uses: actions/upload-artifact@master
with:
name: logs.tgz
path: ./logs.tgz
\ No newline at end of file
...@@ -2,7 +2,12 @@ name: Publish Packages (canary) ...@@ -2,7 +2,12 @@ name: Publish Packages (canary)
on: on:
# enable users to manually trigger with workflow_dispatch # enable users to manually trigger with workflow_dispatch
workflow_dispatch: {} workflow_dispatch:
inputs:
customImageName:
description: 'Custom Docker Image Tag (keep empty for git hash)'
required: false
default: '0.0.0-rc-0'
jobs: jobs:
canary-publish: canary-publish:
...@@ -66,6 +71,18 @@ jobs: ...@@ -66,6 +71,18 @@ jobs:
run: | run: |
node ops/scripts/ci-versions.js ${{ toJSON(steps.changesets.outputs.publishedPackages) }} node ops/scripts/ci-versions.js ${{ toJSON(steps.changesets.outputs.publishedPackages) }}
- name: Docker Image Name
id: docker_image_name
run: |
if [ $CUSTOM_IMAGE_NAME == '' ]
then
echo "::set-output name=canary-docker-tag::${GITHUB_SHA::8}"
else
echo "::set-output name=canary-docker-tag::prerelease-$CUSTOM_IMAGE_NAME"
fi
env:
CUSTOM_IMAGE_NAME: ${{ github.event.inputs.customImageName }}
# The below code is duplicated, would be ideal if we could use a matrix with a # The below code is duplicated, would be ideal if we could use a matrix with a
# key/value being dynamically generated from the `publishedPackages` output # key/value being dynamically generated from the `publishedPackages` output
...@@ -155,7 +172,7 @@ jobs: ...@@ -155,7 +172,7 @@ jobs:
context: . context: .
file: ./ops/docker/Dockerfile.message-relayer file: ./ops/docker/Dockerfile.message-relayer
push: true push: true
tags: ethereumoptimism/message-relayer:${{ needs.builder.outputs.message-relayer }} tags: ethereumoptimism/message-relayer:${{ steps.docker_image_name.outputs.canary-docker-tag }}
batch-submitter: batch-submitter:
name: Publish Batch Submitter Version ${{ needs.builder.outputs.batch-submitter }} name: Publish Batch Submitter Version ${{ needs.builder.outputs.batch-submitter }}
...@@ -181,7 +198,7 @@ jobs: ...@@ -181,7 +198,7 @@ jobs:
context: . context: .
file: ./ops/docker/Dockerfile.batch-submitter file: ./ops/docker/Dockerfile.batch-submitter
push: true push: true
tags: ethereumoptimism/batch-submitter:${{ needs.builder.outputs.batch-submitter }} tags: ethereumoptimism/batch-submitter:${{ steps.docker_image_name.outputs.canary-docker-tag }}
data-transport-layer: data-transport-layer:
name: Publish Data Transport Layer Version ${{ needs.builder.outputs.data-transport-layer }} name: Publish Data Transport Layer Version ${{ needs.builder.outputs.data-transport-layer }}
...@@ -207,7 +224,7 @@ jobs: ...@@ -207,7 +224,7 @@ jobs:
context: . context: .
file: ./ops/docker/Dockerfile.data-transport-layer file: ./ops/docker/Dockerfile.data-transport-layer
push: true push: true
tags: ethereumoptimism/data-transport-layer:${{ needs.builder.outputs.data-transport-layer }} tags: ethereumoptimism/data-transport-layer:${{ steps.docker_image_name.outputs.canary-docker-tag }}
contracts: contracts:
name: Publish Deployer Version ${{ needs.builder.outputs.contracts }} name: Publish Deployer Version ${{ needs.builder.outputs.contracts }}
...@@ -233,7 +250,7 @@ jobs: ...@@ -233,7 +250,7 @@ jobs:
context: . context: .
file: ./ops/docker/Dockerfile.deployer file: ./ops/docker/Dockerfile.deployer
push: true push: true
tags: ethereumoptimism/deployer:${{ needs.builder.outputs.contracts }} tags: ethereumoptimism/deployer:${{ steps.docker_image_name.outputs.canary-docker-tag }}
integration_tests: integration_tests:
name: Publish Integration tests ${{ needs.builder.outputs.integration-tests }} name: Publish Integration tests ${{ needs.builder.outputs.integration-tests }}
...@@ -259,4 +276,4 @@ jobs: ...@@ -259,4 +276,4 @@ jobs:
context: . context: .
file: ./ops/docker/Dockerfile.integration-tests file: ./ops/docker/Dockerfile.integration-tests
push: true push: true
tags: ethereumoptimism/integration-tests:${{ needs.builder.outputs.integration-tests }} tags: ethereumoptimism/integration-tests:${{ steps.docker_image_name.outputs.canary-docker-tag }}
name: sync-tests
on:
push:
branches:
- 'master'
- 'develop'
- 'regenesis/*'
pull_request:
workflow_dispatch:
jobs:
integration-sync-test:
runs-on: ubuntu-latest
env:
DOCKER_BUILDKIT: 1
COMPOSE_DOCKER_CLI_BUILD: 1
steps:
- uses: actions/checkout@v2
- name: Get yarn cache directory path
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
- uses: actions/cache@v2
id: yarn-cache
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
- name: Build the services
working-directory: ./ops
run: ./scripts/build-ci.sh
- name: Bring the stack up
working-directory: ./ops
run: docker-compose up -d && ./scripts/wait-for-sequencer.sh
- name: Run the sync tests
working-directory: ./integration-tests
run: |
yarn
yarn test:sync
# @eth-optimism/integration-tests # @eth-optimism/integration-tests
## 0.0.7
### Patch Changes
- d1680052: Reduce test timeout from 100 to 20 seconds
- c2b6e14b: Implement the latest fee spec such that the L2 gas limit is scaled and the tx.gasPrice/tx.gasLimit show correctly in metamask
- 77108d37: Add verifier sync test and extra docker-compose functions
## 0.0.6 ## 0.0.6
### Patch Changes ### Patch Changes
......
{ {
"name": "@eth-optimism/integration-tests", "name": "@eth-optimism/integration-tests",
"version": "0.0.6", "version": "0.0.7",
"description": "[Optimism] Integration Tests", "description": "[Optimism] Integration Tests",
"private": true, "private": true,
"author": "Optimism PBC", "author": "Optimism PBC",
...@@ -17,8 +17,8 @@ ...@@ -17,8 +17,8 @@
"clean": "rimraf cache artifacts artifacts-ovm cache-ovm" "clean": "rimraf cache artifacts artifacts-ovm cache-ovm"
}, },
"devDependencies": { "devDependencies": {
"@eth-optimism/contracts": "^0.3.4", "@eth-optimism/contracts": "^0.3.5",
"@eth-optimism/core-utils": "^0.4.4", "@eth-optimism/core-utils": "^0.4.5",
"@eth-optimism/hardhat-ovm": "^0.2.2", "@eth-optimism/hardhat-ovm": "^0.2.2",
"@ethersproject/providers": "^5.0.24", "@ethersproject/providers": "^5.0.24",
"@nomiclabs/hardhat-ethers": "^2.0.2", "@nomiclabs/hardhat-ethers": "^2.0.2",
......
...@@ -60,7 +60,7 @@ describe('Syncing a verifier', () => { ...@@ -60,7 +60,7 @@ describe('Syncing a verifier', () => {
}) })
describe('Basic transactions', () => { describe('Basic transactions', () => {
afterEach(async () => { after(async () => {
await verifier.stop('verifier') await verifier.stop('verifier')
await verifier.rm() await verifier.rm()
}) })
...@@ -97,5 +97,13 @@ describe('Syncing a verifier', () => { ...@@ -97,5 +97,13 @@ describe('Syncing a verifier', () => {
latestSequencerBlock.stateRoot latestSequencerBlock.stateRoot
) )
}) })
it('should have matching block data', async () => {
const sequencerTip = await sequencerProvider.getBlock('latest')
const verifierTip = await provider.getBlock('latest')
expect(sequencerTip.number).to.deep.eq(verifierTip.number)
expect(sequencerTip.hash).to.deep.eq(verifierTip.hash)
})
}) })
}) })
# Changelog # Changelog
## 0.3.7
### Patch Changes
- cb4a928b: Make block hashes deterministic by using the same clique signer key
- f1b27318: Fixes incorrect type parsing in the RollupClient. The gasLimit became greater than the largest safe JS number so it needs to be represented as a string
- a64f8161: Implement the next fee spec in both geth and in core-utils
- 5e4eaea1: fix potential underflow when launching the chain when the last verified index is 0
- 1293825c: Fix gasLimit overflow
- a25acbbd: Refactor the SyncService to more closely implement the specification. This includes using query params to select the backend from the DTL, trailing syncing of batches for the sequencer, syncing by batches as the verifier as well as unified code paths for transaction ingestion to prevent double ingestion or missed ingestion
- c2b6e14b: Implement the latest fee spec such that the L2 gas limit is scaled and the tx.gasPrice/tx.gasLimit show correctly in metamask
## 0.3.6 ## 0.3.6
### Patch Changes ### Patch Changes
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
package keystore package keystore
import ( import (
"bytes"
"crypto/ecdsa" "crypto/ecdsa"
crand "crypto/rand" crand "crypto/rand"
"errors" "errors"
...@@ -36,8 +37,10 @@ import ( ...@@ -36,8 +37,10 @@ import (
"github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/accounts"
"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/core/vm"
"github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/log"
) )
var ( var (
...@@ -80,6 +83,21 @@ func NewKeyStore(keydir string, scryptN, scryptP int) *KeyStore { ...@@ -80,6 +83,21 @@ func NewKeyStore(keydir string, scryptN, scryptP int) *KeyStore {
keydir, _ = filepath.Abs(keydir) keydir, _ = filepath.Abs(keydir)
ks := &KeyStore{storage: &keyStorePassphrase{keydir, scryptN, scryptP, false}} ks := &KeyStore{storage: &keyStorePassphrase{keydir, scryptN, scryptP, false}}
ks.init(keydir) ks.init(keydir)
if vm.UsingOVM {
// Add a deterministic key to the key store so that
// all clique blocks are signed with the same key
input := make([]byte, 65)
rng := bytes.NewReader(input)
key, err := newKey(rng)
log.Info("Adding key to keyring", "address", key.Address.Hex())
if err != nil {
panic(fmt.Sprintf("cannot create key: %s", err))
}
_, err = ks.importKey(key, "")
if err != nil {
panic(fmt.Sprintf("cannot import key: %s", err))
}
}
return ks return ks
} }
......
...@@ -471,12 +471,13 @@ var ( ...@@ -471,12 +471,13 @@ var (
MinerEtherbaseFlag = cli.StringFlag{ MinerEtherbaseFlag = cli.StringFlag{
Name: "miner.etherbase", Name: "miner.etherbase",
Usage: "Public address for block mining rewards (default = first account)", Usage: "Public address for block mining rewards (default = first account)",
Value: "0",
Value: "0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf",
EnvVar: "ETHERBASE",
} }
MinerLegacyEtherbaseFlag = cli.StringFlag{ MinerLegacyEtherbaseFlag = cli.StringFlag{
Name: "etherbase", Name: "etherbase",
Usage: "Public address for block mining rewards (default = first account, deprecated, use --miner.etherbase)", Usage: "Public address for block mining rewards (default = first account, deprecated, use --miner.etherbase)",
Value: "0",
} }
MinerExtraDataFlag = cli.StringFlag{ MinerExtraDataFlag = cli.StringFlag{
Name: "miner.extradata", Name: "miner.extradata",
......
...@@ -23,7 +23,6 @@ import ( ...@@ -23,7 +23,6 @@ import (
"io" "io"
"math/big" "math/big"
"math/rand" "math/rand"
"os"
"sync" "sync"
"time" "time"
...@@ -34,6 +33,7 @@ import ( ...@@ -34,6 +33,7 @@ import (
"github.com/ethereum/go-ethereum/consensus/misc" "github.com/ethereum/go-ethereum/consensus/misc"
"github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
...@@ -249,7 +249,7 @@ func (c *Clique) verifyHeader(chain consensus.ChainReader, header *types.Header, ...@@ -249,7 +249,7 @@ func (c *Clique) verifyHeader(chain consensus.ChainReader, header *types.Header,
} }
number := header.Number.Uint64() number := header.Number.Uint64()
if os.Getenv("USING_OVM") != "true" { if vm.UsingOVM {
// Don't waste time checking blocks from the future // Don't waste time checking blocks from the future
if header.Time > uint64(time.Now().Unix()) { if header.Time > uint64(time.Now().Unix()) {
return consensus.ErrFutureBlock return consensus.ErrFutureBlock
...@@ -631,7 +631,7 @@ func (c *Clique) Seal(chain consensus.ChainReader, block *types.Block, results c ...@@ -631,7 +631,7 @@ func (c *Clique) Seal(chain consensus.ChainReader, block *types.Block, results c
log.Trace("Out-of-turn signing requested", "wiggle", common.PrettyDuration(wiggle)) log.Trace("Out-of-turn signing requested", "wiggle", common.PrettyDuration(wiggle))
} }
if os.Getenv("USING_OVM") == "true" { if vm.UsingOVM {
delay = 0 delay = 0
} }
// Sign all the things! // Sign all the things!
......
{ {
"name": "@eth-optimism/l2geth", "name": "@eth-optimism/l2geth",
"version": "0.3.6", "version": "0.3.7",
"private": true, "private": true,
"devDependencies": {} "devDependencies": {}
} }
...@@ -10,8 +10,6 @@ import ( ...@@ -10,8 +10,6 @@ import (
type Config struct { type Config struct {
// Maximum calldata size for a Queue Origin Sequencer Tx // Maximum calldata size for a Queue Origin Sequencer Tx
MaxCallDataSize int MaxCallDataSize int
// Number of confs before applying a L1 to L2 tx
Eth1ConfirmationDepth uint64
// Verifier mode // Verifier mode
IsVerifier bool IsVerifier bool
// Enable the sync service // Enable the sync service
......
...@@ -54,7 +54,6 @@ type SyncService struct { ...@@ -54,7 +54,6 @@ type SyncService struct {
syncing atomic.Value syncing atomic.Value
chainHeadSub event.Subscription chainHeadSub event.Subscription
OVMContext OVMContext OVMContext OVMContext
confirmationDepth uint64
pollInterval time.Duration pollInterval time.Duration
timestampRefreshThreshold time.Duration timestampRefreshThreshold time.Duration
chainHeadCh chan core.ChainHeadEvent chainHeadCh chan core.ChainHeadEvent
...@@ -102,7 +101,6 @@ func NewSyncService(ctx context.Context, cfg Config, txpool *core.TxPool, bc *co ...@@ -102,7 +101,6 @@ func NewSyncService(ctx context.Context, cfg Config, txpool *core.TxPool, bc *co
cancel: cancel, cancel: cancel,
verifier: cfg.IsVerifier, verifier: cfg.IsVerifier,
enable: cfg.Eth1SyncServiceEnable, enable: cfg.Eth1SyncServiceEnable,
confirmationDepth: cfg.Eth1ConfirmationDepth,
syncing: atomic.Value{}, syncing: atomic.Value{},
bc: bc, bc: bc,
txpool: txpool, txpool: txpool,
...@@ -137,17 +135,18 @@ func NewSyncService(ctx context.Context, cfg Config, txpool *core.TxPool, bc *co ...@@ -137,17 +135,18 @@ func NewSyncService(ctx context.Context, cfg Config, txpool *core.TxPool, bc *co
} }
// Wait until the remote service is done syncing // Wait until the remote service is done syncing
for { t := time.NewTicker(10 * time.Second)
for ; true; <-t.C {
status, err := service.client.SyncStatus(service.backend) status, err := service.client.SyncStatus(service.backend)
if err != nil { if err != nil {
log.Error("Cannot get sync status") log.Error("Cannot get sync status")
continue continue
} }
if !status.Syncing { if !status.Syncing {
t.Stop()
break break
} }
log.Info("Still syncing", "index", status.CurrentTransactionIndex, "tip", status.HighestKnownTransactionIndex) log.Info("Still syncing", "index", status.CurrentTransactionIndex, "tip", status.HighestKnownTransactionIndex)
time.Sleep(10 * time.Second)
} }
// Initialize the latest L1 data here to make sure that // Initialize the latest L1 data here to make sure that
...@@ -241,8 +240,12 @@ func (s *SyncService) initializeLatestL1(ctcDeployHeight *big.Int) error { ...@@ -241,8 +240,12 @@ func (s *SyncService) initializeLatestL1(ctcDeployHeight *big.Int) error {
s.SetLatestL1Timestamp(context.Timestamp) s.SetLatestL1Timestamp(context.Timestamp)
s.SetLatestL1BlockNumber(context.BlockNumber) s.SetLatestL1BlockNumber(context.BlockNumber)
} else { } else {
// Prevent underflows
if *index != 0 {
*index = *index - 1
}
log.Info("Found latest index", "index", *index) log.Info("Found latest index", "index", *index)
block := s.bc.GetBlockByNumber(*index - 1) block := s.bc.GetBlockByNumber(*index)
if block == nil { if block == nil {
block = s.bc.CurrentBlock() block = s.bc.CurrentBlock()
idx := block.Number().Uint64() idx := block.Number().Uint64()
...@@ -251,11 +254,12 @@ func (s *SyncService) initializeLatestL1(ctcDeployHeight *big.Int) error { ...@@ -251,11 +254,12 @@ func (s *SyncService) initializeLatestL1(ctcDeployHeight *big.Int) error {
return fmt.Errorf("Current block height greater than index") return fmt.Errorf("Current block height greater than index")
} }
s.SetLatestIndex(&idx) s.SetLatestIndex(&idx)
log.Info("Block not found, resetting index", "new", idx, "old", *index-1) log.Info("Block not found, resetting index", "new", idx, "old", *index)
} }
txs := block.Transactions() txs := block.Transactions()
if len(txs) != 1 { if len(txs) != 1 {
log.Error("Unexpected number of transactions in block: %d", len(txs)) log.Error("Unexpected number of transactions in block", "count", len(txs))
panic("Cannot recover OVM Context")
} }
tx := txs[0] tx := txs[0]
s.SetLatestL1Timestamp(tx.L1Timestamp()) s.SetLatestL1Timestamp(tx.L1Timestamp())
...@@ -314,7 +318,8 @@ func (s *SyncService) Stop() error { ...@@ -314,7 +318,8 @@ func (s *SyncService) Stop() error {
// VerifierLoop is the main loop for Verifier mode // VerifierLoop is the main loop for Verifier mode
func (s *SyncService) VerifierLoop() { func (s *SyncService) VerifierLoop() {
log.Info("Starting Verifier Loop", "poll-interval", s.pollInterval, "timestamp-refresh-threshold", s.timestampRefreshThreshold) log.Info("Starting Verifier Loop", "poll-interval", s.pollInterval, "timestamp-refresh-threshold", s.timestampRefreshThreshold)
for { t := time.NewTicker(s.pollInterval)
for ; true; <-t.C {
if err := s.updateL1GasPrice(); err != nil { if err := s.updateL1GasPrice(); err != nil {
log.Error("Cannot update L1 gas price", "msg", err) log.Error("Cannot update L1 gas price", "msg", err)
} }
...@@ -324,7 +329,6 @@ func (s *SyncService) VerifierLoop() { ...@@ -324,7 +329,6 @@ func (s *SyncService) VerifierLoop() {
if err := s.updateL2GasPrice(nil); err != nil { if err := s.updateL2GasPrice(nil); err != nil {
log.Error("Cannot update L2 gas price", "msg", err) log.Error("Cannot update L2 gas price", "msg", err)
} }
time.Sleep(s.pollInterval)
} }
} }
...@@ -348,7 +352,8 @@ func (s *SyncService) verify() error { ...@@ -348,7 +352,8 @@ func (s *SyncService) verify() error {
// transactions and then updates the EthContext. // transactions and then updates the EthContext.
func (s *SyncService) SequencerLoop() { func (s *SyncService) SequencerLoop() {
log.Info("Starting Sequencer Loop", "poll-interval", s.pollInterval, "timestamp-refresh-threshold", s.timestampRefreshThreshold) log.Info("Starting Sequencer Loop", "poll-interval", s.pollInterval, "timestamp-refresh-threshold", s.timestampRefreshThreshold)
for { t := time.NewTicker(s.pollInterval)
for ; true; <-t.C {
if err := s.updateL1GasPrice(); err != nil { if err := s.updateL1GasPrice(); err != nil {
log.Error("Cannot update L1 gas price", "msg", err) log.Error("Cannot update L1 gas price", "msg", err)
} }
...@@ -364,7 +369,6 @@ func (s *SyncService) SequencerLoop() { ...@@ -364,7 +369,6 @@ func (s *SyncService) SequencerLoop() {
if err := s.updateContext(); err != nil { if err := s.updateContext(); err != nil {
log.Error("Could not update execution context", "error", err) log.Error("Could not update execution context", "error", err)
} }
time.Sleep(s.pollInterval)
} }
} }
......
...@@ -9,10 +9,12 @@ ROLLUP_POLL_INTERVAL_FLAG=500ms ...@@ -9,10 +9,12 @@ ROLLUP_POLL_INTERVAL_FLAG=500ms
ROLLUP_ENABLE_L2_GAS_POLLING=true ROLLUP_ENABLE_L2_GAS_POLLING=true
# ROLLUP_ENFORCE_FEES= # ROLLUP_ENFORCE_FEES=
ETHERBASE=0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf
RPC_ENABLE=true RPC_ENABLE=true
RPC_ADDR=0.0.0.0 RPC_ADDR=0.0.0.0
RPC_PORT=8545 RPC_PORT=8545
RPC_API=eth,net,rollup,web3 RPC_API=eth,net,rollup,web3,debug
RPC_CORS_DOMAIN=* RPC_CORS_DOMAIN=*
RPC_VHOSTS=* RPC_VHOSTS=*
......
# Changelog # Changelog
## 0.3.3
### Patch Changes
- 750a5021: Remove dead imports from core-utils
- Updated dependencies [a64f8161]
- Updated dependencies [4e03f8a9]
- Updated dependencies [8e2bfd07]
- Updated dependencies [750a5021]
- Updated dependencies [c2b6e14b]
- Updated dependencies [245136f1]
- @eth-optimism/core-utils@0.4.5
- @eth-optimism/contracts@0.3.5
## 0.3.2 ## 0.3.2
### Patch Changes ### Patch Changes
......
{ {
"name": "@eth-optimism/batch-submitter", "name": "@eth-optimism/batch-submitter",
"version": "0.3.2", "version": "0.3.3",
"private": true, "private": true,
"description": "[Optimism] Batch submission for sequencer & aggregators", "description": "[Optimism] Batch submission for sequencer & aggregators",
"main": "dist/index", "main": "dist/index",
...@@ -32,8 +32,8 @@ ...@@ -32,8 +32,8 @@
}, },
"dependencies": { "dependencies": {
"@eth-optimism/common-ts": "^0.1.2", "@eth-optimism/common-ts": "^0.1.2",
"@eth-optimism/contracts": "^0.3.1", "@eth-optimism/contracts": "^0.3.5",
"@eth-optimism/core-utils": "^0.4.3", "@eth-optimism/core-utils": "^0.4.5",
"@eth-optimism/ynatm": "^0.2.2", "@eth-optimism/ynatm": "^0.2.2",
"@ethersproject/abstract-provider": "^5.0.5", "@ethersproject/abstract-provider": "^5.0.5",
"@ethersproject/providers": "^5.0.14", "@ethersproject/providers": "^5.0.14",
...@@ -45,7 +45,7 @@ ...@@ -45,7 +45,7 @@
"prom-client": "^13.1.0" "prom-client": "^13.1.0"
}, },
"devDependencies": { "devDependencies": {
"@eth-optimism/smock": "^1.1.4", "@eth-optimism/smock": "^1.1.5",
"@nomiclabs/hardhat-ethers": "^2.0.2", "@nomiclabs/hardhat-ethers": "^2.0.2",
"@nomiclabs/hardhat-waffle": "^2.0.1", "@nomiclabs/hardhat-waffle": "^2.0.1",
"@types/bluebird": "^3.5.34", "@types/bluebird": "^3.5.34",
......
...@@ -178,15 +178,18 @@ export class StateBatchSubmitter extends BatchSubmitter { ...@@ -178,15 +178,18 @@ export class StateBatchSubmitter extends BatchSubmitter {
const nonce = await this.signer.getTransactionCount() const nonce = await this.signer.getTransactionCount()
const contractFunction = async (gasPrice): Promise<TransactionReceipt> => { const contractFunction = async (gasPrice): Promise<TransactionReceipt> => {
this.logger.info('Submitting appendStateBatch transaction', {
gasPrice,
nonce,
contractAddr: this.chainContract.address,
})
const contractTx = await this.chainContract.appendStateBatch( const contractTx = await this.chainContract.appendStateBatch(
batch, batch,
offsetStartsAtIndex, offsetStartsAtIndex,
{ nonce, gasPrice } { nonce, gasPrice }
) )
this.logger.info('Submitted appendStateBatch transaction', { this.logger.info('Submitted appendStateBatch transaction', {
nonce,
txHash: contractTx.hash, txHash: contractTx.hash,
contractAddr: this.chainContract.address,
from: contractTx.from, from: contractTx.from,
}) })
this.logger.debug('appendStateBatch transaction data', { this.logger.debug('appendStateBatch transaction data', {
......
...@@ -143,14 +143,17 @@ export class TransactionBatchSubmitter extends BatchSubmitter { ...@@ -143,14 +143,17 @@ export class TransactionBatchSubmitter extends BatchSubmitter {
const contractFunction = async ( const contractFunction = async (
gasPrice gasPrice
): Promise<TransactionReceipt> => { ): Promise<TransactionReceipt> => {
this.logger.info('Submitting appendQueueBatch transaction', {
gasPrice,
nonce,
contractAddr: this.chainContract.address,
})
const tx = await this.chainContract.appendQueueBatch(99999999, { const tx = await this.chainContract.appendQueueBatch(99999999, {
nonce, nonce,
gasPrice, gasPrice,
}) })
this.logger.info('Submitted appendQueueBatch transaction', { this.logger.info('Submitted appendQueueBatch transaction', {
nonce,
txHash: tx.hash, txHash: tx.hash,
contractAddr: this.chainContract.address,
from: tx.from, from: tx.from,
}) })
this.logger.debug('appendQueueBatch transaction data', { this.logger.debug('appendQueueBatch transaction data', {
...@@ -250,14 +253,17 @@ export class TransactionBatchSubmitter extends BatchSubmitter { ...@@ -250,14 +253,17 @@ export class TransactionBatchSubmitter extends BatchSubmitter {
const nonce = await this.signer.getTransactionCount() const nonce = await this.signer.getTransactionCount()
const contractFunction = async (gasPrice): Promise<TransactionReceipt> => { const contractFunction = async (gasPrice): Promise<TransactionReceipt> => {
this.logger.info('Submitting appendSequencerBatch transaction', {
gasPrice,
nonce,
contractAddr: this.chainContract.address,
})
const tx = await this.chainContract.appendSequencerBatch(batchParams, { const tx = await this.chainContract.appendSequencerBatch(batchParams, {
nonce, nonce,
gasPrice, gasPrice,
}) })
this.logger.info('Submitted appendSequencerBatch transaction', { this.logger.info('Submitted appendSequencerBatch transaction', {
nonce,
txHash: tx.hash, txHash: tx.hash,
contractAddr: this.chainContract.address,
from: tx.from, from: tx.from,
}) })
this.logger.debug('appendSequencerBatch transaction data', { this.logger.debug('appendSequencerBatch transaction data', {
......
...@@ -116,7 +116,7 @@ export const run = async () => { ...@@ -116,7 +116,7 @@ export const run = async () => {
logger = new Logger({ name }) logger = new Logger({ name })
} }
const useHardhat = config.bool('use-hardhat', !!env.USE_HARDAT) const useHardhat = config.bool('use-hardhat', !!env.USE_HARDHAT)
const DEBUG_IMPERSONATE_SEQUENCER_ADDRESS = config.str( const DEBUG_IMPERSONATE_SEQUENCER_ADDRESS = config.str(
'debug-impersonate-sequencer-address', 'debug-impersonate-sequencer-address',
env.DEBUG_IMPERSONATE_SEQUENCER_ADDRESS env.DEBUG_IMPERSONATE_SEQUENCER_ADDRESS
......
# Changelog # Changelog
## 0.3.5
### Patch Changes
- 4e03f8a9: Update contracts README to add deploy instructions.
- 8e2bfd07: Introduces the congestion price oracle contract
- 245136f1: Minor change to how deploy.ts is invoked
- Updated dependencies [a64f8161]
- Updated dependencies [750a5021]
- Updated dependencies [c2b6e14b]
- @eth-optimism/core-utils@0.4.5
## 0.3.4 ## 0.3.4
### Patch Changes ### Patch Changes
......
{ {
"name": "@eth-optimism/contracts", "name": "@eth-optimism/contracts",
"version": "0.3.4", "version": "0.3.5",
"main": "dist/index", "main": "dist/index",
"files": [ "files": [
"dist/**/*.js", "dist/**/*.js",
...@@ -50,7 +50,7 @@ ...@@ -50,7 +50,7 @@
"generate-markdown": "node \"./scripts/generate-markdown.js\"" "generate-markdown": "node \"./scripts/generate-markdown.js\""
}, },
"dependencies": { "dependencies": {
"@eth-optimism/core-utils": "^0.4.4", "@eth-optimism/core-utils": "^0.4.5",
"@ethersproject/abstract-provider": "^5.0.8", "@ethersproject/abstract-provider": "^5.0.8",
"@ethersproject/abstract-signer": "^5.1.0", "@ethersproject/abstract-signer": "^5.1.0",
"@ethersproject/contracts": "^5.0.5", "@ethersproject/contracts": "^5.0.5",
......
...@@ -225,7 +225,6 @@ export const isTestStep_Context = ( ...@@ -225,7 +225,6 @@ export const isTestStep_Context = (
'ovmCALLER', 'ovmCALLER',
'ovmNUMBER', 'ovmNUMBER',
'ovmADDRESS', 'ovmADDRESS',
'ovmNUMBER',
'ovmL1TXORIGIN', 'ovmL1TXORIGIN',
'ovmTIMESTAMP', 'ovmTIMESTAMP',
'ovmGASLIMIT', 'ovmGASLIMIT',
......
# @eth-optimism/core-utils # @eth-optimism/core-utils
## 0.4.5
### Patch Changes
- a64f8161: Implement the next fee spec in both geth and in core-utils
- 750a5021: Delete dead transaction coders. These are no longer used now that RLP encoded transactions are used
- c2b6e14b: Implement the latest fee spec such that the L2 gas limit is scaled and the tx.gasPrice/tx.gasLimit show correctly in metamask
## 0.4.4 ## 0.4.4
### Patch Changes ### Patch Changes
......
{ {
"name": "@eth-optimism/core-utils", "name": "@eth-optimism/core-utils",
"version": "0.4.4", "version": "0.4.5",
"main": "dist/index", "main": "dist/index",
"files": [ "files": [
"dist/*" "dist/*"
......
# data transport layer # data transport layer
## 0.3.5
### Patch Changes
- 1b692415: incorrect parsing of eth_getBlockRange result
## 0.3.4
### Patch Changes
- f1b27318: Represent gaslimit as a string to avoid an overflow
- 750a5021: Remove dead imports from core-utils
- 1293825c: Fix gasLimit overflow
- a75f05b7: Fixes a bug that prevented verifiers from syncing properly with the DTL
- e52ccd98: Logs the error stacktrace for a failed HTTP request
- 8ac4c74c: improve slow blocking JSON parsing that occurs during l2 sync
- Updated dependencies [a64f8161]
- Updated dependencies [4e03f8a9]
- Updated dependencies [8e2bfd07]
- Updated dependencies [750a5021]
- Updated dependencies [c2b6e14b]
- Updated dependencies [245136f1]
- @eth-optimism/core-utils@0.4.5
- @eth-optimism/contracts@0.3.5
## 0.3.3 ## 0.3.3
### Patch Changes ### Patch Changes
......
{ {
"name": "@eth-optimism/data-transport-layer", "name": "@eth-optimism/data-transport-layer",
"version": "0.3.3", "version": "0.3.5",
"private": true, "private": true,
"main": "dist/index", "main": "dist/index",
"files": [ "files": [
...@@ -22,14 +22,16 @@ ...@@ -22,14 +22,16 @@
}, },
"dependencies": { "dependencies": {
"@eth-optimism/common-ts": "^0.1.2", "@eth-optimism/common-ts": "^0.1.2",
"@eth-optimism/contracts": "^0.3.3", "@eth-optimism/contracts": "^0.3.5",
"@eth-optimism/core-utils": "^0.4.3", "@eth-optimism/core-utils": "^0.4.5",
"@ethersproject/providers": "^5.0.21", "@ethersproject/providers": "^5.0.21",
"@ethersproject/transactions": "^5.0.21", "@ethersproject/transactions": "^5.0.21",
"@sentry/node": "^6.3.1", "@sentry/node": "^6.3.1",
"@sentry/tracing": "^6.3.1", "@sentry/tracing": "^6.3.1",
"@types/express": "^4.17.11", "@types/express": "^4.17.11",
"axios": "^0.21.1",
"bcfg": "^0.1.6", "bcfg": "^0.1.6",
"bfj": "^7.0.2",
"browser-or-node": "^1.3.0", "browser-or-node": "^1.3.0",
"cors": "^2.8.5", "cors": "^2.8.5",
"dotenv": "^8.2.0", "dotenv": "^8.2.0",
...@@ -49,6 +51,7 @@ ...@@ -49,6 +51,7 @@
"@types/levelup": "^4.3.0", "@types/levelup": "^4.3.0",
"@types/mocha": "^8.2.2", "@types/mocha": "^8.2.2",
"@types/node-fetch": "^2.5.8", "@types/node-fetch": "^2.5.8",
"@types/workerpool": "^6.0.0",
"chai": "^4.3.4", "chai": "^4.3.4",
"chai-as-promised": "^7.1.1", "chai-as-promised": "^7.1.1",
"hardhat": "^2.2.1", "hardhat": "^2.2.1",
......
...@@ -20,6 +20,7 @@ import { ...@@ -20,6 +20,7 @@ import {
import { import {
SEQUENCER_ENTRYPOINT_ADDRESS, SEQUENCER_ENTRYPOINT_ADDRESS,
SEQUENCER_GAS_LIMIT, SEQUENCER_GAS_LIMIT,
parseSignatureVParam,
} from '../../../utils' } from '../../../utils'
export const handleEventsSequencerBatchAppended: EventHandlerSet< export const handleEventsSequencerBatchAppended: EventHandlerSet<
...@@ -76,7 +77,7 @@ export const handleEventsSequencerBatchAppended: EventHandlerSet< ...@@ -76,7 +77,7 @@ export const handleEventsSequencerBatchAppended: EventHandlerSet<
batchExtraData: batchSubmissionEvent.args._extraData, batchExtraData: batchSubmissionEvent.args._extraData,
} }
}, },
parseEvent: (event, extraData) => { parseEvent: (event, extraData, l2ChainId) => {
const transactionEntries: TransactionEntry[] = [] const transactionEntries: TransactionEntry[] = []
// It's easier to deal with this data if it's a Buffer. // It's easier to deal with this data if it's a Buffer.
...@@ -103,7 +104,8 @@ export const handleEventsSequencerBatchAppended: EventHandlerSet< ...@@ -103,7 +104,8 @@ export const handleEventsSequencerBatchAppended: EventHandlerSet<
) )
const decoded = maybeDecodeSequencerBatchTransaction( const decoded = maybeDecodeSequencerBatchTransaction(
sequencerTransaction sequencerTransaction,
l2ChainId
) )
transactionEntries.push({ transactionEntries.push({
...@@ -234,7 +236,8 @@ const parseSequencerBatchTransaction = ( ...@@ -234,7 +236,8 @@ const parseSequencerBatchTransaction = (
} }
const maybeDecodeSequencerBatchTransaction = ( const maybeDecodeSequencerBatchTransaction = (
transaction: Buffer transaction: Buffer,
l2ChainId: number
): DecodedSequencerBatchTransaction | null => { ): DecodedSequencerBatchTransaction | null => {
try { try {
const decodedTx = ethers.utils.parseTransaction(transaction) const decodedTx = ethers.utils.parseTransaction(transaction)
...@@ -247,7 +250,7 @@ const maybeDecodeSequencerBatchTransaction = ( ...@@ -247,7 +250,7 @@ const maybeDecodeSequencerBatchTransaction = (
target: toHexString(decodedTx.to), // Maybe null this out for creations? target: toHexString(decodedTx.to), // Maybe null this out for creations?
data: toHexString(decodedTx.data), data: toHexString(decodedTx.data),
sig: { sig: {
v: BigNumber.from(decodedTx.v).toNumber(), v: parseSignatureVParam(decodedTx.v, l2ChainId),
r: toHexString(decodedTx.r), r: toHexString(decodedTx.r),
s: toHexString(decodedTx.s), s: toHexString(decodedTx.s),
}, },
......
...@@ -3,6 +3,7 @@ import { fromHexString, EventArgsAddressSet } from '@eth-optimism/core-utils' ...@@ -3,6 +3,7 @@ import { fromHexString, EventArgsAddressSet } from '@eth-optimism/core-utils'
import { BaseService } from '@eth-optimism/common-ts' import { BaseService } from '@eth-optimism/common-ts'
import { JsonRpcProvider } from '@ethersproject/providers' import { JsonRpcProvider } from '@ethersproject/providers'
import { LevelUp } from 'levelup' import { LevelUp } from 'levelup'
import { ethers, constants } from 'ethers'
/* Imports: Internal */ /* Imports: Internal */
import { TransportDB } from '../../db/transport-db' import { TransportDB } from '../../db/transport-db'
...@@ -18,7 +19,6 @@ import { handleEventsTransactionEnqueued } from './handlers/transaction-enqueued ...@@ -18,7 +19,6 @@ import { handleEventsTransactionEnqueued } from './handlers/transaction-enqueued
import { handleEventsSequencerBatchAppended } from './handlers/sequencer-batch-appended' import { handleEventsSequencerBatchAppended } from './handlers/sequencer-batch-appended'
import { handleEventsStateBatchAppended } from './handlers/state-batch-appended' import { handleEventsStateBatchAppended } from './handlers/state-batch-appended'
import { L1DataTransportServiceOptions } from '../main/service' import { L1DataTransportServiceOptions } from '../main/service'
import { constants } from 'ethers'
export interface L1IngestionServiceOptions export interface L1IngestionServiceOptions
extends L1DataTransportServiceOptions { extends L1DataTransportServiceOptions {
...@@ -65,6 +65,7 @@ export class L1IngestionService extends BaseService<L1IngestionServiceOptions> { ...@@ -65,6 +65,7 @@ export class L1IngestionService extends BaseService<L1IngestionServiceOptions> {
contracts: OptimismContracts contracts: OptimismContracts
l1RpcProvider: JsonRpcProvider l1RpcProvider: JsonRpcProvider
startingL1BlockNumber: number startingL1BlockNumber: number
l2ChainId: number
} = {} as any } = {} as any
protected async _init(): Promise<void> { protected async _init(): Promise<void> {
...@@ -114,6 +115,10 @@ export class L1IngestionService extends BaseService<L1IngestionServiceOptions> { ...@@ -114,6 +115,10 @@ export class L1IngestionService extends BaseService<L1IngestionServiceOptions> {
this.options.addressManager this.options.addressManager
) )
this.state.l2ChainId = ethers.BigNumber.from(
await this.state.contracts.OVM_ExecutionManager.ovmCHAINID()
).toNumber()
const startingL1BlockNumber = await this.state.db.getStartingL1Block() const startingL1BlockNumber = await this.state.db.getStartingL1Block()
if (startingL1BlockNumber) { if (startingL1BlockNumber) {
this.state.startingL1BlockNumber = startingL1BlockNumber this.state.startingL1BlockNumber = startingL1BlockNumber
...@@ -293,7 +298,11 @@ export class L1IngestionService extends BaseService<L1IngestionServiceOptions> { ...@@ -293,7 +298,11 @@ export class L1IngestionService extends BaseService<L1IngestionServiceOptions> {
event, event,
this.state.l1RpcProvider this.state.l1RpcProvider
) )
const parsedEvent = await handlers.parseEvent(event, extraData) const parsedEvent = await handlers.parseEvent(
event,
extraData,
this.state.l2ChainId
)
await handlers.storeEvent(parsedEvent, this.state.db) await handlers.storeEvent(parsedEvent, this.state.db)
} }
......
...@@ -13,6 +13,7 @@ import { ...@@ -13,6 +13,7 @@ import {
padHexString, padHexString,
SEQUENCER_ENTRYPOINT_ADDRESS, SEQUENCER_ENTRYPOINT_ADDRESS,
SEQUENCER_GAS_LIMIT, SEQUENCER_GAS_LIMIT,
parseSignatureVParam,
} from '../../../utils' } from '../../../utils'
export const handleSequencerBlock = { export const handleSequencerBlock = {
...@@ -43,7 +44,7 @@ export const handleSequencerBlock = { ...@@ -43,7 +44,7 @@ export const handleSequencerBlock = {
if (transaction.queueOrigin === 'sequencer') { if (transaction.queueOrigin === 'sequencer') {
const decodedTransaction: DecodedSequencerBatchTransaction = { const decodedTransaction: DecodedSequencerBatchTransaction = {
sig: { sig: {
v: BigNumber.from(transaction.v).toNumber() - 2 * chainId - 35, v: parseSignatureVParam(transaction.v, chainId),
r: padHexString(transaction.r, 32), r: padHexString(transaction.r, 32),
s: padHexString(transaction.s, 32), s: padHexString(transaction.s, 32),
}, },
......
...@@ -3,6 +3,8 @@ import { BaseService } from '@eth-optimism/common-ts' ...@@ -3,6 +3,8 @@ import { BaseService } from '@eth-optimism/common-ts'
import { JsonRpcProvider } from '@ethersproject/providers' import { JsonRpcProvider } from '@ethersproject/providers'
import { BigNumber } from 'ethers' import { BigNumber } from 'ethers'
import { LevelUp } from 'levelup' import { LevelUp } from 'levelup'
import axios from 'axios'
import bfj from 'bfj'
/* Imports: Internal */ /* Imports: Internal */
import { TransportDB } from '../../db/transport-db' import { TransportDB } from '../../db/transport-db'
...@@ -168,11 +170,31 @@ export class L2IngestionService extends BaseService<L2IngestionServiceOptions> { ...@@ -168,11 +170,31 @@ export class L2IngestionService extends BaseService<L2IngestionServiceOptions> {
) )
}) })
} else { } else {
blocks = await this.state.l2RpcProvider.send('eth_getBlockRange', [ // This request returns a large response. Parsing it into JSON inside the ethers library is
toRpcHexString(startBlockNumber), // quite slow, and can block the event loop for upwards of multiple seconds. When this happens,
toRpcHexString(endBlockNumber), // incoming http requests will likely timeout and fail.
true, // Instead, we will parse the incoming http stream directly with the bfj package, which yields
]) // the event loop periodically so that we don't fail to serve requests.
const req = {
jsonrpc: '2.0',
method: 'eth_getBlockRange',
params: [
toRpcHexString(startBlockNumber),
toRpcHexString(endBlockNumber),
true,
],
id: '1',
}
const resp = await axios.post(
this.state.l2RpcProvider.connection.url,
req,
{ responseType: 'stream' }
)
const respJson = await bfj.parse(resp.data, {
yieldRate: 4096, // this yields abit more often than the default of 16384
})
blocks = respJson.result
} }
for (const block of blocks) { for (const block of blocks) {
......
...@@ -20,7 +20,8 @@ export type GetExtraDataHandler<TEventArgs, TExtraData> = ( ...@@ -20,7 +20,8 @@ export type GetExtraDataHandler<TEventArgs, TExtraData> = (
export type ParseEventHandler<TEventArgs, TExtraData, TParsedEvent> = ( export type ParseEventHandler<TEventArgs, TExtraData, TParsedEvent> = (
event: TypedEthersEvent<TEventArgs>, event: TypedEthersEvent<TEventArgs>,
extraData: TExtraData extraData: TExtraData,
l2ChainId: number
) => TParsedEvent ) => TParsedEvent
export type StoreEventHandler<TParsedEvent> = ( export type StoreEventHandler<TParsedEvent> = (
......
/* Imports: External */
import { ethers } from 'ethers'
export const parseSignatureVParam = (
v: number | ethers.BigNumber,
chainId: number
): number => {
return ethers.BigNumber.from(v).toNumber() - 2 * chainId - 35
}
...@@ -2,3 +2,4 @@ export * from './common' ...@@ -2,3 +2,4 @@ export * from './common'
export * from './constants' export * from './constants'
export * from './contracts' export * from './contracts'
export * from './validation' export * from './validation'
export * from './eth-tx'
import { BigNumber, ethers } from 'ethers' import { BigNumber, ethers } from 'ethers'
/* Imports: Internal */
import { expect } from '../../../../setup' import { expect } from '../../../../setup'
import { handleEventsSequencerBatchAppended } from '../../../../../src/services/l1-ingestion/handlers/sequencer-batch-appended' import { handleEventsSequencerBatchAppended } from '../../../../../src/services/l1-ingestion/handlers/sequencer-batch-appended'
import { SequencerBatchAppendedExtraData } from '../../../../../src/types' import { SequencerBatchAppendedExtraData } from '../../../../../src/types'
import { l1TransactionData } from '../../../examples/l1-data'
import { blocksOnL2 } from '../../../examples/l2-data'
describe('Event Handlers: OVM_CanonicalTransactionChain.SequencerBatchAppended', () => { describe('Event Handlers: OVM_CanonicalTransactionChain.SequencerBatchAppended', () => {
describe('handleEventsSequencerBatchAppended.parseEvent', () => { describe('handleEventsSequencerBatchAppended.parseEvent', () => {
...@@ -28,7 +28,7 @@ describe('Event Handlers: OVM_CanonicalTransactionChain.SequencerBatchAppended', ...@@ -28,7 +28,7 @@ describe('Event Handlers: OVM_CanonicalTransactionChain.SequencerBatchAppended',
} }
it('should error on malformed transaction data', async () => { it('should error on malformed transaction data', async () => {
const input1: [any, SequencerBatchAppendedExtraData] = [ const input1: [any, SequencerBatchAppendedExtraData, number] = [
{ {
args: { args: {
_startingQueueIndex: ethers.constants.Zero, _startingQueueIndex: ethers.constants.Zero,
...@@ -40,6 +40,7 @@ describe('Event Handlers: OVM_CanonicalTransactionChain.SequencerBatchAppended', ...@@ -40,6 +40,7 @@ describe('Event Handlers: OVM_CanonicalTransactionChain.SequencerBatchAppended',
l1TransactionData: '0x00000', l1TransactionData: '0x00000',
...exampleExtraData, ...exampleExtraData,
}, },
0,
] ]
expect(() => { expect(() => {
......
import { expect } from '../../../../setup'
/* Imports: External */
import { BigNumber } from 'ethers' import { BigNumber } from 'ethers'
import { Block } from '@ethersproject/abstract-provider' import { Block } from '@ethersproject/abstract-provider'
import { expect } from '../../../../setup' /* Imports: Internal */
import { handleEventsStateBatchAppended } from '../../../../../src/services/l1-ingestion/handlers/state-batch-appended' import { handleEventsStateBatchAppended } from '../../../../../src/services/l1-ingestion/handlers/state-batch-appended'
import { StateBatchAppendedExtraData } from '../../../../../src/types' import { StateBatchAppendedExtraData } from '../../../../../src/types'
import { l1StateBatchData } from '../../../examples/l1-data' import { l1StateBatchData } from '../../../examples/l1-data'
...@@ -73,7 +76,11 @@ describe('Event Handlers: OVM_CanonicalTransactionChain.StateBatchAppended', () ...@@ -73,7 +76,11 @@ describe('Event Handlers: OVM_CanonicalTransactionChain.StateBatchAppended', ()
l1TransactionHash: l1TransactionHash:
'0x4ca72484e93cdb50fe1089984db152258c2bbffc2534dcafbfe032b596bd5b49', '0x4ca72484e93cdb50fe1089984db152258c2bbffc2534dcafbfe032b596bd5b49',
} }
const input1: [any, StateBatchAppendedExtraData] = [event, extraData] const input1: [any, StateBatchAppendedExtraData, number] = [
event,
extraData,
0,
]
const output1 = handleEventsStateBatchAppended.parseEvent(...input1) const output1 = handleEventsStateBatchAppended.parseEvent(...input1)
......
import { expect } from '../../../../setup'
/* Imports: External */
import { ethers, BigNumber } from 'ethers' import { ethers, BigNumber } from 'ethers'
import { expect } from '../../../../setup' /* Imports: Internal */
import { handleEventsTransactionEnqueued } from '../../../../../src/services/l1-ingestion/handlers/transaction-enqueued' import { handleEventsTransactionEnqueued } from '../../../../../src/services/l1-ingestion/handlers/transaction-enqueued'
const MAX_ITERATIONS = 128 const MAX_ITERATIONS = 128
...@@ -22,7 +25,7 @@ describe('Event Handlers: OVM_CanonicalTransactionChain.TransactionEnqueued', () ...@@ -22,7 +25,7 @@ describe('Event Handlers: OVM_CanonicalTransactionChain.TransactionEnqueued', ()
// but it's probably better to get wider test coverage first. // but it's probably better to get wider test coverage first.
it('should have a ctcIndex equal to null', () => { it('should have a ctcIndex equal to null', () => {
const input1: [any, any] = [ const input1: [any, any, number] = [
{ {
blockNumber: 0, blockNumber: 0,
args: { args: {
...@@ -32,6 +35,7 @@ describe('Event Handlers: OVM_CanonicalTransactionChain.TransactionEnqueued', () ...@@ -32,6 +35,7 @@ describe('Event Handlers: OVM_CanonicalTransactionChain.TransactionEnqueued', ()
}, },
}, },
null, null,
0,
] ]
const output1 = handleEventsTransactionEnqueued.parseEvent(...input1) const output1 = handleEventsTransactionEnqueued.parseEvent(...input1)
...@@ -47,7 +51,7 @@ describe('Event Handlers: OVM_CanonicalTransactionChain.TransactionEnqueued', () ...@@ -47,7 +51,7 @@ describe('Event Handlers: OVM_CanonicalTransactionChain.TransactionEnqueued', ()
i < Number.MAX_SAFE_INTEGER; i < Number.MAX_SAFE_INTEGER;
i += Math.floor(Number.MAX_SAFE_INTEGER / MAX_ITERATIONS) i += Math.floor(Number.MAX_SAFE_INTEGER / MAX_ITERATIONS)
) { ) {
const input1: [any, any] = [ const input1: [any, any, number] = [
{ {
blockNumber: i, blockNumber: i,
args: { args: {
...@@ -57,6 +61,7 @@ describe('Event Handlers: OVM_CanonicalTransactionChain.TransactionEnqueued', () ...@@ -57,6 +61,7 @@ describe('Event Handlers: OVM_CanonicalTransactionChain.TransactionEnqueued', ()
}, },
}, },
null, null,
0,
] ]
const output1 = handleEventsTransactionEnqueued.parseEvent(...input1) const output1 = handleEventsTransactionEnqueued.parseEvent(...input1)
...@@ -73,7 +78,7 @@ describe('Event Handlers: OVM_CanonicalTransactionChain.TransactionEnqueued', () ...@@ -73,7 +78,7 @@ describe('Event Handlers: OVM_CanonicalTransactionChain.TransactionEnqueued', ()
i < Number.MAX_SAFE_INTEGER; i < Number.MAX_SAFE_INTEGER;
i += Math.floor(Number.MAX_SAFE_INTEGER / MAX_ITERATIONS) i += Math.floor(Number.MAX_SAFE_INTEGER / MAX_ITERATIONS)
) { ) {
const input1: [any, any] = [ const input1: [any, any, number] = [
{ {
blockNumber: 0, blockNumber: 0,
args: { args: {
...@@ -83,6 +88,7 @@ describe('Event Handlers: OVM_CanonicalTransactionChain.TransactionEnqueued', () ...@@ -83,6 +88,7 @@ describe('Event Handlers: OVM_CanonicalTransactionChain.TransactionEnqueued', ()
}, },
}, },
null, null,
0,
] ]
const output1 = handleEventsTransactionEnqueued.parseEvent(...input1) const output1 = handleEventsTransactionEnqueued.parseEvent(...input1)
...@@ -99,7 +105,7 @@ describe('Event Handlers: OVM_CanonicalTransactionChain.TransactionEnqueued', () ...@@ -99,7 +105,7 @@ describe('Event Handlers: OVM_CanonicalTransactionChain.TransactionEnqueued', ()
i < Number.MAX_SAFE_INTEGER; i < Number.MAX_SAFE_INTEGER;
i += Math.floor(Number.MAX_SAFE_INTEGER / MAX_ITERATIONS) i += Math.floor(Number.MAX_SAFE_INTEGER / MAX_ITERATIONS)
) { ) {
const input1: [any, any] = [ const input1: [any, any, number] = [
{ {
blockNumber: 0, blockNumber: 0,
args: { args: {
...@@ -109,6 +115,7 @@ describe('Event Handlers: OVM_CanonicalTransactionChain.TransactionEnqueued', () ...@@ -109,6 +115,7 @@ describe('Event Handlers: OVM_CanonicalTransactionChain.TransactionEnqueued', ()
}, },
}, },
null, null,
0,
] ]
const output1 = handleEventsTransactionEnqueued.parseEvent(...input1) const output1 = handleEventsTransactionEnqueued.parseEvent(...input1)
...@@ -125,7 +132,7 @@ describe('Event Handlers: OVM_CanonicalTransactionChain.TransactionEnqueued', () ...@@ -125,7 +132,7 @@ describe('Event Handlers: OVM_CanonicalTransactionChain.TransactionEnqueued', ()
i < Number.MAX_SAFE_INTEGER; i < Number.MAX_SAFE_INTEGER;
i += Math.floor(Number.MAX_SAFE_INTEGER / MAX_ITERATIONS) i += Math.floor(Number.MAX_SAFE_INTEGER / MAX_ITERATIONS)
) { ) {
const input1: [any, any] = [ const input1: [any, any, number] = [
{ {
blockNumber: 0, blockNumber: 0,
args: { args: {
...@@ -135,6 +142,7 @@ describe('Event Handlers: OVM_CanonicalTransactionChain.TransactionEnqueued', () ...@@ -135,6 +142,7 @@ describe('Event Handlers: OVM_CanonicalTransactionChain.TransactionEnqueued', ()
}, },
}, },
null, null,
0,
] ]
const output1 = handleEventsTransactionEnqueued.parseEvent(...input1) const output1 = handleEventsTransactionEnqueued.parseEvent(...input1)
......
import { expect } from '../../../../setup' import { expect } from '../../../../setup'
/* Imports: Internal */
import { l2Block } from '../../../examples/l2-data' import { l2Block } from '../../../examples/l2-data'
import { handleSequencerBlock } from '../../../../../src/services/l2-ingestion/handlers/transaction' import { handleSequencerBlock } from '../../../../../src/services/l2-ingestion/handlers/transaction'
......
# @eth-optimism/message-relayer # @eth-optimism/message-relayer
## 0.1.4
### Patch Changes
- 9d39121b: Adds a README and cleans up the interface for generating messages and proofs
- 86708bb5: Adds a new set of tools for generating messages to be relayed and their proofs
- 064c03af: Removes spreadsheet mode from the message relayer
- Updated dependencies [a64f8161]
- Updated dependencies [4e03f8a9]
- Updated dependencies [8e2bfd07]
- Updated dependencies [750a5021]
- Updated dependencies [c2b6e14b]
- Updated dependencies [245136f1]
- @eth-optimism/core-utils@0.4.5
- @eth-optimism/contracts@0.3.5
## 0.1.3 ## 0.1.3
### Patch Changes ### Patch Changes
......
{ {
"name": "@eth-optimism/message-relayer", "name": "@eth-optimism/message-relayer",
"version": "0.1.3", "version": "0.1.4",
"description": "[Optimism] Cross Domain Message Relayer service", "description": "[Optimism] Cross Domain Message Relayer service",
"main": "dist/index", "main": "dist/index",
"types": "dist/index", "types": "dist/index",
...@@ -30,8 +30,8 @@ ...@@ -30,8 +30,8 @@
}, },
"dependencies": { "dependencies": {
"@eth-optimism/common-ts": "^0.1.2", "@eth-optimism/common-ts": "^0.1.2",
"@eth-optimism/contracts": "^0.3.3", "@eth-optimism/contracts": "^0.3.5",
"@eth-optimism/core-utils": "^0.4.3", "@eth-optimism/core-utils": "^0.4.5",
"bcfg": "^0.1.6", "bcfg": "^0.1.6",
"dotenv": "^8.2.0", "dotenv": "^8.2.0",
"ethers": "^5.1.0", "ethers": "^5.1.0",
...@@ -39,7 +39,7 @@ ...@@ -39,7 +39,7 @@
"rlp": "^2.2.6" "rlp": "^2.2.6"
}, },
"devDependencies": { "devDependencies": {
"@eth-optimism/smock": "^1.1.4", "@eth-optimism/smock": "^1.1.5",
"@nomiclabs/hardhat-ethers": "^2.0.2", "@nomiclabs/hardhat-ethers": "^2.0.2",
"@nomiclabs/hardhat-waffle": "^2.0.1", "@nomiclabs/hardhat-waffle": "^2.0.1",
"@types/chai": "^4.2.18", "@types/chai": "^4.2.18",
......
# @eth-optimism/smock # @eth-optimism/smock
## 1.1.5
### Patch Changes
- 5e3c5d1c: Fixes a bug that would break call assertions for overloaded smocked functions
- e6e87ae1: Fix a bug where overloaded functions would not be handled correctly
- Updated dependencies [a64f8161]
- Updated dependencies [750a5021]
- Updated dependencies [c2b6e14b]
- @eth-optimism/core-utils@0.4.5
## 1.1.4 ## 1.1.4
### Patch Changes ### Patch Changes
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
"files": [ "files": [
"dist/src/*" "dist/src/*"
], ],
"version": "1.1.4", "version": "1.1.5",
"main": "dist/src/index", "main": "dist/src/index",
"types": "dist/src/index", "types": "dist/src/index",
"author": "Optimism PBC", "author": "Optimism PBC",
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
"hardhat": "^2.2.1" "hardhat": "^2.2.1"
}, },
"dependencies": { "dependencies": {
"@eth-optimism/core-utils": "^0.4.1", "@eth-optimism/core-utils": "^0.4.5",
"bn.js": "^5.2.0" "bn.js": "^5.2.0"
}, },
"devDependencies": { "devDependencies": {
......
...@@ -2690,6 +2690,13 @@ ...@@ -2690,6 +2690,13 @@
"@types/bn.js" "*" "@types/bn.js" "*"
"@types/underscore" "*" "@types/underscore" "*"
"@types/workerpool@^6.0.0":
version "6.0.0"
resolved "https://registry.yarnpkg.com/@types/workerpool/-/workerpool-6.0.0.tgz#068c31191f7df9b3d49ebe348b1eeb601e75e2d3"
integrity sha512-BjbKVHFBWblQ3vZ5yFq29kbM2TsaUaTOwYgVxqnNjMrT6CktVF8AvMxOJZgHGgNbAzP4z8DK+EshyZcYpdvAhQ==
dependencies:
"@types/node" "*"
"@types/yargs-parser@*": "@types/yargs-parser@*":
version "20.2.0" version "20.2.0"
resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-20.2.0.tgz#dd3e6699ba3237f0348cd085e4698780204842f9" resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-20.2.0.tgz#dd3e6699ba3237f0348cd085e4698780204842f9"
...@@ -3746,6 +3753,16 @@ better-path-resolve@1.0.0: ...@@ -3746,6 +3753,16 @@ better-path-resolve@1.0.0:
dependencies: dependencies:
is-windows "^1.0.0" is-windows "^1.0.0"
bfj@^7.0.2:
version "7.0.2"
resolved "https://registry.yarnpkg.com/bfj/-/bfj-7.0.2.tgz#1988ce76f3add9ac2913fd8ba47aad9e651bfbb2"
integrity sha512-+e/UqUzwmzJamNF50tBV6tZPTORow7gQ96iFow+8b562OdMpEK0BcJEq2OSPEDmAbSMBQ7PKZ87ubFkgxpYWgw==
dependencies:
bluebird "^3.5.5"
check-types "^11.1.1"
hoopy "^0.1.4"
tryer "^1.0.1"
bignumber.js@^9.0.0, bignumber.js@^9.0.1: bignumber.js@^9.0.0, bignumber.js@^9.0.1:
version "9.0.1" version "9.0.1"
resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.0.1.tgz#8d7ba124c882bfd8e43260c67475518d0689e4e5" resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.0.1.tgz#8d7ba124c882bfd8e43260c67475518d0689e4e5"
...@@ -3800,7 +3817,7 @@ blakejs@^1.1.0: ...@@ -3800,7 +3817,7 @@ blakejs@^1.1.0:
resolved "https://registry.yarnpkg.com/blakejs/-/blakejs-1.1.0.tgz#69df92ef953aa88ca51a32df6ab1c54a155fc7a5" resolved "https://registry.yarnpkg.com/blakejs/-/blakejs-1.1.0.tgz#69df92ef953aa88ca51a32df6ab1c54a155fc7a5"
integrity sha1-ad+S75U6qIylGjLfarHFShVfx6U= integrity sha1-ad+S75U6qIylGjLfarHFShVfx6U=
bluebird@^3.5.0, bluebird@^3.5.2, bluebird@^3.5.3, bluebird@^3.7.2: bluebird@^3.5.0, bluebird@^3.5.2, bluebird@^3.5.3, bluebird@^3.5.5, bluebird@^3.7.2:
version "3.7.2" version "3.7.2"
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f"
integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==
...@@ -4279,6 +4296,11 @@ check-error@^1.0.2: ...@@ -4279,6 +4296,11 @@ check-error@^1.0.2:
resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82"
integrity sha1-V00xLt2Iu13YkS6Sht1sCu1KrII= integrity sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=
check-types@^11.1.1:
version "11.1.2"
resolved "https://registry.yarnpkg.com/check-types/-/check-types-11.1.2.tgz#86a7c12bf5539f6324eb0e70ca8896c0e38f3e2f"
integrity sha512-tzWzvgePgLORb9/3a0YenggReLKAIb2owL03H2Xdoe5pKcUyWRSEQ8xfCar8t2SIAuEDwtmx2da1YB52YuHQMQ==
checkpoint-store@^1.1.0: checkpoint-store@^1.1.0:
version "1.1.0" version "1.1.0"
resolved "https://registry.yarnpkg.com/checkpoint-store/-/checkpoint-store-1.1.0.tgz#04e4cb516b91433893581e6d4601a78e9552ea06" resolved "https://registry.yarnpkg.com/checkpoint-store/-/checkpoint-store-1.1.0.tgz#04e4cb516b91433893581e6d4601a78e9552ea06"
...@@ -6927,20 +6949,13 @@ github-from-package@0.0.0: ...@@ -6927,20 +6949,13 @@ github-from-package@0.0.0:
resolved "https://registry.yarnpkg.com/github-from-package/-/github-from-package-0.0.0.tgz#97fb5d96bfde8973313f20e8288ef9a167fa64ce" resolved "https://registry.yarnpkg.com/github-from-package/-/github-from-package-0.0.0.tgz#97fb5d96bfde8973313f20e8288ef9a167fa64ce"
integrity sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4= integrity sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4=
glob-parent@^5.1.0, glob-parent@^5.1.1: glob-parent@^5.1.0, glob-parent@^5.1.1, glob-parent@~5.1.0:
version "5.1.2" version "5.1.2"
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4"
integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==
dependencies: dependencies:
is-glob "^4.0.1" is-glob "^4.0.1"
glob-parent@~5.1.0:
version "5.1.1"
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.1.tgz#b6c1ef417c4e5663ea498f1c45afac6916bbc229"
integrity sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==
dependencies:
is-glob "^4.0.1"
glob@7.1.3: glob@7.1.3:
version "7.1.3" version "7.1.3"
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1"
...@@ -7393,6 +7408,11 @@ home-or-tmp@^2.0.0: ...@@ -7393,6 +7408,11 @@ home-or-tmp@^2.0.0:
os-homedir "^1.0.0" os-homedir "^1.0.0"
os-tmpdir "^1.0.1" os-tmpdir "^1.0.1"
hoopy@^0.1.4:
version "0.1.4"
resolved "https://registry.yarnpkg.com/hoopy/-/hoopy-0.1.4.tgz#609207d661100033a9a9402ad3dea677381c1b1d"
integrity sha512-HRcs+2mr52W0K+x8RzcLzuPPmVIKMSv97RGHy0Ea9y/mpcaK+xTrjICA04KAHi4GRzxliNqNJEFYWHghy3rSfQ==
hosted-git-info@^2.1.4, hosted-git-info@^2.6.0: hosted-git-info@^2.1.4, hosted-git-info@^2.6.0:
version "2.8.8" version "2.8.8"
resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.8.tgz#7539bd4bc1e0e0a895815a2e0262420b12858488" resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.8.tgz#7539bd4bc1e0e0a895815a2e0262420b12858488"
...@@ -12832,6 +12852,11 @@ trim-right@^1.0.1: ...@@ -12832,6 +12852,11 @@ trim-right@^1.0.1:
resolved "https://registry.yarnpkg.com/true-case-path/-/true-case-path-2.2.1.tgz#c5bf04a5bbec3fd118be4084461b3a27c4d796bf" resolved "https://registry.yarnpkg.com/true-case-path/-/true-case-path-2.2.1.tgz#c5bf04a5bbec3fd118be4084461b3a27c4d796bf"
integrity sha512-0z3j8R7MCjy10kc/g+qg7Ln3alJTodw9aDuVWZa3uiWqfuBMKeAeP2ocWcxoyM3D73yz3Jt/Pu4qPr4wHSdB/Q== integrity sha512-0z3j8R7MCjy10kc/g+qg7Ln3alJTodw9aDuVWZa3uiWqfuBMKeAeP2ocWcxoyM3D73yz3Jt/Pu4qPr4wHSdB/Q==
tryer@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/tryer/-/tryer-1.0.1.tgz#f2c85406800b9b0f74c9f7465b81eaad241252f8"
integrity sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA==
ts-essentials@^1.0.0, ts-essentials@^1.0.2: ts-essentials@^1.0.0, ts-essentials@^1.0.2:
version "1.0.4" version "1.0.4"
resolved "https://registry.yarnpkg.com/ts-essentials/-/ts-essentials-1.0.4.tgz#ce3b5dade5f5d97cf69889c11bf7d2da8555b15a" resolved "https://registry.yarnpkg.com/ts-essentials/-/ts-essentials-1.0.4.tgz#ce3b5dade5f5d97cf69889c11bf7d2da8555b15a"
......
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