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
a6f578c8
Commit
a6f578c8
authored
Jan 07, 2022
by
Matthew Slipper
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'upstream/develop' into feat/bss-multiple-txs
parents
36a43683
cebc747c
Changes
12
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
312 additions
and
94 deletions
+312
-94
fair-eyes-build.md
.changeset/fair-eyes-build.md
+5
-0
shaggy-brooms-shave.md
.changeset/shaggy-brooms-shave.md
+5
-0
backend.go
go/proxyd/backend.go
+34
-3
config.go
go/proxyd/config.go
+10
-9
proxyd.go
go/proxyd/proxyd.go
+4
-0
server.go
go/proxyd/server.go
+26
-6
l2-gasprice.ts
packages/contracts/tasks/l2-gasprice.ts
+56
-9
cross-chain-provider.ts
packages/sdk/src/cross-chain-provider.ts
+17
-4
cross-chain-provider.ts
packages/sdk/src/interfaces/cross-chain-provider.ts
+1
-1
cross-chain-erc20-pair.spec.ts
packages/sdk/test/cross-chain-erc20-pair.spec.ts
+20
-21
cross-chain-messenger.spec.ts
packages/sdk/test/cross-chain-messenger.spec.ts
+8
-9
cross-chain-provider.spec.ts
packages/sdk/test/cross-chain-provider.spec.ts
+126
-32
No files found.
.changeset/fair-eyes-build.md
0 → 100644
View file @
a6f578c8
---
'
@eth-optimism/proxyd'
:
minor
---
Add X-Forwarded-For header when proxying RPCs on proxyd
.changeset/shaggy-brooms-shave.md
0 → 100644
View file @
a6f578c8
---
'
@eth-optimism/contracts'
:
patch
---
Update hardhat task for managing the gas oracle
go/proxyd/backend.go
View file @
a6f578c8
...
...
@@ -7,16 +7,18 @@ import (
"encoding/json"
"errors"
"fmt"
"github.com/ethereum/go-ethereum/log"
"github.com/gorilla/websocket"
"github.com/prometheus/client_golang/prometheus"
"io"
"io/ioutil"
"math"
"math/rand"
"net/http"
"strconv"
"strings"
"time"
"github.com/ethereum/go-ethereum/log"
"github.com/gorilla/websocket"
"github.com/prometheus/client_golang/prometheus"
)
const
(
...
...
@@ -84,6 +86,8 @@ type Backend struct {
maxRPS
int
maxWSConns
int
outOfServiceInterval
time
.
Duration
stripTrailingXFF
bool
proxydIP
string
}
type
BackendOpt
func
(
b
*
Backend
)
...
...
@@ -140,6 +144,18 @@ func WithTLSConfig(tlsConfig *tls.Config) BackendOpt {
}
}
func
WithStrippedTrailingXFF
()
BackendOpt
{
return
func
(
b
*
Backend
)
{
b
.
stripTrailingXFF
=
true
}
}
func
WithProxydIP
(
ip
string
)
BackendOpt
{
return
func
(
b
*
Backend
)
{
b
.
proxydIP
=
ip
}
}
func
NewBackend
(
name
string
,
rpcURL
string
,
...
...
@@ -163,6 +179,10 @@ func NewBackend(
opt
(
backend
)
}
if
!
backend
.
stripTrailingXFF
&&
backend
.
proxydIP
==
""
{
log
.
Warn
(
"proxied requests' XFF header will not contain the proxyd ip address"
)
}
return
backend
}
...
...
@@ -316,7 +336,18 @@ func (b *Backend) doForward(ctx context.Context, rpcReq *RPCReq) (*RPCRes, error
httpReq
.
SetBasicAuth
(
b
.
authUsername
,
b
.
authPassword
)
}
xForwardedFor
:=
GetXForwardedFor
(
ctx
)
if
b
.
stripTrailingXFF
{
ipList
:=
strings
.
Split
(
xForwardedFor
,
", "
)
if
len
(
ipList
)
>
0
{
xForwardedFor
=
ipList
[
0
]
}
}
else
if
b
.
proxydIP
!=
""
{
xForwardedFor
=
fmt
.
Sprintf
(
"%s, %s"
,
xForwardedFor
,
b
.
proxydIP
)
}
httpReq
.
Header
.
Set
(
"content-type"
,
"application/json"
)
httpReq
.
Header
.
Set
(
"X-Forwarded-For"
,
xForwardedFor
)
httpRes
,
err
:=
b
.
client
.
Do
(
httpReq
)
if
err
!=
nil
{
...
...
go/proxyd/config.go
View file @
a6f578c8
...
...
@@ -32,15 +32,16 @@ type BackendOptions struct {
}
type
BackendConfig
struct
{
Username
string
`toml:"username"`
Password
string
`toml:"password"`
RPCURL
string
`toml:"rpc_url"`
WSURL
string
`toml:"ws_url"`
MaxRPS
int
`toml:"max_rps"`
MaxWSConns
int
`toml:"max_ws_conns"`
CAFile
string
`toml:"ca_file"`
ClientCertFile
string
`toml:"client_cert_file"`
ClientKeyFile
string
`toml:"client_key_file"`
Username
string
`toml:"username"`
Password
string
`toml:"password"`
RPCURL
string
`toml:"rpc_url"`
WSURL
string
`toml:"ws_url"`
MaxRPS
int
`toml:"max_rps"`
MaxWSConns
int
`toml:"max_ws_conns"`
CAFile
string
`toml:"ca_file"`
ClientCertFile
string
`toml:"client_cert_file"`
ClientKeyFile
string
`toml:"client_key_file"`
StripTrailingXFF
bool
`toml:"strip_trailing_xff"`
}
type
BackendsConfig
map
[
string
]
*
BackendConfig
...
...
go/proxyd/proxyd.go
View file @
a6f578c8
...
...
@@ -96,6 +96,10 @@ func Start(config *Config) error {
log
.
Info
(
"using custom TLS config for backend"
,
"name"
,
name
)
opts
=
append
(
opts
,
WithTLSConfig
(
tlsConfig
))
}
if
cfg
.
StripTrailingXFF
{
opts
=
append
(
opts
,
WithStrippedTrailingXFF
())
}
opts
=
append
(
opts
,
WithProxydIP
(
os
.
Getenv
(
"PROXYD_IP"
)))
back
:=
NewBackend
(
name
,
rpcURL
,
wsURL
,
lim
,
opts
...
)
backendNames
=
append
(
backendNames
,
name
)
backendsByName
[
name
]
=
back
...
...
go/proxyd/server.go
View file @
a6f578c8
...
...
@@ -5,20 +5,23 @@ import (
"encoding/json"
"errors"
"fmt"
"io"
"net/http"
"strconv"
"strings"
"time"
"github.com/ethereum/go-ethereum/log"
"github.com/gorilla/mux"
"github.com/gorilla/websocket"
"github.com/prometheus/client_golang/prometheus"
"github.com/rs/cors"
"io"
"net/http"
"strconv"
"time"
)
const
(
ContextKeyAuth
=
"authorization"
ContextKeyReqID
=
"req_id"
ContextKeyAuth
=
"authorization"
ContextKeyReqID
=
"req_id"
ContextKeyXForwardedFor
=
"x_forwarded_for"
)
type
Server
struct
{
...
...
@@ -214,7 +217,16 @@ func (s *Server) populateContext(w http.ResponseWriter, r *http.Request) context
return
nil
}
xff
:=
r
.
Header
.
Get
(
"X-Forwarded-For"
)
if
xff
==
""
{
ipPort
:=
strings
.
Split
(
r
.
RemoteAddr
,
":"
)
if
len
(
ipPort
)
==
2
{
xff
=
ipPort
[
0
]
}
}
ctx
:=
context
.
WithValue
(
r
.
Context
(),
ContextKeyAuth
,
s
.
authenticatedPaths
[
authorization
])
ctx
=
context
.
WithValue
(
ctx
,
ContextKeyXForwardedFor
,
xff
)
return
context
.
WithValue
(
ctx
,
ContextKeyReqID
,
...
...
@@ -271,3 +283,11 @@ func GetReqID(ctx context.Context) string {
}
return
reqId
}
func
GetXForwardedFor
(
ctx
context
.
Context
)
string
{
xff
,
ok
:=
ctx
.
Value
(
ContextKeyXForwardedFor
)
.
(
string
)
if
!
ok
{
return
""
}
return
xff
}
packages/contracts/tasks/l2-gasprice.ts
View file @
a6f578c8
...
...
@@ -7,8 +7,25 @@ import { predeploys } from '../src/predeploys'
import
{
getContractDefinition
}
from
'
../src/contract-defs
'
task
(
'
set-l2-gasprice
'
)
.
addOptionalParam
(
'
l2GasPrice
'
,
'
Gas Price to set on L2
'
,
0
,
types
.
int
)
.
addOptionalParam
(
'
l2GasPrice
'
,
'
Gas Price to set on L2
'
,
undefined
,
types
.
int
)
.
addOptionalParam
(
'
transactionGasPrice
'
,
'
tx.gasPrice
'
,
undefined
,
types
.
int
)
.
addOptionalParam
(
'
overhead
'
,
'
amortized additional gas used by each batch that users must pay for
'
,
undefined
,
types
.
int
)
.
addOptionalParam
(
'
scalar
'
,
'
amount to scale up the gas to charge
'
,
undefined
,
types
.
int
)
.
addOptionalParam
(
'
contractsRpcUrl
'
,
'
Sequencer HTTP Endpoint
'
,
...
...
@@ -42,15 +59,45 @@ task('set-l2-gasprice')
throw
new
Error
(
`Incorrect key. Owner
${
owner
}
, Signer
${
addr
}
`
)
}
// List the current values
const
gasPrice
=
await
GasPriceOracle
.
callStatic
.
gasPrice
()
cons
ole
.
log
(
`Gas Price is currently
${
gasPrice
.
toString
()}
`
)
cons
ole
.
log
(
`Setting Gas Price to
${
args
.
l2GasPrice
}
`
)
cons
t
scalar
=
await
GasPriceOracle
.
callStatic
.
scalar
(
)
cons
t
overhead
=
await
GasPriceOracle
.
callStatic
.
overhead
(
)
const
tx
=
await
GasPriceOracle
.
connect
(
signer
).
setGasPrice
(
args
.
l2GasPrice
,
{
gasPrice
:
args
.
transactionGasPrice
}
)
console
.
log
(
'
Current values:
'
)
console
.
log
(
`Gas Price:
${
gasPrice
.
toString
()}
`
)
console
.
log
(
`Scalar:
${
scalar
.
toString
()}
`
)
console
.
log
(
`Overhead:
${
overhead
.
toString
()}
`
)
if
(
args
.
l2GasPrice
!==
undefined
)
{
console
.
log
(
`Setting gas price to
${
args
.
l2GasPrice
}
`
)
const
tx
=
await
GasPriceOracle
.
connect
(
signer
).
setGasPrice
(
args
.
l2GasPrice
,
{
gasPrice
:
args
.
transactionGasPrice
}
)
const
receipt
=
await
tx
.
wait
()
console
.
log
(
`Success -
${
receipt
.
transactionHash
}
`
)
const
receipt
=
await
tx
.
wait
()
console
.
log
(
`Success -
${
receipt
.
transactionHash
}
`
)
}
if
(
args
.
scalar
!==
undefined
)
{
console
.
log
(
`Setting scalar to
${
args
.
scalar
}
`
)
const
tx
=
await
GasPriceOracle
.
connect
(
signer
).
setScalar
(
args
.
scalar
,
{
gasPrice
:
args
.
transactionGasPrice
,
})
const
receipt
=
await
tx
.
wait
()
console
.
log
(
`Success -
${
receipt
.
transactionHash
}
`
)
}
if
(
args
.
overhead
!==
undefined
)
{
console
.
log
(
`Setting overhead to
${
args
.
overhead
}
`
)
const
tx
=
await
GasPriceOracle
.
connect
(
signer
).
setOverhead
(
args
.
overhead
,
{
gasPrice
:
args
.
transactionGasPrice
}
)
const
receipt
=
await
tx
.
wait
()
console
.
log
(
`Success -
${
receipt
.
transactionHash
}
`
)
}
})
packages/sdk/src/cross-chain-provider.ts
View file @
a6f578c8
...
...
@@ -5,6 +5,7 @@ import {
TransactionReceipt
,
}
from
'
@ethersproject/abstract-provider
'
import
{
ethers
,
BigNumber
,
Event
}
from
'
ethers
'
import
{
sleep
}
from
'
@eth-optimism/core-utils
'
import
{
ICrossChainProvider
,
OEContracts
,
...
...
@@ -395,15 +396,27 @@ export class CrossChainProvider implements ICrossChainProvider {
return
null
}
public
async
waitForMessageRec
ie
pt
(
public
async
waitForMessageRec
ei
pt
(
message
:
MessageLike
,
opts
?
:
{
opts
:
{
confirmations
?:
number
pollIntervalMs
?:
number
timeoutMs
?:
number
}
}
=
{}
):
Promise
<
MessageReceipt
>
{
throw
new
Error
(
'
Not implemented
'
)
let
totalTimeMs
=
0
while
(
totalTimeMs
<
(
opts
.
timeoutMs
||
Infinity
))
{
const
tick
=
Date
.
now
()
const
receipt
=
await
this
.
getMessageReceipt
(
message
)
if
(
receipt
!==
null
)
{
return
receipt
}
else
{
await
sleep
(
opts
.
pollIntervalMs
||
4000
)
totalTimeMs
+=
Date
.
now
()
-
tick
}
}
throw
new
Error
(
`timed out waiting for message receipt`
)
}
public
async
estimateL2MessageGasLimit
(
...
...
packages/sdk/src/interfaces/cross-chain-provider.ts
View file @
a6f578c8
...
...
@@ -186,7 +186,7 @@ export interface ICrossChainProvider {
* @returns CrossChainMessage receipt including receipt of the transaction that relayed the
* given message.
*/
waitForMessageRec
ie
pt
(
waitForMessageRec
ei
pt
(
message
:
MessageLike
,
opts
?:
{
confirmations
?:
number
...
...
packages/sdk/test/cross-chain-erc20-pair.spec.ts
View file @
a6f578c8
/* eslint-disable @typescript-eslint/no-empty-function */
import
'
./setup
'
describe
(
'
CrossChainERC20Pair
'
,
()
=>
{
describe
(
'
construction
'
,
()
=>
{
it
(
'
should have a messenger
'
,
()
=>
{}
)
it
(
'
should have a messenger
'
)
describe
(
'
when the token is a standard bridge token
'
,
()
=>
{
it
(
'
should resolve the correct bridge
'
,
()
=>
{}
)
it
(
'
should resolve the correct bridge
'
)
})
describe
(
'
when the token is SNX
'
,
()
=>
{
it
(
'
should resolve the correct bridge
'
,
()
=>
{}
)
it
(
'
should resolve the correct bridge
'
)
})
describe
(
'
when the token is DAI
'
,
()
=>
{
it
(
'
should resolve the correct bridge
'
,
()
=>
{}
)
it
(
'
should resolve the correct bridge
'
)
})
describe
(
'
when a custom adapter is provided
'
,
()
=>
{
it
(
'
should use the custom adapter
'
,
()
=>
{}
)
it
(
'
should use the custom adapter
'
)
})
})
describe
(
'
deposit
'
,
()
=>
{
describe
(
'
when the user has enough balance and allowance
'
,
()
=>
{
describe
(
'
when the token is a standard bridge token
'
,
()
=>
{
it
(
'
should trigger a token deposit
'
,
()
=>
{}
)
it
(
'
should trigger a token deposit
'
)
})
describe
(
'
when the token is ETH
'
,
()
=>
{
it
(
'
should trigger a token deposit
'
,
()
=>
{}
)
it
(
'
should trigger a token deposit
'
)
})
describe
(
'
when the token is SNX
'
,
()
=>
{
it
(
'
should trigger a token deposit
'
,
()
=>
{}
)
it
(
'
should trigger a token deposit
'
)
})
describe
(
'
when the token is DAI
'
,
()
=>
{
it
(
'
should trigger a token deposit
'
,
()
=>
{}
)
it
(
'
should trigger a token deposit
'
)
})
})
describe
(
'
when the user does not have enough balance
'
,
()
=>
{
it
(
'
should throw an error
'
,
()
=>
{}
)
it
(
'
should throw an error
'
)
})
describe
(
'
when the user has not given enough allowance to the bridge
'
,
()
=>
{
it
(
'
should throw an error
'
,
()
=>
{}
)
it
(
'
should throw an error
'
)
})
})
describe
(
'
withdraw
'
,
()
=>
{
describe
(
'
when the user has enough balance
'
,
()
=>
{
describe
(
'
when the token is a standard bridge token
'
,
()
=>
{
it
(
'
should trigger a token withdrawal
'
,
()
=>
{}
)
it
(
'
should trigger a token withdrawal
'
)
})
describe
(
'
when the token is ETH
'
,
()
=>
{
it
(
'
should trigger a token withdrawal
'
,
()
=>
{}
)
it
(
'
should trigger a token withdrawal
'
)
})
describe
(
'
when the token is SNX
'
,
()
=>
{
it
(
'
should trigger a token withdrawal
'
,
()
=>
{}
)
it
(
'
should trigger a token withdrawal
'
)
})
describe
(
'
when the token is DAI
'
,
()
=>
{
it
(
'
should trigger a token withdrawal
'
,
()
=>
{}
)
it
(
'
should trigger a token withdrawal
'
)
})
})
describe
(
'
when the user does not have enough balance
'
,
()
=>
{
it
(
'
should throw an error
'
,
()
=>
{}
)
it
(
'
should throw an error
'
)
})
})
describe
(
'
populateTransaction
'
,
()
=>
{
describe
(
'
deposit
'
,
()
=>
{
it
(
'
should populate the transaction with the correct values
'
,
()
=>
{}
)
it
(
'
should populate the transaction with the correct values
'
)
})
describe
(
'
withdraw
'
,
()
=>
{
it
(
'
should populate the transaction with the correct values
'
,
()
=>
{}
)
it
(
'
should populate the transaction with the correct values
'
)
})
})
describe
(
'
estimateGas
'
,
()
=>
{
describe
(
'
deposit
'
,
()
=>
{
it
(
'
should estimate gas required for the transaction
'
,
()
=>
{}
)
it
(
'
should estimate gas required for the transaction
'
)
})
describe
(
'
withdraw
'
,
()
=>
{
it
(
'
should estimate gas required for the transaction
'
,
()
=>
{}
)
it
(
'
should estimate gas required for the transaction
'
)
})
})
})
packages/sdk/test/cross-chain-messenger.spec.ts
View file @
a6f578c8
/* eslint-disable @typescript-eslint/no-empty-function */
import
'
./setup
'
describe
(
'
CrossChainMessenger
'
,
()
=>
{
describe
(
'
sendMessage
'
,
()
=>
{
describe
(
'
when no l2GasLimit is provided
'
,
()
=>
{
it
(
'
should send a message with an estimated l2GasLimit
'
,
()
=>
{}
)
it
(
'
should send a message with an estimated l2GasLimit
'
)
})
describe
(
'
when an l2GasLimit is provided
'
,
()
=>
{
it
(
'
should send a message with the provided l2GasLimit
'
,
()
=>
{}
)
it
(
'
should send a message with the provided l2GasLimit
'
)
})
})
describe
(
'
resendMessage
'
,
()
=>
{
describe
(
'
when the message being resent exists
'
,
()
=>
{
it
(
'
should resend the message with the new gas limit
'
,
()
=>
{}
)
it
(
'
should resend the message with the new gas limit
'
)
})
describe
(
'
when the message being resent does not exist
'
,
()
=>
{
it
(
'
should throw an error
'
,
()
=>
{}
)
it
(
'
should throw an error
'
)
})
})
describe
(
'
finalizeMessage
'
,
()
=>
{
describe
(
'
when the message being finalized exists
'
,
()
=>
{
describe
(
'
when the message is ready to be finalized
'
,
()
=>
{
it
(
'
should finalize the message
'
,
()
=>
{}
)
it
(
'
should finalize the message
'
)
})
describe
(
'
when the message is not ready to be finalized
'
,
()
=>
{
it
(
'
should throw an error
'
,
()
=>
{}
)
it
(
'
should throw an error
'
)
})
describe
(
'
when the message has already been finalized
'
,
()
=>
{
it
(
'
should throw an error
'
,
()
=>
{}
)
it
(
'
should throw an error
'
)
})
})
describe
(
'
when the message being finalized does not exist
'
,
()
=>
{
it
(
'
should throw an error
'
,
()
=>
{}
)
it
(
'
should throw an error
'
)
})
})
})
packages/sdk/test/cross-chain-provider.spec.ts
View file @
a6f578c8
/* eslint-disable @typescript-eslint/no-empty-function */
import
{
expect
}
from
'
./setup
'
import
{
Provider
}
from
'
@ethersproject/abstract-provider
'
import
{
Contract
}
from
'
ethers
'
...
...
@@ -383,24 +382,26 @@ describe('CrossChainProvider', () => {
describe
(
'
getMessagesByAddress
'
,
()
=>
{
describe
(
'
when the address has sent messages
'
,
()
=>
{
describe
(
'
when no direction is specified
'
,
()
=>
{
it
(
'
should find all messages sent by the address
'
,
()
=>
{}
)
it
(
'
should find all messages sent by the address
'
)
})
describe
(
'
when a direction is specified
'
,
()
=>
{
it
(
'
should find all messages only in the given direction
'
,
()
=>
{}
)
it
(
'
should find all messages only in the given direction
'
)
})
describe
(
'
when a block range is specified
'
,
()
=>
{
it
(
'
should find all messages within the block range
'
,
()
=>
{}
)
it
(
'
should find all messages within the block range
'
)
})
describe
(
'
when both a direction and a block range are specified
'
,
()
=>
{
it
(
'
should find all messages only in the given direction and within the block range
'
,
()
=>
{})
it
(
'
should find all messages only in the given direction and within the block range
'
)
})
})
describe
(
'
when the address has not sent messages
'
,
()
=>
{
it
(
'
should find nothing
'
,
()
=>
{}
)
it
(
'
should find nothing
'
)
})
})
...
...
@@ -784,44 +785,44 @@ describe('CrossChainProvider', () => {
describe
(
'
getMessageStatus
'
,
()
=>
{
describe
(
'
when the message is an L1 => L2 message
'
,
()
=>
{
describe
(
'
when the message has not been executed on L2 yet
'
,
()
=>
{
it
(
'
should return a status of UNCONFIRMED_L1_TO_L2_MESSAGE
'
,
()
=>
{}
)
it
(
'
should return a status of UNCONFIRMED_L1_TO_L2_MESSAGE
'
)
})
describe
(
'
when the message has been executed on L2
'
,
()
=>
{
it
(
'
should return a status of RELAYED
'
,
()
=>
{}
)
it
(
'
should return a status of RELAYED
'
)
})
describe
(
'
when the message has been executed but failed
'
,
()
=>
{
it
(
'
should return a status of FAILED_L1_TO_L2_MESSAGE
'
,
()
=>
{}
)
it
(
'
should return a status of FAILED_L1_TO_L2_MESSAGE
'
)
})
})
describe
(
'
when the message is an L2 => L1 message
'
,
()
=>
{
describe
(
'
when the message state root has not been published
'
,
()
=>
{
it
(
'
should return a status of STATE_ROOT_NOT_PUBLISHED
'
,
()
=>
{}
)
it
(
'
should return a status of STATE_ROOT_NOT_PUBLISHED
'
)
})
describe
(
'
when the message state root is still in the challenge period
'
,
()
=>
{
it
(
'
should return a status of IN_CHALLENGE_PERIOD
'
,
()
=>
{}
)
it
(
'
should return a status of IN_CHALLENGE_PERIOD
'
)
})
describe
(
'
when the message is no longer in the challenge period
'
,
()
=>
{
describe
(
'
when the message has been relayed successfully
'
,
()
=>
{
it
(
'
should return a status of RELAYED
'
,
()
=>
{}
)
it
(
'
should return a status of RELAYED
'
)
})
describe
(
'
when the message has been relayed but the relay failed
'
,
()
=>
{
it
(
'
should return a status of READY_FOR_RELAY
'
,
()
=>
{}
)
it
(
'
should return a status of READY_FOR_RELAY
'
)
})
describe
(
'
when the message has not been relayed
'
,
()
=>
{
it
(
'
should return a status of READY_FOR_RELAY
'
,
()
=>
{}
)
it
(
'
should return a status of READY_FOR_RELAY
'
)
})
})
})
describe
(
'
when the message does not exist
'
,
()
=>
{
it
(
'
should throw an error
'
,
()
=>
{}
)
it
(
'
should throw an error
'
)
})
})
...
...
@@ -982,64 +983,157 @@ describe('CrossChainProvider', () => {
// track of
})
describe
(
'
waitForMessageReciept
'
,
()
=>
{
describe
(
'
waitForMessageReceipt
'
,
()
=>
{
let
l2Messenger
:
Contract
let
provider
:
CrossChainProvider
beforeEach
(
async
()
=>
{
l2Messenger
=
(
await
(
await
ethers
.
getContractFactory
(
'
MockMessenger
'
)
).
deploy
())
as
any
provider
=
new
CrossChainProvider
({
l1Provider
:
ethers
.
provider
,
l2Provider
:
ethers
.
provider
,
l1ChainId
:
31337
,
contracts
:
{
l2
:
{
L2CrossDomainMessenger
:
l2Messenger
.
address
,
},
},
})
})
describe
(
'
when the message receipt already exists
'
,
()
=>
{
it
(
'
should immediately return the receipt
'
,
()
=>
{})
it
(
'
should immediately return the receipt
'
,
async
()
=>
{
const
message
=
{
direction
:
MessageDirection
.
L1_TO_L2
,
target
:
'
0x
'
+
'
11
'
.
repeat
(
20
),
sender
:
'
0x
'
+
'
22
'
.
repeat
(
20
),
message
:
'
0x
'
+
'
33
'
.
repeat
(
64
),
messageNonce
:
1234
,
logIndex
:
0
,
blockNumber
:
1234
,
transactionHash
:
'
0x
'
+
'
44
'
.
repeat
(
32
),
}
const
tx
=
await
l2Messenger
.
triggerRelayedMessageEvents
([
hashCrossChainMessage
(
message
),
])
const
messageReceipt
=
await
provider
.
waitForMessageReceipt
(
message
)
expect
(
messageReceipt
.
receiptStatus
).
to
.
equal
(
1
)
expect
(
omit
(
messageReceipt
.
transactionReceipt
,
'
confirmations
'
)
).
to
.
deep
.
equal
(
omit
(
await
ethers
.
provider
.
getTransactionReceipt
(
tx
.
hash
),
'
confirmations
'
)
)
})
})
describe
(
'
when the message receipt does not exist already
'
,
()
=>
{
describe
(
'
when no extra options are provided
'
,
()
=>
{
it
(
'
should wait for the receipt to be published
'
,
()
=>
{})
it
(
'
should wait forever for the receipt if the receipt is never published
'
,
()
=>
{})
it
(
'
should wait for the receipt to be published
'
,
async
()
=>
{
const
message
=
{
direction
:
MessageDirection
.
L1_TO_L2
,
target
:
'
0x
'
+
'
11
'
.
repeat
(
20
),
sender
:
'
0x
'
+
'
22
'
.
repeat
(
20
),
message
:
'
0x
'
+
'
33
'
.
repeat
(
64
),
messageNonce
:
1234
,
logIndex
:
0
,
blockNumber
:
1234
,
transactionHash
:
'
0x
'
+
'
44
'
.
repeat
(
32
),
}
setTimeout
(
async
()
=>
{
await
l2Messenger
.
triggerRelayedMessageEvents
([
hashCrossChainMessage
(
message
),
])
},
5000
)
const
tick
=
Date
.
now
()
const
messageReceipt
=
await
provider
.
waitForMessageReceipt
(
message
)
const
tock
=
Date
.
now
()
expect
(
messageReceipt
.
receiptStatus
).
to
.
equal
(
1
)
expect
(
tock
-
tick
).
to
.
be
.
greaterThan
(
5000
)
})
it
(
'
should wait forever for the receipt if the receipt is never published
'
,
()
=>
{
// Not sure how to easily test this without introducing some sort of cancellation token
// I don't want the promise to loop forever and make the tests never finish.
})
})
describe
(
'
when a timeout is provided
'
,
()
=>
{
it
(
'
should throw an error if the timeout is reached
'
,
()
=>
{})
})
})
it
(
'
should throw an error if the timeout is reached
'
,
async
()
=>
{
const
message
=
{
direction
:
MessageDirection
.
L1_TO_L2
,
target
:
'
0x
'
+
'
11
'
.
repeat
(
20
),
sender
:
'
0x
'
+
'
22
'
.
repeat
(
20
),
message
:
'
0x
'
+
'
33
'
.
repeat
(
64
),
messageNonce
:
1234
,
logIndex
:
0
,
blockNumber
:
1234
,
transactionHash
:
'
0x
'
+
'
44
'
.
repeat
(
32
),
}
describe
(
'
when the message does not exist
'
,
()
=>
{
it
(
'
should throw an error
'
,
()
=>
{})
await
expect
(
provider
.
waitForMessageReceipt
(
message
,
{
timeoutMs
:
10000
,
})
).
to
.
be
.
rejectedWith
(
'
timed out waiting for message receipt
'
)
})
})
})
})
describe
(
'
estimateL2MessageGasLimit
'
,
()
=>
{
it
(
'
should perform a gas estimation of the L2 action
'
,
()
=>
{}
)
it
(
'
should perform a gas estimation of the L2 action
'
)
})
describe
(
'
estimateMessageWaitTimeBlocks
'
,
()
=>
{
describe
(
'
when the message exists
'
,
()
=>
{
describe
(
'
when the message is an L1 => L2 message
'
,
()
=>
{
describe
(
'
when the message has not been executed on L2 yet
'
,
()
=>
{
it
(
'
should return the estimated blocks until the message will be confirmed on L2
'
,
()
=>
{})
it
(
'
should return the estimated blocks until the message will be confirmed on L2
'
)
})
describe
(
'
when the message has been executed on L2
'
,
()
=>
{
it
(
'
should return 0
'
,
()
=>
{}
)
it
(
'
should return 0
'
)
})
})
describe
(
'
when the message is an L2 => L1 message
'
,
()
=>
{
describe
(
'
when the state root has not been published
'
,
()
=>
{
it
(
'
should return the estimated blocks until the state root will be published and pass the challenge period
'
,
()
=>
{})
it
(
'
should return the estimated blocks until the state root will be published and pass the challenge period
'
)
})
describe
(
'
when the state root is within the challenge period
'
,
()
=>
{
it
(
'
should return the estimated blocks until the state root passes the challenge period
'
,
()
=>
{})
it
(
'
should return the estimated blocks until the state root passes the challenge period
'
)
})
describe
(
'
when the state root passes the challenge period
'
,
()
=>
{
it
(
'
should return 0
'
,
()
=>
{}
)
it
(
'
should return 0
'
)
})
})
})
describe
(
'
when the message does not exist
'
,
()
=>
{
it
(
'
should throw an error
'
,
()
=>
{}
)
it
(
'
should throw an error
'
)
})
})
describe
(
'
estimateMessageWaitTimeSeconds
'
,
()
=>
{
it
(
'
should be the result of estimateMessageWaitTimeBlocks multiplied by the L1 block time
'
,
()
=>
{})
it
(
'
should be the result of estimateMessageWaitTimeBlocks multiplied by the L1 block time
'
)
})
})
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