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 (
...
@@ -7,16 +7,18 @@ import (
"encoding/json"
"encoding/json"
"errors"
"errors"
"fmt"
"fmt"
"github.com/ethereum/go-ethereum/log"
"github.com/gorilla/websocket"
"github.com/prometheus/client_golang/prometheus"
"io"
"io"
"io/ioutil"
"io/ioutil"
"math"
"math"
"math/rand"
"math/rand"
"net/http"
"net/http"
"strconv"
"strconv"
"strings"
"time"
"time"
"github.com/ethereum/go-ethereum/log"
"github.com/gorilla/websocket"
"github.com/prometheus/client_golang/prometheus"
)
)
const
(
const
(
...
@@ -84,6 +86,8 @@ type Backend struct {
...
@@ -84,6 +86,8 @@ type Backend struct {
maxRPS
int
maxRPS
int
maxWSConns
int
maxWSConns
int
outOfServiceInterval
time
.
Duration
outOfServiceInterval
time
.
Duration
stripTrailingXFF
bool
proxydIP
string
}
}
type
BackendOpt
func
(
b
*
Backend
)
type
BackendOpt
func
(
b
*
Backend
)
...
@@ -140,6 +144,18 @@ func WithTLSConfig(tlsConfig *tls.Config) BackendOpt {
...
@@ -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
(
func
NewBackend
(
name
string
,
name
string
,
rpcURL
string
,
rpcURL
string
,
...
@@ -163,6 +179,10 @@ func NewBackend(
...
@@ -163,6 +179,10 @@ func NewBackend(
opt
(
backend
)
opt
(
backend
)
}
}
if
!
backend
.
stripTrailingXFF
&&
backend
.
proxydIP
==
""
{
log
.
Warn
(
"proxied requests' XFF header will not contain the proxyd ip address"
)
}
return
backend
return
backend
}
}
...
@@ -316,7 +336,18 @@ func (b *Backend) doForward(ctx context.Context, rpcReq *RPCReq) (*RPCRes, error
...
@@ -316,7 +336,18 @@ func (b *Backend) doForward(ctx context.Context, rpcReq *RPCReq) (*RPCRes, error
httpReq
.
SetBasicAuth
(
b
.
authUsername
,
b
.
authPassword
)
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
(
"content-type"
,
"application/json"
)
httpReq
.
Header
.
Set
(
"X-Forwarded-For"
,
xForwardedFor
)
httpRes
,
err
:=
b
.
client
.
Do
(
httpReq
)
httpRes
,
err
:=
b
.
client
.
Do
(
httpReq
)
if
err
!=
nil
{
if
err
!=
nil
{
...
...
go/proxyd/config.go
View file @
a6f578c8
...
@@ -32,15 +32,16 @@ type BackendOptions struct {
...
@@ -32,15 +32,16 @@ type BackendOptions struct {
}
}
type
BackendConfig
struct
{
type
BackendConfig
struct
{
Username
string
`toml:"username"`
Username
string
`toml:"username"`
Password
string
`toml:"password"`
Password
string
`toml:"password"`
RPCURL
string
`toml:"rpc_url"`
RPCURL
string
`toml:"rpc_url"`
WSURL
string
`toml:"ws_url"`
WSURL
string
`toml:"ws_url"`
MaxRPS
int
`toml:"max_rps"`
MaxRPS
int
`toml:"max_rps"`
MaxWSConns
int
`toml:"max_ws_conns"`
MaxWSConns
int
`toml:"max_ws_conns"`
CAFile
string
`toml:"ca_file"`
CAFile
string
`toml:"ca_file"`
ClientCertFile
string
`toml:"client_cert_file"`
ClientCertFile
string
`toml:"client_cert_file"`
ClientKeyFile
string
`toml:"client_key_file"`
ClientKeyFile
string
`toml:"client_key_file"`
StripTrailingXFF
bool
`toml:"strip_trailing_xff"`
}
}
type
BackendsConfig
map
[
string
]
*
BackendConfig
type
BackendsConfig
map
[
string
]
*
BackendConfig
...
...
go/proxyd/proxyd.go
View file @
a6f578c8
...
@@ -96,6 +96,10 @@ func Start(config *Config) error {
...
@@ -96,6 +96,10 @@ func Start(config *Config) error {
log
.
Info
(
"using custom TLS config for backend"
,
"name"
,
name
)
log
.
Info
(
"using custom TLS config for backend"
,
"name"
,
name
)
opts
=
append
(
opts
,
WithTLSConfig
(
tlsConfig
))
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
...
)
back
:=
NewBackend
(
name
,
rpcURL
,
wsURL
,
lim
,
opts
...
)
backendNames
=
append
(
backendNames
,
name
)
backendNames
=
append
(
backendNames
,
name
)
backendsByName
[
name
]
=
back
backendsByName
[
name
]
=
back
...
...
go/proxyd/server.go
View file @
a6f578c8
...
@@ -5,20 +5,23 @@ import (
...
@@ -5,20 +5,23 @@ import (
"encoding/json"
"encoding/json"
"errors"
"errors"
"fmt"
"fmt"
"io"
"net/http"
"strconv"
"strings"
"time"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/log"
"github.com/gorilla/mux"
"github.com/gorilla/mux"
"github.com/gorilla/websocket"
"github.com/gorilla/websocket"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus"
"github.com/rs/cors"
"github.com/rs/cors"
"io"
"net/http"
"strconv"
"time"
)
)
const
(
const
(
ContextKeyAuth
=
"authorization"
ContextKeyAuth
=
"authorization"
ContextKeyReqID
=
"req_id"
ContextKeyReqID
=
"req_id"
ContextKeyXForwardedFor
=
"x_forwarded_for"
)
)
type
Server
struct
{
type
Server
struct
{
...
@@ -214,7 +217,16 @@ func (s *Server) populateContext(w http.ResponseWriter, r *http.Request) context
...
@@ -214,7 +217,16 @@ func (s *Server) populateContext(w http.ResponseWriter, r *http.Request) context
return
nil
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
(
r
.
Context
(),
ContextKeyAuth
,
s
.
authenticatedPaths
[
authorization
])
ctx
=
context
.
WithValue
(
ctx
,
ContextKeyXForwardedFor
,
xff
)
return
context
.
WithValue
(
return
context
.
WithValue
(
ctx
,
ctx
,
ContextKeyReqID
,
ContextKeyReqID
,
...
@@ -271,3 +283,11 @@ func GetReqID(ctx context.Context) string {
...
@@ -271,3 +283,11 @@ func GetReqID(ctx context.Context) string {
}
}
return
reqId
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'
...
@@ -7,8 +7,25 @@ import { predeploys } from '../src/predeploys'
import
{
getContractDefinition
}
from
'
../src/contract-defs
'
import
{
getContractDefinition
}
from
'
../src/contract-defs
'
task
(
'
set-l2-gasprice
'
)
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
(
'
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
(
.
addOptionalParam
(
'
contractsRpcUrl
'
,
'
contractsRpcUrl
'
,
'
Sequencer HTTP Endpoint
'
,
'
Sequencer HTTP Endpoint
'
,
...
@@ -42,15 +59,45 @@ task('set-l2-gasprice')
...
@@ -42,15 +59,45 @@ task('set-l2-gasprice')
throw
new
Error
(
`Incorrect key. Owner
${
owner
}
, Signer
${
addr
}
`
)
throw
new
Error
(
`Incorrect key. Owner
${
owner
}
, Signer
${
addr
}
`
)
}
}
// List the current values
const
gasPrice
=
await
GasPriceOracle
.
callStatic
.
gasPrice
()
const
gasPrice
=
await
GasPriceOracle
.
callStatic
.
gasPrice
()
cons
ole
.
log
(
`Gas Price is currently
${
gasPrice
.
toString
()}
`
)
cons
t
scalar
=
await
GasPriceOracle
.
callStatic
.
scalar
(
)
cons
ole
.
log
(
`Setting Gas Price to
${
args
.
l2GasPrice
}
`
)
cons
t
overhead
=
await
GasPriceOracle
.
callStatic
.
overhead
(
)
const
tx
=
await
GasPriceOracle
.
connect
(
signer
).
setGasPrice
(
console
.
log
(
'
Current values:
'
)
args
.
l2GasPrice
,
console
.
log
(
`Gas Price:
${
gasPrice
.
toString
()}
`
)
{
gasPrice
:
args
.
transactionGasPrice
}
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
()
const
receipt
=
await
tx
.
wait
()
console
.
log
(
`Success -
${
receipt
.
transactionHash
}
`
)
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 {
...
@@ -5,6 +5,7 @@ import {
TransactionReceipt
,
TransactionReceipt
,
}
from
'
@ethersproject/abstract-provider
'
}
from
'
@ethersproject/abstract-provider
'
import
{
ethers
,
BigNumber
,
Event
}
from
'
ethers
'
import
{
ethers
,
BigNumber
,
Event
}
from
'
ethers
'
import
{
sleep
}
from
'
@eth-optimism/core-utils
'
import
{
import
{
ICrossChainProvider
,
ICrossChainProvider
,
OEContracts
,
OEContracts
,
...
@@ -395,15 +396,27 @@ export class CrossChainProvider implements ICrossChainProvider {
...
@@ -395,15 +396,27 @@ export class CrossChainProvider implements ICrossChainProvider {
return
null
return
null
}
}
public
async
waitForMessageRec
ie
pt
(
public
async
waitForMessageRec
ei
pt
(
message
:
MessageLike
,
message
:
MessageLike
,
opts
?
:
{
opts
:
{
confirmations
?:
number
confirmations
?:
number
pollIntervalMs
?:
number
pollIntervalMs
?:
number
timeoutMs
?:
number
timeoutMs
?:
number
}
}
=
{}
):
Promise
<
MessageReceipt
>
{
):
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
(
public
async
estimateL2MessageGasLimit
(
...
...
packages/sdk/src/interfaces/cross-chain-provider.ts
View file @
a6f578c8
...
@@ -186,7 +186,7 @@ export interface ICrossChainProvider {
...
@@ -186,7 +186,7 @@ export interface ICrossChainProvider {
* @returns CrossChainMessage receipt including receipt of the transaction that relayed the
* @returns CrossChainMessage receipt including receipt of the transaction that relayed the
* given message.
* given message.
*/
*/
waitForMessageRec
ie
pt
(
waitForMessageRec
ei
pt
(
message
:
MessageLike
,
message
:
MessageLike
,
opts
?:
{
opts
?:
{
confirmations
?:
number
confirmations
?:
number
...
...
packages/sdk/test/cross-chain-erc20-pair.spec.ts
View file @
a6f578c8
/* eslint-disable @typescript-eslint/no-empty-function */
import
'
./setup
'
import
'
./setup
'
describe
(
'
CrossChainERC20Pair
'
,
()
=>
{
describe
(
'
CrossChainERC20Pair
'
,
()
=>
{
describe
(
'
construction
'
,
()
=>
{
describe
(
'
construction
'
,
()
=>
{
it
(
'
should have a messenger
'
,
()
=>
{}
)
it
(
'
should have a messenger
'
)
describe
(
'
when the token is a standard bridge token
'
,
()
=>
{
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
'
,
()
=>
{
describe
(
'
when the token is SNX
'
,
()
=>
{
it
(
'
should resolve the correct bridge
'
,
()
=>
{}
)
it
(
'
should resolve the correct bridge
'
)
})
})
describe
(
'
when the token is DAI
'
,
()
=>
{
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
'
,
()
=>
{
describe
(
'
when a custom adapter is provided
'
,
()
=>
{
it
(
'
should use the custom adapter
'
,
()
=>
{}
)
it
(
'
should use the custom adapter
'
)
})
})
})
})
describe
(
'
deposit
'
,
()
=>
{
describe
(
'
deposit
'
,
()
=>
{
describe
(
'
when the user has enough balance and allowance
'
,
()
=>
{
describe
(
'
when the user has enough balance and allowance
'
,
()
=>
{
describe
(
'
when the token is a standard bridge token
'
,
()
=>
{
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
'
,
()
=>
{
describe
(
'
when the token is ETH
'
,
()
=>
{
it
(
'
should trigger a token deposit
'
,
()
=>
{}
)
it
(
'
should trigger a token deposit
'
)
})
})
describe
(
'
when the token is SNX
'
,
()
=>
{
describe
(
'
when the token is SNX
'
,
()
=>
{
it
(
'
should trigger a token deposit
'
,
()
=>
{}
)
it
(
'
should trigger a token deposit
'
)
})
})
describe
(
'
when the token is DAI
'
,
()
=>
{
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
'
,
()
=>
{
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
'
,
()
=>
{
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
(
'
withdraw
'
,
()
=>
{
describe
(
'
when the user has enough balance
'
,
()
=>
{
describe
(
'
when the user has enough balance
'
,
()
=>
{
describe
(
'
when the token is a standard bridge token
'
,
()
=>
{
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
'
,
()
=>
{
describe
(
'
when the token is ETH
'
,
()
=>
{
it
(
'
should trigger a token withdrawal
'
,
()
=>
{}
)
it
(
'
should trigger a token withdrawal
'
)
})
})
describe
(
'
when the token is SNX
'
,
()
=>
{
describe
(
'
when the token is SNX
'
,
()
=>
{
it
(
'
should trigger a token withdrawal
'
,
()
=>
{}
)
it
(
'
should trigger a token withdrawal
'
)
})
})
describe
(
'
when the token is DAI
'
,
()
=>
{
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
'
,
()
=>
{
describe
(
'
when the user does not have enough balance
'
,
()
=>
{
it
(
'
should throw an error
'
,
()
=>
{}
)
it
(
'
should throw an error
'
)
})
})
})
})
describe
(
'
populateTransaction
'
,
()
=>
{
describe
(
'
populateTransaction
'
,
()
=>
{
describe
(
'
deposit
'
,
()
=>
{
describe
(
'
deposit
'
,
()
=>
{
it
(
'
should populate the transaction with the correct values
'
,
()
=>
{}
)
it
(
'
should populate the transaction with the correct values
'
)
})
})
describe
(
'
withdraw
'
,
()
=>
{
describe
(
'
withdraw
'
,
()
=>
{
it
(
'
should populate the transaction with the correct values
'
,
()
=>
{}
)
it
(
'
should populate the transaction with the correct values
'
)
})
})
})
})
describe
(
'
estimateGas
'
,
()
=>
{
describe
(
'
estimateGas
'
,
()
=>
{
describe
(
'
deposit
'
,
()
=>
{
describe
(
'
deposit
'
,
()
=>
{
it
(
'
should estimate gas required for the transaction
'
,
()
=>
{}
)
it
(
'
should estimate gas required for the transaction
'
)
})
})
describe
(
'
withdraw
'
,
()
=>
{
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
'
import
'
./setup
'
describe
(
'
CrossChainMessenger
'
,
()
=>
{
describe
(
'
CrossChainMessenger
'
,
()
=>
{
describe
(
'
sendMessage
'
,
()
=>
{
describe
(
'
sendMessage
'
,
()
=>
{
describe
(
'
when no l2GasLimit is provided
'
,
()
=>
{
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
'
,
()
=>
{
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
(
'
resendMessage
'
,
()
=>
{
describe
(
'
when the message being resent exists
'
,
()
=>
{
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
'
,
()
=>
{
describe
(
'
when the message being resent does not exist
'
,
()
=>
{
it
(
'
should throw an error
'
,
()
=>
{}
)
it
(
'
should throw an error
'
)
})
})
})
})
describe
(
'
finalizeMessage
'
,
()
=>
{
describe
(
'
finalizeMessage
'
,
()
=>
{
describe
(
'
when the message being finalized exists
'
,
()
=>
{
describe
(
'
when the message being finalized exists
'
,
()
=>
{
describe
(
'
when the message is ready to be finalized
'
,
()
=>
{
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
'
,
()
=>
{
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
'
,
()
=>
{
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
'
,
()
=>
{
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
{
expect
}
from
'
./setup
'
import
{
Provider
}
from
'
@ethersproject/abstract-provider
'
import
{
Provider
}
from
'
@ethersproject/abstract-provider
'
import
{
Contract
}
from
'
ethers
'
import
{
Contract
}
from
'
ethers
'
...
@@ -383,24 +382,26 @@ describe('CrossChainProvider', () => {
...
@@ -383,24 +382,26 @@ describe('CrossChainProvider', () => {
describe
(
'
getMessagesByAddress
'
,
()
=>
{
describe
(
'
getMessagesByAddress
'
,
()
=>
{
describe
(
'
when the address has sent messages
'
,
()
=>
{
describe
(
'
when the address has sent messages
'
,
()
=>
{
describe
(
'
when no direction is specified
'
,
()
=>
{
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
'
,
()
=>
{
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
'
,
()
=>
{
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
'
,
()
=>
{
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
'
,
()
=>
{
describe
(
'
when the address has not sent messages
'
,
()
=>
{
it
(
'
should find nothing
'
,
()
=>
{}
)
it
(
'
should find nothing
'
)
})
})
})
})
...
@@ -784,44 +785,44 @@ describe('CrossChainProvider', () => {
...
@@ -784,44 +785,44 @@ describe('CrossChainProvider', () => {
describe
(
'
getMessageStatus
'
,
()
=>
{
describe
(
'
getMessageStatus
'
,
()
=>
{
describe
(
'
when the message is an L1 => L2 message
'
,
()
=>
{
describe
(
'
when the message is an L1 => L2 message
'
,
()
=>
{
describe
(
'
when the message has not been executed on L2 yet
'
,
()
=>
{
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
'
,
()
=>
{
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
'
,
()
=>
{
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 is an L2 => L1 message
'
,
()
=>
{
describe
(
'
when the message state root has not been published
'
,
()
=>
{
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
'
,
()
=>
{
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 is no longer in the challenge period
'
,
()
=>
{
describe
(
'
when the message has been relayed successfully
'
,
()
=>
{
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
'
,
()
=>
{
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
'
,
()
=>
{
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
'
,
()
=>
{
describe
(
'
when the message does not exist
'
,
()
=>
{
it
(
'
should throw an error
'
,
()
=>
{}
)
it
(
'
should throw an error
'
)
})
})
})
})
...
@@ -982,64 +983,157 @@ describe('CrossChainProvider', () => {
...
@@ -982,64 +983,157 @@ describe('CrossChainProvider', () => {
// track of
// 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
'
,
()
=>
{
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 the message receipt does not exist already
'
,
()
=>
{
describe
(
'
when no extra options are provided
'
,
()
=>
{
describe
(
'
when no extra options are provided
'
,
()
=>
{
it
(
'
should wait for the receipt to be published
'
,
()
=>
{})
it
(
'
should wait for the receipt to be published
'
,
async
()
=>
{
it
(
'
should wait forever for the receipt if the receipt is never published
'
,
()
=>
{})
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
'
,
()
=>
{
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
'
,
()
=>
{
await
expect
(
it
(
'
should throw an error
'
,
()
=>
{})
provider
.
waitForMessageReceipt
(
message
,
{
timeoutMs
:
10000
,
})
).
to
.
be
.
rejectedWith
(
'
timed out waiting for message receipt
'
)
})
})
})
})
})
})
describe
(
'
estimateL2MessageGasLimit
'
,
()
=>
{
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
(
'
estimateMessageWaitTimeBlocks
'
,
()
=>
{
describe
(
'
when the message exists
'
,
()
=>
{
describe
(
'
when the message exists
'
,
()
=>
{
describe
(
'
when the message is an L1 => L2 message
'
,
()
=>
{
describe
(
'
when the message is an L1 => L2 message
'
,
()
=>
{
describe
(
'
when the message has not been executed on L2 yet
'
,
()
=>
{
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
'
,
()
=>
{
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 message is an L2 => L1 message
'
,
()
=>
{
describe
(
'
when the state root has not been published
'
,
()
=>
{
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
'
,
()
=>
{
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
'
,
()
=>
{
describe
(
'
when the state root passes the challenge period
'
,
()
=>
{
it
(
'
should return 0
'
,
()
=>
{}
)
it
(
'
should return 0
'
)
})
})
})
})
})
})
describe
(
'
when the message does not exist
'
,
()
=>
{
describe
(
'
when the message does not exist
'
,
()
=>
{
it
(
'
should throw an error
'
,
()
=>
{}
)
it
(
'
should throw an error
'
)
})
})
})
})
describe
(
'
estimateMessageWaitTimeSeconds
'
,
()
=>
{
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