Commit 16c4e367 authored by Sebastian Stammler's avatar Sebastian Stammler Committed by GitHub

ops-bedrock: Beacon-chain devnet with Dencun + Ecotone upgrade (#9117)

* ops-bedrock: beacon-chain devnet with fork to L1 Dencun and L2 Ecotone

ops-bedrock: clean up file names, drop unused stateviz

ops-bedrock: dockerfile for lighthouse from source

ops-bedrock: devnet validator keystores

ops-bedrock: dev chain config

generate genesis.ssz, work in progress devnet setup

lighthouse CLI tweaks

ops-bedrock: more CLI tweaks

devnet: fix validator keys loading

ops-bedrock: cleanup L1 geth setup and jwt-secret usage

ops-bedrock: fix L1 engine API endpoint

op-chain-ops: insert dev L1 contracts

devnet fixes

more fixes

schedule L2 Delta and Ecotone forks

op-chain-ops: fix lint

ops-bedrock: docker-compose config comments about special options

ops-bedrock: adjust beacon node log level
Co-authored-by: default avatarSebastian Stammler <seb@oplabs.co>

* devnet: Add eth2-testnet-genesis installation step

* op-e2e: fix pre-Ecotone tests

* ops-bedrock: Fix entrypoint scripts

* op-e2e: Fix TestPreEcotone

* op-e2e: Fix hardfork validation tests

* op-e2e: Enable L1 Cancun at genesis for Ecotone system configs

* ci: use eth2-testnet-genesis tag v0.10.0

* op-e2e: use <fork>SystemConfig instead of manipulating fields

* op-e2e/actions: process beacon block root for Cancun L1s

* op-e2e/actions: fix TestBlockTimeBatchType

* op-e2e: add beacon endpoint to L1 setup

* op-e2e/actions: fix more tests...

* op-e2e/actions: fix manual setting of delta offset

* op-e2e/actions: set blob source in plasma tests

* devnet: sleep at start of tests

* ops-bedrock: remove fetch-all-sidecars for l1 lh from docker-compose

* op-e2e: fix Makefile go test flags

* op-chain-ops: Add 4788 deployer address to L1 genesis creation

* op-e2e: remove outdated TODO code

* ci: read eth2-testnet-genesis version from json

* fix l1 genesis & cci config

* rename beacon-data/deposit_contract_block.txt

* cci: dump l1-bn and l1-vs logs

* few improvements

* Move to op-e2e devnet withdrawals test

* set l1 block time to 6s in devnet template

* fix game resolve helper, to handle resolve race condition

* lower da windows

* devnet: bump plasma windows to 16

* fix: adjust plasma test params for smaller challenge window sizes

* bump lighthouse, remove src Dockerfile

* revert devnet python script commenting out

the test isn't run from this script any more anyways
that was just temporary while debugging

* remove deprecated options

ligthouse deprecated http-allow-sync-stalled
docker-compose deprecated the version tag

* retry start block fetching in L2 genesis cmd

* add CL to devnet L1 startup step

* ignore receipt for resolveClaim call in FinalizeWithdrawal

* forward tx trace as custom error type, use in withdrawal test

* return receipt in SendTx

---------
Co-authored-by: default avatarprotolambda <proto@protolambda.com>
Co-authored-by: default avatartchardin <tdotchardin@gmail.com>
parent b28f9eef
......@@ -1165,6 +1165,10 @@ jobs:
echo '76a04354dba9980fcbc35bece2957b30 geth-alltools-linux-amd64-1.13.14-2bd6bd01.tar.gz' | md5sum -c -
tar -xzvf geth-alltools-linux-amd64-1.13.14-2bd6bd01.tar.gz
sudo cp geth-alltools-linux-amd64-1.13.14-2bd6bd01/* /usr/local/bin
- run:
name: Install eth2-testnet-genesis
command: |
go install -v github.com/protolambda/eth2-testnet-genesis@$(jq -r .eth2_testnet_genesis < versions.json)
- run:
name: foundryup
command: |
......@@ -1219,14 +1223,16 @@ jobs:
docker tag "$IMAGE_BASE_PREFIX/op-challenger:<<pipeline.git.revision>>" "$IMAGE_BASE_PREFIX/op-challenger:devnet"
docker tag "$IMAGE_BASE_PREFIX/da-server:<<pipeline.git.revision>>" "$IMAGE_BASE_PREFIX/da-server:devnet"
- run:
name: pnpm i
name: pnpm install and build
command: |
pnpm i && pnpm build
pnpm install && pnpm build
- run:
name: Bring up the stack
command: |
# Specify like this to avoid a forced rebuild of the contracts + devnet L1
PYTHONPATH=./bedrock-devnet python3 ./bedrock-devnet/main.py --monorepo-dir=.
echo "Waiting for 10 seconds to give the devnet time to settle in..."
sleep 10
- run:
name: Test the stack
command: make devnet-test
......@@ -1245,6 +1251,16 @@ jobs:
command: |
docker logs ops-bedrock-l1-1 || echo "No logs."
when: on_fail
- run:
name: Dump l1-bn logs
command: |
docker logs ops-bedrock-l1-bn-1 || echo "No logs."
when: on_fail
- run:
name: Dump l1-vc logs
command: |
docker logs ops-bedrock-l1-vc-1 || echo "No logs."
when: on_fail
- run:
name: Dump op-batcher logs
command: |
......
......@@ -164,6 +164,9 @@ pre-devnet: submodules ## Prepares for running a local devnet
@if ! [ -x "$(command -v geth)" ]; then \
make install-geth; \
fi
@if ! [ -x "$(command -v eth2-testnet-genesis)" ]; then \
make install-eth2-testnet-genesis; \
fi
@if [ ! -e op-program/bin ]; then \
make cannon-prestate; \
fi
......@@ -176,7 +179,7 @@ devnet-up: pre-devnet ## Starts the local devnet
.PHONY: devnet-up
devnet-test: pre-devnet ## Runs tests on the local devnet
PYTHONPATH=./bedrock-devnet $(PYTHON) ./bedrock-devnet/main.py --monorepo-dir=. --test
make -C op-e2e test-devnet
.PHONY: devnet-test
devnet-down: ## Stops the local devnet
......@@ -233,3 +236,7 @@ install-geth: ## Installs or updates Geth if versions do not match
go install -v github.com/ethereum/go-ethereum/cmd/geth@$(shell jq -r .geth < versions.json); \
echo "Installed geth!"; true)
.PHONY: install-geth
install-eth2-testnet-genesis:
go install -v github.com/protolambda/eth2-testnet-genesis@$(shell jq -r .eth2_testnet_genesis < versions.json)
.PHONY: install-eth2-testnet-genesis
......@@ -206,8 +206,12 @@ def devnet_deploy(paths):
'--outfile.l1', paths.genesis_l1_path,
], cwd=paths.op_node_dir)
run_command([
'sh', 'l1-generate-beacon-genesis.sh',
], cwd=paths.ops_bedrock_dir)
log.info('Starting L1.')
run_command(['docker', 'compose', 'up', '-d', 'l1'], cwd=paths.ops_bedrock_dir, env={
run_command(['docker', 'compose', 'up', '-d', 'l1', 'l1-bn', 'l1-vc'], cwd=paths.ops_bedrock_dir, env={
'PWD': paths.ops_bedrock_dir
})
wait_up(8545)
......@@ -269,7 +273,7 @@ def devnet_deploy(paths):
else:
docker_env['DGF_ADDRESS'] = dispute_game_factory
docker_env['DG_TYPE'] = '254'
docker_env['PROPOSAL_INTERVAL'] = '10s'
docker_env['PROPOSAL_INTERVAL'] = '12s'
if DEVNET_PLASMA:
docker_env['PLASMA_ENABLED'] = 'true'
......
......@@ -60,7 +60,7 @@ require (
github.com/beorn7/perks v1.0.1 // indirect
github.com/bits-and-blooms/bitset v1.10.0 // indirect
github.com/boltdb/bolt v1.3.1 // indirect
github.com/btcsuite/btcd/btcec/v2 v2.2.0 // indirect
github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect
github.com/btcsuite/btcd/btcutil v1.1.5 // indirect
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
......@@ -75,7 +75,7 @@ require (
github.com/crate-crypto/go-ipa v0.0.0-20231025140028-3c0104f4b233 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect
github.com/deckarep/golang-set/v2 v2.1.0 // indirect
github.com/deckarep/golang-set/v2 v2.3.0 // indirect
github.com/decred/dcrd/crypto/blake256 v1.0.1 // indirect
github.com/deepmap/oapi-codegen v1.8.2 // indirect
github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de // indirect
......@@ -93,7 +93,7 @@ require (
github.com/francoispqt/gojay v1.2.13 // indirect
github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 // indirect
github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46 // indirect
github.com/getsentry/sentry-go v0.18.0 // indirect
github.com/getsentry/sentry-go v0.20.0 // indirect
github.com/go-ini/ini v1.67.0 // indirect
github.com/go-ole/go-ole v1.3.0 // indirect
github.com/go-sourcemap/sourcemap v2.1.3+incompatible // indirect
......@@ -193,7 +193,7 @@ require (
github.com/quic-go/quic-go v0.44.0 // indirect
github.com/quic-go/webtransport-go v0.8.0 // indirect
github.com/raulk/go-watchdog v1.3.0 // indirect
github.com/rivo/uniseg v0.4.3 // indirect
github.com/rivo/uniseg v0.4.4 // indirect
github.com/rogpeppe/go-internal v1.10.0 // indirect
github.com/rs/cors v1.11.0 // indirect
github.com/rs/xid v1.5.0 // indirect
......
......@@ -56,8 +56,8 @@ github.com/btcsuite/btcd v0.24.2 h1:aLmxPguqxza+4ag8R1I2nnJjSu2iFn/kqtHTIImswcY=
github.com/btcsuite/btcd v0.24.2/go.mod h1:5C8ChTkl5ejr3WHj8tkQSCmydiMEPB0ZhQhehpq7Dgg=
github.com/btcsuite/btcd/btcec/v2 v2.1.0/go.mod h1:2VzYrv4Gm4apmbVVsSq5bqf1Ec8v56E48Vt0Y/umPgA=
github.com/btcsuite/btcd/btcec/v2 v2.1.3/go.mod h1:ctjw4H1kknNJmRN4iP1R7bTQ+v3GJkZBd6mui8ZsAZE=
github.com/btcsuite/btcd/btcec/v2 v2.2.0 h1:fzn1qaOt32TuLjFlkzYSsBC35Q3KUjT1SwPxiMSCF5k=
github.com/btcsuite/btcd/btcec/v2 v2.2.0/go.mod h1:U7MHm051Al6XmscBQ0BoNydpOTsFAn707034b5nY8zU=
github.com/btcsuite/btcd/btcec/v2 v2.3.2 h1:5n0X6hX0Zk+6omWcihdYvdAlGf2DfasC0GMf7DClJ3U=
github.com/btcsuite/btcd/btcec/v2 v2.3.2/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04=
github.com/btcsuite/btcd/btcutil v1.0.0/go.mod h1:Uoxwv0pqYWhD//tfTiipkxNfdhG9UrLwaeswfjfdF0A=
github.com/btcsuite/btcd/btcutil v1.1.0/go.mod h1:5OapHB7A2hBBWLm48mmw4MOHNJCcUBTwmWH/0Jn8VHE=
github.com/btcsuite/btcd/btcutil v1.1.5 h1:+wER79R5670vs/ZusMTF1yTcRYE5GUsFbdjdisflzM8=
......@@ -134,8 +134,8 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c h1:pFUpOrbxDR6AkioZ1ySsx5yxlDQZ8stG2b88gTPxgJU=
github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c/go.mod h1:6UhI8N9EjYm1c2odKpFpAYeR8dsBeM7PtzQhRgxRr9U=
github.com/deckarep/golang-set/v2 v2.1.0 h1:g47V4Or+DUdzbs8FxCCmgb6VYd+ptPAngjM6dtGktsI=
github.com/deckarep/golang-set/v2 v2.1.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4=
github.com/deckarep/golang-set/v2 v2.3.0 h1:qs18EKUfHm2X9fA50Mr/M5hccg2tNnVqsiBImnyDs0g=
github.com/deckarep/golang-set/v2 v2.3.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4=
github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc=
github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y=
github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo=
......@@ -202,8 +202,8 @@ github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46 h1:BAIP2Gihuqh
github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46/go.mod h1:QNpY22eby74jVhqH4WhDLDwxc/vqsern6pW+u2kbkpc=
github.com/getkin/kin-openapi v0.53.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4=
github.com/getkin/kin-openapi v0.61.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4=
github.com/getsentry/sentry-go v0.18.0 h1:MtBW5H9QgdcJabtZcuJG80BMOwaBpkRDZkxRkNC1sN0=
github.com/getsentry/sentry-go v0.18.0/go.mod h1:Kgon4Mby+FJ7ZWHFUAZgVaIa8sxHtnRJRLTXZr51aKQ=
github.com/getsentry/sentry-go v0.20.0 h1:bwXW98iMRIWxn+4FgPW7vMrjmbym6HblXALmhjHmQaQ=
github.com/getsentry/sentry-go v0.20.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
github.com/go-chi/chi/v5 v5.0.0/go.mod h1:BBug9lr0cqtdAhsu6R4AAdvufI0/XBzAQSsUqJpoZOs=
......@@ -667,8 +667,8 @@ github.com/quic-go/webtransport-go v0.8.0/go.mod h1:N99tjprW432Ut5ONql/aUhSLT0YV
github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk=
github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtDqv66NfsMU=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.4.3 h1:utMvzDsuh3suAEnhH0RdHmoPbU648o6CvXxTx4SBMOw=
github.com/rivo/uniseg v0.4.3/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis=
github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
......
package beacondeposit
import (
_ "embed"
"encoding/json"
"fmt"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/types"
)
//go:embed l1_empty_beacon_deposit_contract.json
var l1EmptyBeaconDepositContractJSON []byte
func InsertEmptyBeaconDepositContract(gen *core.Genesis, addr common.Address) error {
var beaconDepositContractAccount types.Account
if err := json.Unmarshal(l1EmptyBeaconDepositContractJSON, &beaconDepositContractAccount); err != nil {
return fmt.Errorf("failed to read beacon deposit contract definition: %w", err)
}
gen.Alloc[addr] = beaconDepositContractAccount
return nil
}
......@@ -176,7 +176,7 @@ func NewL1Genesis(config *DeployConfig) (*core.Genesis, error) {
}
difficulty := config.L1GenesisBlockDifficulty
if difficulty == nil {
difficulty = newHexBig(1)
difficulty = newHexBig(0) // default to Merge-compatible difficulty value
}
timestamp := config.L1GenesisBlockTimestamp
if timestamp == 0 {
......
......@@ -8,7 +8,11 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum-optimism/optimism/op-chain-ops/genesis/beacondeposit"
"github.com/ethereum-optimism/optimism/op-service/predeploys"
)
// PrecompileCount represents the number of precompile addresses
......@@ -46,6 +50,24 @@ func BuildL1DeveloperGenesis(config *DeployConfig, dump *foundry.ForgeAllocs, l1
}
})
beaconDepositAddr := common.HexToAddress("0x1111111111111111111111111111111111111111")
if err := beacondeposit.InsertEmptyBeaconDepositContract(genesis, beaconDepositAddr); err != nil {
return nil, fmt.Errorf("failed to insert beacon deposit contract into L1 dev genesis: %w", err)
}
// For 4788, make sure the 4788 beacon-roots contract is there.
// (required to be there before L1 Dencun activation)
genesis.Alloc[predeploys.EIP4788ContractAddr] = types.Account{
Balance: new(big.Int),
Nonce: 1,
Code: predeploys.EIP4788ContractCode,
}
// Also record the virtual deployer address
genesis.Alloc[predeploys.EIP4788ContractDeployer] = types.Account{
Balance: new(big.Int),
Nonce: 1,
}
return genesis, nil
}
......
......@@ -36,6 +36,10 @@ test-fault-proofs: pre-test
$(go_test) $(go_test_flags) ./faultproofs
.PHONY: test-faultproofs
test-devnet: pre-test
$(go_test) $(go_test_flags) ./devnet
.PHONY: test-devnet
cannon-prestate:
make -C .. cannon-prestate
.PHONY: cannon-prestate
......
......@@ -161,6 +161,10 @@ func LargeL1Gaps(gt *testing.T, deltaTimeOffset *hexutil.Uint64) {
dp.DeployConfig.L2BlockTime = 2
dp.DeployConfig.SequencerWindowSize = 4
dp.DeployConfig.MaxSequencerDrift = 32
dp.DeployConfig.L2GenesisEcotoneTimeOffset = nil
dp.DeployConfig.L2GenesisFjordTimeOffset = nil
// TODO(client-pod#831): The Ecotone (and Fjord) activation blocks don't include user txs,
// so disabling these forks for now.
applyDeltaTimeOffset(dp, deltaTimeOffset)
sd := e2eutils.Setup(t, dp, defaultAlloc)
log := testlog.Logger(t, log.LevelDebug)
......@@ -169,6 +173,7 @@ func LargeL1Gaps(gt *testing.T, deltaTimeOffset *hexutil.Uint64) {
signer := types.LatestSigner(sd.L2Cfg.Config)
cl := sequencerEngine.EthClient()
aliceNonce := uint64(0) // manual nonce, avoid pending-tx nonce management, that causes flakes
aliceTx := func() {
tx := types.MustSignNewTx(dp.Secrets.Alice, signer, &types.DynamicFeeTx{
......@@ -211,8 +216,8 @@ func LargeL1Gaps(gt *testing.T, deltaTimeOffset *hexutil.Uint64) {
miner.ActL1EndBlock(t)
sequencer.ActL1HeadSignal(t)
sequencer.ActL2PipelineFull(t)
makeL2BlockWithAliceTx()
makeL2BlockWithAliceTx()
makeL2BlockWithAliceTx() // 1
makeL2BlockWithAliceTx() // 2
for i := 0; i < 7; i++ {
batcher.ActSubmitAll(t)
......@@ -223,7 +228,7 @@ func LargeL1Gaps(gt *testing.T, deltaTimeOffset *hexutil.Uint64) {
sequencer.ActL2PipelineFull(t)
makeL2BlockWithAliceTx()
makeL2BlockWithAliceTx()
}
} // 14 + 2 = 16
n, err := cl.NonceAt(t.Ctx(), dp.Addresses.Alice, nil)
require.NoError(t, err)
......
......@@ -11,6 +11,7 @@ import (
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/state"
"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/log"
"github.com/ethereum/go-ethereum/trie"
......@@ -82,6 +83,7 @@ func (s *L1Miner) ActL1StartBlock(timeDelta uint64) Action {
Extra: []byte("L1 was here"),
MixDigest: common.Hash{}, // TODO: maybe randomize this (prev-randao value)
}
if s.l1Cfg.Config.IsLondon(header.Number) {
header.BaseFee = eip1559.CalcBaseFee(s.l1Cfg.Config, parent, header.Time)
// At the transition, double the gas limit so the gas target is equal to the old gas limit.
......@@ -89,14 +91,29 @@ func (s *L1Miner) ActL1StartBlock(timeDelta uint64) Action {
header.GasLimit = parent.GasLimit * s.l1Cfg.Config.ElasticityMultiplier()
}
}
if s.l1Cfg.Config.IsShanghai(header.Number, header.Time) {
header.WithdrawalsHash = &types.EmptyWithdrawalsHash
}
if s.l1Cfg.Config.IsCancun(header.Number, header.Time) {
header.BlobGasUsed = new(uint64)
header.ExcessBlobGas = new(uint64)
root := crypto.Keccak256Hash([]byte("fake-beacon-block-root"), header.Number.Bytes())
header.ParentBeaconRoot = &root
// Copied from op-program/client/l2/engineapi/block_processor.go
// TODO(client-pod#826)
// Unfortunately this is not part of any Geth environment setup,
// we just have to apply it, like how the Geth block-builder worker does.
context := core.NewEVMBlockContext(header, s.l1Chain, nil, s.l1Chain.Config(), statedb)
// NOTE: Unlikely to be needed for the beacon block root, but we setup any precompile overrides anyways for forwards-compatibility
var precompileOverrides vm.PrecompileOverrides
if vmConfig := s.l1Chain.GetVMConfig(); vmConfig != nil && vmConfig.OptimismPrecompileOverrides != nil {
precompileOverrides = vmConfig.OptimismPrecompileOverrides
}
vmenv := vm.NewEVM(context, vm.TxContext{}, statedb, s.l1Chain.Config(), vm.Config{OptimismPrecompileOverrides: precompileOverrides})
core.ProcessBeaconBlockRoot(*header.ParentBeaconRoot, vmenv, statedb)
}
s.l1Building = true
......
package actions
import (
"encoding/binary"
"testing"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/consensus/beacon"
"github.com/ethereum/go-ethereum/consensus/ethash"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/triedb"
"github.com/ethereum/go-ethereum/triedb/hashdb"
......@@ -55,6 +56,7 @@ func TestL1Replica_ActL1RPCFail(gt *testing.T) {
func TestL1Replica_ActL1Sync(gt *testing.T) {
t := NewDefaultTesting(gt)
dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams)
dp.DeployConfig.L1CancunTimeOffset = nil
sd := e2eutils.Setup(t, dp, defaultAlloc)
log := testlog.Logger(t, log.LevelDebug)
genesisBlock := sd.L1Cfg.ToBlock()
......@@ -63,13 +65,17 @@ func TestL1Replica_ActL1Sync(gt *testing.T) {
tdb := triedb.NewDatabase(db, &triedb.Config{HashDB: hashdb.Defaults})
sd.L1Cfg.MustCommit(db, tdb)
chainA, _ := core.GenerateChain(sd.L1Cfg.Config, genesisBlock, consensus, db, 10, func(n int, g *core.BlockGen) {
g.SetCoinbase(common.Address{'A'})
})
gen := func(s string) func(n int, g *core.BlockGen) {
return func(n int, g *core.BlockGen) {
root := crypto.Keccak256Hash([]byte(s),
binary.BigEndian.AppendUint64(nil, uint64(n)))
g.SetParentBeaconRoot(root)
}
}
chainA, _ := core.GenerateChain(sd.L1Cfg.Config, genesisBlock, consensus, db, 10, gen("A"))
chainA = append(append([]*types.Block{}, genesisBlock), chainA...)
chainB, _ := core.GenerateChain(sd.L1Cfg.Config, chainA[3], consensus, db, 10, func(n int, g *core.BlockGen) {
g.SetCoinbase(common.Address{'B'})
})
chainB, _ := core.GenerateChain(sd.L1Cfg.Config, chainA[3], consensus, db, 10, gen("B"))
chainB = append(append([]*types.Block{}, chainA[:4]...), chainB...)
require.NotEqual(t, chainA[9], chainB[9], "need different chains")
canonL1 := func(blocks []*types.Block) func(num uint64) *types.Block {
......
......@@ -46,7 +46,7 @@ func TestProposerBatchType(t *testing.T) {
func RunProposerTest(gt *testing.T, deltaTimeOffset *hexutil.Uint64) {
t := NewDefaultTesting(gt)
dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams)
dp.DeployConfig.L2GenesisDeltaTimeOffset = deltaTimeOffset
applyDeltaTimeOffset(dp, deltaTimeOffset)
sd := e2eutils.Setup(t, dp, defaultAlloc)
log := testlog.Logger(t, log.LevelDebug)
miner, seqEngine, sequencer := setupSequencerTest(t, sd, log)
......
......@@ -49,8 +49,8 @@ type PlasmaParam func(p *e2eutils.TestParams)
func NewL2PlasmaDA(t Testing, params ...PlasmaParam) *L2PlasmaDA {
p := &e2eutils.TestParams{
MaxSequencerDrift: 40,
SequencerWindowSize: 120,
ChannelTimeout: 120,
SequencerWindowSize: 12,
ChannelTimeout: 12,
L1BlockTime: 12,
UsePlasma: true,
}
......@@ -81,7 +81,7 @@ func NewL2PlasmaDA(t Testing, params ...PlasmaParam) *L2PlasmaDA {
daMgr := plasma.NewPlasmaDAWithStorage(log, plasmaCfg, storage, &plasma.NoopMetrics{})
sequencer := NewL2Sequencer(t, log, l1F, nil, daMgr, engCl, sd.RollupCfg, 0)
sequencer := NewL2Sequencer(t, log, l1F, miner.BlobStore(), daMgr, engCl, sd.RollupCfg, 0)
miner.ActL1SetFeeRecipient(common.Address{'A'})
sequencer.ActL2PipelineFull(t)
......@@ -139,7 +139,7 @@ func (a *L2PlasmaDA) NewVerifier(t Testing) *L2Verifier {
daMgr := plasma.NewPlasmaDAWithStorage(a.log, a.plasmaCfg, a.storage, &plasma.NoopMetrics{})
verifier := NewL2Verifier(t, a.log, l1F, nil, daMgr, engCl, a.sd.RollupCfg, &sync.Config{}, safedb.Disabled)
verifier := NewL2Verifier(t, a.log, l1F, a.miner.BlobStore(), daMgr, engCl, a.sd.RollupCfg, &sync.Config{}, safedb.Disabled)
return verifier
}
......@@ -453,10 +453,6 @@ func TestPlasma_SequencerStalledMultiChallenges(gt *testing.T) {
t := NewDefaultTesting(gt)
a := NewL2PlasmaDA(t)
// generate some initial L1 blocks.
a.ActL1Blocks(t, 5)
a.sequencer.ActL1HeadSignal(t)
// create a new tx on l2 and commit it to l1
a.ActNewL2Tx(t)
......@@ -489,7 +485,7 @@ func TestPlasma_SequencerStalledMultiChallenges(gt *testing.T) {
})
// include it in L1
a.miner.ActL1StartBlock(120)(t)
a.miner.ActL1StartBlock(12)(t)
a.miner.ActL1IncludeTx(a.dp.Addresses.Batcher)(t)
a.miner.ActL1EndBlock(t)
......
......@@ -25,7 +25,7 @@ import (
func setupReorgTest(t Testing, config *e2eutils.TestParams, deltaTimeOffset *hexutil.Uint64) (*e2eutils.SetupData, *e2eutils.DeployParams, *L1Miner, *L2Sequencer, *L2Engine, *L2Verifier, *L2Engine, *L2Batcher) {
dp := e2eutils.MakeDeployParams(t, config)
dp.DeployConfig.L2GenesisDeltaTimeOffset = deltaTimeOffset
applyDeltaTimeOffset(dp, deltaTimeOffset)
sd := e2eutils.Setup(t, dp, defaultAlloc)
log := testlog.Logger(t, log.LevelDebug)
......@@ -147,13 +147,6 @@ func ReorgFlipFlop(gt *testing.T, deltaTimeOffset *hexutil.Uint64) {
minerCl := miner.L1Client(t, sd.RollupCfg)
verifEngClient := verifierEng.EngineClient(t, sd.RollupCfg)
checkVerifEngine := func() {
// TODO: geth preserves L2 chain with origin A1 after flip-flopping to B?
//ref, err := verifEngClient.L2BlockRefByLabel(t.Ctx(), eth.Unsafe)
//require.NoError(t, err)
//t.Logf("l2 unsafe head %s with origin %s", ref, ref.L1Origin)
//require.NotEqual(t, verifier.L2Unsafe().Hash, ref.ParentHash, "TODO off by one, engine syncs A0 after reorging back from B, while rollup node only inserts up to A0 (excl.)")
//require.Equal(t, verifier.L2Unsafe(), ref, "verifier safe head of engine matches rollup client")
ref, err := verifEngClient.L2BlockRefByLabel(t.Ctx(), eth.Safe)
require.NoError(t, err)
require.Equal(t, verifier.L2Safe(), ref, "verifier safe head of engine matches rollup client")
......@@ -605,7 +598,7 @@ func RestartOpGeth(gt *testing.T, deltaTimeOffset *hexutil.Uint64) {
return nil
}
dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams)
dp.DeployConfig.L2GenesisDeltaTimeOffset = deltaTimeOffset
applyDeltaTimeOffset(dp, deltaTimeOffset)
sd := e2eutils.Setup(t, dp, defaultAlloc)
log := testlog.Logger(t, log.LevelDebug)
jwtPath := e2eutils.WriteDefaultJWT(t)
......@@ -693,7 +686,7 @@ func RestartOpGeth(gt *testing.T, deltaTimeOffset *hexutil.Uint64) {
func ConflictingL2Blocks(gt *testing.T, deltaTimeOffset *hexutil.Uint64) {
t := NewDefaultTesting(gt)
dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams)
dp.DeployConfig.L2GenesisDeltaTimeOffset = deltaTimeOffset
applyDeltaTimeOffset(dp, deltaTimeOffset)
sd := e2eutils.Setup(t, dp, defaultAlloc)
log := testlog.Logger(t, log.LevelDebug)
......
......@@ -40,7 +40,7 @@ func TestDropSpanBatchBeforeHardfork(gt *testing.T) {
}
dp := e2eutils.MakeDeployParams(t, p)
// do not activate Delta hardfork for verifier
dp.DeployConfig.L2GenesisDeltaTimeOffset = nil
applyDeltaTimeOffset(dp, nil)
sd := e2eutils.Setup(t, dp, defaultAlloc)
log := testlog.Logger(t, log.LevelError)
miner, seqEngine, sequencer := setupSequencerTest(t, sd, log)
......@@ -131,7 +131,7 @@ func TestHardforkMiddleOfSpanBatch(gt *testing.T) {
// Activate HF in the middle of the first epoch
deltaOffset := hexutil.Uint64(6)
dp.DeployConfig.L2GenesisDeltaTimeOffset = &deltaOffset
applyDeltaTimeOffset(dp, &deltaOffset)
sd := e2eutils.Setup(t, dp, defaultAlloc)
log := testlog.Logger(t, log.LevelError)
miner, seqEngine, sequencer := setupSequencerTest(t, sd, log)
......@@ -239,7 +239,7 @@ func TestAcceptSingularBatchAfterHardfork(gt *testing.T) {
dp := e2eutils.MakeDeployParams(t, p)
// activate Delta hardfork for verifier.
dp.DeployConfig.L2GenesisDeltaTimeOffset = &minTs
applyDeltaTimeOffset(dp, &minTs)
sd := e2eutils.Setup(t, dp, defaultAlloc)
log := testlog.Logger(t, log.LevelError)
miner, seqEngine, sequencer := setupSequencerTest(t, sd, log)
......@@ -325,7 +325,7 @@ func TestMixOfBatchesAfterHardfork(gt *testing.T) {
dp := e2eutils.MakeDeployParams(t, p)
// Activate Delta hardfork for verifier.
dp.DeployConfig.L2GenesisDeltaTimeOffset = &minTs
applyDeltaTimeOffset(dp, &minTs)
sd := e2eutils.Setup(t, dp, defaultAlloc)
log := testlog.Logger(t, log.LevelError)
miner, seqEngine, sequencer := setupSequencerTest(t, sd, log)
......@@ -415,7 +415,7 @@ func TestSpanBatchEmptyChain(gt *testing.T) {
dp := e2eutils.MakeDeployParams(t, p)
minTs := hexutil.Uint64(0)
// Activate Delta hardfork
dp.DeployConfig.L2GenesisDeltaTimeOffset = &minTs
applyDeltaTimeOffset(dp, &minTs)
sd := e2eutils.Setup(t, dp, defaultAlloc)
log := testlog.Logger(t, log.LevelError)
miner, seqEngine, sequencer := setupSequencerTest(t, sd, log)
......@@ -478,7 +478,7 @@ func TestSpanBatchLowThroughputChain(gt *testing.T) {
dp := e2eutils.MakeDeployParams(t, p)
minTs := hexutil.Uint64(0)
// Activate Delta hardfork
dp.DeployConfig.L2GenesisDeltaTimeOffset = &minTs
applyDeltaTimeOffset(dp, &minTs)
sd := e2eutils.Setup(t, dp, defaultAlloc)
log := testlog.Logger(t, log.LevelError)
miner, seqEngine, sequencer := setupSequencerTest(t, sd, log)
......@@ -592,7 +592,7 @@ func TestBatchEquivalence(gt *testing.T) {
// Delta activated deploy config
dp := e2eutils.MakeDeployParams(t, p)
minTs := hexutil.Uint64(0)
dp.DeployConfig.L2GenesisDeltaTimeOffset = &minTs
applyDeltaTimeOffset(dp, &minTs)
sdDeltaActivated := e2eutils.Setup(t, dp, defaultAlloc)
// Delta deactivated deploy config
......
......@@ -66,7 +66,7 @@ func TestSyncBatchType(t *testing.T) {
func DerivationWithFlakyL1RPC(gt *testing.T, deltaTimeOffset *hexutil.Uint64) {
t := NewDefaultTesting(gt)
dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams)
dp.DeployConfig.L2GenesisDeltaTimeOffset = deltaTimeOffset
applyDeltaTimeOffset(dp, deltaTimeOffset)
sd := e2eutils.Setup(t, dp, defaultAlloc)
log := testlog.Logger(t, log.LevelError) // mute all the temporary derivation errors that we forcefully create
_, _, miner, sequencer, _, verifier, _, batcher := setupReorgTestActors(t, dp, sd, log)
......@@ -106,7 +106,7 @@ func DerivationWithFlakyL1RPC(gt *testing.T, deltaTimeOffset *hexutil.Uint64) {
func FinalizeWhileSyncing(gt *testing.T, deltaTimeOffset *hexutil.Uint64) {
t := NewDefaultTesting(gt)
dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams)
dp.DeployConfig.L2GenesisDeltaTimeOffset = deltaTimeOffset
applyDeltaTimeOffset(dp, deltaTimeOffset)
sd := e2eutils.Setup(t, dp, defaultAlloc)
log := testlog.Logger(t, log.LevelError) // mute all the temporary derivation errors that we forcefully create
_, _, miner, sequencer, _, verifier, _, batcher := setupReorgTestActors(t, dp, sd, log)
......@@ -182,7 +182,7 @@ func TestBackupUnsafe(gt *testing.T) {
dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams)
minTs := hexutil.Uint64(0)
// Activate Delta hardfork
dp.DeployConfig.L2GenesisDeltaTimeOffset = &minTs
applyDeltaTimeOffset(dp, &minTs)
dp.DeployConfig.L2BlockTime = 2
sd := e2eutils.Setup(t, dp, defaultAlloc)
log := testlog.Logger(t, log.LvlInfo)
......@@ -343,7 +343,7 @@ func TestBackupUnsafeReorgForkChoiceInputError(gt *testing.T) {
dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams)
minTs := hexutil.Uint64(0)
// Activate Delta hardfork
dp.DeployConfig.L2GenesisDeltaTimeOffset = &minTs
applyDeltaTimeOffset(dp, &minTs)
dp.DeployConfig.L2BlockTime = 2
sd := e2eutils.Setup(t, dp, defaultAlloc)
log := testlog.Logger(t, log.LvlInfo)
......@@ -476,7 +476,7 @@ func TestBackupUnsafeReorgForkChoiceNotInputError(gt *testing.T) {
dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams)
minTs := hexutil.Uint64(0)
// Activate Delta hardfork
dp.DeployConfig.L2GenesisDeltaTimeOffset = &minTs
applyDeltaTimeOffset(dp, &minTs)
dp.DeployConfig.L2BlockTime = 2
sd := e2eutils.Setup(t, dp, defaultAlloc)
log := testlog.Logger(t, log.LvlInfo)
......@@ -893,7 +893,7 @@ func TestInvalidPayloadInSpanBatch(gt *testing.T) {
dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams)
minTs := hexutil.Uint64(0)
// Activate Delta hardfork
dp.DeployConfig.L2GenesisDeltaTimeOffset = &minTs
applyDeltaTimeOffset(dp, &minTs)
dp.DeployConfig.L2BlockTime = 2
sd := e2eutils.Setup(t, dp, defaultAlloc)
log := testlog.Logger(t, log.LevelInfo)
......@@ -998,7 +998,7 @@ func TestSpanBatchAtomicity_Consolidation(gt *testing.T) {
dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams)
minTs := hexutil.Uint64(0)
// Activate Delta hardfork
dp.DeployConfig.L2GenesisDeltaTimeOffset = &minTs
applyDeltaTimeOffset(dp, &minTs)
dp.DeployConfig.L2BlockTime = 2
sd := e2eutils.Setup(t, dp, defaultAlloc)
log := testlog.Logger(t, log.LevelInfo)
......@@ -1059,7 +1059,7 @@ func TestSpanBatchAtomicity_ForceAdvance(gt *testing.T) {
dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams)
minTs := hexutil.Uint64(0)
// Activate Delta hardfork
dp.DeployConfig.L2GenesisDeltaTimeOffset = &minTs
applyDeltaTimeOffset(dp, &minTs)
dp.DeployConfig.L2BlockTime = 2
sd := e2eutils.Setup(t, dp, defaultAlloc)
log := testlog.Logger(t, log.LevelInfo)
......
......@@ -53,7 +53,7 @@ func BatcherKeyRotation(gt *testing.T, deltaTimeOffset *hexutil.Uint64) {
dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams)
dp.DeployConfig.L2BlockTime = 2
dp.DeployConfig.L2GenesisDeltaTimeOffset = deltaTimeOffset
applyDeltaTimeOffset(dp, deltaTimeOffset)
sd := e2eutils.Setup(t, dp, defaultAlloc)
log := testlog.Logger(t, log.LevelDebug)
miner, seqEngine, sequencer := setupSequencerTest(t, sd, log)
......@@ -227,7 +227,7 @@ func BatcherKeyRotation(gt *testing.T, deltaTimeOffset *hexutil.Uint64) {
func GPOParamsChange(gt *testing.T, deltaTimeOffset *hexutil.Uint64) {
t := NewDefaultTesting(gt)
dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams)
dp.DeployConfig.L2GenesisDeltaTimeOffset = deltaTimeOffset
applyDeltaTimeOffset(dp, deltaTimeOffset)
sd := e2eutils.Setup(t, dp, defaultAlloc)
log := testlog.Logger(t, log.LevelDebug)
miner, seqEngine, sequencer := setupSequencerTest(t, sd, log)
......@@ -354,7 +354,7 @@ func GPOParamsChange(gt *testing.T, deltaTimeOffset *hexutil.Uint64) {
func GasLimitChange(gt *testing.T, deltaTimeOffset *hexutil.Uint64) {
t := NewDefaultTesting(gt)
dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams)
dp.DeployConfig.L2GenesisDeltaTimeOffset = deltaTimeOffset
applyDeltaTimeOffset(dp, deltaTimeOffset)
sd := e2eutils.Setup(t, dp, defaultAlloc)
log := testlog.Logger(t, log.LevelDebug)
miner, seqEngine, sequencer := setupSequencerTest(t, sd, log)
......
......@@ -20,7 +20,7 @@ func TestMintOnRevertedDeposit(t *testing.T) {
cfg := DefaultSystemConfig(t)
delete(cfg.Nodes, "verifier")
sys, err := cfg.Start(t)
require.Nil(t, err, "Error starting up system")
require.NoError(t, err, "Error starting up system")
defer sys.Close()
l1Client := sys.Clients["l1"]
......@@ -29,13 +29,13 @@ func TestMintOnRevertedDeposit(t *testing.T) {
// create signer
aliceKey := cfg.Secrets.Alice
opts, err := bind.NewKeyedTransactorWithChainID(aliceKey, cfg.L1ChainIDBig())
require.Nil(t, err)
require.NoError(t, err)
fromAddr := opts.From
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
startBalance, err := l2Verif.BalanceAt(ctx, fromAddr, nil)
cancel()
require.Nil(t, err)
require.NoError(t, err)
ctx, cancel = context.WithTimeout(context.Background(), 1*time.Second)
startNonce, err := l2Verif.NonceAt(ctx, fromAddr, nil)
......@@ -56,7 +56,7 @@ func TestMintOnRevertedDeposit(t *testing.T) {
ctx, cancel = context.WithTimeout(context.Background(), 15*time.Second)
endBalance, err := wait.ForBalanceChange(ctx, l2Verif, fromAddr, startBalance)
cancel()
require.Nil(t, err)
require.NoError(t, err)
ctx, cancel = context.WithTimeout(context.Background(), 1*time.Second)
toAddrBalance, err := l2Verif.BalanceAt(ctx, toAddr, nil)
......@@ -81,14 +81,14 @@ func TestDepositTxCreateContract(t *testing.T) {
delete(cfg.Nodes, "verifier")
sys, err := cfg.Start(t)
require.Nil(t, err, "Error starting up system")
require.NoError(t, err, "Error starting up system")
defer sys.Close()
l1Client := sys.Clients["l1"]
l2Client := sys.Clients["sequencer"]
opts, err := bind.NewKeyedTransactorWithChainID(cfg.Secrets.Alice, cfg.L1ChainIDBig())
require.Nil(t, err)
require.NoError(t, err)
// Simple constructor that is prefixed to the actual contract code
// Results in the contract code being returned as the code for the new contract
......
package devnet
import (
"context"
"testing"
"time"
e2e "github.com/ethereum-optimism/optimism/op-e2e"
"github.com/ethereum-optimism/optimism/op-service/testlog"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"golang.org/x/exp/slog"
)
func TestDevnet(t *testing.T) {
lgr := testlog.Logger(t, slog.LevelDebug)
ctx, done := context.WithTimeout(context.Background(), time.Minute)
defer done()
sys, err := NewSystem(ctx, lgr)
require.NoError(t, err)
t.Run("SyncFinalized", func(t *testing.T) {
// SyncFinalized can run in parallel to Withdrawals test, because propopser
// already posts unfinalized output roots in devnet mode.
t.Parallel()
testSyncFinalized(t, sys)
})
t.Run("Withdrawal", func(t *testing.T) {
t.Parallel()
e2e.RunWithdrawalsTest(t, sys)
})
}
func testSyncFinalized(t *testing.T, sys *System) {
const timeout = 4 * time.Minute
ctx, done := context.WithTimeout(context.Background(), timeout)
defer done()
require.EventuallyWithT(t, func(tc *assert.CollectT) {
ss, err := sys.Rollup.SyncStatus(ctx)
assert.NoError(tc, err)
if err != nil {
t.Log(err)
return
}
t.Logf("SyncStatus: %+v", ss)
assert.NotZero(tc, ss.FinalizedL2.Number)
}, timeout, 2*time.Second)
}
package devnet
import (
"context"
"crypto/ecdsa"
"os"
"path/filepath"
"github.com/ethereum-optimism/optimism/op-chain-ops/genesis"
e2e "github.com/ethereum-optimism/optimism/op-e2e"
"github.com/ethereum-optimism/optimism/op-e2e/config"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils"
op_service "github.com/ethereum-optimism/optimism/op-service"
"github.com/ethereum-optimism/optimism/op-service/dial"
"github.com/ethereum-optimism/optimism/op-service/sources"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/log"
)
// TODO(#10968): read from docker-compose.yml
const (
L1RPCURL = "http://127.0.0.1:8545"
L2RPCURL = "http://127.0.0.1:9545"
RollupURL = "http://127.0.0.1:7545"
)
type System struct {
L1 *ethclient.Client
L2 *ethclient.Client
Rollup *sources.RollupClient
Cfg e2e.SystemConfig
}
func NewSystem(ctx context.Context, lgr log.Logger) (sys *System, err error) {
sys = new(System)
sys.L1, err = dial.DialEthClientWithTimeout(ctx, dial.DefaultDialTimeout, lgr, L1RPCURL)
if err != nil {
return nil, err
}
sys.L2, err = dial.DialEthClientWithTimeout(ctx, dial.DefaultDialTimeout, lgr, L2RPCURL)
if err != nil {
return nil, err
}
sys.Rollup, err = dial.DialRollupClientWithTimeout(ctx, dial.DefaultDialTimeout, lgr, RollupURL)
if err != nil {
return nil, err
}
secrets, err := e2eutils.DefaultMnemonicConfig.Secrets()
if err != nil {
return nil, err
}
// TODO(#10968): We need to re-read the deploy config because op-e2e/config.init() overwrites
// some deploy config variables. This will be fixed soon.
cwd, err := os.Getwd()
if err != nil {
return nil, err
}
root, err := op_service.FindMonorepoRoot(cwd)
if err != nil {
return nil, err
}
deployConfigPath := filepath.Join(root, "packages", "contracts-bedrock", "deploy-config", "devnetL1.json")
deployConfig, err := genesis.NewDeployConfig(deployConfigPath)
if err != nil {
return nil, err
}
// Incomplete SystemConfig suffices for withdrawal test (only consumer right now)
sys.Cfg = e2e.SystemConfig{
DeployConfig: deployConfig,
L1Deployments: config.L1Deployments.Copy(),
Secrets: secrets,
}
return sys, nil
}
func (s System) NodeClient(role string) *ethclient.Client {
switch role {
case e2e.RoleL1:
return s.L1
case e2e.RoleSeq, e2e.RoleVerif:
// we have only one L2 node
return s.L2
default:
panic("devnet.System: unknown role: " + role)
}
}
func (s System) RollupClient(string) *sources.RollupClient {
// we ignore role, have only one L2 rollup
return s.Rollup
}
func (s System) Config() e2e.SystemConfig {
return s.Cfg
}
func (s System) TestAccount(idx int) *ecdsa.PrivateKey {
// first 12 indices are in use by the devnet
return s.Cfg.Secrets.AccountAtIdx(13 + idx)
}
......@@ -138,13 +138,19 @@ func (f *fakePoS) Start() error {
tim.Stop()
return nil
}
envelope, err := f.engineAPI.GetPayloadV3(*res.PayloadID)
var envelope *engine.ExecutionPayloadEnvelope
if isCancun {
envelope, err = f.engineAPI.GetPayloadV3(*res.PayloadID)
} else {
envelope, err = f.engineAPI.GetPayloadV2(*res.PayloadID)
}
if err != nil {
f.log.Error("failed to finish building L1 block", "err", err)
continue
}
blobHashes := make([]common.Hash, 0) // must be non-nil even when empty, due to geth engine API checks
if envelope.BlobsBundle != nil {
for _, commitment := range envelope.BlobsBundle.Commitments {
if len(commitment) != 48 {
f.log.Error("got malformed kzg commitment from engine", "commitment", commitment)
......@@ -156,17 +162,18 @@ func (f *fakePoS) Start() error {
f.log.Error("invalid or incomplete blob data", "collected", len(blobHashes), "engine", len(envelope.BlobsBundle.Commitments))
continue
}
if isCancun {
if _, err := f.engineAPI.NewPayloadV3(*envelope.ExecutionPayload, blobHashes, &parentBeaconBlockRoot); err != nil {
f.log.Error("failed to insert built L1 block", "err", err)
continue
}
if isCancun {
_, err = f.engineAPI.NewPayloadV3(*envelope.ExecutionPayload, blobHashes, &parentBeaconBlockRoot)
} else {
if _, err := f.engineAPI.NewPayloadV2(*envelope.ExecutionPayload); err != nil {
_, err = f.engineAPI.NewPayloadV2(*envelope.ExecutionPayload)
}
if err != nil {
f.log.Error("failed to insert built L1 block", "err", err)
continue
}
}
if envelope.BlobsBundle != nil {
slot := (envelope.ExecutionPayload.Timestamp - f.eth.BlockChain().Genesis().Time()) / f.blockTime
if f.beacon == nil {
......
......@@ -3,6 +3,7 @@ package e2eutils
import (
"crypto/ecdsa"
"fmt"
"strconv"
hdwallet "github.com/ethereum-optimism/go-ethereum-hdwallet"
"github.com/ethereum/go-ethereum/accounts"
......@@ -11,6 +12,8 @@ import (
"github.com/ethereum/go-ethereum/crypto"
)
const defaultHDPathPrefix = "m/44'/60'/0'/0/"
// DefaultMnemonicConfig is the default mnemonic used in testing.
// We prefer a mnemonic rather than direct private keys to make it easier
// to export all testing keys in external tooling for use during debugging.
......@@ -189,3 +192,14 @@ func (a *Addresses) All() []common.Address {
a.Mallory,
}
}
func (s *Secrets) AccountAtIdx(idx int) *ecdsa.PrivateKey {
account := accounts.Account{URL: accounts.URL{
Path: defaultHDPathPrefix + strconv.Itoa(idx),
}}
pk, err := s.Wallet.PrivateKey(account)
if err != nil {
panic(err)
}
return pk
}
......@@ -233,9 +233,11 @@ func UseFaultProofs() bool {
}
func UseL2OO() bool {
return os.Getenv("OP_E2E_USE_L2OO") == "true"
return (os.Getenv("OP_E2E_USE_L2OO") == "true" ||
os.Getenv("DEVNET_L2OO") == "true")
}
func UsePlasma() bool {
return os.Getenv("OP_E2E_USE_PLASMA") == "true"
return (os.Getenv("OP_E2E_USE_PLASMA") == "true" ||
os.Getenv("DEVNET_PLASMA") == "true")
}
......@@ -22,6 +22,7 @@ type SendTxOpt func(cfg *sendTxCfg)
type sendTxCfg struct {
receiptStatus uint64
ignoreReceiptStatus bool
}
func makeSendTxCfg(opts ...SendTxOpt) *sendTxCfg {
......@@ -40,6 +41,12 @@ func WithReceiptFail() SendTxOpt {
}
}
func WithReceiptStatusIgnore() SendTxOpt {
return func(cfg *sendTxCfg) {
cfg.ignoreReceiptStatus = true
}
}
func RequireSendTx(t *testing.T, ctx context.Context, client *ethclient.Client, candidate txmgr.TxCandidate, privKey *ecdsa.PrivateKey, opts ...SendTxOpt) (*types.Transaction, *types.Receipt) {
tx, rcpt, err := SendTx(ctx, client, candidate, privKey, opts...)
require.NoError(t, err, "Failed to send transaction")
......@@ -94,11 +101,11 @@ func SendTx(ctx context.Context, client *ethclient.Client, candidate txmgr.TxCan
})
err = client.SendTransaction(ctx, tx)
if err != nil {
return nil, nil, fmt.Errorf("failed to send transaction: %w", errutil.TryAddRevertReason(err))
return nil, nil, fmt.Errorf("failed to send transaction (tx: %s): %w", tx.Hash(), errutil.TryAddRevertReason(err))
}
receipt, err := wait.ForReceipt(ctx, client, tx.Hash(), cfg.receiptStatus)
receipt, err := wait.ForReceiptMaybe(ctx, client, tx.Hash(), cfg.receiptStatus, cfg.ignoreReceiptStatus)
if err != nil {
return nil, nil, fmt.Errorf("failed to find OK receipt: %w", err)
return tx, receipt, fmt.Errorf("failed to find OK receipt (tx: %s): %w", tx.Hash(), err)
}
return tx, receipt, nil
}
......@@ -33,14 +33,19 @@ func ForBalanceChange(ctx context.Context, client *ethclient.Client, address com
}
func ForReceiptOK(ctx context.Context, client *ethclient.Client, hash common.Hash) (*types.Receipt, error) {
return ForReceipt(ctx, client, hash, types.ReceiptStatusSuccessful)
return ForReceiptMaybe(ctx, client, hash, types.ReceiptStatusSuccessful, false)
}
func ForReceiptFail(ctx context.Context, client *ethclient.Client, hash common.Hash) (*types.Receipt, error) {
return ForReceipt(ctx, client, hash, types.ReceiptStatusFailed)
return ForReceiptMaybe(ctx, client, hash, types.ReceiptStatusFailed, false)
}
func ForReceipt(ctx context.Context, client *ethclient.Client, hash common.Hash, status uint64) (*types.Receipt, error) {
return ForReceiptMaybe(ctx, client, hash, status, false)
}
// ForReceiptMaybe waits for the receipt, but may be configured to ignore the status
func ForReceiptMaybe(ctx context.Context, client *ethclient.Client, hash common.Hash, status uint64, statusIgnore bool) (*types.Receipt, error) {
ctx, cancel := context.WithTimeout(ctx, 2*time.Minute)
defer cancel()
ticker := time.NewTicker(100 * time.Millisecond)
......@@ -61,36 +66,59 @@ func ForReceipt(ctx context.Context, client *ethclient.Client, hash common.Hash,
if err != nil {
return nil, fmt.Errorf("failed to get receipt for tx %s: %w", hash, err)
}
if receipt.Status != status {
printDebugTrace(ctx, client, hash)
return receipt, fmt.Errorf("expected status %d, but got %d", status, receipt.Status)
if !statusIgnore && receipt.Status != status {
trace, err := DebugTraceTx(ctx, client, hash)
if err != nil {
// still return receipt if trace couldn't be obtained
return receipt, fmt.Errorf("unexpected receipt status %d, error tracing tx: %w", receipt.Status, err)
}
return receipt, &ReceiptStatusError{Status: receipt.Status, TxTrace: trace}
}
return receipt, nil
}
}
type jsonRawString string
type (
ReceiptStatusError struct {
Status uint64
TxTrace *TxTrace
}
func (s *jsonRawString) UnmarshalJSON(input []byte) error {
str := jsonRawString(input)
*s = str
return nil
CallTrace struct {
From common.Address `json:"from"`
Gas hexutil.Uint64 `json:"gas"`
GasUsed hexutil.Uint64 `json:"gasUsed"`
To common.Address `json:"to"`
Input hexutil.Bytes `json:"input"`
Output hexutil.Bytes `json:"output"`
Error string `json:"error"`
Value hexutil.U256 `json:"value"`
Type string `json:"type"`
}
TxTrace struct {
CallTrace
Calls []CallTrace `json:"calls"`
}
)
func (rse *ReceiptStatusError) Error() string {
return fmt.Sprintf("unexpected receipt status %d (tx trace: %+v)", rse.Status, rse.TxTrace)
}
// printDebugTrace logs debug_traceTransaction output to aid in debugging unexpected receipt statuses
func printDebugTrace(ctx context.Context, client *ethclient.Client, txHash common.Hash) {
var trace jsonRawString
// DebugTraceTx logs debug_traceTransaction output to aid in debugging unexpected receipt statuses
func DebugTraceTx(ctx context.Context, client *ethclient.Client, txHash common.Hash) (*TxTrace, error) {
trace := new(TxTrace)
options := map[string]any{
"enableReturnData": true,
"tracer": "callTracer",
"tracerConfig": map[string]any{},
}
err := client.Client().CallContext(ctx, &trace, "debug_traceTransaction", hexutil.Bytes(txHash.Bytes()), options)
err := client.Client().CallContext(ctx, trace, "debug_traceTransaction", hexutil.Bytes(txHash.Bytes()), options)
if err != nil {
fmt.Printf("TxTrace unavailable: %v\n", err)
return
return nil, fmt.Errorf("calling debug_traceTransaction: %w", err)
}
fmt.Printf("TxTrace: %v\n", trace)
return trace, nil
}
func For(ctx context.Context, rate time.Duration, cb func() (bool, error)) error {
......
......@@ -40,7 +40,10 @@ func TestSystem4844E2E(t *testing.T) {
func testSystem4844E2E(t *testing.T, multiBlob bool, daType batcherFlags.DataAvailabilityType) {
InitParallel(t)
cfg := DefaultSystemConfig(t)
cfg := EcotoneSystemConfig(t, &genesisTime)
cfg.DataAvailabilityType = daType
cfg.DeployConfig.L1GenesisBlockBaseFeePerGas = (*hexutil.Big)(big.NewInt(7000))
const maxBlobs = 6
var maxL1TxSize int
if multiBlob {
......@@ -51,13 +54,6 @@ func testSystem4844E2E(t *testing.T, multiBlob bool, daType batcherFlags.DataAva
maxL1TxSize = derive.FrameV0OverHeadSize + 100
cfg.BatcherMaxL1TxSizeBytes = uint64(maxL1TxSize)
}
cfg.DataAvailabilityType = daType
genesisActivation := hexutil.Uint64(0)
cfg.DeployConfig.L1CancunTimeOffset = &genesisActivation
cfg.DeployConfig.L2GenesisDeltaTimeOffset = &genesisActivation
cfg.DeployConfig.L2GenesisEcotoneTimeOffset = &genesisActivation
cfg.DeployConfig.L1GenesisBlockBaseFeePerGas = (*hexutil.Big)(big.NewInt(7000))
// For each test we intentionally block the batcher by submitting an incompatible tx type up
// front. This lets us test the ability for the batcher to clear out the incompatible
......@@ -82,7 +78,7 @@ func testSystem4844E2E(t *testing.T, multiBlob bool, daType batcherFlags.DataAva
}()
sys, err := cfg.Start(t, action)
require.Nil(t, err, "Error starting up system")
require.NoError(t, err, "Error starting up system")
defer sys.Close()
log := testlog.Logger(t, log.LevelInfo)
......
......@@ -72,15 +72,13 @@ func TestPrecompiles(t *testing.T) {
t.Run(test.name, func(t *testing.T) {
op_e2e.InitParallel(t, op_e2e.UsesCannon)
ctx := context.Background()
cfg := op_e2e.DefaultSystemConfig(t)
genesisTime := hexutil.Uint64(0)
cfg := op_e2e.EcotoneSystemConfig(t, &genesisTime)
// We don't need a verifier - just the sequencer is enough
delete(cfg.Nodes, "verifier")
// Use a small sequencer window size to avoid test timeout while waiting for empty blocks
// But not too small to ensure that our claim and subsequent state change is published
cfg.DeployConfig.SequencerWindowSize = 16
minTs := hexutil.Uint64(0)
cfg.DeployConfig.L2GenesisDeltaTimeOffset = &minTs
cfg.DeployConfig.L2GenesisEcotoneTimeOffset = &minTs
sys, err := cfg.Start(t)
require.Nil(t, err, "Error starting up system")
......
......@@ -55,7 +55,7 @@ func NewOpGeth(t testing.TB, ctx context.Context, cfg *SystemConfig) (*OpGeth, e
logger := testlog.Logger(t, log.LevelCrit)
l1Genesis, err := genesis.BuildL1DeveloperGenesis(cfg.DeployConfig, config.L1Allocs, config.L1Deployments)
require.Nil(t, err)
require.NoError(t, err)
l1Block := l1Genesis.ToBlock()
var allocsMode genesis.L2AllocsMode
......@@ -67,7 +67,7 @@ func NewOpGeth(t testing.TB, ctx context.Context, cfg *SystemConfig) (*OpGeth, e
}
l2Allocs := config.L2Allocs(allocsMode)
l2Genesis, err := genesis.BuildL2Genesis(cfg.DeployConfig, l2Allocs, l1Block)
require.Nil(t, err)
require.NoError(t, err)
l2GenesisBlock := l2Genesis.ToBlock()
rollupGenesis := rollup.Genesis{
......@@ -86,8 +86,8 @@ func NewOpGeth(t testing.TB, ctx context.Context, cfg *SystemConfig) (*OpGeth, e
var node EthInstance
if cfg.ExternalL2Shim == "" {
gethNode, _, err := geth.InitL2("l2", big.NewInt(int64(cfg.DeployConfig.L2ChainID)), l2Genesis, cfg.JWTFilePath)
require.Nil(t, err)
require.Nil(t, gethNode.Start())
require.NoError(t, err)
require.NoError(t, gethNode.Start())
node = gethNode
} else {
externalNode := (&ExternalRunner{
......@@ -113,14 +113,14 @@ func NewOpGeth(t testing.TB, ctx context.Context, cfg *SystemConfig) (*OpGeth, e
nil,
sources.EngineClientDefaultConfig(rollupCfg),
)
require.Nil(t, err)
require.NoError(t, err)
l2Client, err := ethclient.Dial(selectEndpoint(node))
require.Nil(t, err)
require.NoError(t, err)
genesisPayload, err := eth.BlockAsPayload(l2GenesisBlock, cfg.DeployConfig.CanyonTime(l2GenesisBlock.Time()))
require.Nil(t, err)
require.NoError(t, err)
return &OpGeth{
node: node,
L2Client: l2Client,
......@@ -151,14 +151,14 @@ func (d *OpGeth) AddL2Block(ctx context.Context, txs ...*types.Transaction) (*et
}
res, err := d.StartBlockBuilding(ctx, attrs)
if err != nil {
return nil, err
return nil, fmt.Errorf("start block building: %w", err)
}
envelope, err := d.l2Engine.GetPayload(ctx, eth.PayloadInfo{ID: *res.PayloadID, Timestamp: uint64(attrs.Timestamp)})
payload := envelope.ExecutionPayload
if err != nil {
return nil, err
return nil, fmt.Errorf("get payload: %w", err)
}
if !reflect.DeepEqual(payload.Transactions, attrs.Transactions) {
return nil, errors.New("required transactions were not included")
......@@ -166,7 +166,7 @@ func (d *OpGeth) AddL2Block(ctx context.Context, txs ...*types.Transaction) (*et
status, err := d.l2Engine.NewPayload(ctx, payload, envelope.ParentBeaconBlockRoot)
if err != nil {
return nil, err
return nil, fmt.Errorf("new payload: %w", err)
}
if status.Status != eth.ExecutionValid {
return nil, fmt.Errorf("%w: %s", ErrNewPayloadNotValid, status.Status)
......@@ -178,7 +178,7 @@ func (d *OpGeth) AddL2Block(ctx context.Context, txs ...*types.Transaction) (*et
}
res, err = d.l2Engine.ForkchoiceUpdate(ctx, &fc, nil)
if err != nil {
return nil, err
return nil, fmt.Errorf("forkchoice update: %w", err)
}
if res.PayloadStatus.Status != eth.ExecutionValid {
return nil, fmt.Errorf("%w: %s", ErrForkChoiceUpdatedNotValid, res.PayloadStatus.Status)
......@@ -235,6 +235,10 @@ func (d *OpGeth) CreatePayloadAttributes(txs ...*types.Transaction) (*eth.Payloa
var parentBeaconBlockRoot *common.Hash
if d.L2ChainConfig.IsEcotone(uint64(timestamp)) {
parentBeaconBlockRoot = d.L1Head.ParentBeaconRoot()
// In case L1 hasn't activated Dencun yet.
if parentBeaconBlockRoot == nil {
parentBeaconBlockRoot = &(common.Hash{})
}
}
attrs := eth.PayloadAttributes{
......
This diff is collapsed.
......@@ -9,7 +9,6 @@ import (
"testing"
"time"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/rpc"
"github.com/stretchr/testify/require"
......@@ -308,7 +307,7 @@ func setupBatcher(t *testing.T, sys *System, conductors map[string]*conductor) {
}
func sequencerFailoverSystemConfig(t *testing.T, ports map[string]int) SystemConfig {
cfg := DefaultSystemConfig(t)
cfg := EcotoneSystemConfig(t, &genesisTime)
delete(cfg.Nodes, "sequencer")
cfg.Nodes[Sequencer1Name] = sequencerCfg(ports[Sequencer1Name])
cfg.Nodes[Sequencer2Name] = sequencerCfg(ports[Sequencer2Name])
......@@ -325,9 +324,6 @@ func sequencerFailoverSystemConfig(t *testing.T, ports map[string]int) SystemCon
Sequencer3Name: {VerifierName, Sequencer1Name},
VerifierName: {Sequencer1Name, Sequencer2Name},
}
offset := hexutil.Uint64(0)
cfg.DeployConfig.L2GenesisDeltaTimeOffset = &offset
cfg.DeployConfig.L2GenesisEcotoneTimeOffset = &offset
return cfg
}
......
......@@ -68,7 +68,16 @@ import (
"github.com/ethereum-optimism/optimism/op-service/txmgr"
)
var testingJWTSecret = [32]byte{123}
const (
RoleSeq = "sequencer"
RoleVerif = "verifier"
RoleL1 = "l1"
)
var (
testingJWTSecret = [32]byte{123}
genesisTime = hexutil.Uint64(0)
)
func newTxMgrConfig(l1Addr string, privKey *ecdsa.PrivateKey) txmgr.CLIConfig {
return txmgr.CLIConfig{
......@@ -116,7 +125,7 @@ func DefaultSystemConfig(t testing.TB) SystemConfig {
JWTSecret: testingJWTSecret,
BlobsPath: t.TempDir(),
Nodes: map[string]*rollupNode.Config{
"sequencer": {
RoleSeq: {
Driver: driver.Config{
VerifierConfDepth: 0,
SequencerConfDepth: 0,
......@@ -133,7 +142,7 @@ func DefaultSystemConfig(t testing.TB) SystemConfig {
ConfigPersistence: &rollupNode.DisabledConfigPersistence{},
Sync: sync.Config{SyncMode: sync.CLSync},
},
"verifier": {
RoleVerif: {
Driver: driver.Config{
VerifierConfDepth: 0,
SequencerConfDepth: 0,
......@@ -151,8 +160,8 @@ func DefaultSystemConfig(t testing.TB) SystemConfig {
},
},
Loggers: map[string]log.Logger{
"verifier": testlog.Logger(t, log.LevelInfo).New("role", "verifier"),
"sequencer": testlog.Logger(t, log.LevelInfo).New("role", "sequencer"),
RoleVerif: testlog.Logger(t, log.LevelInfo).New("role", RoleVerif),
RoleSeq: testlog.Logger(t, log.LevelInfo).New("role", RoleSeq),
"batcher": testlog.Logger(t, log.LevelInfo).New("role", "batcher"),
"proposer": testlog.Logger(t, log.LevelCrit).New("role", "proposer"),
},
......@@ -166,6 +175,43 @@ func DefaultSystemConfig(t testing.TB) SystemConfig {
}
}
func RegolithSystemConfig(t *testing.T, regolithTimeOffset *hexutil.Uint64) SystemConfig {
cfg := DefaultSystemConfig(t)
cfg.DeployConfig.L2GenesisRegolithTimeOffset = regolithTimeOffset
cfg.DeployConfig.L2GenesisCanyonTimeOffset = nil
cfg.DeployConfig.L2GenesisDeltaTimeOffset = nil
cfg.DeployConfig.L2GenesisEcotoneTimeOffset = nil
cfg.DeployConfig.L2GenesisFjordTimeOffset = nil
// ADD NEW FORKS HERE!
return cfg
}
func CanyonSystemConfig(t *testing.T, canyonTimeOffset *hexutil.Uint64) SystemConfig {
cfg := RegolithSystemConfig(t, &genesisTime)
cfg.DeployConfig.L2GenesisCanyonTimeOffset = canyonTimeOffset
return cfg
}
func DeltaSystemConfig(t *testing.T, deltaTimeOffset *hexutil.Uint64) SystemConfig {
cfg := CanyonSystemConfig(t, &genesisTime)
cfg.DeployConfig.L2GenesisDeltaTimeOffset = deltaTimeOffset
return cfg
}
func EcotoneSystemConfig(t *testing.T, ecotoneTimeOffset *hexutil.Uint64) SystemConfig {
cfg := DeltaSystemConfig(t, &genesisTime)
// from Ecotone onwards, activate L1 Cancun at genesis
cfg.DeployConfig.L1CancunTimeOffset = &genesisTime
cfg.DeployConfig.L2GenesisEcotoneTimeOffset = ecotoneTimeOffset
return cfg
}
func FjordSystemConfig(t *testing.T, fjordTimeOffset *hexutil.Uint64) SystemConfig {
cfg := EcotoneSystemConfig(t, &genesisTime)
cfg.DeployConfig.L2GenesisFjordTimeOffset = fjordTimeOffset
return cfg
}
func writeDefaultJWT(t testing.TB) string {
// Sadly the geth node config cannot load JWT secret from memory, it has to be a file
jwtPath := path.Join(t.TempDir(), "jwt_secret")
......@@ -304,6 +350,8 @@ type System struct {
rollupClients map[string]*sources.RollupClient
}
func (sys *System) Config() SystemConfig { return sys.Cfg }
// AdvanceTime advances the system clock by the given duration.
// If the [System.TimeTravelClock] is nil, this is a no-op.
func (sys *System) AdvanceTime(d time.Duration) {
......@@ -566,11 +614,11 @@ func (cfg SystemConfig) Start(t *testing.T, _opts ...SystemConfigOption) (*Syste
// Initialize nodes
l1Node, l1Backend, err := geth.InitL1(cfg.DeployConfig.L1ChainID, cfg.DeployConfig.L1BlockTime, l1Genesis, c,
path.Join(cfg.BlobsPath, "l1_el"), bcn, cfg.GethOptions["l1"]...)
path.Join(cfg.BlobsPath, "l1_el"), bcn, cfg.GethOptions[RoleL1]...)
if err != nil {
return nil, err
}
sys.EthInstances["l1"] = &GethInstance{
sys.EthInstances[RoleL1] = &GethInstance{
Backend: l1Backend,
Node: l1Node,
}
......@@ -613,7 +661,7 @@ func (cfg SystemConfig) Start(t *testing.T, _opts ...SystemConfigOption) (*Syste
// TODO: refactor testing to allow use of in-process rpc connections instead
// of only websockets (which are required for external eth client tests).
for name, nodeCfg := range cfg.Nodes {
configureL1(nodeCfg, sys.EthInstances["l1"])
configureL1(nodeCfg, sys.EthInstances[RoleL1], sys.L1BeaconEndpoint())
configureL2(nodeCfg, sys.EthInstances[name], cfg.JWTSecret)
if sys.RollupConfig.EcotoneTime != nil {
nodeCfg.Beacon = &rollupNode.L1BeaconEndpointConfig{BeaconAddr: sys.L1BeaconAPIAddr}
......@@ -629,8 +677,8 @@ func (cfg SystemConfig) Start(t *testing.T, _opts ...SystemConfigOption) (*Syste
}
rawL1Client := rpc.DialInProc(l1Srv)
l1Client := ethclient.NewClient(rawL1Client)
sys.Clients["l1"] = l1Client
sys.RawClients["l1"] = rawL1Client
sys.Clients[RoleL1] = l1Client
sys.RawClients[RoleL1] = rawL1Client
for name, ethInst := range sys.EthInstances {
rawClient, err := rpc.DialContext(ctx, ethInst.WSEndpoint())
if err != nil {
......@@ -772,7 +820,7 @@ func (cfg SystemConfig) Start(t *testing.T, _opts ...SystemConfigOption) (*Syste
}
// Don't start batch submitter and proposer if there's no sequencer.
if sys.RollupNodes["sequencer"] == nil {
if sys.RollupNodes[RoleSeq] == nil {
return sys, nil
}
......@@ -780,13 +828,13 @@ func (cfg SystemConfig) Start(t *testing.T, _opts ...SystemConfigOption) (*Syste
var proposerCLIConfig *l2os.CLIConfig
if e2eutils.UseFaultProofs() {
proposerCLIConfig = &l2os.CLIConfig{
L1EthRpc: sys.EthInstances["l1"].WSEndpoint(),
RollupRpc: sys.RollupNodes["sequencer"].HTTPEndpoint(),
L1EthRpc: sys.EthInstances[RoleL1].WSEndpoint(),
RollupRpc: sys.RollupNodes[RoleSeq].HTTPEndpoint(),
DGFAddress: config.L1Deployments.DisputeGameFactoryProxy.Hex(),
ProposalInterval: 6 * time.Second,
DisputeGameType: 254, // Fast game type
PollInterval: 50 * time.Millisecond,
TxMgrConfig: newTxMgrConfig(sys.EthInstances["l1"].WSEndpoint(), cfg.Secrets.Proposer),
TxMgrConfig: newTxMgrConfig(sys.EthInstances[RoleL1].WSEndpoint(), cfg.Secrets.Proposer),
AllowNonFinalized: cfg.NonFinalizedProposals,
LogConfig: oplog.CLIConfig{
Level: log.LvlInfo,
......@@ -795,11 +843,11 @@ func (cfg SystemConfig) Start(t *testing.T, _opts ...SystemConfigOption) (*Syste
}
} else {
proposerCLIConfig = &l2os.CLIConfig{
L1EthRpc: sys.EthInstances["l1"].WSEndpoint(),
RollupRpc: sys.RollupNodes["sequencer"].HTTPEndpoint(),
L1EthRpc: sys.EthInstances[RoleL1].WSEndpoint(),
RollupRpc: sys.RollupNodes[RoleSeq].HTTPEndpoint(),
L2OOAddress: config.L1Deployments.L2OutputOracleProxy.Hex(),
PollInterval: 50 * time.Millisecond,
TxMgrConfig: newTxMgrConfig(sys.EthInstances["l1"].WSEndpoint(), cfg.Secrets.Proposer),
TxMgrConfig: newTxMgrConfig(sys.EthInstances[RoleL1].WSEndpoint(), cfg.Secrets.Proposer),
AllowNonFinalized: cfg.NonFinalizedProposals,
LogConfig: oplog.CLIConfig{
Level: log.LvlInfo,
......@@ -837,9 +885,9 @@ func (cfg SystemConfig) Start(t *testing.T, _opts ...SystemConfigOption) (*Syste
}
batcherCLIConfig := &bss.CLIConfig{
L1EthRpc: sys.EthInstances["l1"].WSEndpoint(),
L2EthRpc: sys.EthInstances["sequencer"].WSEndpoint(),
RollupRpc: sys.RollupNodes["sequencer"].HTTPEndpoint(),
L1EthRpc: sys.EthInstances[RoleL1].WSEndpoint(),
L2EthRpc: sys.EthInstances[RoleSeq].WSEndpoint(),
RollupRpc: sys.RollupNodes[RoleSeq].HTTPEndpoint(),
MaxPendingTransactions: cfg.MaxPendingTransactions,
MaxChannelDuration: 1,
MaxL1TxSize: batcherMaxL1TxSizeBytes,
......@@ -848,7 +896,7 @@ func (cfg SystemConfig) Start(t *testing.T, _opts ...SystemConfigOption) (*Syste
ApproxComprRatio: 0.4,
SubSafetyMargin: 4,
PollInterval: 50 * time.Millisecond,
TxMgrConfig: newTxMgrConfig(sys.EthInstances["l1"].WSEndpoint(), cfg.Secrets.Batcher),
TxMgrConfig: newTxMgrConfig(sys.EthInstances[RoleL1].WSEndpoint(), cfg.Secrets.Batcher),
LogConfig: oplog.CLIConfig{
Level: log.LevelInfo,
Format: oplog.FormatText,
......@@ -919,7 +967,20 @@ func (sys *System) newMockNetPeer() (host.Host, error) {
}
func (sys *System) BatcherHelper() *batcher.Helper {
return batcher.NewHelper(sys.t, sys.Cfg.Secrets.Batcher, sys.RollupConfig, sys.NodeClient("l1"))
return batcher.NewHelper(sys.t, sys.Cfg.Secrets.Batcher, sys.RollupConfig, sys.NodeClient(RoleL1))
}
func (sys *System) TestAccount(idx int) *ecdsa.PrivateKey {
switch idx {
case 0:
return sys.Cfg.Secrets.Alice
case 1:
return sys.Cfg.Secrets.Bob
case 2:
return sys.Cfg.Secrets.Mallory
default:
panic(fmt.Sprintf("System: no test account for index %d", idx))
}
}
func UseHTTP() bool {
......@@ -934,7 +995,7 @@ func selectEndpoint(node EthInstance) string {
return node.WSEndpoint()
}
func configureL1(rollupNodeCfg *rollupNode.Config, l1Node EthInstance) {
func configureL1(rollupNodeCfg *rollupNode.Config, l1Node EthInstance, beaconEndpoint string) {
l1EndpointConfig := selectEndpoint(l1Node)
rollupNodeCfg.L1 = &rollupNode.L1EndpointConfig{
L1NodeAddr: l1EndpointConfig,
......@@ -945,6 +1006,9 @@ func configureL1(rollupNodeCfg *rollupNode.Config, l1Node EthInstance) {
HttpPollInterval: time.Millisecond * 100,
MaxConcurrency: 10,
}
rollupNodeCfg.Beacon = &rollupNode.L1BeaconEndpointConfig{
BeaconAddr: beaconEndpoint,
}
}
type WSOrHTTPEndpoint interface {
......
......@@ -33,7 +33,6 @@ import (
"github.com/ethereum-optimism/optimism/op-e2e/bindings"
"github.com/ethereum-optimism/optimism/op-e2e/config"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/geth"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/transactions"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait"
......@@ -225,8 +224,7 @@ func TestSystemE2EDencunAtGenesis(t *testing.T) {
InitParallel(t)
cfg := DefaultSystemConfig(t)
genesisActivation := hexutil.Uint64(0)
cfg.DeployConfig.L1CancunTimeOffset = &genesisActivation
cfg.DeployConfig.L1CancunTimeOffset = &genesisTime
sys, err := cfg.Start(t)
require.Nil(t, err, "Error starting up system")
......@@ -245,9 +243,7 @@ func TestSystemE2EDencunAtGenesisWithBlobs(t *testing.T) {
InitParallel(t)
cfg := DefaultSystemConfig(t)
// cancun is on from genesis:
genesisActivation := hexutil.Uint64(0)
cfg.DeployConfig.L1CancunTimeOffset = &genesisActivation // i.e. turn cancun on at genesis time + 0
cfg.DeployConfig.L1CancunTimeOffset = &genesisTime
sys, err := cfg.Start(t)
require.Nil(t, err, "Error starting up system")
......@@ -795,7 +791,7 @@ func TestSystemP2PAltSync(t *testing.T) {
},
},
}
configureL1(syncNodeCfg, sys.EthInstances["l1"])
configureL1(syncNodeCfg, sys.EthInstances["l1"], sys.L1BeaconEndpoint())
syncerL2Engine, _, err := geth.InitL2("syncer", big.NewInt(int64(cfg.DeployConfig.L2ChainID)), sys.L2GenesisCfg, cfg.JWTFilePath)
require.NoError(t, err)
require.NoError(t, syncerL2Engine.Start())
......@@ -1041,17 +1037,6 @@ func TestL1InfoContract(t *testing.T) {
checkInfoList("On verifier with state", l1InfosFromVerifierState)
}
// calcGasFees determines the actual cost of the transaction given a specific base fee
// This does not include the L1 data fee charged from L2 transactions.
func calcGasFees(gasUsed uint64, gasTipCap *big.Int, gasFeeCap *big.Int, baseFee *big.Int) *big.Int {
x := new(big.Int).Add(gasTipCap, baseFee)
// If tip + basefee > gas fee cap, clamp it to the gas fee cap
if x.Cmp(gasFeeCap) > 0 {
x = gasFeeCap
}
return x.Mul(x, new(big.Int).SetUint64(gasUsed))
}
// TestWithdrawals checks that a deposit and then withdrawal execution succeeds. It verifies the
// balance changes on L1 and L2 and has to include gas fees in the balance checks.
// It does not check that the withdrawal can be executed prior to the end of the finality period.
......@@ -1062,103 +1047,10 @@ func TestWithdrawals(t *testing.T) {
cfg.DeployConfig.FinalizationPeriodSeconds = 2 // 2s finalization period
sys, err := cfg.Start(t)
require.Nil(t, err, "Error starting up system")
require.NoError(t, err, "Error starting up system")
defer sys.Close()
l1Client := sys.Clients["l1"]
l2Seq := sys.Clients["sequencer"]
l2Verif := sys.Clients["verifier"]
// Transactor Account
ethPrivKey := cfg.Secrets.Alice
fromAddr := crypto.PubkeyToAddress(ethPrivKey.PublicKey)
// Create L1 signer
opts, err := bind.NewKeyedTransactorWithChainID(ethPrivKey, cfg.L1ChainIDBig())
require.Nil(t, err)
// Start L2 balance
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
startBalanceBeforeDeposit, err := l2Verif.BalanceAt(ctx, fromAddr, nil)
require.Nil(t, err)
// Send deposit tx
mintAmount := big.NewInt(1_000_000_000_000)
opts.Value = mintAmount
SendDepositTx(t, cfg, l1Client, l2Verif, opts, func(l2Opts *DepositTxOpts) {
l2Opts.Value = common.Big0
})
// Confirm L2 balance
ctx, cancel = context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
endBalanceAfterDeposit, err := wait.ForBalanceChange(ctx, l2Verif, fromAddr, startBalanceBeforeDeposit)
require.Nil(t, err)
diff := new(big.Int)
diff = diff.Sub(endBalanceAfterDeposit, startBalanceBeforeDeposit)
require.Equal(t, mintAmount, diff, "Did not get expected balance change after mint")
// Start L2 balance for withdrawal
ctx, cancel = context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
startBalanceBeforeWithdrawal, err := l2Seq.BalanceAt(ctx, fromAddr, nil)
require.Nil(t, err)
withdrawAmount := big.NewInt(500_000_000_000)
tx, receipt := SendWithdrawal(t, cfg, l2Seq, ethPrivKey, func(opts *WithdrawalTxOpts) {
opts.Value = withdrawAmount
opts.VerifyOnClients(l2Verif)
})
// Verify L2 balance after withdrawal
ctx, cancel = context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
header, err := l2Verif.HeaderByNumber(ctx, receipt.BlockNumber)
require.Nil(t, err)
ctx, cancel = context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
endBalanceAfterWithdrawal, err := wait.ForBalanceChange(ctx, l2Seq, fromAddr, startBalanceBeforeWithdrawal)
require.Nil(t, err)
// Take fee into account
diff = new(big.Int).Sub(startBalanceBeforeWithdrawal, endBalanceAfterWithdrawal)
fees := calcGasFees(receipt.GasUsed, tx.GasTipCap(), tx.GasFeeCap(), header.BaseFee)
fees = fees.Add(fees, receipt.L1Fee)
diff = diff.Sub(diff, fees)
require.Equal(t, withdrawAmount, diff)
// Take start balance on L1
ctx, cancel = context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
startBalanceBeforeFinalize, err := l1Client.BalanceAt(ctx, fromAddr, nil)
require.Nil(t, err)
proveReceipt, finalizeReceipt, resolveClaimReceipt, resolveReceipt := ProveAndFinalizeWithdrawal(t, cfg, sys, "verifier", ethPrivKey, receipt)
// Verify balance after withdrawal
ctx, cancel = context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
endBalanceAfterFinalize, err := wait.ForBalanceChange(ctx, l1Client, fromAddr, startBalanceBeforeFinalize)
require.Nil(t, err)
// Ensure that withdrawal - gas fees are added to the L1 balance
// Fun fact, the fee is greater than the withdrawal amount
// NOTE: The gas fees include *both* the ProveWithdrawalTransaction and FinalizeWithdrawalTransaction transactions.
diff = new(big.Int).Sub(endBalanceAfterFinalize, startBalanceBeforeFinalize)
proveFee := new(big.Int).Mul(new(big.Int).SetUint64(proveReceipt.GasUsed), proveReceipt.EffectiveGasPrice)
finalizeFee := new(big.Int).Mul(new(big.Int).SetUint64(finalizeReceipt.GasUsed), finalizeReceipt.EffectiveGasPrice)
fees = new(big.Int).Add(proveFee, finalizeFee)
if e2eutils.UseFaultProofs() {
resolveClaimFee := new(big.Int).Mul(new(big.Int).SetUint64(resolveClaimReceipt.GasUsed), resolveClaimReceipt.EffectiveGasPrice)
resolveFee := new(big.Int).Mul(new(big.Int).SetUint64(resolveReceipt.GasUsed), resolveReceipt.EffectiveGasPrice)
fees = new(big.Int).Add(fees, resolveClaimFee)
fees = new(big.Int).Add(fees, resolveFee)
}
withdrawAmount = withdrawAmount.Sub(withdrawAmount, fees)
require.Equal(t, withdrawAmount, diff)
RunWithdrawalsTest(t, sys)
}
type stateGetterAdapter struct {
......@@ -1181,35 +1073,23 @@ func (sga *stateGetterAdapter) GetState(addr common.Address, key common.Hash) co
func TestFees(t *testing.T) {
t.Run("pre-regolith", func(t *testing.T) {
InitParallel(t)
cfg := DefaultSystemConfig(t)
cfg := RegolithSystemConfig(t, nil)
cfg.DeployConfig.L1GenesisBlockBaseFeePerGas = (*hexutil.Big)(big.NewInt(7))
cfg.DeployConfig.L2GenesisRegolithTimeOffset = nil
cfg.DeployConfig.L2GenesisCanyonTimeOffset = nil
cfg.DeployConfig.L2GenesisDeltaTimeOffset = nil
cfg.DeployConfig.L2GenesisEcotoneTimeOffset = nil
testFees(t, cfg)
})
t.Run("regolith", func(t *testing.T) {
InitParallel(t)
cfg := DefaultSystemConfig(t)
cfg := RegolithSystemConfig(t, &genesisTime)
cfg.DeployConfig.L1GenesisBlockBaseFeePerGas = (*hexutil.Big)(big.NewInt(7))
cfg.DeployConfig.L2GenesisRegolithTimeOffset = new(hexutil.Uint64)
cfg.DeployConfig.L2GenesisCanyonTimeOffset = nil
cfg.DeployConfig.L2GenesisDeltaTimeOffset = nil
cfg.DeployConfig.L2GenesisEcotoneTimeOffset = nil
testFees(t, cfg)
})
t.Run("ecotone", func(t *testing.T) {
InitParallel(t)
cfg := DefaultSystemConfig(t)
cfg := EcotoneSystemConfig(t, &genesisTime)
cfg.DeployConfig.L1GenesisBlockBaseFeePerGas = (*hexutil.Big)(big.NewInt(7))
cfg.DeployConfig.L2GenesisRegolithTimeOffset = new(hexutil.Uint64)
cfg.DeployConfig.L2GenesisCanyonTimeOffset = new(hexutil.Uint64)
cfg.DeployConfig.L2GenesisDeltaTimeOffset = new(hexutil.Uint64)
cfg.DeployConfig.L2GenesisEcotoneTimeOffset = new(hexutil.Uint64)
testFees(t, cfg)
})
t.Run("fjord", func(t *testing.T) {
......@@ -1414,8 +1294,7 @@ func testFees(t *testing.T, cfg SystemConfig) {
func StopStartBatcher(t *testing.T, deltaTimeOffset *hexutil.Uint64) {
InitParallel(t)
cfg := DefaultSystemConfig(t)
cfg.DeployConfig.L2GenesisDeltaTimeOffset = deltaTimeOffset
cfg := DeltaSystemConfig(t, deltaTimeOffset)
sys, err := cfg.Start(t)
require.NoError(t, err, "Error starting up system")
defer sys.Close()
......
......@@ -30,7 +30,7 @@ func SendDepositTx(t *testing.T, cfg SystemConfig, l1Client *ethclient.Client, l
// Find deposit contract
depositContract, err := bindings.NewOptimismPortal(cfg.L1Deployments.OptimismPortalProxy, l1Client)
require.Nil(t, err)
require.NoError(t, err)
// Finally send TX
// Add 10% padding for the L1 gas limit because the estimation process can be affected by the 1559 style cost scale
......@@ -38,13 +38,15 @@ func SendDepositTx(t *testing.T, cfg SystemConfig, l1Client *ethclient.Client, l
tx, err := transactions.PadGasEstimate(l1Opts, 1.1, func(opts *bind.TransactOpts) (*types.Transaction, error) {
return depositContract.DepositTransaction(opts, l2Opts.ToAddr, l2Opts.Value, l2Opts.GasLimit, l2Opts.IsCreation, l2Opts.Data)
})
require.Nil(t, err, "with deposit tx")
require.NoError(t, err, "with deposit tx")
t.Logf("SendDepositTx: transaction sent: %v", tx.Hash())
// Wait for transaction on L1
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
l1Receipt, err := wait.ForReceiptOK(ctx, l1Client, tx.Hash())
require.Nil(t, err, "Waiting for deposit tx on L1")
require.NoError(t, err, "Waiting for deposit tx on L1")
t.Logf("SendDepositTx: included on L1")
// Wait for transaction to be included on L2
reconstructedDep, err := derive.UnmarshalDepositLogEvent(l1Receipt.Logs[0])
......@@ -52,6 +54,7 @@ func SendDepositTx(t *testing.T, cfg SystemConfig, l1Client *ethclient.Client, l
tx = types.NewTx(reconstructedDep)
l2Receipt, err := wait.ForReceipt(ctx, l2Client, tx.Hash(), l2Opts.ExpectedStatus)
require.NoError(t, err, "Waiting for deposit tx on L2")
t.Logf("SendDepositTx: arrived on L2")
return l2Receipt
}
......@@ -144,3 +147,14 @@ func defaultTxOpts() *TxOpts {
ExpectedStatus: types.ReceiptStatusSuccessful,
}
}
// calcGasFees determines the actual cost of the transaction given a specific base fee
// This does not include the L1 data fee charged from L2 transactions.
func calcGasFees(gasUsed uint64, gasTipCap *big.Int, gasFeeCap *big.Int, baseFee *big.Int) *big.Int {
x := new(big.Int).Add(gasTipCap, baseFee)
// If tip + basefee > gas fee cap, clamp it to the gas fee cap
if x.Cmp(gasFeeCap) > 0 {
x = gasFeeCap
}
return x.Mul(x, new(big.Int).SetUint64(gasUsed))
}
package op_e2e
import (
"context"
"crypto/ecdsa"
"math/big"
"testing"
"time"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/stretchr/testify/require"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait"
"github.com/ethereum-optimism/optimism/op-service/sources"
)
type CommonSystem interface {
NodeClient(role string) *ethclient.Client
RollupClient(role string) *sources.RollupClient
Config() SystemConfig
TestAccount(int) *ecdsa.PrivateKey
}
// TestWithdrawals checks that a deposit and then withdrawal execution succeeds. It verifies the
// balance changes on L1 and L2 and has to include gas fees in the balance checks.
// It does not check that the withdrawal can be executed prior to the end of the finality period.
func RunWithdrawalsTest(t *testing.T, sys CommonSystem) {
t.Logf("WithdrawalsTest: running with FP == %t", e2eutils.UseFaultProofs())
cfg := sys.Config()
l1Client := sys.NodeClient(RoleL1)
l2Seq := sys.NodeClient(RoleSeq)
l2Verif := sys.NodeClient(RoleVerif)
// Transactor Account
ethPrivKey := sys.TestAccount(0)
fromAddr := crypto.PubkeyToAddress(ethPrivKey.PublicKey)
// Create L1 signer
opts, err := bind.NewKeyedTransactorWithChainID(ethPrivKey, cfg.L1ChainIDBig())
require.NoError(t, err)
// Start L2 balance
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
startBalanceBeforeDeposit, err := l2Verif.BalanceAt(ctx, fromAddr, nil)
require.NoError(t, err)
// Send deposit tx
mintAmount := big.NewInt(1_000_000_000_000)
opts.Value = mintAmount
t.Logf("WithdrawalsTest: depositing %v with L2 start balance %v...", mintAmount, startBalanceBeforeDeposit)
SendDepositTx(t, cfg, l1Client, l2Verif, opts, func(l2Opts *DepositTxOpts) {
l2Opts.Value = common.Big0
})
t.Log("WithdrawalsTest: waiting for balance change...")
// Confirm L2 balance
ctx, cancel = context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
endBalanceAfterDeposit, err := wait.ForBalanceChange(ctx, l2Verif, fromAddr, startBalanceBeforeDeposit)
require.NoError(t, err)
diff := new(big.Int)
diff = diff.Sub(endBalanceAfterDeposit, startBalanceBeforeDeposit)
require.Equal(t, mintAmount, diff, "Did not get expected balance change after mint")
// Start L2 balance for withdrawal
ctx, cancel = context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
startBalanceBeforeWithdrawal, err := l2Seq.BalanceAt(ctx, fromAddr, nil)
require.NoError(t, err)
withdrawAmount := big.NewInt(500_000_000_000)
t.Logf("WithdrawalsTest: sending L2 withdrawal for %v...", withdrawAmount)
tx, receipt := SendWithdrawal(t, cfg, l2Seq, ethPrivKey, func(opts *WithdrawalTxOpts) {
opts.Value = withdrawAmount
opts.VerifyOnClients(l2Verif)
})
// Verify L2 balance after withdrawal
ctx, cancel = context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
header, err := l2Verif.HeaderByNumber(ctx, receipt.BlockNumber)
require.NoError(t, err)
ctx, cancel = context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
t.Log("WithdrawalsTest: waiting for L2 balance change...")
endBalanceAfterWithdrawal, err := wait.ForBalanceChange(ctx, l2Seq, fromAddr, startBalanceBeforeWithdrawal)
require.NoError(t, err)
// Take fee into account
diff = new(big.Int).Sub(startBalanceBeforeWithdrawal, endBalanceAfterWithdrawal)
fees := calcGasFees(receipt.GasUsed, tx.GasTipCap(), tx.GasFeeCap(), header.BaseFee)
fees = fees.Add(fees, receipt.L1Fee)
diff = diff.Sub(diff, fees)
require.Equal(t, withdrawAmount, diff)
// Take start balance on L1
ctx, cancel = context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
startBalanceBeforeFinalize, err := l1Client.BalanceAt(ctx, fromAddr, nil)
require.NoError(t, err)
t.Log("WithdrawalsTest: ProveAndFinalizeWithdrawal...")
proveReceipt, finalizeReceipt, resolveClaimReceipt, resolveReceipt := ProveAndFinalizeWithdrawal(t, cfg, sys, RoleVerif, ethPrivKey, receipt)
// Verify balance after withdrawal
ctx, cancel = context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
t.Log("WithdrawalsTest: waiting for L1 balance change...")
endBalanceAfterFinalize, err := wait.ForBalanceChange(ctx, l1Client, fromAddr, startBalanceBeforeFinalize)
require.NoError(t, err)
t.Logf("WithdrawalsTest: L1 balance changed from %v to %v", startBalanceBeforeFinalize, endBalanceAfterFinalize)
// Ensure that withdrawal - gas fees are added to the L1 balance
// Fun fact, the fee is greater than the withdrawal amount
// NOTE: The gas fees include *both* the ProveWithdrawalTransaction and FinalizeWithdrawalTransaction transactions.
diff = new(big.Int).Sub(endBalanceAfterFinalize, startBalanceBeforeFinalize)
proveFee := new(big.Int).Mul(new(big.Int).SetUint64(proveReceipt.GasUsed), proveReceipt.EffectiveGasPrice)
finalizeFee := new(big.Int).Mul(new(big.Int).SetUint64(finalizeReceipt.GasUsed), finalizeReceipt.EffectiveGasPrice)
fees = new(big.Int).Add(proveFee, finalizeFee)
if e2eutils.UseFaultProofs() {
resolveClaimFee := new(big.Int).Mul(new(big.Int).SetUint64(resolveClaimReceipt.GasUsed), resolveClaimReceipt.EffectiveGasPrice)
resolveFee := new(big.Int).Mul(new(big.Int).SetUint64(resolveReceipt.GasUsed), resolveReceipt.EffectiveGasPrice)
fees = new(big.Int).Add(fees, resolveClaimFee)
fees = new(big.Int).Add(fees, resolveFee)
}
withdrawAmount = withdrawAmount.Sub(withdrawAmount, fees)
require.Equal(t, withdrawAmount, diff)
}
......@@ -3,6 +3,7 @@ package op_e2e
import (
"context"
"crypto/ecdsa"
"errors"
"math/big"
"testing"
"time"
......@@ -10,6 +11,8 @@ import (
"github.com/ethereum-optimism/optimism/op-chain-ops/crossdomain"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts/metrics"
gameTypes "github.com/ethereum-optimism/optimism/op-challenger/game/types"
"github.com/ethereum-optimism/optimism/op-e2e/config"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/geth"
......@@ -28,6 +31,8 @@ import (
"github.com/stretchr/testify/require"
)
const SolErrClaimAlreadyResolved = "0xf1a94581"
type ClientProvider interface {
NodeClient(name string) *ethclient.Client
}
......@@ -100,15 +105,15 @@ func ProveWithdrawal(t *testing.T, cfg SystemConfig, clients ClientProvider, l2N
ctx, cancel := context.WithTimeout(context.Background(), 40*time.Duration(cfg.DeployConfig.L1BlockTime)*time.Second)
defer cancel()
l1Client := clients.NodeClient("l1")
l1Client := clients.NodeClient(RoleL1)
var blockNumber uint64
var err error
if e2eutils.UseFaultProofs() {
blockNumber, err = wait.ForGamePublished(ctx, l1Client, config.L1Deployments.OptimismPortalProxy, config.L1Deployments.DisputeGameFactoryProxy, l2WithdrawalReceipt.BlockNumber)
require.Nil(t, err)
require.NoError(t, err)
} else {
blockNumber, err = wait.ForOutputRootPublished(ctx, l1Client, config.L1Deployments.L2OutputOracleProxy, l2WithdrawalReceipt.BlockNumber)
require.Nil(t, err)
require.NoError(t, err)
}
receiptCl := clients.NodeClient(l2NodeName)
......@@ -119,25 +124,25 @@ func ProveWithdrawal(t *testing.T, cfg SystemConfig, clients ClientProvider, l2N
defer cancel()
// Get the latest header
header, err := receiptCl.HeaderByNumber(ctx, new(big.Int).SetUint64(blockNumber))
require.Nil(t, err)
require.NoError(t, err)
oracle, err := bindings.NewL2OutputOracleCaller(config.L1Deployments.L2OutputOracleProxy, l1Client)
require.Nil(t, err)
require.NoError(t, err)
factory, err := bindings.NewDisputeGameFactoryCaller(config.L1Deployments.DisputeGameFactoryProxy, l1Client)
require.Nil(t, err)
require.NoError(t, err)
portal2, err := bindingspreview.NewOptimismPortal2Caller(config.L1Deployments.OptimismPortalProxy, l1Client)
require.Nil(t, err)
require.NoError(t, err)
params, err := ProveWithdrawalParameters(context.Background(), proofCl, receiptCl, blockCl, l2WithdrawalReceipt.TxHash, header, oracle, factory, portal2)
require.Nil(t, err)
require.NoError(t, err)
portal, err := bindings.NewOptimismPortal(config.L1Deployments.OptimismPortalProxy, l1Client)
require.Nil(t, err)
require.NoError(t, err)
opts, err := bind.NewKeyedTransactorWithChainID(ethPrivKey, cfg.L1ChainIDBig())
require.Nil(t, err)
require.NoError(t, err)
// Prove withdrawal
tx, err := portal.ProveWithdrawalTransaction(
......@@ -154,11 +159,11 @@ func ProveWithdrawal(t *testing.T, cfg SystemConfig, clients ClientProvider, l2N
params.OutputRootProof,
params.WithdrawalProof,
)
require.Nil(t, err)
require.NoError(t, err)
// Ensure that our withdrawal was proved successfully
proveReceipt, err := geth.WaitForTransaction(tx.Hash(), l1Client, 3*time.Duration(cfg.DeployConfig.L1BlockTime)*time.Second)
require.Nil(t, err, "prove withdrawal")
require.NoError(t, err, "prove withdrawal")
require.Equal(t, types.ReceiptStatusSuccessful, proveReceipt.Status)
return params, proveReceipt
}
......@@ -186,60 +191,81 @@ func FinalizeWithdrawal(t *testing.T, cfg SystemConfig, l1Client *ethclient.Clie
}
opts, err := bind.NewKeyedTransactorWithChainID(privKey, cfg.L1ChainIDBig())
require.Nil(t, err)
require.NoError(t, err)
var resolveClaimReceipt *types.Receipt
var resolveReceipt *types.Receipt
if e2eutils.UseFaultProofs() {
portal2, err := bindingspreview.NewOptimismPortal2(config.L1Deployments.OptimismPortalProxy, l1Client)
require.Nil(t, err)
require.NoError(t, err)
wdHash, err := wd.Hash()
require.Nil(t, err)
require.NoError(t, err)
game, err := portal2.ProvenWithdrawals(&bind.CallOpts{}, wdHash, opts.From)
require.Nil(t, err)
require.NoError(t, err)
require.NotNil(t, game, "withdrawal should be proven")
caller := batching.NewMultiCaller(l1Client.Client(), batching.DefaultBatchSize)
gameContract, err := contracts.NewFaultDisputeGameContract(context.Background(), metrics.NoopContractMetrics, game.DisputeGameProxy, caller)
require.Nil(t, err)
require.NoError(t, err)
timedCtx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
require.NoError(t, wait.For(timedCtx, time.Second, func() (bool, error) {
err := gameContract.CallResolveClaim(context.Background(), 0)
if err != nil {
t.Logf("Could not resolve dispute game claim: %v", err)
}
return err == nil, nil
}))
t.Log("FinalizeWithdrawal: resolveClaim...")
tx, err := gameContract.ResolveClaimTx(0)
require.NoError(t, err, "create resolveClaim tx")
_, resolveClaimReceipt = transactions.RequireSendTx(t, ctx, l1Client, tx, privKey)
_, resolveClaimReceipt, err = transactions.SendTx(ctx, l1Client, tx, privKey)
var rsErr *wait.ReceiptStatusError
if errors.As(err, &rsErr) && rsErr.TxTrace.Output.String() == SolErrClaimAlreadyResolved {
t.Logf("resolveClaim failed (tx: %s) because claim got already resolved", resolveClaimReceipt.TxHash)
} else {
require.NoError(t, err)
}
t.Log("FinalizeWithdrawal: resolve...")
tx, err = gameContract.ResolveTx()
require.NoError(t, err, "create resolve tx")
_, resolveReceipt = transactions.RequireSendTx(t, ctx, l1Client, tx, privKey)
_, resolveReceipt = transactions.RequireSendTx(t, ctx, l1Client, tx, privKey, transactions.WithReceiptStatusIgnore())
if resolveReceipt.Status == types.ReceiptStatusFailed {
t.Logf("resolve failed (tx: %s)! But game may have resolved already. Checking now...", resolveReceipt.TxHash)
// it may have failed because someone else front-ran this by calling `resolve()` first.
status, err := gameContract.GetStatus(ctx)
require.NoError(t, err)
require.Equal(t, gameTypes.GameStatusDefenderWon, status, "game must have resolved with defender won")
t.Logf("resolve was not needed, the game was already resolved")
}
}
if e2eutils.UseFaultProofs() {
t.Log("FinalizeWithdrawal: waiting for successful withdrawal check...")
err := wait.ForWithdrawalCheck(ctx, l1Client, wd, config.L1Deployments.OptimismPortalProxy, opts.From)
require.Nil(t, err)
require.NoError(t, err)
} else {
t.Log("FinalizeWithdrawal: waiting for finalization...")
err := wait.ForFinalizationPeriod(ctx, l1Client, withdrawalProofReceipt.BlockNumber, config.L1Deployments.L2OutputOracleProxy)
require.Nil(t, err)
require.NoError(t, err)
}
portal, err := bindings.NewOptimismPortal(config.L1Deployments.OptimismPortalProxy, l1Client)
require.Nil(t, err)
require.NoError(t, err)
// Finalize withdrawal
t.Log("FinalizeWithdrawal: finalizing withdrawal...")
tx, err := portal.FinalizeWithdrawalTransaction(opts, wd.WithdrawalTransaction())
require.Nil(t, err)
require.NoError(t, err)
// Ensure that our withdrawal was finalized successfully
finalizeReceipt, err := wait.ForReceiptOK(ctx, l1Client, tx.Hash())
require.Nil(t, err, "finalize withdrawal")
require.NoError(t, err, "finalize withdrawal")
require.Equal(t, types.ReceiptStatusSuccessful, finalizeReceipt.Status)
return finalizeReceipt, resolveClaimReceipt, resolveReceipt
}
package genesis
import (
"context"
"errors"
"fmt"
"time"
"github.com/ethereum-optimism/optimism/op-service/retry"
"github.com/ethereum-optimism/optimism/op-service/sources/batching"
"github.com/urfave/cli/v2"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/log"
......@@ -77,7 +79,6 @@ var Subcommands = cli.Commands{
Usage: "Generates a L1 genesis state file",
Flags: l1Flags,
Action: func(ctx *cli.Context) error {
deployConfig := ctx.String(deployConfigFlag.Name)
config, err := genesis.NewDeployConfig(deployConfig)
if err != nil {
......@@ -165,15 +166,16 @@ var Subcommands = cli.Commands{
caller := batching.NewMultiCaller(client.Client(), batching.DefaultBatchSize)
sysCfg := NewSystemConfigContract(caller, config.SystemConfigProxy)
startBlock, err := sysCfg.StartBlock(context.Background())
startBlock, err := sysCfg.StartBlock(ctx.Context)
if err != nil {
return fmt.Errorf("failed to fetch startBlock from SystemConfig: %w", err)
}
log.Info("Using L1 Start Block", "number", startBlock)
l1StartBlock, err := client.BlockByNumber(context.Background(), startBlock)
// retry because local devnet can experience a race condition where L1 geth isn't ready yet
l1StartBlock, err := retry.Do(ctx.Context, 24, retry.Fixed(1*time.Second), func() (*types.Block, error) { return client.BlockByNumber(ctx.Context, startBlock) })
if err != nil {
return fmt.Errorf("cannot fetch block by number: %w", err)
return fmt.Errorf("fetching start block by number: %w", err)
}
log.Info("Fetched L1 Start Block", "hash", l1StartBlock.Hash().Hex())
......
......@@ -27,6 +27,7 @@ func (c ErrorCode) IsEngineError() bool {
// Engine error codes used to be -3200x, but were rebased to -3800x:
// https://github.com/ethereum/execution-apis/pull/214
const (
InvalidParams ErrorCode = -32602
UnknownPayload ErrorCode = -38001 // Payload does not exist / is not available.
InvalidForkchoiceState ErrorCode = -38002 // Forkchoice state is invalid / inconsistent.
InvalidPayloadAttributes ErrorCode = -38003 // Payload attributes are invalid / inconsistent.
......
......@@ -13,4 +13,5 @@ var (
EIP4788ContractAddr = common.HexToAddress("0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02")
EIP4788ContractCode = common.FromHex("0x3373fffffffffffffffffffffffffffffffffffffffe14604d57602036146024575f5ffd5b5f35801560495762001fff810690815414603c575f5ffd5b62001fff01545f5260205ff35b5f5ffd5b62001fff42064281555f359062001fff015500")
EIP4788ContractCodeHash = common.HexToHash("0xf57acd40259872606d76197ef052f3d35588dadf919ee1f0e3cb9b62d3f4b02c")
EIP4788ContractDeployer = common.HexToAddress("0x0B799C86a49DEeb90402691F1041aa3AF2d3C875")
)
......@@ -100,7 +100,7 @@ func (s *EngineAPIClient) ForkchoiceUpdate(ctx context.Context, fc *eth.Forkchoi
if rpcErr, ok := err.(rpc.Error); ok {
code := eth.ErrorCode(rpcErr.ErrorCode())
switch code {
case eth.InvalidForkchoiceState, eth.InvalidPayloadAttributes:
case eth.InvalidParams, eth.InvalidForkchoiceState, eth.InvalidPayloadAttributes:
return nil, eth.InputError{
Inner: err,
Code: code,
......
data:
eth2-val-tools keystores --source-min=0 --source-max=64 \
--source-mnemonic="test test test test test test test test test test test junk" --out-loc=data && \
rm -rf data/lodestar-secrets data/nimbus-keys data/prysm data/teku-keys data/teku-secrets
# Minimal config
# Extends the minimal preset
PRESET_BASE: 'minimal'
# Free-form short name of the network that this configuration applies to - known
# canonical network names include:
# * 'mainnet' - there can be only one
# * 'prater' - testnet
# Must match the regex: [a-z0-9\-]
CONFIG_NAME: 'minimal'
# Transition
# ---------------------------------------------------------------
# 2**256-2**10 for testing minimal network
TERMINAL_TOTAL_DIFFICULTY: 115792089237316195423570985008687907853269984665640564039457584007913129638912
# By default, don't use these params
TERMINAL_BLOCK_HASH: 0x0000000000000000000000000000000000000000000000000000000000000000
TERMINAL_BLOCK_HASH_ACTIVATION_EPOCH: 18446744073709551615
# Genesis
# ---------------------------------------------------------------
# [customized]
MIN_GENESIS_ACTIVE_VALIDATOR_COUNT: 64
# Jan 3, 2020
MIN_GENESIS_TIME: 1578009600
# Highest byte set to 0xFF, this is dev network
GENESIS_FORK_VERSION: 0x000000FF
# [customized] don't wait with genesis if we don't have to
GENESIS_DELAY: 0
# Forking
# ---------------------------------------------------------------
# Values provided for illustrative purposes.
# Individual tests/testnets may set different values.
# Altair
ALTAIR_FORK_VERSION: 0x01000001
ALTAIR_FORK_EPOCH: 0
# Bellatrix
BELLATRIX_FORK_VERSION: 0x02000001
BELLATRIX_FORK_EPOCH: 0
# Capella
CAPELLA_FORK_VERSION: 0x03000001
CAPELLA_FORK_EPOCH: 0
# DENEB
DENEB_FORK_VERSION: 0x04000001
# TODO: activate Deneb at genesis
DENEB_FORK_EPOCH: 1
# EIP6110
EIP6110_FORK_VERSION: 0x05000001
EIP6110_FORK_EPOCH: 18446744073709551615
# EIP7002
EIP7002_FORK_VERSION: 0x05000001
EIP7002_FORK_EPOCH: 18446744073709551615
# WHISK
WHISK_FORK_VERSION: 0x06000001
WHISK_FORK_EPOCH: 18446744073709551615
# Time parameters
# ---------------------------------------------------------------
# [customized] Faster for testing purposes
SECONDS_PER_SLOT: 6
# 14 (estimate from Eth1 mainnet)
SECONDS_PER_ETH1_BLOCK: 14
# 2**8 (= 256) epochs
MIN_VALIDATOR_WITHDRAWABILITY_DELAY: 256
# [customized] higher frequency of committee turnover and faster time to acceptable voluntary exit
SHARD_COMMITTEE_PERIOD: 64
# [customized] process deposits more quickly, but insecure
ETH1_FOLLOW_DISTANCE: 16
# Validator cycle
# ---------------------------------------------------------------
# 2**2 (= 4)
INACTIVITY_SCORE_BIAS: 4
# 2**4 (= 16)
INACTIVITY_SCORE_RECOVERY_RATE: 16
# 2**4 * 10**9 (= 16,000,000,000) Gwei
EJECTION_BALANCE: 16000000000
# [customized] more easily demonstrate the difference between this value and the activation churn limit
MIN_PER_EPOCH_CHURN_LIMIT: 2
# [customized] scale queue churn at much lower validator counts for testing
CHURN_LIMIT_QUOTIENT: 32
# [New in Deneb:EIP7514] [customized]
MAX_PER_EPOCH_ACTIVATION_CHURN_LIMIT: 4
# Fork choice
# ---------------------------------------------------------------
# 40%
PROPOSER_SCORE_BOOST: 40
# 20%
REORG_HEAD_WEIGHT_THRESHOLD: 20
# 160%
REORG_PARENT_WEIGHT_THRESHOLD: 160
# `2` epochs
REORG_MAX_EPOCHS_SINCE_FINALIZATION: 2
# Deposit contract
# ---------------------------------------------------------------
# Local Optimism monorepo devnet
DEPOSIT_CHAIN_ID: 900
DEPOSIT_NETWORK_ID: 900
# Configured on a per testnet basis
DEPOSIT_CONTRACT_ADDRESS: 0x1111111111111111111111111111111111111111
# Networking
# ---------------------------------------------------------------
# `10 * 2**20` (= 10485760, 10 MiB)
GOSSIP_MAX_SIZE: 10485760
# `2**10` (= 1024)
MAX_REQUEST_BLOCKS: 1024
# `2**8` (= 256)
EPOCHS_PER_SUBNET_SUBSCRIPTION: 256
# [customized] `MIN_VALIDATOR_WITHDRAWABILITY_DELAY + CHURN_LIMIT_QUOTIENT // 2` (= 272)
MIN_EPOCHS_FOR_BLOCK_REQUESTS: 272
# `10 * 2**20` (=10485760, 10 MiB)
MAX_CHUNK_SIZE: 10485760
# 5s
TTFB_TIMEOUT: 5
# 10s
RESP_TIMEOUT: 10
ATTESTATION_PROPAGATION_SLOT_RANGE: 32
# 500ms
MAXIMUM_GOSSIP_CLOCK_DISPARITY: 500
MESSAGE_DOMAIN_INVALID_SNAPPY: 0x00000000
MESSAGE_DOMAIN_VALID_SNAPPY: 0x01000000
# 2 subnets per node
SUBNETS_PER_NODE: 2
# 2**8 (= 64)
ATTESTATION_SUBNET_COUNT: 64
ATTESTATION_SUBNET_EXTRA_BITS: 0
# ceillog2(ATTESTATION_SUBNET_COUNT) + ATTESTATION_SUBNET_EXTRA_BITS
ATTESTATION_SUBNET_PREFIX_BITS: 6
# Deneb
# `2**7` (=128)
MAX_REQUEST_BLOCKS_DENEB: 128
# MAX_REQUEST_BLOCKS_DENEB * MAX_BLOBS_PER_BLOCK
MAX_REQUEST_BLOB_SIDECARS: 768
# `2**12` (= 4096 epochs, ~18 days)
MIN_EPOCHS_FOR_BLOB_SIDECARS_REQUESTS: 4096
# `6`
BLOB_SIDECAR_SUBNET_COUNT: 6
{"crypto":{"kdf":{"function":"pbkdf2","params":{"dklen":32,"c":262144,"prf":"hmac-sha256","salt":"4fe22290246afebf4d2b064581ba0cec5853b0e8a1de24b5262e0c82fc265f8e"},"message":""},"checksum":{"function":"sha256","params":{},"message":"3449e5f82bd7470632dbc5d672c09dbe07b0d56e3afda32583c3a57000aebde4"},"cipher":{"function":"aes-128-ctr","params":{"iv":"fa773de4e25f34a4ffa61fcde5bbaa3b"},"message":"2422da8705b02af0124aebcbbc0ef713f051a96f3b0865ea830dd9817e0ff88d"}},"description":"0x82626f97b0fc009c2d2e098e2c3b21922c6525d314552674899953fbb1c4cb48d01966e80167f81b1a36e78e2a6362a9","pubkey":"82626f97b0fc009c2d2e098e2c3b21922c6525d314552674899953fbb1c4cb48d01966e80167f81b1a36e78e2a6362a9","path":"","uuid":"2ddc2811-ec6e-4214-8234-5570e66e063c","version":4}
\ No newline at end of file
{"crypto":{"kdf":{"function":"pbkdf2","params":{"dklen":32,"c":262144,"prf":"hmac-sha256","salt":"06180aad1e6bdce9976df02d9adde20075ec7f1dd0dfe5548931bcc7d20d521d"},"message":""},"checksum":{"function":"sha256","params":{},"message":"1325dcbf0ccf26036061b1023ea16e2a1dce44097cfc2d298b6f5494ffb9183f"},"cipher":{"function":"aes-128-ctr","params":{"iv":"be4f24aa47c00d28d80bbec4a8c10929"},"message":"d0fd7c50df094cbe66d3d4e79f3aa495c184a872846ca3cc1784d4a261de0a5a"}},"description":"0x847cddf22fe1483b2808f08bb98586deba65165fab87d7c60f8081af495c3d9ba234ce61150840ac28d8833f721b08d4","pubkey":"847cddf22fe1483b2808f08bb98586deba65165fab87d7c60f8081af495c3d9ba234ce61150840ac28d8833f721b08d4","path":"","uuid":"1ae91dc4-8908-47f3-bd86-ceb28a69b707","version":4}
\ No newline at end of file
{"crypto":{"kdf":{"function":"pbkdf2","params":{"dklen":32,"c":262144,"prf":"hmac-sha256","salt":"77011468ee55740bd05331195df734a376a29ba77211c8ba8dbf724909eb8a5a"},"message":""},"checksum":{"function":"sha256","params":{},"message":"27f2109b206b5125be011346f5ebb3e616a0be3e44e425a6a6caf34238f31138"},"cipher":{"function":"aes-128-ctr","params":{"iv":"2b695bf8e39b9537dd8033e3b63e4c83"},"message":"00f4282db1b0df65ed295da45007f98a99c969eb7c38574ecf6b271976091b56"}},"description":"0x85242431f0f8a0e939f2e469d6d35473e72a9577bf81a5ae16b345cddf1c50eecc5c7520b9580d9717c166a9835664fd","pubkey":"85242431f0f8a0e939f2e469d6d35473e72a9577bf81a5ae16b345cddf1c50eecc5c7520b9580d9717c166a9835664fd","path":"","uuid":"050c1327-b008-47d3-9b37-42eacbfc5b9c","version":4}
\ No newline at end of file
{"crypto":{"kdf":{"function":"pbkdf2","params":{"dklen":32,"c":262144,"prf":"hmac-sha256","salt":"54cedb59cb00dcfc39c9f5ac8b638b5dff308d05d1438e68ab08792dd772ec9b"},"message":""},"checksum":{"function":"sha256","params":{},"message":"ad761cb2c3be4af0b18eef64d92475e6bf1284c075655ccb4b88c55586b4f4f8"},"cipher":{"function":"aes-128-ctr","params":{"iv":"f1e1203891e238645723187c9aab77ac"},"message":"eed5dcee59a3bc823994e623080e732a6f157721a7e90bd477d3d07953b31f16"}},"description":"0x858b74656127a05134b7614d5fba180e97739c99cf60a42498f1e9c7eda0a88a5fce2d8bc8df5010a5260f96db1b132b","pubkey":"858b74656127a05134b7614d5fba180e97739c99cf60a42498f1e9c7eda0a88a5fce2d8bc8df5010a5260f96db1b132b","path":"","uuid":"dbca8e9d-38e8-4d19-8474-55d3d07fec91","version":4}
\ No newline at end of file
{"crypto":{"kdf":{"function":"pbkdf2","params":{"dklen":32,"c":262144,"prf":"hmac-sha256","salt":"7cfc984164311e96c91045c2d49463849002c86cef7986e051a5cb8afbb68fa8"},"message":""},"checksum":{"function":"sha256","params":{},"message":"cbe8a4b3e1f5344c1fa6fec5e850fea89771058a0cd3ebb0b28f7da8f7d4e7a2"},"cipher":{"function":"aes-128-ctr","params":{"iv":"d5b17e18c2bed62b9f194615cf4a3231"},"message":"dd17e6fb77023acb91da9e2b14507965483eebf872fa3f2f36e9e5f70db9c420"}},"description":"0x85bc68a8c76d4f706648059fa2d3b387c86ee65082e5fc16713794c6c0f8277d37c72783abe1c47ad3de97bd33ef66a3","pubkey":"85bc68a8c76d4f706648059fa2d3b387c86ee65082e5fc16713794c6c0f8277d37c72783abe1c47ad3de97bd33ef66a3","path":"","uuid":"c9e6d511-12f7-4224-9605-8fca49050258","version":4}
\ No newline at end of file
{"crypto":{"kdf":{"function":"pbkdf2","params":{"dklen":32,"c":262144,"prf":"hmac-sha256","salt":"e1dfddfc5a0bdbf335e36be27de935ddae37958f41db8d13f030a9562808123d"},"message":""},"checksum":{"function":"sha256","params":{},"message":"cd1f66410107382e06ad4737a9656ba6559e36cd9ecb9a08eed38b11d5d527b7"},"cipher":{"function":"aes-128-ctr","params":{"iv":"08439739e786d101199cb9a91e4bafe4"},"message":"e7024da53ac7c391d822e4c5dc0c6444163500f96dcce3c909a065aeb4ee0cf8"}},"description":"0x87fa175dd34496aee3b88a482accaa19e271be98265981949c42769cd45b3d67afcc060167b2effc748ff15076b11b27","pubkey":"87fa175dd34496aee3b88a482accaa19e271be98265981949c42769cd45b3d67afcc060167b2effc748ff15076b11b27","path":"","uuid":"ce67d829-97ed-4565-bcc9-cdcd0115752c","version":4}
\ No newline at end of file
{"crypto":{"kdf":{"function":"pbkdf2","params":{"dklen":32,"c":262144,"prf":"hmac-sha256","salt":"8c8cc5bf2d62552731455bd4fa1d427c83fedaf88f34c52dfef9e39a64099f33"},"message":""},"checksum":{"function":"sha256","params":{},"message":"074dcaa0d4f43211e157dbe3b0d18963be933a526f5ab85d3ec5c1915477e177"},"cipher":{"function":"aes-128-ctr","params":{"iv":"bee61a632899b0ea20288316c5ed1ad3"},"message":"45acc245b165d8de04cc2aac3055d0d04b5520d06b7a1cd640fe36b643256ba0"}},"description":"0x88091d52b099523e2717d3a526f8a41a7ff20ca4e4b4d153ebafe6f9265e58f8aa45f1e415d598c758e684bcb376577b","pubkey":"88091d52b099523e2717d3a526f8a41a7ff20ca4e4b4d153ebafe6f9265e58f8aa45f1e415d598c758e684bcb376577b","path":"","uuid":"2418cbcc-31c1-482f-b8b3-955f5d88687e","version":4}
\ No newline at end of file
{"crypto":{"kdf":{"function":"pbkdf2","params":{"dklen":32,"c":262144,"prf":"hmac-sha256","salt":"0e9802773278a8a4cee4adf630d1a01197890197b8b6456688d6b83a8d296c67"},"message":""},"checksum":{"function":"sha256","params":{},"message":"d4659cb400189cef49de0513438d05a608048c99db179760247ac5f52d84a97a"},"cipher":{"function":"aes-128-ctr","params":{"iv":"8e368f7a2924750081e08dce6c7badaa"},"message":"0affd34ecca31e6ab1365c192f5cc6e99a8ca4530b6f7538f38f8fe6ec253669"}},"description":"0x89929f3a811cf44f70d60ccaa4571dff9371c73f60b70b7a50f2cf816861daeb14499b112890a200963d82d324c2ee8f","pubkey":"89929f3a811cf44f70d60ccaa4571dff9371c73f60b70b7a50f2cf816861daeb14499b112890a200963d82d324c2ee8f","path":"","uuid":"f45c0b95-9237-4182-86b5-5de17935c6ae","version":4}
\ No newline at end of file
{"crypto":{"kdf":{"function":"pbkdf2","params":{"dklen":32,"c":262144,"prf":"hmac-sha256","salt":"2d6605e4a19941cff380f27c7ceee1ee8d7669eab81d7b295f37ec86d6941ab8"},"message":""},"checksum":{"function":"sha256","params":{},"message":"1cad7cbe0931181ed4422ff4ab07d44ebb5b0edf069b7e03dc1eeb1135a13b7a"},"cipher":{"function":"aes-128-ctr","params":{"iv":"50735b3a1543c2ef1957b9dcd1b84542"},"message":"c2cbe92c2949e2f54bc8663e6e220d1dd1855727092efef5f90c8cd1ade19a44"}},"description":"0x89931c9f649137fe9a6d59a455bcc695af861fa080fef0d598cc2ae66ed193939d12e72cf0a6f081ada36b4090f864cc","pubkey":"89931c9f649137fe9a6d59a455bcc695af861fa080fef0d598cc2ae66ed193939d12e72cf0a6f081ada36b4090f864cc","path":"","uuid":"c4eb26fd-6a56-4b34-9df2-3cff9b774ee7","version":4}
\ No newline at end of file
{"crypto":{"kdf":{"function":"pbkdf2","params":{"dklen":32,"c":262144,"prf":"hmac-sha256","salt":"72190c032943f3b38c89c40f965e860961c7809596a8b096603c2209ef4f3d86"},"message":""},"checksum":{"function":"sha256","params":{},"message":"b52524babdc2ba22be28f4bbdcbaf291bce03b992309bcc293445dacb6891568"},"cipher":{"function":"aes-128-ctr","params":{"iv":"19d8a4eb788154940787c4db97ceffbc"},"message":"5cf8bbf0f64e72efb0e833684f686aaa3826a707f826bb9703499c1172f8f5f1"}},"description":"0x89d3dbfe89713fa12d2735e2379da4391e22169e967cc93eac815fd4a5e4fd374b0a4e468a44ea6e1f6ca6072a6382c9","pubkey":"89d3dbfe89713fa12d2735e2379da4391e22169e967cc93eac815fd4a5e4fd374b0a4e468a44ea6e1f6ca6072a6382c9","path":"","uuid":"080ba40c-6c06-4166-b2f9-3055b1b62545","version":4}
\ No newline at end of file
{"crypto":{"kdf":{"function":"pbkdf2","params":{"dklen":32,"c":262144,"prf":"hmac-sha256","salt":"d9061f57053552a106af1f6b1e2cc680bd9a0f1e541ffe35b1c2bbfbdf19f2ac"},"message":""},"checksum":{"function":"sha256","params":{},"message":"d8644473e84b5901dac27867a860319a7b5fcbda53a8d29fdb62b72eee42d2ea"},"cipher":{"function":"aes-128-ctr","params":{"iv":"174b31bcb04bef8daf767dbe2af9f893"},"message":"1e5ac7573e2c130da11a72629f3ac6d6df2197b7d26b3fc79454a3f6caedad3d"}},"description":"0x8b49344506042460fc40f4a60d64079e86a29e87cffe29ebd8908fd1803ca21f53c0665145291ea5e34b30a01dca7cb5","pubkey":"8b49344506042460fc40f4a60d64079e86a29e87cffe29ebd8908fd1803ca21f53c0665145291ea5e34b30a01dca7cb5","path":"","uuid":"ef623e82-54de-478a-9674-551a85058d7b","version":4}
\ No newline at end of file
{"crypto":{"kdf":{"function":"pbkdf2","params":{"dklen":32,"c":262144,"prf":"hmac-sha256","salt":"629bd00c15b1765ab966ce0e830ea460c154b6af60019d1bb6f43f8ddc2e59d8"},"message":""},"checksum":{"function":"sha256","params":{},"message":"c81efb48cfd3cf0ca9e2b92390aeaedd15bc9c564c91a3e2d9c5c8dcb6acf07e"},"cipher":{"function":"aes-128-ctr","params":{"iv":"4e856dfffbf6ea694561c5131de340a4"},"message":"395a327305309bad52cfbc71872a9a5a75eb05edb96a704103f96781bc3a3ec8"}},"description":"0x8bf7c9c9972045c582b7363af44e93da26aef3c8fce81a0469d0c5f48199312f73953ce3c3547b91f543b5586a307c38","pubkey":"8bf7c9c9972045c582b7363af44e93da26aef3c8fce81a0469d0c5f48199312f73953ce3c3547b91f543b5586a307c38","path":"","uuid":"8b3d5064-f084-4081-8520-c0283a216ff0","version":4}
\ No newline at end of file
{"crypto":{"kdf":{"function":"pbkdf2","params":{"dklen":32,"c":262144,"prf":"hmac-sha256","salt":"a60354a5e403eca8710791416ed9a1309e26751793d1bd47ff6d61ea293ad07a"},"message":""},"checksum":{"function":"sha256","params":{},"message":"de959d0a9c90df6238dfd8266f1323ea4f0ce9ace14c84382b9e4528b4115d0a"},"cipher":{"function":"aes-128-ctr","params":{"iv":"efe15ed40a2ddea66ecd98923f3793c4"},"message":"acac10231732aa1c0ac74d4e30c38f91a32b72667b965c21fe07a57d1929c52c"}},"description":"0x8c3d37929876321cfb221b3dca80feb1c38159ee83e01d1ad60fd16d9d2c78993a41643ec1e7af2d6a0ff8dfb05467ea","pubkey":"8c3d37929876321cfb221b3dca80feb1c38159ee83e01d1ad60fd16d9d2c78993a41643ec1e7af2d6a0ff8dfb05467ea","path":"","uuid":"92fe7abc-484b-483c-a5b6-2ecfedfc9c71","version":4}
\ No newline at end of file
{"crypto":{"kdf":{"function":"pbkdf2","params":{"dklen":32,"c":262144,"prf":"hmac-sha256","salt":"673ce24491afd5e9437b17f9085a9d298b3c8ac0c572042aaae99d138a12a57c"},"message":""},"checksum":{"function":"sha256","params":{},"message":"5f4fa65b92c6d9b9318a2a008b5ae79ac9beeb8f63d8c59b952e7641c3e75398"},"cipher":{"function":"aes-128-ctr","params":{"iv":"2ce3ba046a2887cf460a3c93099f23f7"},"message":"49e8548c042626c21708d841b4b06e306ab0a3a87a249c99bd24a3c845ce3339"}},"description":"0x8ca1bccbe513b4503f8496b8468c42718972718feff4e3d5eec970f3c56ac0e2a8d4d59ad331db9cbea643ea775314bb","pubkey":"8ca1bccbe513b4503f8496b8468c42718972718feff4e3d5eec970f3c56ac0e2a8d4d59ad331db9cbea643ea775314bb","path":"","uuid":"83479ecc-3701-435b-bb6d-f6c49e06af30","version":4}
\ No newline at end of file
{"crypto":{"kdf":{"function":"pbkdf2","params":{"dklen":32,"c":262144,"prf":"hmac-sha256","salt":"6f3978f97c3695b9a44dcee1a9331b369a3e37d9fa6038984fb38754df90154e"},"message":""},"checksum":{"function":"sha256","params":{},"message":"df5f6c2889fb29578447d24b1e0b0c3f1e0ae2367f9667c878b15a34a5a207a9"},"cipher":{"function":"aes-128-ctr","params":{"iv":"eebd02bcff009d19658ca8aa90cb73b3"},"message":"68a274683a15219a108a5b357fb511bacbda7d5829addcfd6b728c065fc0ca3e"}},"description":"0x8cf690a81a1eab3d0554acfc7087e0b9ad3dcd50b9612893f56bd1536b6865092f60e7cef0c81e2acf97f287f4d28d1d","pubkey":"8cf690a81a1eab3d0554acfc7087e0b9ad3dcd50b9612893f56bd1536b6865092f60e7cef0c81e2acf97f287f4d28d1d","path":"","uuid":"11b3e915-d74b-46b8-8729-7e037a7d325c","version":4}
\ No newline at end of file
{"crypto":{"kdf":{"function":"pbkdf2","params":{"dklen":32,"c":262144,"prf":"hmac-sha256","salt":"8ebedbef03a42b58d37ffc617c8bfdaa2ca5592b6e7a602f045cb35e2aa19457"},"message":""},"checksum":{"function":"sha256","params":{},"message":"1b89ea54dcd5dad917966c804a17fe9bc2bd4888fc6add9970872f6cb6fc5aea"},"cipher":{"function":"aes-128-ctr","params":{"iv":"537553ce87ba63a407f3913bffd9eeb7"},"message":"ce1ac2342a9cfdfa825ea0c0f376768b85f1f4d14fbcdba37ca2e7564739585e"}},"description":"0x8dc5f6f45cc02e68b008e6035492c3c10835e9247899a5bccc559aa3158e581a71803401124d9fd4797476f33351b0d1","pubkey":"8dc5f6f45cc02e68b008e6035492c3c10835e9247899a5bccc559aa3158e581a71803401124d9fd4797476f33351b0d1","path":"","uuid":"3a09f870-5895-46d4-8d8d-87310c620886","version":4}
\ No newline at end of file
{"crypto":{"kdf":{"function":"pbkdf2","params":{"dklen":32,"c":262144,"prf":"hmac-sha256","salt":"3de45f779f795ff53f6c7718b404c8f94dfcb373380ecf04d65df3d41409f2f3"},"message":""},"checksum":{"function":"sha256","params":{},"message":"3a49323def5f3784bf242e5194aef5a3b78da1104097e85058dc6bc8f976c635"},"cipher":{"function":"aes-128-ctr","params":{"iv":"e9986e1e6ab0f66c8f1bb4993b442433"},"message":"075148d186136e7993c80ee509eb237b3f26383b3c9f058c5af215bbdac30f85"}},"description":"0x8df81a9e3c61ff1cba9f13c792f1c933131b6d155e8b552d673df44fad4530b68c4e86e9cd2e5cc93a3b806c6b00f4a6","pubkey":"8df81a9e3c61ff1cba9f13c792f1c933131b6d155e8b552d673df44fad4530b68c4e86e9cd2e5cc93a3b806c6b00f4a6","path":"","uuid":"22bf2efb-f763-4579-a9f1-63a8d6645b6b","version":4}
\ No newline at end of file
{"crypto":{"kdf":{"function":"pbkdf2","params":{"dklen":32,"c":262144,"prf":"hmac-sha256","salt":"aae723ae4b7a14544e6cef9af34e47f403c8e3cda91012f4ae3fe296d9b424ec"},"message":""},"checksum":{"function":"sha256","params":{},"message":"9e02cc77ee983ffff4d9026764d87fe6d2d03d0f9f17b888db733becb5d65ce1"},"cipher":{"function":"aes-128-ctr","params":{"iv":"3dcdb98ce07ae531a919ee0cc3d2eda4"},"message":"915d9e88ad73131bb163eb309902ced191ba9dc8b828f5a9292c84979448f3f2"}},"description":"0x8efdefbccd6479b9953a5ec6416e6d48201865968567379b213040dbf0be7efa00d66343c21a7e801d6bfd7403cfcfa7","pubkey":"8efdefbccd6479b9953a5ec6416e6d48201865968567379b213040dbf0be7efa00d66343c21a7e801d6bfd7403cfcfa7","path":"","uuid":"fd4b5a8a-1b81-4d05-bfe8-d6a80a1ee4a2","version":4}
\ No newline at end of file
{"crypto":{"kdf":{"function":"pbkdf2","params":{"dklen":32,"c":262144,"prf":"hmac-sha256","salt":"7ba91e0cff869b1d3a5c64b04151e95cb8abd66a425972da1cf0bf2b8dbb92d5"},"message":""},"checksum":{"function":"sha256","params":{},"message":"d1a78a837a22d4e71e906d84c2b68b395a5c6908ab4a3fd48d5d8a8a700347ee"},"cipher":{"function":"aes-128-ctr","params":{"iv":"a5d85e94a3ddbf2e5b8cc39418756395"},"message":"392ae7850e8e58525b36ce98f0e7b5554a84e825f313d01fdee815a8f853972a"}},"description":"0x8f1e06e20ac5dd13518bd6c5e19c0a00a9dac968a13167087d9f8199bcb2e93fcb53199f2400ab2f398958761d7c33e6","pubkey":"8f1e06e20ac5dd13518bd6c5e19c0a00a9dac968a13167087d9f8199bcb2e93fcb53199f2400ab2f398958761d7c33e6","path":"","uuid":"97ac3679-1491-41af-9b96-87952764096e","version":4}
\ No newline at end of file
{"crypto":{"kdf":{"function":"pbkdf2","params":{"dklen":32,"c":262144,"prf":"hmac-sha256","salt":"4354cdf8bc87f97cce3a829a881c5caa2b4f5dcf14dad9da87054f68c1eda2d7"},"message":""},"checksum":{"function":"sha256","params":{},"message":"b46463ee3a57475bfda5ef60c6941bfa6d5b51367a01f34ba01d39bd749557d5"},"cipher":{"function":"aes-128-ctr","params":{"iv":"e503a7c9ef8cce006c52d95d05620bb1"},"message":"8ef859792a742cb3e3b5d65621136e8a46da35e318a3b74a1676660f55dfaba0"}},"description":"0x91838562f203c048b60308d5dae4e845977b8bd946806886f91f23038df2759e9306efcb56f15d57498a68ee789bf5ce","pubkey":"91838562f203c048b60308d5dae4e845977b8bd946806886f91f23038df2759e9306efcb56f15d57498a68ee789bf5ce","path":"","uuid":"5f5698c5-3614-4235-ae1a-ae6462d284eb","version":4}
\ No newline at end of file
{"crypto":{"kdf":{"function":"pbkdf2","params":{"dklen":32,"c":262144,"prf":"hmac-sha256","salt":"a8f84442380929bbfda32d1901d8650bf6ceefe638f6db72df9b71ad26eea435"},"message":""},"checksum":{"function":"sha256","params":{},"message":"287dac54dc72f49383964e19c59afc6188227503190e850f7359e908ba3d9768"},"cipher":{"function":"aes-128-ctr","params":{"iv":"28ab6100763fb19910281aa6ef94094a"},"message":"75c3ce9aeae28bd1e4998c5ab30b849bc27ba1aa42f3f744ecca2160cec2d5b1"}},"description":"0x935b301be1f67fc6a896b57309e546bfc1ae731a19b73777ca848fb81f4d8d7b9a5c1cf8ad54d5e1eda09f2095d848cb","pubkey":"935b301be1f67fc6a896b57309e546bfc1ae731a19b73777ca848fb81f4d8d7b9a5c1cf8ad54d5e1eda09f2095d848cb","path":"","uuid":"dea203e5-c65c-45c5-87d8-745d830fa6fd","version":4}
\ No newline at end of file
{"crypto":{"kdf":{"function":"pbkdf2","params":{"dklen":32,"c":262144,"prf":"hmac-sha256","salt":"ef851439a0c6178adfc660dd065e8c64215881219cccb30823cb83390a1a1588"},"message":""},"checksum":{"function":"sha256","params":{},"message":"42b7dab9ceba32abfbc049d91b92260e3b533779256f064b0d9578d4e733cdb7"},"cipher":{"function":"aes-128-ctr","params":{"iv":"19230ce0c517121afffe1bb5a426dbf1"},"message":"6d0773c27a2e10d572b2f427844cdf36634fc1f1121fd8aa407a42fd4a139a53"}},"description":"0x9401d4c66e72e596e0072c27de5bcf3c99900011d36f01219b9e0dc54c852393378b4a0bd12084032c6f02de2dcf1296","pubkey":"9401d4c66e72e596e0072c27de5bcf3c99900011d36f01219b9e0dc54c852393378b4a0bd12084032c6f02de2dcf1296","path":"","uuid":"e1c50412-79b3-4d79-8e92-fae2757306e6","version":4}
\ No newline at end of file
{"crypto":{"kdf":{"function":"pbkdf2","params":{"dklen":32,"c":262144,"prf":"hmac-sha256","salt":"e59a7ef8b181001e35b5282723e71f27c343780c914d57c314beafc45331b388"},"message":""},"checksum":{"function":"sha256","params":{},"message":"1ce21ffa547ebd1dbe90689945a03d5d5082e4edcf1c13deebf9c9986e439769"},"cipher":{"function":"aes-128-ctr","params":{"iv":"48b433c468bf69c858bbc76b3eea5fec"},"message":"f58e232e3c4c83e3fa6d1f741360e0d1d885cf0e6d3f1177cb78619146026b87"}},"description":"0x95123a9757f7295b4cdfeb8808d9d7de69761477db3a34aabe2cb4bffc466b65618b91a0e2f33c95d23d38665d68c506","pubkey":"95123a9757f7295b4cdfeb8808d9d7de69761477db3a34aabe2cb4bffc466b65618b91a0e2f33c95d23d38665d68c506","path":"","uuid":"a0f2f507-9518-4e85-91be-bb4c82917392","version":4}
\ No newline at end of file
{"crypto":{"kdf":{"function":"pbkdf2","params":{"dklen":32,"c":262144,"prf":"hmac-sha256","salt":"930f062874ddab4711655d01f1c0eff4d8d8f55acffd80fae3e89d46d65c6387"},"message":""},"checksum":{"function":"sha256","params":{},"message":"16ad2bae69677d8a44f26f76f3b0a5e8f66f6424b434bc5f126ed92a9c6c6e7b"},"cipher":{"function":"aes-128-ctr","params":{"iv":"a28281839d3932afca7707038fbca9c7"},"message":"626f90ad5587f17bcb5a847fb2090a847c269f8a453fbc774a8cd1ca6eac75bf"}},"description":"0x95419a10ad9771dc7545637bc14e4eb7938e0bcc57a42000ddbb117750570fb5ce290679d326a0783e6c780be23df6d8","pubkey":"95419a10ad9771dc7545637bc14e4eb7938e0bcc57a42000ddbb117750570fb5ce290679d326a0783e6c780be23df6d8","path":"","uuid":"ae2f5d56-3ead-4656-b0fc-a57720cc5258","version":4}
\ No newline at end of file
{"crypto":{"kdf":{"function":"pbkdf2","params":{"dklen":32,"c":262144,"prf":"hmac-sha256","salt":"e325f6ae6ef00f6330bdbe27496d71fa63b6bb9086cbb12280a7f655f64b0000"},"message":""},"checksum":{"function":"sha256","params":{},"message":"38d3586ea8ef46a6bc16b8ee73b5397dd05bc8928e89daa85b9a00e0fc569cf2"},"cipher":{"function":"aes-128-ctr","params":{"iv":"bc4460ec9ed604f9695f6eadfd4c9c73"},"message":"41074ed5c32a30d18c2dabb69f95093add6a387892ad42d637d60b52b3942631"}},"description":"0x958979725c3497149c8f1ed2e3f073a56207ff17218ba3fef7fbcc6e07bbd7b8fc528ff646a49e9c1a145ed27017ef4d","pubkey":"958979725c3497149c8f1ed2e3f073a56207ff17218ba3fef7fbcc6e07bbd7b8fc528ff646a49e9c1a145ed27017ef4d","path":"","uuid":"e0a5cc41-7572-4338-88f4-19e466ff243b","version":4}
\ No newline at end of file
{"crypto":{"kdf":{"function":"pbkdf2","params":{"dklen":32,"c":262144,"prf":"hmac-sha256","salt":"688bfc5fd816a419b59aef97086abdee0b7600696b0f0a59ff618a80ac35c38b"},"message":""},"checksum":{"function":"sha256","params":{},"message":"125a53a325bf3e026ff7724446ac08d05402170e5eb13c7b06d89a694e4cd3ce"},"cipher":{"function":"aes-128-ctr","params":{"iv":"eb0438b60356d72aad02caa8997d715f"},"message":"6d52b787bbb3fafa8bbb0527d95677a777ca2e0c930bf7d402fe924e4c5d61be"}},"description":"0x961d5cb5deed3612dfbbbffccada34d5a940bcb9b8002452be08d3d69e69274a98854b140744d2640da797cbe910b1cd","pubkey":"961d5cb5deed3612dfbbbffccada34d5a940bcb9b8002452be08d3d69e69274a98854b140744d2640da797cbe910b1cd","path":"","uuid":"e58e48a0-5cc5-40f3-8688-f9320c02f052","version":4}
\ No newline at end of file
{"crypto":{"kdf":{"function":"pbkdf2","params":{"dklen":32,"c":262144,"prf":"hmac-sha256","salt":"0b80daab3265d2c15fcc8e45fd7a69616eb8684441c1cb076feb6dc333616fef"},"message":""},"checksum":{"function":"sha256","params":{},"message":"b65c5e4f700c7e6b973e17f94eeec8b20ab45a709aae9351d937fc4f7370d006"},"cipher":{"function":"aes-128-ctr","params":{"iv":"7ce656fb9fbae5dc49f01edcdf1e34b1"},"message":"a2a0a0a02eb2c1495ce447dc253686b2e258f08e69179428b20704d8dfa48856"}},"description":"0x980f54178ab1e2d21822e9cd7327acb170269e6215cc8151f5f9c74d3e9ed4fd8e2d5b03c0d5b187edf0b56b6d2fc2fc","pubkey":"980f54178ab1e2d21822e9cd7327acb170269e6215cc8151f5f9c74d3e9ed4fd8e2d5b03c0d5b187edf0b56b6d2fc2fc","path":"","uuid":"505c518f-6566-4a6c-8137-1d5b011b7319","version":4}
\ No newline at end of file
{"crypto":{"kdf":{"function":"pbkdf2","params":{"dklen":32,"c":262144,"prf":"hmac-sha256","salt":"1cc1dca6925ee63fd0abadc370f247724b076822045e258c006ccc06e54b2e1f"},"message":""},"checksum":{"function":"sha256","params":{},"message":"aca0e4e797a4f80eaa9dc9e325032ec114adde8038c9aeb546cb3c4b4f870e33"},"cipher":{"function":"aes-128-ctr","params":{"iv":"74f8171fab4462d8ad888af5bccfad15"},"message":"140c6c8ea776d0a5c06ed69fd5ec7b01e3271748aca57777939c5a8eeb0068df"}},"description":"0x988085e2781db7997526af727a32b8660d4022251202f534ba6edda299d5b1fad5a706fe85cab523478abd5e10d68e51","pubkey":"988085e2781db7997526af727a32b8660d4022251202f534ba6edda299d5b1fad5a706fe85cab523478abd5e10d68e51","path":"","uuid":"a33551a7-345c-4cad-ab82-f70cd7bc5a37","version":4}
\ No newline at end of file
{"crypto":{"kdf":{"function":"pbkdf2","params":{"dklen":32,"c":262144,"prf":"hmac-sha256","salt":"753d70731e228de115f39ec8426e922d7204a33d9b5a90e6eeac90984a3c79dd"},"message":""},"checksum":{"function":"sha256","params":{},"message":"984c2be8c777cf3b8c213df38ecc5267a0d040e4f8e0a0c2bc3746f47ff08ee1"},"cipher":{"function":"aes-128-ctr","params":{"iv":"6cd8ab19991c7195cd5e6a9bb89efd5d"},"message":"77993e8bcf7f91f3b6d0554876d35995d8a0704a3e9e2cbf27d9fb7419f5b3a0"}},"description":"0x99729eb9833e428853a7444653824aac579864675d6c69c1fc79423f4aba0d51153a40f31c1082816ddb0cdce31bc6b2","pubkey":"99729eb9833e428853a7444653824aac579864675d6c69c1fc79423f4aba0d51153a40f31c1082816ddb0cdce31bc6b2","path":"","uuid":"ae79b2e2-27d6-4997-8547-8ae93d555e94","version":4}
\ No newline at end of file
{"crypto":{"kdf":{"function":"pbkdf2","params":{"dklen":32,"c":262144,"prf":"hmac-sha256","salt":"a99c0f1a8e0a389333e46331c4da736e9aa3a89f0b218e41c3ed895bfcfec11e"},"message":""},"checksum":{"function":"sha256","params":{},"message":"89ba5465e78b9751b0e7c2fe3b94fc2e5bc8167b683bec9c366f6fe1d6205fd9"},"cipher":{"function":"aes-128-ctr","params":{"iv":"60d12696eff428d2ae10e8ac95ee873d"},"message":"53ede6abe0479229ed5dce788d52ead0482d3be841b34114cb044a0ddb66990c"}},"description":"0x99804a3e664ba9d8b0a91fdb6127f2753932e41c6f62d1c26edd5f81a12f0eb7bdc9df0d58121436cabd07261f2bcdbd","pubkey":"99804a3e664ba9d8b0a91fdb6127f2753932e41c6f62d1c26edd5f81a12f0eb7bdc9df0d58121436cabd07261f2bcdbd","path":"","uuid":"53db7652-11a8-4fc8-bb6a-5454264b1267","version":4}
\ No newline at end of file
{"crypto":{"kdf":{"function":"pbkdf2","params":{"dklen":32,"c":262144,"prf":"hmac-sha256","salt":"4c91cede9e40f6316a2fbd4f0c329ec8b71bdf21a2fabb73739d2061e1cfb9af"},"message":""},"checksum":{"function":"sha256","params":{},"message":"e469aa28317dbe07393c196195bfe4e8d83eaedcf36124f9a8c8403333503539"},"cipher":{"function":"aes-128-ctr","params":{"iv":"a431b7b2ae3ab47166c1311394191ca9"},"message":"879da66d9feb64b577ff98ecfd26f03e7bfbee47f8b580b44e252e7e391c5fd7"}},"description":"0xa125a3659c269801fb2e00c8f38d6b6fbe91a85dc99691db008cf325ef4ca7443c6fbc8a9131acf885d6169f859b8b1c","pubkey":"a125a3659c269801fb2e00c8f38d6b6fbe91a85dc99691db008cf325ef4ca7443c6fbc8a9131acf885d6169f859b8b1c","path":"","uuid":"69afdc9c-849b-42f0-95f6-fb5ced622e77","version":4}
\ No newline at end of file
{"crypto":{"kdf":{"function":"pbkdf2","params":{"dklen":32,"c":262144,"prf":"hmac-sha256","salt":"63e8b33d851627dd20c17a2edcb1d45e9de28330b4a9154f9ef288f9e7257df2"},"message":""},"checksum":{"function":"sha256","params":{},"message":"90af011259c8e0a1def459dc71a2f319a799a588f0b098eec4aa6e97205e4225"},"cipher":{"function":"aes-128-ctr","params":{"iv":"388d1e0f78ffd27fe60cc37be28238a2"},"message":"28bec7ca5d7ce57188668a511a12e90ad2dec556e1fbe9167674c115e45112bd"}},"description":"0xa1ae1d14d16cf61a6ae0c9589a19a8f38e161f02dbd98c9f5400fc63689af3af2c146bcfb46f0d94469502947d19d6df","pubkey":"a1ae1d14d16cf61a6ae0c9589a19a8f38e161f02dbd98c9f5400fc63689af3af2c146bcfb46f0d94469502947d19d6df","path":"","uuid":"fcd67356-2eec-4da7-b4f9-ad698d6ed177","version":4}
\ No newline at end of file
{"crypto":{"kdf":{"function":"pbkdf2","params":{"dklen":32,"c":262144,"prf":"hmac-sha256","salt":"7021a99d82bc3946731ff2b0c352f56c1f462390adb68e8dbdf5ca039e68164a"},"message":""},"checksum":{"function":"sha256","params":{},"message":"59367ead91d74a1f7f6c4c7d694f8e21321adecbfd184d64739b2b6926933d6e"},"cipher":{"function":"aes-128-ctr","params":{"iv":"a9137d5732fde4f96bf093f2481e6f02"},"message":"ffdc02fdc62e3b81f45d76812d65edf560e853f0939b3fb5e7d7504416d078e6"}},"description":"0xa2794c3671f0520ffa1032dac4ef67b0a00a65255e522449bf8cabd775db13dd22871f64e710a09344739ef66c1f578f","pubkey":"a2794c3671f0520ffa1032dac4ef67b0a00a65255e522449bf8cabd775db13dd22871f64e710a09344739ef66c1f578f","path":"","uuid":"2acb6709-6271-49ac-99f7-fc5217445213","version":4}
\ No newline at end of file
{"crypto":{"kdf":{"function":"pbkdf2","params":{"dklen":32,"c":262144,"prf":"hmac-sha256","salt":"0085434c922d5984a180cfb808df5ae84773db853a1a4759e9edaf8a4072f3c2"},"message":""},"checksum":{"function":"sha256","params":{},"message":"b08bd95d0a66f156db25dccb6e6d4f358254f28d17a47c85a256a97856c020e0"},"cipher":{"function":"aes-128-ctr","params":{"iv":"073bc2804d4eaa2868fb10340ca30a35"},"message":"6210086729e239f3ba0fe33f17f161d8cfcfe0a39db899f7f6b73eca26e9c086"}},"description":"0xa2ab702302efc9f00d6f50b367de843c24ef708f609b20205b46771f6603dd005a271aaeb589c4fc50cdf137ac66ff1a","pubkey":"a2ab702302efc9f00d6f50b367de843c24ef708f609b20205b46771f6603dd005a271aaeb589c4fc50cdf137ac66ff1a","path":"","uuid":"6e73dea6-67f5-42e3-9a21-71c4b3251b82","version":4}
\ No newline at end of file
{"crypto":{"kdf":{"function":"pbkdf2","params":{"dklen":32,"c":262144,"prf":"hmac-sha256","salt":"425ab401e5a5478a0660b8b5b0656a078b7d1183fa270a9a07fcde0141802faf"},"message":""},"checksum":{"function":"sha256","params":{},"message":"04c06ee5d22c9542a88464cdf4ef0b284d4364c0a3c180cbe0d618c8287bbb2f"},"cipher":{"function":"aes-128-ctr","params":{"iv":"469a33505a89ea8ff25c52aa4ff5b4f7"},"message":"147811f37c99d5cdfe4d598e74974673aeb0e133f67c68c2c579dcf6f4fa5fee"}},"description":"0xa39882700ed7f72fcdbac07081b7c0c912cb8647ed8494926e6c9c2fc1a7415c7c60e3afcc3d3278fe25b50b851c3ad5","pubkey":"a39882700ed7f72fcdbac07081b7c0c912cb8647ed8494926e6c9c2fc1a7415c7c60e3afcc3d3278fe25b50b851c3ad5","path":"","uuid":"146bbdbf-b547-4709-9818-4619f72e88d0","version":4}
\ No newline at end of file
{"crypto":{"kdf":{"function":"pbkdf2","params":{"dklen":32,"c":262144,"prf":"hmac-sha256","salt":"891aee417983042a974cdda70323bf15b3d48a07c6a6a43cd616529bde447578"},"message":""},"checksum":{"function":"sha256","params":{},"message":"470112a9797aecdba96148e12d0e39efd8dc36a0ee426846292d0b5c65bb0054"},"cipher":{"function":"aes-128-ctr","params":{"iv":"d8af70eb6e71786a20b91d9e1143e5b5"},"message":"2280821079d1901cb21d595f9d8647c2f1f41d4367629ce702520060e7348d91"}},"description":"0xa3ed99f5e10128dcfa3553c0875021d57da6578892e368d97d6ca4b5d1da961523bde2765e21d64eed8b9eec079f3ff2","pubkey":"a3ed99f5e10128dcfa3553c0875021d57da6578892e368d97d6ca4b5d1da961523bde2765e21d64eed8b9eec079f3ff2","path":"","uuid":"1556556d-b333-408a-bec0-bbe011f86534","version":4}
\ No newline at end of file
{"crypto":{"kdf":{"function":"pbkdf2","params":{"dklen":32,"c":262144,"prf":"hmac-sha256","salt":"37ec58829b487dc8ac673f02da50013fab1d5d6835db51fc08769657a02d0091"},"message":""},"checksum":{"function":"sha256","params":{},"message":"cda3958a57d51e2e715de3c8c356cc1027a2ed59a17aba9faf74d29c435fa7ca"},"cipher":{"function":"aes-128-ctr","params":{"iv":"aa03f5a49949c042e7ac9aa2c14b6c23"},"message":"cb1f18956ec0b714aad516e2d980b8429b7030d2a1ed17a15029b8be99890ebf"}},"description":"0xa459e9ad0870b24aeb95d53b437014dc5dd97bbe38d78b51797da732e26e70e47ae97eb6d16ace2b7b21961fe9c27904","pubkey":"a459e9ad0870b24aeb95d53b437014dc5dd97bbe38d78b51797da732e26e70e47ae97eb6d16ace2b7b21961fe9c27904","path":"","uuid":"2f9c8c1f-f426-4301-99b1-f59e9e4bc3e8","version":4}
\ No newline at end of file
{"crypto":{"kdf":{"function":"pbkdf2","params":{"dklen":32,"c":262144,"prf":"hmac-sha256","salt":"ff1c4efb60282b87636843136084f6460d018510c67ac9df951319eb95051564"},"message":""},"checksum":{"function":"sha256","params":{},"message":"18536933d901c57b3b71d459f708fe2ff441b8a1039d017e36df05e82c5872d9"},"cipher":{"function":"aes-128-ctr","params":{"iv":"ed880a51dfeb7a5890ba8e3c70cf7761"},"message":"f80861b33bdd0b5782fdbfd1a0b1263a18420d354db3ebcf5026ba979b692c3b"}},"description":"0xa4662c910f9eda828898a0cddd61332aca5808be1efedb7aedae7978a0bc7f9d2a35baf97f913ca920c957c4e2b7a18c","pubkey":"a4662c910f9eda828898a0cddd61332aca5808be1efedb7aedae7978a0bc7f9d2a35baf97f913ca920c957c4e2b7a18c","path":"","uuid":"c183a2c4-1e92-496b-b3db-c0bfddb48788","version":4}
\ No newline at end of file
{"crypto":{"kdf":{"function":"pbkdf2","params":{"dklen":32,"c":262144,"prf":"hmac-sha256","salt":"b620fcfdbc893c53a9258cfeba99d0bae4c91d5fedfd524c0760b0ef81955fcb"},"message":""},"checksum":{"function":"sha256","params":{},"message":"5be9cf03728161cbf9b21fa068e6271ca43bc2f78c317a399266df7059a07f85"},"cipher":{"function":"aes-128-ctr","params":{"iv":"02303b2bf2f758d22d9972eec2c76c65"},"message":"94c15c0f66e86f134e1d5de55f0df1845639e0d16af9502f810e86c89aef1d5f"}},"description":"0xa77a318dd834183c3e3b3921c94b1dbb8d1bb2c619e0c492a592c2de5a91e73b5c054bba52619355ed34012386a7aa1d","pubkey":"a77a318dd834183c3e3b3921c94b1dbb8d1bb2c619e0c492a592c2de5a91e73b5c054bba52619355ed34012386a7aa1d","path":"","uuid":"8579d9bb-fa7c-4745-9c7f-83e278b1ec2b","version":4}
\ No newline at end of file
{"crypto":{"kdf":{"function":"pbkdf2","params":{"dklen":32,"c":262144,"prf":"hmac-sha256","salt":"9126c985f9ee3ab128e78500a926e60669f67f54802705f662bb0a1f5740c233"},"message":""},"checksum":{"function":"sha256","params":{},"message":"51c35360d2f139904ea0f44a964b4d7f25c141de1c02376b7fcb7e5779081c4e"},"cipher":{"function":"aes-128-ctr","params":{"iv":"7de0ffb22a5cd001395f309b71f7538b"},"message":"487754759dfc5a284b348e044288a0908ca5c935706916c78bce755ad5cf94a8"}},"description":"0xa86404df6d392d2ba08e01a3a967bfd58f081f45bec4e68bf91302f1918870f80719e78a33fa95c520e929e0d58bf38c","pubkey":"a86404df6d392d2ba08e01a3a967bfd58f081f45bec4e68bf91302f1918870f80719e78a33fa95c520e929e0d58bf38c","path":"","uuid":"252dc4ff-21e1-4930-8c61-547fd903c716","version":4}
\ No newline at end of file
{"crypto":{"kdf":{"function":"pbkdf2","params":{"dklen":32,"c":262144,"prf":"hmac-sha256","salt":"b0def3e91ec4fe4aca05b11da303cc0472be06b1b37bb04f1bf7d29e8cfb6675"},"message":""},"checksum":{"function":"sha256","params":{},"message":"b900dfdf5a139c495e17607c828e21eae187ec47b2b9d15e64e675772faa9f98"},"cipher":{"function":"aes-128-ctr","params":{"iv":"6adf8ac8e67682f32ff136d4229436de"},"message":"477e2ea41df26888050d30e470b1ac50869892b04b13b8efd036ca649152e790"}},"description":"0xa8a4c939ec0ee6ff6c58ace82cb82a603fd246defc10fdb37f6d66b5d1f2a1f9fa962547f87ec3aa611402f00bcec0a8","pubkey":"a8a4c939ec0ee6ff6c58ace82cb82a603fd246defc10fdb37f6d66b5d1f2a1f9fa962547f87ec3aa611402f00bcec0a8","path":"","uuid":"5782dbdf-d91a-4c96-894b-5d57457dcc84","version":4}
\ No newline at end of file
{"crypto":{"kdf":{"function":"pbkdf2","params":{"dklen":32,"c":262144,"prf":"hmac-sha256","salt":"1f9025f171884d87f597274b409f55d899e9a7641ced4e5017505305e6437328"},"message":""},"checksum":{"function":"sha256","params":{},"message":"c4802211a62b4e0cd74267065dea7b4271e72102598804cf723bc8b95ac696e2"},"cipher":{"function":"aes-128-ctr","params":{"iv":"8b3ca528f1778b95100feadbc56c6fe1"},"message":"98e9efb3e8632377236d8584793020a7cc0af6b7765ad243de9dcaef7877949e"}},"description":"0xa8b7eaa52875524b0b4716b56d2f377cb878ceb51b925c0a7fa4629f16b2a8161e28aed5c6446ff1889ab7473c86b6f3","pubkey":"a8b7eaa52875524b0b4716b56d2f377cb878ceb51b925c0a7fa4629f16b2a8161e28aed5c6446ff1889ab7473c86b6f3","path":"","uuid":"ef4f908e-ee90-45ec-b717-68e77cc2f831","version":4}
\ No newline at end of file
{"crypto":{"kdf":{"function":"pbkdf2","params":{"dklen":32,"c":262144,"prf":"hmac-sha256","salt":"847ff0062d2cd5094de172d71c0bdc9832101f1ee07800fb62a7cd55e91efc6c"},"message":""},"checksum":{"function":"sha256","params":{},"message":"389a2e456fdccf2e5ed889510a17994c7dab12cd69962474652905fcf80002f7"},"cipher":{"function":"aes-128-ctr","params":{"iv":"aab0815923a903318a92b73f7467f8d1"},"message":"9823d3cad661f6328673e1ce251fe452072f0cce1c01ace15eaa772d3714e409"}},"description":"0xa90d4602211e30aa9f2d0fdb179bd113492028ca5e0da87871c18777fa8ecd3162a4085ddf7582f65803111715a22d01","pubkey":"a90d4602211e30aa9f2d0fdb179bd113492028ca5e0da87871c18777fa8ecd3162a4085ddf7582f65803111715a22d01","path":"","uuid":"7aae888f-6c7e-45e4-8cbd-91422970b0d3","version":4}
\ No newline at end of file
{"crypto":{"kdf":{"function":"pbkdf2","params":{"dklen":32,"c":262144,"prf":"hmac-sha256","salt":"5fe9757abf49bbadcc35c1cf08e9484846149a3dabe51a43c537117a6eae31f5"},"message":""},"checksum":{"function":"sha256","params":{},"message":"83bcd6e426a7b4dccc3540c81b582a9be8c8267452270a15a6f5c6b6eab66769"},"cipher":{"function":"aes-128-ctr","params":{"iv":"f69a4d31d0e2c8637419e70eb98e63d3"},"message":"7579945e9a0f1e73a729f46a691922d3047fb1fbdcc3dbb9f49b03764fefd2a9"}},"description":"0xa960c5230b2348f3121d891aeabb2d3598893f7d32c675b6a4ef40a1331fe4b9010150dffd379e3216b3dcf0edb23259","pubkey":"a960c5230b2348f3121d891aeabb2d3598893f7d32c675b6a4ef40a1331fe4b9010150dffd379e3216b3dcf0edb23259","path":"","uuid":"c27373e5-c738-401c-9551-76682c2665b2","version":4}
\ No newline at end of file
{"crypto":{"kdf":{"function":"pbkdf2","params":{"dklen":32,"c":262144,"prf":"hmac-sha256","salt":"ba21660ec1ce6e70318886da4525be863f49040d147f92fb6a2821f273ac828e"},"message":""},"checksum":{"function":"sha256","params":{},"message":"21d7b3a88c0e33e9a315138868bd744925eeb20f92f5019be7cbcaac3ee6f44b"},"cipher":{"function":"aes-128-ctr","params":{"iv":"d6254ab979c3117c47c5af3a59103440"},"message":"f50504dc23aa0d2db36f805ebb6bc50a49cb5d06a473a0e7ecfe822d76982578"}},"description":"0xaacaf07d7ade408847d18ef8410f6da332ab0a370c337007e64ce98343369aac023e825f2b8e72e8ed34e2b064577a4b","pubkey":"aacaf07d7ade408847d18ef8410f6da332ab0a370c337007e64ce98343369aac023e825f2b8e72e8ed34e2b064577a4b","path":"","uuid":"27670283-e5f4-4f29-a8bc-136fec31839e","version":4}
\ No newline at end of file
{"crypto":{"kdf":{"function":"pbkdf2","params":{"dklen":32,"c":262144,"prf":"hmac-sha256","salt":"be554291d05cd0afb52d8537bf5616b49d0424009d1ca203830ba508725634c8"},"message":""},"checksum":{"function":"sha256","params":{},"message":"fb6ea8e5c528a41307f8a6e1303118766dd082c07ffa64d300e8e8edd0e30b85"},"cipher":{"function":"aes-128-ctr","params":{"iv":"a881e24cacbea534e7bcb65befbfdcdb"},"message":"d53e6b55bf042dbe8fbfa6fabcd028abfd2bc7bb16356e517a978b12002ea33c"}},"description":"0xab0b0a68c9ab8ef73338f8ee1bce7bdfb4fdd1020b4163bec31b952651141db4c8db7fc4b0c97cb8645ad2a58344c1c8","pubkey":"ab0b0a68c9ab8ef73338f8ee1bce7bdfb4fdd1020b4163bec31b952651141db4c8db7fc4b0c97cb8645ad2a58344c1c8","path":"","uuid":"7f5b50fc-7739-40c3-b0ff-b879d5533ecd","version":4}
\ No newline at end of file
{"crypto":{"kdf":{"function":"pbkdf2","params":{"dklen":32,"c":262144,"prf":"hmac-sha256","salt":"cc86f1102953b50f239e50cd5d0508bf27d31f01723050c71053f4e68942b061"},"message":""},"checksum":{"function":"sha256","params":{},"message":"d444a4a2dd65f7ed26a595b1d4c05e45cddfc773981aba5246adbf8ad3c82a58"},"cipher":{"function":"aes-128-ctr","params":{"iv":"7756fd2a98414d9eee07550ca742af68"},"message":"108d3b282a3f0afe594743a75019cc41eafcda5f29d9e35a2356e9ff43c0e004"}},"description":"0xae23fb1b0c76e4fd9800c18945094932655fa3a6aea990392c08c16e9816b3637b3818f609bf774e7277aa9901f1140a","pubkey":"ae23fb1b0c76e4fd9800c18945094932655fa3a6aea990392c08c16e9816b3637b3818f609bf774e7277aa9901f1140a","path":"","uuid":"2c10b4f1-5d20-4378-bd31-e84961da09b3","version":4}
\ No newline at end of file
{"crypto":{"kdf":{"function":"pbkdf2","params":{"dklen":32,"c":262144,"prf":"hmac-sha256","salt":"9a852ed9a9cc2911a4bb731219b6e1926eea780ff5918944949a855ef6ac2da3"},"message":""},"checksum":{"function":"sha256","params":{},"message":"d9a713c7c22d1e8a587e7f3ae62f436b2f91569e3bed454e72ddb0d642c5bda6"},"cipher":{"function":"aes-128-ctr","params":{"iv":"6b55b4251902cf6385d1d9c3d300271e"},"message":"f6bb3548d1f615b09b93caf991ab90dc502348fdc58f8f94b5fc8c0f00dfa980"}},"description":"0xae809a58eb62ac77b1a9c4b0ba4a3e3dc5024027de9f568cc91b66f1b7426feb4dfc61a5b8117c51c6a0c92f007a29ca","pubkey":"ae809a58eb62ac77b1a9c4b0ba4a3e3dc5024027de9f568cc91b66f1b7426feb4dfc61a5b8117c51c6a0c92f007a29ca","path":"","uuid":"50ed2d49-fd6f-4e32-99e5-05a357b451a6","version":4}
\ No newline at end of file
{"crypto":{"kdf":{"function":"pbkdf2","params":{"dklen":32,"c":262144,"prf":"hmac-sha256","salt":"69361a0225b597776b65529a5268695afdf7c4cd28e7f90909766904701036d5"},"message":""},"checksum":{"function":"sha256","params":{},"message":"084d097dcce0b0df53c6a1b20d3dbb93c9b11cef8822153c1fd4f9853ed06d43"},"cipher":{"function":"aes-128-ctr","params":{"iv":"be7718e336eb310145f16f834b1e2a0f"},"message":"adfbc37561cbe1aeb30ac4f3fa761ee51d8b11e5aa2abf656bf66bbe6322544a"}},"description":"0xaf88318ed207829fe806e3a78499a64d13b0cf033812d949cf0f0446bba2fc38fc50a311156c3439f11885b05a340f74","pubkey":"af88318ed207829fe806e3a78499a64d13b0cf033812d949cf0f0446bba2fc38fc50a311156c3439f11885b05a340f74","path":"","uuid":"f7cc37c5-0aca-4fa0-bd05-16bdcfe3f717","version":4}
\ No newline at end of file
{"crypto":{"kdf":{"function":"pbkdf2","params":{"dklen":32,"c":262144,"prf":"hmac-sha256","salt":"f6775f8e221aa31b35a0c18b2c40f92eb0b38e8030d90db3015c1f1c58fc9556"},"message":""},"checksum":{"function":"sha256","params":{},"message":"15f2f960449114b53943779ba11638fb4901f34a2daa0fc2db86c38a67cceb88"},"cipher":{"function":"aes-128-ctr","params":{"iv":"e2f8295bbd79b81a9262fd9793592e0c"},"message":"c3ccdf3ae5d9521790484bf30927dd4df5538089769867937f59366a7cc7a516"}},"description":"0xaff9f2432d328bba781aa2a6bac512a225d2a528cbe83eeb542c3e51defa5e6c4681955f2a5300f23b98e86aa64fb735","pubkey":"aff9f2432d328bba781aa2a6bac512a225d2a528cbe83eeb542c3e51defa5e6c4681955f2a5300f23b98e86aa64fb735","path":"","uuid":"74842e8b-3c17-4e34-8301-c2da372a4f2c","version":4}
\ No newline at end of file
{"crypto":{"kdf":{"function":"pbkdf2","params":{"dklen":32,"c":262144,"prf":"hmac-sha256","salt":"8018c4ef812975a38c1bcdfe1ea416788f3d75f2eed253dd66169a36cdccd980"},"message":""},"checksum":{"function":"sha256","params":{},"message":"f61b31ecb3442886834db3d876e6335040dd3aa79628710b7a71ace7b2a57bd3"},"cipher":{"function":"aes-128-ctr","params":{"iv":"ba502cb72793bbecf09bd2abd1f9eb91"},"message":"2ffd8d94499affce1a12fdb56f64dd4e121fa2e7785e64c434f07af939297825"}},"description":"0xb0591fe44b7eba93e4f088344d0b924bbe3c7ed9bfb42bf0193ea020f2c7eb8a53c8ebcb0d0f929201c399230005f3e7","pubkey":"b0591fe44b7eba93e4f088344d0b924bbe3c7ed9bfb42bf0193ea020f2c7eb8a53c8ebcb0d0f929201c399230005f3e7","path":"","uuid":"35466570-87e6-4fa6-9501-c51b237c3264","version":4}
\ No newline at end of file
{"crypto":{"kdf":{"function":"pbkdf2","params":{"dklen":32,"c":262144,"prf":"hmac-sha256","salt":"9bdf0f8ada04db3009f371f03f9982b1226bf643c6bf061c0a5cfdff450abeae"},"message":""},"checksum":{"function":"sha256","params":{},"message":"dc5aae2966367d7df5db0142c6fd9d843728871020d3033f22fba235ffa5c002"},"cipher":{"function":"aes-128-ctr","params":{"iv":"b9261a9008e086c50b590b726d2cba12"},"message":"452be06e5336656fa83ed2ce330f6a0ac604e916603d05aade62d30bf3084e95"}},"description":"0xb154fd14f7e9c617a1845078cc17f838621b4cfc1279eb11bd11afa4d913f0230cf81feda1f2b0f7bd7eb7a26d51cd28","pubkey":"b154fd14f7e9c617a1845078cc17f838621b4cfc1279eb11bd11afa4d913f0230cf81feda1f2b0f7bd7eb7a26d51cd28","path":"","uuid":"40d4cb00-c0e0-481a-9260-352284d6931a","version":4}
\ No newline at end of file
{"crypto":{"kdf":{"function":"pbkdf2","params":{"dklen":32,"c":262144,"prf":"hmac-sha256","salt":"b052e1293f780d4f59fdca1d5a04bfe955b7cc217f355d0d93fe68e3afa7da3d"},"message":""},"checksum":{"function":"sha256","params":{},"message":"8464b7a7202ce59cda9ba32bc7cbdf45bb2bf56ba2979cf17d0e0b2e1be91ca4"},"cipher":{"function":"aes-128-ctr","params":{"iv":"b88305786708e267a2b53d98bbb4b356"},"message":"c5a00ed0a845f9156c897bd17fd283ab3d49c3fe89b250a2879f54232fc650dd"}},"description":"0xb178bccfd693edfb8d163a2050dfb251b2a4d5b4e4a7b3787354964159d9f4d0890a263601eeeff5c8a0663486b3fca8","pubkey":"b178bccfd693edfb8d163a2050dfb251b2a4d5b4e4a7b3787354964159d9f4d0890a263601eeeff5c8a0663486b3fca8","path":"","uuid":"4294e300-689f-40c7-9163-c00f85a6bccb","version":4}
\ No newline at end of file
{"crypto":{"kdf":{"function":"pbkdf2","params":{"dklen":32,"c":262144,"prf":"hmac-sha256","salt":"2b68195855fe007ea47dbaf06854e0c013a5eacd92f0bb8de04b5e733c7bcf53"},"message":""},"checksum":{"function":"sha256","params":{},"message":"9db460ecd97d68516c6c8c95de3b584dcc638c59bc279c250ea33bb14e1f90e5"},"cipher":{"function":"aes-128-ctr","params":{"iv":"09a47646d984c74c0c5e3eeb4fa36cb0"},"message":"b73778ed355bcb1b96988cc50c5b298159e7aff6c2047bc0ce85c2bcab50c525"}},"description":"0xb22df594adad3ae08c339d6e2079ec7b4c69cab5e8f5fb55680221ba40ffcd384844639a8775af10f3d02d10a5b18dab","pubkey":"b22df594adad3ae08c339d6e2079ec7b4c69cab5e8f5fb55680221ba40ffcd384844639a8775af10f3d02d10a5b18dab","path":"","uuid":"44458937-3370-4fff-924f-1d45280dd915","version":4}
\ No newline at end of file
{"crypto":{"kdf":{"function":"pbkdf2","params":{"dklen":32,"c":262144,"prf":"hmac-sha256","salt":"172f598c2094d101f495e0fb5810dd13cb6028426740841fbc40b1488d7a5e37"},"message":""},"checksum":{"function":"sha256","params":{},"message":"b6bca817fe232b3310f057c41c207f9c9cbcbfd3ba960d869ef0060ebb70f414"},"cipher":{"function":"aes-128-ctr","params":{"iv":"0ebe408ff1c454481b322a843a6b5e45"},"message":"7a05be68d7e6eb885c14c6d63335891c5bbe221080d9c2e4d392a40db8a990af"}},"description":"0xb2c65e1c252c703d96a29edc5e4b6d22b905a560842a2cebe06842182e9bc783e7be6def84e8332173e120c8fdd633f1","pubkey":"b2c65e1c252c703d96a29edc5e4b6d22b905a560842a2cebe06842182e9bc783e7be6def84e8332173e120c8fdd633f1","path":"","uuid":"8768f03f-8521-4590-8ab5-b48b535b9cce","version":4}
\ No newline at end of file
{"crypto":{"kdf":{"function":"pbkdf2","params":{"dklen":32,"c":262144,"prf":"hmac-sha256","salt":"3b38d4a0a1e98af0ecf09e5143977d555e67c1e442e8c97e4d886f533158a949"},"message":""},"checksum":{"function":"sha256","params":{},"message":"cc90c4fc06312d486af9344f0a984fb66c2d5e988debfc24c608c5a5869a5b47"},"cipher":{"function":"aes-128-ctr","params":{"iv":"1ff23925adda4503082fd3f3266fc0f7"},"message":"0ecb62eee6351b0048b75f55cb9ccf3a8db83f9a995869ef3e6d8ec9c49513de"}},"description":"0xb35142bcfe0b34acd33d38a42af340f3d4c033a5ded38b7cb186ca368c011d39cf82f782d810c6941e541b8df9041940","pubkey":"b35142bcfe0b34acd33d38a42af340f3d4c033a5ded38b7cb186ca368c011d39cf82f782d810c6941e541b8df9041940","path":"","uuid":"8c0d8f10-047f-4ea8-8f2f-00ca5b2163b9","version":4}
\ No newline at end of file
{"crypto":{"kdf":{"function":"pbkdf2","params":{"dklen":32,"c":262144,"prf":"hmac-sha256","salt":"7101309649b9a6f975535fe18e535f7d1670a3398ed1ca01ab267766d5e8972a"},"message":""},"checksum":{"function":"sha256","params":{},"message":"3d7b66005e008f50ceb2058c8cb671b5615e6c4d7d59fe41e5cb099ef1c5e78e"},"cipher":{"function":"aes-128-ctr","params":{"iv":"7e000b001c57805226c6f77b19abd454"},"message":"f7720aabec498d140fcb2af93d0a9f648c7350a2d258a6a79ae1dd177309b059"}},"description":"0xb37774192885fd4974e3621e13020acb2208c2b25f0754d3ee5d606fe98da22f9dc64db33d9744422250f643594c0b2b","pubkey":"b37774192885fd4974e3621e13020acb2208c2b25f0754d3ee5d606fe98da22f9dc64db33d9744422250f643594c0b2b","path":"","uuid":"c2ffefc5-8f61-47dc-8deb-99b66f6b0a04","version":4}
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment