Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
N
nebula
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
exchain
nebula
Commits
78bd8d8a
Unverified
Commit
78bd8d8a
authored
Mar 02, 2023
by
mergify[bot]
Committed by
GitHub
Mar 02, 2023
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'develop' into aj/devnet-updates
parents
b5ef081a
551c4198
Changes
20
Show whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
205 additions
and
126 deletions
+205
-126
nasty-chairs-agree.md
.changeset/nasty-chairs-agree.md
+5
-0
config.yml
.circleci/config.yml
+1
-2
CODEOWNERS
.github/CODEOWNERS
+1
-0
channel_builder.go
op-batcher/batcher/channel_builder.go
+87
-40
channel_manager.go
op-batcher/batcher/channel_manager.go
+11
-12
config.go
op-batcher/batcher/config.go
+24
-13
driver.go
op-batcher/batcher/driver.go
+8
-7
flags.go
op-batcher/flags/flags.go
+8
-1
migration_test.go
op-e2e/migration_test.go
+4
-3
setup.go
op-e2e/setup.go
+4
-24
system_test.go
op-e2e/system_test.go
+3
-3
system_tob_test.go
op-e2e/system_tob_test.go
+3
-4
docker-compose.yml
ops-bedrock/docker-compose.yml
+4
-3
cli.ts
packages/atst/src/cli.ts
+11
-1
index.ts
packages/atst/src/index.ts
+2
-0
encodeRawKey.ts
packages/atst/src/lib/encodeRawKey.ts
+5
-3
parseAttestationBytes.spec.ts
packages/atst/src/lib/parseAttestationBytes.spec.ts
+12
-2
parseAttestationBytes.ts
packages/atst/src/lib/parseAttestationBytes.ts
+1
-1
readAttestation.spec.ts
packages/atst/src/lib/readAttestation.spec.ts
+0
-1
stringifyAttestationBytes.ts
packages/atst/src/lib/stringifyAttestationBytes.ts
+11
-6
No files found.
.changeset/nasty-chairs-agree.md
0 → 100644
View file @
78bd8d8a
---
'
@eth-optimism/atst'
:
minor
---
Fix string type that should be
`0x${string}`
.circleci/config.yml
View file @
78bd8d8a
...
@@ -525,8 +525,7 @@ jobs:
...
@@ -525,8 +525,7 @@ jobs:
# constraint that gotestsum does not currently (nor likely will) accept files from different pacakges when building.
# constraint that gotestsum does not currently (nor likely will) accept files from different pacakges when building.
OP_TESTLOG_DISABLE_COLOR=true OP_E2E_DISABLE_PARALLEL=true OP_E2E_USE_HTTP=<<parameters.use_http>> gotestsum \
OP_TESTLOG_DISABLE_COLOR=true OP_E2E_DISABLE_PARALLEL=true OP_E2E_USE_HTTP=<<parameters.use_http>> gotestsum \
--format=standard-verbose --junitfile=/tmp/test-results/<<parameters.module>>_http_<<parameters.use_http>>.xml \
--format=standard-verbose --junitfile=/tmp/test-results/<<parameters.module>>_http_<<parameters.use_http>>.xml \
./... \
-- -timeout=20m ./...
-- -timeout=20m
working_directory
:
<<parameters.module>>
working_directory
:
<<parameters.module>>
-
store_test_results
:
-
store_test_results
:
path
:
/tmp/test-results
path
:
/tmp/test-results
...
...
.github/CODEOWNERS
View file @
78bd8d8a
...
@@ -19,6 +19,7 @@
...
@@ -19,6 +19,7 @@
/packages/migration-data @ethereum-optimism/legacy-reviewers
/packages/migration-data @ethereum-optimism/legacy-reviewers
/packages/replica-healthcheck @ethereum-optimism/legacy-reviewers
/packages/replica-healthcheck @ethereum-optimism/legacy-reviewers
/packages/sdk @ethereum-optimism/ecopod
/packages/sdk @ethereum-optimism/ecopod
/packages/atst @ethereum-optimism/ecopod
# Bedrock codebases
# Bedrock codebases
/bedrock-devnet @ethereum-optimism/go-reviewers
/bedrock-devnet @ethereum-optimism/go-reviewers
...
...
op-batcher/batcher/channel_builder.go
View file @
78bd8d8a
...
@@ -18,6 +18,15 @@ type ChannelConfig struct {
...
@@ -18,6 +18,15 @@ type ChannelConfig struct {
// The maximum number of L1 blocks that the inclusion transactions of a
// The maximum number of L1 blocks that the inclusion transactions of a
// channel's frames can span.
// channel's frames can span.
ChannelTimeout
uint64
ChannelTimeout
uint64
// Builder Config
// MaxChannelDuration is the maximum duration (in #L1-blocks) to keep the
// channel open. This allows control over how long a channel is kept open
// during times of low transaction volume.
//
// If 0, duration checks are disabled.
MaxChannelDuration
uint64
// The batcher tx submission safety margin (in #L1-blocks) to subtract from
// The batcher tx submission safety margin (in #L1-blocks) to subtract from
// a channel's timeout and sequencing window, to guarantee safe inclusion of
// a channel's timeout and sequencing window, to guarantee safe inclusion of
// a channel on L1.
// a channel on L1.
...
@@ -50,12 +59,17 @@ func (c ChannelConfig) InputThreshold() uint64 {
...
@@ -50,12 +59,17 @@ func (c ChannelConfig) InputThreshold() uint64 {
type
channelBuilder
struct
{
type
channelBuilder
struct
{
cfg
ChannelConfig
cfg
ChannelConfig
// L1 block timestamp of combined channel & sequencing window timeout. 0 if
// L1 block number timeout of combined
// no timeout set yet.
// - channel duration timeout,
// - consensus channel timeout,
// - sequencing window timeout.
// 0 if no block number timeout set yet.
timeout
uint64
timeout
uint64
// reason for currently set timeout
timeoutReason
error
//
marked as full if a) max RLP input bytes, b) max num frames or c) max
//
Reason for the channel being full. Set by setFullErr so it's always
//
allowed frame index (uint16) has been reached
//
guaranteed to be a ChannelFullError wrapping the specific reason.
fullErr
error
fullErr
error
// current channel
// current channel
co
*
derive
.
ChannelOut
co
*
derive
.
ChannelOut
...
@@ -102,28 +116,6 @@ func (c *channelBuilder) Reset() error {
...
@@ -102,28 +116,6 @@ func (c *channelBuilder) Reset() error {
return
c
.
co
.
Reset
()
return
c
.
co
.
Reset
()
}
}
// FramePublished calculates the submission timeout of this channel from the
// given frame inclusion L1-block number. If an older frame tx has already been
// seen, the timeout is not updated.
func
(
c
*
channelBuilder
)
FramePublished
(
l1BlockNum
uint64
)
{
timeout
:=
l1BlockNum
+
c
.
cfg
.
ChannelTimeout
-
c
.
cfg
.
SubSafetyMargin
c
.
updateTimeout
(
timeout
)
}
// TimedOut returns whether the passed block number is after the channel timeout
// block. If no block timeout is set yet, it returns false.
func
(
c
*
channelBuilder
)
TimedOut
(
blockNum
uint64
)
bool
{
return
c
.
timeout
!=
0
&&
blockNum
>=
c
.
timeout
}
// CheckTimeout checks if the channel is timed out at the given block number and
// in this case marks the channel as full with reason ErrChannelTimedOut.
func
(
c
*
channelBuilder
)
CheckTimeout
(
blockNum
uint64
)
{
if
!
c
.
IsFull
()
&&
c
.
TimedOut
(
blockNum
)
{
c
.
setFullErr
(
ErrChannelTimedOut
)
}
}
// AddBlock adds a block to the channel compression pipeline. IsFull should be
// AddBlock adds a block to the channel compression pipeline. IsFull should be
// called aftewards to test whether the channel is full. If full, a new channel
// called aftewards to test whether the channel is full. If full, a new channel
// must be started.
// must be started.
...
@@ -151,7 +143,7 @@ func (c *channelBuilder) AddBlock(block *types.Block) error {
...
@@ -151,7 +143,7 @@ func (c *channelBuilder) AddBlock(block *types.Block) error {
c
.
blocks
=
append
(
c
.
blocks
,
block
)
c
.
blocks
=
append
(
c
.
blocks
,
block
)
c
.
updateSwTimeout
(
batch
)
c
.
updateSwTimeout
(
batch
)
if
c
.
I
nputTargetReached
()
{
if
c
.
i
nputTargetReached
()
{
c
.
setFullErr
(
ErrInputTargetReached
)
c
.
setFullErr
(
ErrInputTargetReached
)
// Adding this block still worked, so don't return error, just mark as full
// Adding this block still worked, so don't return error, just mark as full
}
}
...
@@ -159,25 +151,76 @@ func (c *channelBuilder) AddBlock(block *types.Block) error {
...
@@ -159,25 +151,76 @@ func (c *channelBuilder) AddBlock(block *types.Block) error {
return
nil
return
nil
}
}
// Timeout management
// RegisterL1Block should be called whenever a new L1-block is seen.
//
// It ensures proper tracking of all possible timeouts (max channel duration,
// close to consensus channel timeout, close to end of sequencing window).
func
(
c
*
channelBuilder
)
RegisterL1Block
(
l1BlockNum
uint64
)
{
c
.
updateDurationTimeout
(
l1BlockNum
)
c
.
checkTimeout
(
l1BlockNum
)
}
// FramePublished should be called whenever a frame of this channel got
// published with the L1-block number of the block that the frame got included
// in.
func
(
c
*
channelBuilder
)
FramePublished
(
l1BlockNum
uint64
)
{
timeout
:=
l1BlockNum
+
c
.
cfg
.
ChannelTimeout
-
c
.
cfg
.
SubSafetyMargin
c
.
updateTimeout
(
timeout
,
ErrChannelTimeoutClose
)
}
// updateDurationTimeout updates the block timeout with the channel duration
// timeout derived from the given L1-block number. The timeout is only moved
// forward if the derived timeout is earlier than the currently set timeout.
//
// It does nothing if the max channel duration is set to 0.
func
(
c
*
channelBuilder
)
updateDurationTimeout
(
l1BlockNum
uint64
)
{
if
c
.
cfg
.
MaxChannelDuration
==
0
{
return
}
timeout
:=
l1BlockNum
+
c
.
cfg
.
MaxChannelDuration
c
.
updateTimeout
(
timeout
,
ErrMaxDurationReached
)
}
// updateSwTimeout updates the block timeout with the sequencer window timeout
// updateSwTimeout updates the block timeout with the sequencer window timeout
// derived from the batch's origin L1 block. The timeout is only moved forward
// derived from the batch's origin L1 block. The timeout is only moved forward
// if the derived sequencer window timeout is earlier than the current.
// if the derived sequencer window timeout is earlier than the currently set
// timeout.
func
(
c
*
channelBuilder
)
updateSwTimeout
(
batch
*
derive
.
BatchData
)
{
func
(
c
*
channelBuilder
)
updateSwTimeout
(
batch
*
derive
.
BatchData
)
{
timeout
:=
uint64
(
batch
.
EpochNum
)
+
c
.
cfg
.
SeqWindowSize
-
c
.
cfg
.
SubSafetyMargin
timeout
:=
uint64
(
batch
.
EpochNum
)
+
c
.
cfg
.
SeqWindowSize
-
c
.
cfg
.
SubSafetyMargin
c
.
updateTimeout
(
timeout
)
c
.
updateTimeout
(
timeout
,
ErrSeqWindowClose
)
}
}
// updateTimeout updates the timeout block to the given block number if it is
// updateTimeout updates the timeout block to the given block number if it is
// earlier then the current block timeout, or if it still unset.
// earlier than the current block timeout, or if it still unset.
func
(
c
*
channelBuilder
)
updateTimeout
(
timeoutBlockNum
uint64
)
{
//
// If the timeout is updated, the provided reason will be set as the channel
// full error reason in case the timeout is hit in the future.
func
(
c
*
channelBuilder
)
updateTimeout
(
timeoutBlockNum
uint64
,
reason
error
)
{
if
c
.
timeout
==
0
||
c
.
timeout
>
timeoutBlockNum
{
if
c
.
timeout
==
0
||
c
.
timeout
>
timeoutBlockNum
{
c
.
timeout
=
timeoutBlockNum
c
.
timeout
=
timeoutBlockNum
c
.
timeoutReason
=
reason
}
}
}
}
// InputTargetReached says whether the target amount of input data has been
// checkTimeout checks if the channel is timed out at the given block number and
// in this case marks the channel as full, if it wasn't full alredy.
func
(
c
*
channelBuilder
)
checkTimeout
(
blockNum
uint64
)
{
if
!
c
.
IsFull
()
&&
c
.
TimedOut
(
blockNum
)
{
c
.
setFullErr
(
c
.
timeoutReason
)
}
}
// TimedOut returns whether the passed block number is after the timeout block
// number. If no block timeout is set yet, it returns false.
func
(
c
*
channelBuilder
)
TimedOut
(
blockNum
uint64
)
bool
{
return
c
.
timeout
!=
0
&&
blockNum
>=
c
.
timeout
}
// inputTargetReached says whether the target amount of input data has been
// reached in this channel builder. No more blocks can be added afterwards.
// reached in this channel builder. No more blocks can be added afterwards.
func
(
c
*
channelBuilder
)
I
nputTargetReached
()
bool
{
func
(
c
*
channelBuilder
)
i
nputTargetReached
()
bool
{
return
uint64
(
c
.
co
.
InputBytes
())
>=
c
.
cfg
.
InputThreshold
()
return
uint64
(
c
.
co
.
InputBytes
())
>=
c
.
cfg
.
InputThreshold
()
}
}
...
@@ -190,14 +233,16 @@ func (c *channelBuilder) IsFull() bool {
...
@@ -190,14 +233,16 @@ func (c *channelBuilder) IsFull() bool {
// FullErr returns the reason why the channel is full. If not full yet, it
// FullErr returns the reason why the channel is full. If not full yet, it
// returns nil.
// returns nil.
//
//
// It returns a ChannelFullError wrapping one of
four
possible reasons for the
// It returns a ChannelFullError wrapping one of
six
possible reasons for the
// channel being full:
// channel being full:
// - ErrInputTargetReached if the target amount of input data has been reached,
// - ErrInputTargetReached if the target amount of input data has been reached,
// - derive.MaxRLPBytesPerChannel if the general maximum amount of input data
// - derive.MaxRLPBytesPerChannel if the general maximum amount of input data
// would have been exceeded by the latest AddBlock call,
// would have been exceeded by the latest AddBlock call,
// - ErrMaxFrameIndex if the maximum number of frames has been generated
// - ErrMaxFrameIndex if the maximum number of frames has been generated
// (uint16),
// (uint16),
// - ErrChannelTimedOut if the batcher channel timeout has been reached.
// - ErrMaxDurationReached if the max channel duration got reached.
// - ErrChannelTimeoutClose if the consensus channel timeout got too close.
// - ErrSeqWindowClose if the end of the sequencer window got too close.
func
(
c
*
channelBuilder
)
FullErr
()
error
{
func
(
c
*
channelBuilder
)
FullErr
()
error
{
return
c
.
fullErr
return
c
.
fullErr
}
}
...
@@ -210,9 +255,9 @@ func (c *channelBuilder) setFullErr(err error) {
...
@@ -210,9 +255,9 @@ func (c *channelBuilder) setFullErr(err error) {
// after AddBlock and before iterating over available frames with HasFrame and
// after AddBlock and before iterating over available frames with HasFrame and
// NextFrame.
// NextFrame.
//
//
// If the
input data target hasn't been reached
yet, it will conservatively only
// If the
channel isn't full
yet, it will conservatively only
// pull readily available frames from the compression output.
// pull readily available frames from the compression output.
// If
the target has been reached
, the channel is closed and all remaining
// If
it is full
, the channel is closed and all remaining
// frames will be created, possibly with a small leftover frame.
// frames will be created, possibly with a small leftover frame.
func
(
c
*
channelBuilder
)
OutputFrames
()
error
{
func
(
c
*
channelBuilder
)
OutputFrames
()
error
{
if
c
.
IsFull
()
{
if
c
.
IsFull
()
{
...
@@ -320,7 +365,9 @@ func (c *channelBuilder) PushFrame(id txID, frame []byte) {
...
@@ -320,7 +365,9 @@ func (c *channelBuilder) PushFrame(id txID, frame []byte) {
var
(
var
(
ErrInputTargetReached
=
errors
.
New
(
"target amount of input data reached"
)
ErrInputTargetReached
=
errors
.
New
(
"target amount of input data reached"
)
ErrMaxFrameIndex
=
errors
.
New
(
"max frame index reached (uint16)"
)
ErrMaxFrameIndex
=
errors
.
New
(
"max frame index reached (uint16)"
)
ErrChannelTimedOut
=
errors
.
New
(
"channel timed out"
)
ErrMaxDurationReached
=
errors
.
New
(
"max channel duration reached"
)
ErrChannelTimeoutClose
=
errors
.
New
(
"close to channel timeout"
)
ErrSeqWindowClose
=
errors
.
New
(
"close to sequencer window timeout"
)
)
)
type
ChannelFullError
struct
{
type
ChannelFullError
struct
{
...
...
op-batcher/batcher/channel_manager.go
View file @
78bd8d8a
...
@@ -188,9 +188,6 @@ func (s *channelManager) nextTxData() ([]byte, txID, error) {
...
@@ -188,9 +188,6 @@ func (s *channelManager) nextTxData() ([]byte, txID, error) {
// It currently only uses one frame per transaction. If the pending channel is
// It currently only uses one frame per transaction. If the pending channel is
// full, it only returns the remaining frames of this channel until it got
// full, it only returns the remaining frames of this channel until it got
// successfully fully sent to L1. It returns io.EOF if there's no pending frame.
// successfully fully sent to L1. It returns io.EOF if there's no pending frame.
//
// It currently ignores the l1Head provided and doesn't track channel timeouts
// or the sequencer window span yet.
func
(
s
*
channelManager
)
TxData
(
l1Head
eth
.
BlockID
)
([]
byte
,
txID
,
error
)
{
func
(
s
*
channelManager
)
TxData
(
l1Head
eth
.
BlockID
)
([]
byte
,
txID
,
error
)
{
dataPending
:=
s
.
pendingChannel
!=
nil
&&
s
.
pendingChannel
.
HasFrame
()
dataPending
:=
s
.
pendingChannel
!=
nil
&&
s
.
pendingChannel
.
HasFrame
()
s
.
log
.
Debug
(
"Requested tx data"
,
"l1Head"
,
l1Head
,
"data_pending"
,
dataPending
,
"blocks_pending"
,
len
(
s
.
blocks
))
s
.
log
.
Debug
(
"Requested tx data"
,
"l1Head"
,
l1Head
,
"data_pending"
,
dataPending
,
"blocks_pending"
,
len
(
s
.
blocks
))
...
@@ -211,12 +208,15 @@ func (s *channelManager) TxData(l1Head eth.BlockID) ([]byte, txID, error) {
...
@@ -211,12 +208,15 @@ func (s *channelManager) TxData(l1Head eth.BlockID) ([]byte, txID, error) {
return
nil
,
txID
{},
err
return
nil
,
txID
{},
err
}
}
s
.
checkTimeout
(
l1Head
)
if
err
:=
s
.
processBlocks
();
err
!=
nil
{
if
err
:=
s
.
processBlocks
();
err
!=
nil
{
return
nil
,
txID
{},
err
return
nil
,
txID
{},
err
}
}
// Register current L1 head only after all pending blocks have been
// processed. Even if a timeout will be triggered now, it is better to have
// all pending blocks be included in this channel for submission.
s
.
registerL1Block
(
l1Head
)
if
err
:=
s
.
pendingChannel
.
OutputFrames
();
err
!=
nil
{
if
err
:=
s
.
pendingChannel
.
OutputFrames
();
err
!=
nil
{
return
nil
,
txID
{},
fmt
.
Errorf
(
"creating frames with channel builder: %w"
,
err
)
return
nil
,
txID
{},
fmt
.
Errorf
(
"creating frames with channel builder: %w"
,
err
)
}
}
...
@@ -239,14 +239,13 @@ func (s *channelManager) ensurePendingChannel(l1Head eth.BlockID) error {
...
@@ -239,14 +239,13 @@ func (s *channelManager) ensurePendingChannel(l1Head eth.BlockID) error {
return
nil
return
nil
}
}
// checkTimeout checks the block timeout on the pending channel.
// registerL1Block registers the given block at the pending channel.
func
(
s
*
channelManager
)
checkTimeout
(
l1Head
eth
.
BlockID
)
{
func
(
s
*
channelManager
)
registerL1Block
(
l1Head
eth
.
BlockID
)
{
s
.
pendingChannel
.
CheckTimeout
(
l1Head
.
Number
)
s
.
pendingChannel
.
RegisterL1Block
(
l1Head
.
Number
)
ferr
:=
s
.
pendingChannel
.
FullErr
()
s
.
log
.
Debug
(
"new L1-block registered at channel builder"
,
s
.
log
.
Debug
(
"timeout triggered"
,
"l1Head"
,
l1Head
,
"l1Head"
,
l1Head
,
"
timed_out"
,
errors
.
Is
(
ferr
,
ErrChannelTimedOut
),
"
channel_full"
,
s
.
pendingChannel
.
IsFull
(
),
"full_reason"
,
ferr
,
"full_reason"
,
s
.
pendingChannel
.
FullErr
()
,
)
)
}
}
...
...
op-batcher/batcher/config.go
View file @
78bd8d8a
...
@@ -47,6 +47,16 @@ type CLIConfig struct {
...
@@ -47,6 +47,16 @@ type CLIConfig struct {
// RollupRpc is the HTTP provider URL for the L2 rollup node.
// RollupRpc is the HTTP provider URL for the L2 rollup node.
RollupRpc
string
RollupRpc
string
// MaxChannelDuration is the maximum duration (in #L1-blocks) to keep a
// channel open. This allows to more eagerly send batcher transactions
// during times of low L2 transaction volume. Note that the effective
// L1-block distance between batcher transactions is then MaxChannelDuration
// + NumConfirmations because the batcher waits for NumConfirmations blocks
// after sending a batcher tx and only then starts a new channel.
//
// If 0, duration checks are disabled.
MaxChannelDuration
uint64
// The batcher tx submission safety margin (in #L1-blocks) to subtract from
// The batcher tx submission safety margin (in #L1-blocks) to subtract from
// a channel's timeout and sequencing window, to guarantee safe inclusion of
// a channel's timeout and sequencing window, to guarantee safe inclusion of
// a channel on L1.
// a channel on L1.
...
@@ -143,6 +153,7 @@ func NewConfig(ctx *cli.Context) CLIConfig {
...
@@ -143,6 +153,7 @@ func NewConfig(ctx *cli.Context) CLIConfig {
ResubmissionTimeout
:
ctx
.
GlobalDuration
(
flags
.
ResubmissionTimeoutFlag
.
Name
),
ResubmissionTimeout
:
ctx
.
GlobalDuration
(
flags
.
ResubmissionTimeoutFlag
.
Name
),
/* Optional Flags */
/* Optional Flags */
MaxChannelDuration
:
ctx
.
GlobalUint64
(
flags
.
MaxChannelDurationFlag
.
Name
),
MaxL1TxSize
:
ctx
.
GlobalUint64
(
flags
.
MaxL1TxSizeBytesFlag
.
Name
),
MaxL1TxSize
:
ctx
.
GlobalUint64
(
flags
.
MaxL1TxSizeBytesFlag
.
Name
),
TargetL1TxSize
:
ctx
.
GlobalUint64
(
flags
.
TargetL1TxSizeBytesFlag
.
Name
),
TargetL1TxSize
:
ctx
.
GlobalUint64
(
flags
.
TargetL1TxSizeBytesFlag
.
Name
),
TargetNumFrames
:
ctx
.
GlobalInt
(
flags
.
TargetNumFramesFlag
.
Name
),
TargetNumFrames
:
ctx
.
GlobalInt
(
flags
.
TargetNumFramesFlag
.
Name
),
...
...
op-batcher/batcher/driver.go
View file @
78bd8d8a
...
@@ -90,6 +90,7 @@ func NewBatchSubmitterFromCLIConfig(cfg CLIConfig, l log.Logger) (*BatchSubmitte
...
@@ -90,6 +90,7 @@ func NewBatchSubmitterFromCLIConfig(cfg CLIConfig, l log.Logger) (*BatchSubmitte
Channel
:
ChannelConfig
{
Channel
:
ChannelConfig
{
SeqWindowSize
:
rcfg
.
SeqWindowSize
,
SeqWindowSize
:
rcfg
.
SeqWindowSize
,
ChannelTimeout
:
rcfg
.
ChannelTimeout
,
ChannelTimeout
:
rcfg
.
ChannelTimeout
,
MaxChannelDuration
:
cfg
.
MaxChannelDuration
,
SubSafetyMargin
:
cfg
.
SubSafetyMargin
,
SubSafetyMargin
:
cfg
.
SubSafetyMargin
,
MaxFrameSize
:
cfg
.
MaxL1TxSize
-
1
,
// subtract 1 byte for version
MaxFrameSize
:
cfg
.
MaxL1TxSize
-
1
,
// subtract 1 byte for version
TargetFrameSize
:
cfg
.
TargetL1TxSize
-
1
,
// subtract 1 byte for version
TargetFrameSize
:
cfg
.
TargetL1TxSize
-
1
,
// subtract 1 byte for version
...
...
op-batcher/flags/flags.go
View file @
78bd8d8a
...
@@ -75,6 +75,12 @@ var (
...
@@ -75,6 +75,12 @@ var (
/* Optional flags */
/* Optional flags */
MaxChannelDurationFlag
=
cli
.
Uint64Flag
{
Name
:
"max-channel-duration"
,
Usage
:
"The maximum duration of L1-blocks to keep a channel open. 0 to disable."
,
Value
:
0
,
EnvVar
:
opservice
.
PrefixEnvVar
(
envVarPrefix
,
"MAX_CHANNEL_DURATION"
),
}
MaxL1TxSizeBytesFlag
=
cli
.
Uint64Flag
{
MaxL1TxSizeBytesFlag
=
cli
.
Uint64Flag
{
Name
:
"max-l1-tx-size-bytes"
,
Name
:
"max-l1-tx-size-bytes"
,
Usage
:
"The maximum size of a batch tx submitted to L1."
,
Usage
:
"The maximum size of a batch tx submitted to L1."
,
...
@@ -96,7 +102,7 @@ var (
...
@@ -96,7 +102,7 @@ var (
ApproxComprRatioFlag
=
cli
.
Float64Flag
{
ApproxComprRatioFlag
=
cli
.
Float64Flag
{
Name
:
"approx-compr-ratio"
,
Name
:
"approx-compr-ratio"
,
Usage
:
"The approximate compression ratio (<= 1.0)"
,
Usage
:
"The approximate compression ratio (<= 1.0)"
,
Value
:
1.0
,
Value
:
0.4
,
EnvVar
:
opservice
.
PrefixEnvVar
(
envVarPrefix
,
"APPROX_COMPR_RATIO"
),
EnvVar
:
opservice
.
PrefixEnvVar
(
envVarPrefix
,
"APPROX_COMPR_RATIO"
),
}
}
StoppedFlag
=
cli
.
BoolFlag
{
StoppedFlag
=
cli
.
BoolFlag
{
...
@@ -135,6 +141,7 @@ var requiredFlags = []cli.Flag{
...
@@ -135,6 +141,7 @@ var requiredFlags = []cli.Flag{
}
}
var
optionalFlags
=
[]
cli
.
Flag
{
var
optionalFlags
=
[]
cli
.
Flag
{
MaxChannelDurationFlag
,
MaxL1TxSizeBytesFlag
,
MaxL1TxSizeBytesFlag
,
TargetL1TxSizeBytesFlag
,
TargetL1TxSizeBytesFlag
,
TargetNumFramesFlag
,
TargetNumFramesFlag
,
...
...
op-e2e/migration_test.go
View file @
78bd8d8a
...
@@ -323,11 +323,12 @@ func TestMigration(t *testing.T) {
...
@@ -323,11 +323,12 @@ func TestMigration(t *testing.T) {
L1EthRpc
:
forkedL1URL
,
L1EthRpc
:
forkedL1URL
,
L2EthRpc
:
gethNode
.
WSEndpoint
(),
L2EthRpc
:
gethNode
.
WSEndpoint
(),
RollupRpc
:
rollupNode
.
HTTPEndpoint
(),
RollupRpc
:
rollupNode
.
HTTPEndpoint
(),
MaxChannelDuration
:
1
,
MaxL1TxSize
:
120
_000
,
MaxL1TxSize
:
120
_000
,
TargetL1TxSize
:
624
,
TargetL1TxSize
:
100
_000
,
TargetNumFrames
:
1
,
TargetNumFrames
:
1
,
ApproxComprRatio
:
1.0
,
ApproxComprRatio
:
0.4
,
SubSafetyMargin
:
testSafetyMargin
(
deployCfg
)
,
SubSafetyMargin
:
4
,
PollInterval
:
50
*
time
.
Millisecond
,
PollInterval
:
50
*
time
.
Millisecond
,
NumConfirmations
:
1
,
NumConfirmations
:
1
,
ResubmissionTimeout
:
5
*
time
.
Second
,
ResubmissionTimeout
:
5
*
time
.
Second
,
...
...
op-e2e/setup.go
View file @
78bd8d8a
...
@@ -531,11 +531,12 @@ func (cfg SystemConfig) Start() (*System, error) {
...
@@ -531,11 +531,12 @@ func (cfg SystemConfig) Start() (*System, error) {
L1EthRpc
:
sys
.
Nodes
[
"l1"
]
.
WSEndpoint
(),
L1EthRpc
:
sys
.
Nodes
[
"l1"
]
.
WSEndpoint
(),
L2EthRpc
:
sys
.
Nodes
[
"sequencer"
]
.
WSEndpoint
(),
L2EthRpc
:
sys
.
Nodes
[
"sequencer"
]
.
WSEndpoint
(),
RollupRpc
:
sys
.
RollupNodes
[
"sequencer"
]
.
HTTPEndpoint
(),
RollupRpc
:
sys
.
RollupNodes
[
"sequencer"
]
.
HTTPEndpoint
(),
MaxChannelDuration
:
1
,
MaxL1TxSize
:
120
_000
,
MaxL1TxSize
:
120
_000
,
TargetL1TxSize
:
1
60
,
//624
,
TargetL1TxSize
:
1
00
_000
,
TargetNumFrames
:
1
,
TargetNumFrames
:
1
,
ApproxComprRatio
:
1.0
,
ApproxComprRatio
:
0.4
,
SubSafetyMargin
:
testSafetyMargin
(
cfg
.
DeployConfig
)
,
SubSafetyMargin
:
4
,
PollInterval
:
50
*
time
.
Millisecond
,
PollInterval
:
50
*
time
.
Millisecond
,
NumConfirmations
:
1
,
NumConfirmations
:
1
,
ResubmissionTimeout
:
5
*
time
.
Second
,
ResubmissionTimeout
:
5
*
time
.
Second
,
...
@@ -575,24 +576,3 @@ func hexPriv(in *ecdsa.PrivateKey) string {
...
@@ -575,24 +576,3 @@ func hexPriv(in *ecdsa.PrivateKey) string {
b
:=
e2eutils
.
EncodePrivKey
(
in
)
b
:=
e2eutils
.
EncodePrivKey
(
in
)
return
hexutil
.
Encode
(
b
)
return
hexutil
.
Encode
(
b
)
}
}
// returns a safety margin that heuristically leads to a short channel lifetime
// of netChannelDuration. In current testing setups, we want channels to close
// quickly to have a low latency. We don't optimize for gas consumption.
func
testSafetyMargin
(
cfg
*
genesis
.
DeployConfig
)
uint64
{
// target channel duration after first frame is included on L1
const
netChannelDuration
=
2
// The sequencing window timeout starts from the L1 origin, whereas the
// channel timeout starts from the first L1 inclusion block of any frame.
// So to have comparable values, the sws is converted to an effective
// sequencing window from the first L1 inclusion block, assuming that L2
// blocks are quickly included on L1.
// So we subtract 1 block distance from the origin block and 1 block for
// minging the first frame.
openChannelSeqWindow
:=
cfg
.
SequencerWindowSize
-
2
if
openChannelSeqWindow
>
cfg
.
ChannelTimeout
{
return
cfg
.
ChannelTimeout
-
netChannelDuration
}
else
{
return
openChannelSeqWindow
-
netChannelDuration
}
}
op-e2e/system_test.go
View file @
78bd8d8a
...
@@ -367,9 +367,9 @@ func TestFinalize(t *testing.T) {
...
@@ -367,9 +367,9 @@ func TestFinalize(t *testing.T) {
l2Seq
:=
sys
.
Clients
[
"sequencer"
]
l2Seq
:=
sys
.
Clients
[
"sequencer"
]
// as configured in the extra geth lifecycle in testing setup
// as configured in the extra geth lifecycle in testing setup
finalizedDistance
:=
uint64
(
8
)
const
finalizedDistance
=
8
// Wait enough time for L1 to finalize and L2 to confirm its data in finalized L1 blocks
// Wait enough time for L1 to finalize and L2 to confirm its data in finalized L1 blocks
<-
time
.
After
(
time
.
Duration
((
finalizedDistance
+
4
)
*
cfg
.
DeployConfig
.
L1BlockTime
)
*
time
.
Second
)
time
.
Sleep
(
time
.
Duration
((
finalizedDistance
+
6
)
*
cfg
.
DeployConfig
.
L1BlockTime
)
*
time
.
Second
)
// fetch the finalizes head of geth
// fetch the finalizes head of geth
ctx
,
cancel
:=
context
.
WithTimeout
(
context
.
Background
(),
1
*
time
.
Second
)
ctx
,
cancel
:=
context
.
WithTimeout
(
context
.
Background
(),
1
*
time
.
Second
)
...
@@ -883,7 +883,7 @@ func TestWithdrawals(t *testing.T) {
...
@@ -883,7 +883,7 @@ func TestWithdrawals(t *testing.T) {
require
.
Nil
(
t
,
err
)
require
.
Nil
(
t
,
err
)
// Get l2BlockNumber for proof generation
// Get l2BlockNumber for proof generation
ctx
,
cancel
=
context
.
WithTimeout
(
context
.
Background
(),
3
0
*
time
.
Duration
(
cfg
.
DeployConfig
.
L1BlockTime
)
*
time
.
Second
)
ctx
,
cancel
=
context
.
WithTimeout
(
context
.
Background
(),
4
0
*
time
.
Duration
(
cfg
.
DeployConfig
.
L1BlockTime
)
*
time
.
Second
)
defer
cancel
()
defer
cancel
()
blockNumber
,
err
:=
withdrawals
.
WaitForFinalizationPeriod
(
ctx
,
l1Client
,
predeploys
.
DevOptimismPortalAddr
,
receipt
.
BlockNumber
)
blockNumber
,
err
:=
withdrawals
.
WaitForFinalizationPeriod
(
ctx
,
l1Client
,
predeploys
.
DevOptimismPortalAddr
,
receipt
.
BlockNumber
)
require
.
Nil
(
t
,
err
)
require
.
Nil
(
t
,
err
)
...
...
op-e2e/system_tob_test.go
View file @
78bd8d8a
...
@@ -415,7 +415,6 @@ func TestMixedDepositValidity(t *testing.T) {
...
@@ -415,7 +415,6 @@ func TestMixedDepositValidity(t *testing.T) {
// TestMixedWithdrawalValidity makes a number of withdrawal transactions and ensures ones with modified parameters are
// TestMixedWithdrawalValidity makes a number of withdrawal transactions and ensures ones with modified parameters are
// rejected while unmodified ones are accepted. This runs test cases in different systems.
// rejected while unmodified ones are accepted. This runs test cases in different systems.
func
TestMixedWithdrawalValidity
(
t
*
testing
.
T
)
{
func
TestMixedWithdrawalValidity
(
t
*
testing
.
T
)
{
parallel
(
t
)
// Setup our logger handler
// Setup our logger handler
if
!
verboseGethNodes
{
if
!
verboseGethNodes
{
log
.
Root
()
.
SetHandler
(
log
.
DiscardHandler
())
log
.
Root
()
.
SetHandler
(
log
.
DiscardHandler
())
...
@@ -425,7 +424,7 @@ func TestMixedWithdrawalValidity(t *testing.T) {
...
@@ -425,7 +424,7 @@ func TestMixedWithdrawalValidity(t *testing.T) {
for
i
:=
0
;
i
<=
8
;
i
++
{
for
i
:=
0
;
i
<=
8
;
i
++
{
i
:=
i
// avoid loop var capture
i
:=
i
// avoid loop var capture
t
.
Run
(
fmt
.
Sprintf
(
"withdrawal test#%d"
,
i
+
1
),
func
(
t
*
testing
.
T
)
{
t
.
Run
(
fmt
.
Sprintf
(
"withdrawal test#%d"
,
i
+
1
),
func
(
t
*
testing
.
T
)
{
t
.
Parallel
(
)
parallel
(
t
)
// Create our system configuration, funding all accounts we created for L1/L2, and start it
// Create our system configuration, funding all accounts we created for L1/L2, and start it
cfg
:=
DefaultSystemConfig
(
t
)
cfg
:=
DefaultSystemConfig
(
t
)
cfg
.
DeployConfig
.
FinalizationPeriodSeconds
=
6
cfg
.
DeployConfig
.
FinalizationPeriodSeconds
=
6
...
@@ -528,7 +527,7 @@ func TestMixedWithdrawalValidity(t *testing.T) {
...
@@ -528,7 +527,7 @@ func TestMixedWithdrawalValidity(t *testing.T) {
transactor
.
ExpectedL2Nonce
=
transactor
.
ExpectedL2Nonce
+
1
transactor
.
ExpectedL2Nonce
=
transactor
.
ExpectedL2Nonce
+
1
// Wait for the finalization period, then we can finalize this withdrawal.
// Wait for the finalization period, then we can finalize this withdrawal.
ctx
,
cancel
=
context
.
WithTimeout
(
context
.
Background
(),
25
*
time
.
Duration
(
cfg
.
DeployConfig
.
L1BlockTime
)
*
time
.
Second
)
ctx
,
cancel
=
context
.
WithTimeout
(
context
.
Background
(),
40
*
time
.
Duration
(
cfg
.
DeployConfig
.
L1BlockTime
)
*
time
.
Second
)
blockNumber
,
err
:=
withdrawals
.
WaitForFinalizationPeriod
(
ctx
,
l1Client
,
predeploys
.
DevOptimismPortalAddr
,
receipt
.
BlockNumber
)
blockNumber
,
err
:=
withdrawals
.
WaitForFinalizationPeriod
(
ctx
,
l1Client
,
predeploys
.
DevOptimismPortalAddr
,
receipt
.
BlockNumber
)
cancel
()
cancel
()
require
.
Nil
(
t
,
err
)
require
.
Nil
(
t
,
err
)
...
@@ -658,7 +657,7 @@ func TestMixedWithdrawalValidity(t *testing.T) {
...
@@ -658,7 +657,7 @@ func TestMixedWithdrawalValidity(t *testing.T) {
require
.
Equal
(
t
,
types
.
ReceiptStatusSuccessful
,
proveReceipt
.
Status
)
require
.
Equal
(
t
,
types
.
ReceiptStatusSuccessful
,
proveReceipt
.
Status
)
// Wait for finalization and then create the Finalized Withdrawal Transaction
// Wait for finalization and then create the Finalized Withdrawal Transaction
ctx
,
cancel
=
context
.
WithTimeout
(
context
.
Background
(),
4
0
*
time
.
Duration
(
cfg
.
DeployConfig
.
L1BlockTime
)
*
time
.
Second
)
ctx
,
cancel
=
context
.
WithTimeout
(
context
.
Background
(),
4
5
*
time
.
Duration
(
cfg
.
DeployConfig
.
L1BlockTime
)
*
time
.
Second
)
defer
cancel
()
defer
cancel
()
_
,
err
=
withdrawals
.
WaitForFinalizationPeriod
(
ctx
,
l1Client
,
predeploys
.
DevOptimismPortalAddr
,
header
.
Number
)
_
,
err
=
withdrawals
.
WaitForFinalizationPeriod
(
ctx
,
l1Client
,
predeploys
.
DevOptimismPortalAddr
,
header
.
Number
)
require
.
Nil
(
t
,
err
)
require
.
Nil
(
t
,
err
)
...
...
ops-bedrock/docker-compose.yml
View file @
78bd8d8a
...
@@ -122,11 +122,12 @@ services:
...
@@ -122,11 +122,12 @@ services:
OP_BATCHER_L1_ETH_RPC
:
http://l1:8545
OP_BATCHER_L1_ETH_RPC
:
http://l1:8545
OP_BATCHER_L2_ETH_RPC
:
http://l2:8545
OP_BATCHER_L2_ETH_RPC
:
http://l2:8545
OP_BATCHER_ROLLUP_RPC
:
http://op-node:8545
OP_BATCHER_ROLLUP_RPC
:
http://op-node:8545
OP_BATCHER_MAX_CHANNEL_DURATION
:
1
OP_BATCHER_MAX_L1_TX_SIZE_BYTES
:
120000
OP_BATCHER_MAX_L1_TX_SIZE_BYTES
:
120000
OP_BATCHER_TARGET_L1_TX_SIZE_BYTES
:
624
OP_BATCHER_TARGET_L1_TX_SIZE_BYTES
:
100000
OP_BATCHER_TARGET_NUM_FRAMES
:
1
OP_BATCHER_TARGET_NUM_FRAMES
:
1
OP_BATCHER_APPROX_COMPR_RATIO
:
1.0
OP_BATCHER_APPROX_COMPR_RATIO
:
0.4
OP_BATCHER_SUB_SAFETY_MARGIN
:
6
# SWS is 15, ChannelTimeout is 40
OP_BATCHER_SUB_SAFETY_MARGIN
:
4
# SWS is 15, ChannelTimeout is 40
OP_BATCHER_POLL_INTERVAL
:
1s
OP_BATCHER_POLL_INTERVAL
:
1s
OP_BATCHER_NUM_CONFIRMATIONS
:
1
OP_BATCHER_NUM_CONFIRMATIONS
:
1
OP_BATCHER_SAFE_ABORT_NONCE_TOO_LOW_COUNT
:
3
OP_BATCHER_SAFE_ABORT_NONCE_TOO_LOW_COUNT
:
3
...
...
packages/atst/src/cli.ts
View file @
78bd8d8a
...
@@ -26,6 +26,7 @@ cli
...
@@ -26,6 +26,7 @@ cli
})
})
.
example
(
.
example
(
()
=>
()
=>
// note: private key is just the first testing address when running anvil
`atst read --key "optimist.base-uri" --about 0x2335022c740d17c2837f9C884Bfe4fFdbf0A95D5 --creator 0x60c5C9c98bcBd0b0F2fD89B24c16e533BaA8CdA3`
`atst read --key "optimist.base-uri" --about 0x2335022c740d17c2837f9C884Bfe4fFdbf0A95D5 --creator 0x60c5C9c98bcBd0b0F2fD89B24c16e533BaA8CdA3`
)
)
.
action
(
async
(
options
:
ReadOptions
)
=>
{
.
action
(
async
(
options
:
ReadOptions
)
=>
{
...
@@ -72,6 +73,8 @@ cli
...
@@ -72,6 +73,8 @@ cli
`atst write --key "optimist.base-uri" --about 0x2335022c740d17c2837f9C884Bfe4fFdbf0A95D5 --value "my attestation" --private-key 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 --rpc-url http://localhost:8545`
`atst write --key "optimist.base-uri" --about 0x2335022c740d17c2837f9C884Bfe4fFdbf0A95D5 --value "my attestation" --private-key 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 --rpc-url http://localhost:8545`
)
)
.
action
(
async
(
options
:
WriteOptions
)
=>
{
.
action
(
async
(
options
:
WriteOptions
)
=>
{
const
spinner
=
logger
.
spinner
()
spinner
.
start
(
'
Writing attestation...
'
)
const
{
write
}
=
await
import
(
'
./commands/write
'
)
const
{
write
}
=
await
import
(
'
./commands/write
'
)
// TODO use the native api to do this instead of parsing the raw args
// TODO use the native api to do this instead of parsing the raw args
...
@@ -86,9 +89,16 @@ cli
...
@@ -86,9 +89,16 @@ cli
:
options
.
contract
:
options
.
contract
await
write
({
...
options
,
about
,
privateKey
,
contract
})
await
write
({
...
options
,
about
,
privateKey
,
contract
})
.
then
((
res
)
=>
{
spinner
.
succeed
(
'
Attestation written!
'
)
logger
.
info
(
`Attestation hash:
${
res
}
`
)
})
.
catch
((
e
)
=>
{
logger
.
error
(
e
)
spinner
.
fail
(
'
Attestation failed!
'
)
})
})
})
cli
.
help
()
cli
.
version
(
packageJson
.
version
)
cli
.
version
(
packageJson
.
version
)
void
(
async
()
=>
{
void
(
async
()
=>
{
...
...
packages/atst/src/index.ts
View file @
78bd8d8a
...
@@ -28,3 +28,5 @@ export type { AttestationCreatedEvent } from './types/AttestationCreatedEvent'
...
@@ -28,3 +28,5 @@ export type { AttestationCreatedEvent } from './types/AttestationCreatedEvent'
export
type
{
AttestationReadParams
}
from
'
./types/AttestationReadParams
'
export
type
{
AttestationReadParams
}
from
'
./types/AttestationReadParams
'
export
type
{
DataTypeOption
}
from
'
./types/DataTypeOption
'
export
type
{
DataTypeOption
}
from
'
./types/DataTypeOption
'
export
type
{
WagmiBytes
}
from
'
./types/WagmiBytes
'
export
type
{
WagmiBytes
}
from
'
./types/WagmiBytes
'
// react
export
*
from
'
./react
'
packages/atst/src/lib/encodeRawKey.ts
View file @
78bd8d8a
import
{
ethers
}
from
'
ethers
'
import
{
ethers
}
from
'
ethers
'
export
const
encodeRawKey
=
(
rawKey
:
string
)
=>
{
import
{
WagmiBytes
}
from
'
../types/WagmiBytes
'
export
const
encodeRawKey
=
(
rawKey
:
string
):
WagmiBytes
=>
{
if
(
rawKey
.
length
<
32
)
{
if
(
rawKey
.
length
<
32
)
{
return
ethers
.
utils
.
formatBytes32String
(
rawKey
)
return
ethers
.
utils
.
formatBytes32String
(
rawKey
)
as
WagmiBytes
}
}
const
hash
=
ethers
.
utils
.
keccak256
(
ethers
.
utils
.
toUtf8Bytes
(
rawKey
))
const
hash
=
ethers
.
utils
.
keccak256
(
ethers
.
utils
.
toUtf8Bytes
(
rawKey
))
return
hash
.
slice
(
0
,
64
)
+
'
ff
'
return
(
hash
.
slice
(
0
,
64
)
+
'
ff
'
)
as
WagmiBytes
}
}
packages/atst/src/lib/parseAttestationBytes.spec.ts
View file @
78bd8d8a
...
@@ -41,8 +41,11 @@ describe(parseAttestationBytes.name, () => {
...
@@ -41,8 +41,11 @@ describe(parseAttestationBytes.name, () => {
})
})
it
(
'
should work for raw bytes
'
,
()
=>
{
it
(
'
should work for raw bytes
'
,
()
=>
{
const
bytes
=
'
0x420
'
expect
(
parseAttestationBytes
(
'
0x420
'
,
'
bytes
'
)).
toMatchInlineSnapshot
(
expect
(
parseAttestationBytes
(
bytes
,
'
bytes
'
)).
toBe
(
bytes
)
'
"0x420"
'
)
expect
(
parseAttestationBytes
(
'
0x
'
,
'
string
'
)).
toMatchInlineSnapshot
(
'
""
'
)
expect
(
parseAttestationBytes
(
'
0x0
'
,
'
string
'
)).
toMatchInlineSnapshot
(
'
""
'
)
})
})
it
(
'
should return raw bytes for invalid type
'
,
()
=>
{
it
(
'
should return raw bytes for invalid type
'
,
()
=>
{
...
@@ -57,12 +60,16 @@ describe('parseFoo', () => {
...
@@ -57,12 +60,16 @@ describe('parseFoo', () => {
const
str
=
'
Hello World
'
const
str
=
'
Hello World
'
const
bytes
=
BigNumber
.
from
(
toUtf8Bytes
(
str
)).
toHexString
()
as
WagmiBytes
const
bytes
=
BigNumber
.
from
(
toUtf8Bytes
(
str
)).
toHexString
()
as
WagmiBytes
expect
(
parseString
(
bytes
)).
toBe
(
str
)
expect
(
parseString
(
bytes
)).
toBe
(
str
)
expect
(
parseString
(
'
0x
'
)).
toMatchInlineSnapshot
(
'
""
'
)
expect
(
parseString
(
'
0x0
'
)).
toMatchInlineSnapshot
(
'
""
'
)
expect
(
parseString
(
'
0x0
'
)).
toMatchInlineSnapshot
(
'
""
'
)
})
})
it
(
'
works for numbers
'
,
()
=>
{
it
(
'
works for numbers
'
,
()
=>
{
const
num
=
123
const
num
=
123
const
bytes
=
BigNumber
.
from
(
num
).
toHexString
()
as
WagmiBytes
const
bytes
=
BigNumber
.
from
(
num
).
toHexString
()
as
WagmiBytes
expect
(
parseNumber
(
bytes
)).
toEqual
(
BigNumber
.
from
(
num
))
expect
(
parseNumber
(
bytes
)).
toEqual
(
BigNumber
.
from
(
num
))
expect
(
parseNumber
(
'
0x
'
)).
toEqual
(
BigNumber
.
from
(
0
))
})
})
it
(
'
works for addresses
'
,
()
=>
{
it
(
'
works for addresses
'
,
()
=>
{
...
@@ -74,5 +81,8 @@ describe('parseFoo', () => {
...
@@ -74,5 +81,8 @@ describe('parseFoo', () => {
it
(
'
works for booleans
'
,
()
=>
{
it
(
'
works for booleans
'
,
()
=>
{
const
bytes
=
BigNumber
.
from
(
1
).
toHexString
()
as
WagmiBytes
const
bytes
=
BigNumber
.
from
(
1
).
toHexString
()
as
WagmiBytes
expect
(
parseBool
(
bytes
)).
toBe
(
true
)
expect
(
parseBool
(
bytes
)).
toBe
(
true
)
expect
(
parseBool
(
'
0x
'
)).
toBe
(
false
)
expect
(
parseBool
(
'
0x0
'
)).
toBe
(
false
)
expect
(
parseBool
(
'
0x00000
'
)).
toBe
(
false
)
})
})
})
})
packages/atst/src/lib/parseAttestationBytes.ts
View file @
78bd8d8a
...
@@ -10,7 +10,7 @@ import { ParseBytesReturn } from '../types/ParseBytesReturn'
...
@@ -10,7 +10,7 @@ import { ParseBytesReturn } from '../types/ParseBytesReturn'
* Parses a string attestion
* Parses a string attestion
*/
*/
export
const
parseString
=
(
rawAttestation
:
WagmiBytes
):
string
=>
{
export
const
parseString
=
(
rawAttestation
:
WagmiBytes
):
string
=>
{
rawAttestation
=
rawAttestation
===
'
0x
'
?
'
0x0
'
:
rawAttestation
rawAttestation
=
rawAttestation
===
'
0x
0
'
?
'
0x
'
:
rawAttestation
return
rawAttestation
?
toUtf8String
(
rawAttestation
)
:
''
return
rawAttestation
?
toUtf8String
(
rawAttestation
)
:
''
}
}
...
...
packages/atst/src/lib/readAttestation.spec.ts
View file @
78bd8d8a
...
@@ -39,4 +39,3 @@ describe(readAttestation.name, () => {
...
@@ -39,4 +39,3 @@ describe(readAttestation.name, () => {
)
)
})
})
})
})
packages/atst/src/lib/stringifyAttestationBytes.ts
View file @
78bd8d8a
import
{
Address
}
from
'
@wagmi/core
'
import
{
Address
}
from
'
@wagmi/core
'
import
{
BigNumber
}
from
'
ethers
'
import
{
BigNumber
}
from
'
ethers
'
import
{
isAddress
,
isHexString
,
toUtf8Bytes
}
from
'
ethers/lib/utils.js
'
import
{
hexlify
,
isAddress
,
isHexString
,
toUtf8Bytes
,
}
from
'
ethers/lib/utils.js
'
import
{
WagmiBytes
}
from
'
../types/WagmiBytes
'
import
{
WagmiBytes
}
from
'
../types/WagmiBytes
'
export
const
stringifyAttestationBytes
=
(
export
const
stringifyAttestationBytes
=
(
bytes
:
WagmiBytes
|
string
|
Address
|
number
|
boolean
|
BigNumber
bytes
:
WagmiBytes
|
string
|
Address
|
number
|
boolean
|
BigNumber
)
=>
{
)
:
WagmiBytes
=>
{
bytes
=
bytes
===
'
0x
'
?
'
0x0
'
:
bytes
bytes
=
bytes
===
'
0x
'
?
'
0x0
'
:
bytes
if
(
BigNumber
.
isBigNumber
(
bytes
))
{
if
(
BigNumber
.
isBigNumber
(
bytes
))
{
return
bytes
.
toHexString
()
return
bytes
.
toHexString
()
as
WagmiBytes
}
}
if
(
typeof
bytes
===
'
number
'
)
{
if
(
typeof
bytes
===
'
number
'
)
{
return
BigNumber
.
from
(
bytes
).
toHexString
()
return
BigNumber
.
from
(
bytes
).
toHexString
()
as
WagmiBytes
}
}
if
(
typeof
bytes
===
'
boolean
'
)
{
if
(
typeof
bytes
===
'
boolean
'
)
{
return
bytes
?
'
0x1
'
:
'
0x0
'
return
bytes
?
'
0x1
'
:
'
0x0
'
...
@@ -21,10 +26,10 @@ export const stringifyAttestationBytes = (
...
@@ -21,10 +26,10 @@ export const stringifyAttestationBytes = (
return
bytes
return
bytes
}
}
if
(
isHexString
(
bytes
))
{
if
(
isHexString
(
bytes
))
{
return
bytes
return
bytes
as
WagmiBytes
}
}
if
(
typeof
bytes
===
'
string
'
)
{
if
(
typeof
bytes
===
'
string
'
)
{
return
toUtf8Bytes
(
bytes
)
return
hexlify
(
toUtf8Bytes
(
bytes
))
as
WagmiBytes
}
}
throw
new
Error
(
`unrecognized bytes type
${
bytes
satisfies
never
}
`
)
throw
new
Error
(
`unrecognized bytes type
${
bytes
satisfies
never
}
`
)
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment