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
b8d9fa17
Unverified
Commit
b8d9fa17
authored
Sep 15, 2022
by
Matthew Slipper
Committed by
GitHub
Sep 15, 2022
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #3479 from ethereum-optimism/develop
Develop -> Master
parents
3fe480d4
157ccc84
Changes
22
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
22 changed files
with
539 additions
and
108 deletions
+539
-108
calm-comics-tap.md
.changeset/calm-comics-tap.md
+5
-0
silent-terms-lie.md
.changeset/silent-terms-lie.md
+5
-0
three-weeks-kneel.md
.changeset/three-weeks-kneel.md
+5
-0
go.mod
indexer/go.mod
+2
-5
go.sum
indexer/go.sum
+2
-48
bridge.go
indexer/services/l1/bridge/bridge.go
+5
-0
bridge.go
indexer/services/l2/bridge/bridge.go
+4
-0
weth9.go
op-bindings/bindings/weth9.go
+1
-1
weth9_more.go
op-bindings/bindings/weth9_more.go
+1
-1
encoding.go
op-chain-ops/crossdomain/encoding.go
+72
-0
encoding_test.go
op-chain-ops/crossdomain/encoding_test.go
+30
-0
hashing.go
op-chain-ops/crossdomain/hashing.go
+42
-0
message.go
op-chain-ops/crossdomain/message.go
+72
-0
message_test.go
op-chain-ops/crossdomain/message_test.go
+100
-0
.gas-snapshot
packages/contracts-bedrock/.gas-snapshot
+24
-13
GasPriceOracle.sol
packages/contracts-bedrock/contracts/L2/GasPriceOracle.sol
+2
-2
CrossDomainMessenger.sol
...acts-bedrock/contracts/universal/CrossDomainMessenger.sol
+3
-3
StandardBridge.sol
.../contracts-bedrock/contracts/universal/StandardBridge.sol
+2
-2
config.go
proxyd/config.go
+23
-4
rate_limit_test.go
proxyd/integration_tests/rate_limit_test.go
+60
-10
frontend_rate_limit.toml
proxyd/integration_tests/testdata/frontend_rate_limit.toml
+5
-0
server.go
proxyd/server.go
+74
-19
No files found.
.changeset/calm-comics-tap.md
0 → 100644
View file @
b8d9fa17
---
'
@eth-optimism/contracts-bedrock'
:
patch
---
Make spacer variables private in the Bridge and Messenger contracts so that they cannot be accessed in child contracts.
.changeset/silent-terms-lie.md
0 → 100644
View file @
b8d9fa17
---
'
@eth-optimism/indexer'
:
minor
---
This release supports bedrock contracts and is configured for the public alpha testnet on goerli.
.changeset/three-weeks-kneel.md
0 → 100644
View file @
b8d9fa17
---
'
@eth-optimism/proxyd'
:
minor
---
Support per-method rate limiting
indexer/go.mod
View file @
b8d9fa17
...
...
@@ -5,7 +5,8 @@ go 1.17
replace github.com/ethereum-optimism/optimism/op-bindings v0.0.0 => ../op-bindings
require (
github.com/ethereum/go-ethereum v1.10.21
github.com/ethereum-optimism/optimism/op-bindings v0.0.0
github.com/ethereum/go-ethereum v1.10.23
github.com/getsentry/sentry-go v0.12.0
github.com/google/uuid v1.3.0
github.com/gorilla/mux v1.8.0
...
...
@@ -17,7 +18,6 @@ require (
)
require (
github.com/VictoriaMetrics/fastcache v1.9.0 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/btcsuite/btcd/btcec/v2 v2.2.0 // indirect
github.com/cespare/xxhash/v2 v2.1.2 // indirect
...
...
@@ -30,18 +30,15 @@ require (
github.com/golang/protobuf v1.5.2 // indirect
github.com/gorilla/websocket v1.5.0 // indirect
github.com/hashicorp/go-bexpr v0.1.11 // indirect
github.com/mattn/go-runewidth v0.0.13 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
github.com/mitchellh/mapstructure v1.4.3 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/prometheus/client_model v0.2.0 // indirect
github.com/prometheus/common v0.30.0 // indirect
github.com/prometheus/procfs v0.7.3 // indirect
github.com/prometheus/tsdb v0.10.0 // indirect
github.com/rjeczalik/notify v0.9.2 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/shirou/gopsutil v3.21.11+incompatible // indirect
github.com/syndtr/goleveldb v1.0.1-0.20220614013038-64ee5596c38a // indirect
github.com/tklauser/go-sysconf v0.3.10 // indirect
github.com/tklauser/numcpus v0.4.0 // indirect
github.com/yusufpapurcu/wmi v1.2.2 // indirect
...
...
indexer/go.sum
View file @
b8d9fa17
This diff is collapsed.
Click to expand it.
indexer/services/l1/bridge/bridge.go
View file @
b8d9fa17
...
...
@@ -35,6 +35,11 @@ var defaultBridgeCfgs = map[uint64][]*implConfig{
{
"Standard"
,
"StandardBridge"
,
predeploys
.
DevL1StandardBridge
},
{
"ETH"
,
"ETHBridge"
,
predeploys
.
DevL1StandardBridge
},
},
// Goerli
5
:
{
{
"Standard"
,
"StandardBridge"
,
"0xFf94B6C486350aD92561Ba09bad3a59df764Da92"
},
{
"ETH"
,
"ETHBridge"
,
"0xFf94B6C486350aD92561Ba09bad3a59df764Da92"
},
},
}
var
customBridgeCfgs
=
map
[
uint64
][]
*
implConfig
{
...
...
indexer/services/l2/bridge/bridge.go
View file @
b8d9fa17
...
...
@@ -33,6 +33,10 @@ var defaultBridgeCfgs = map[uint64][]*implConfig{
901
:
{
{
"Standard"
,
"StandardBridge"
,
L2StandardBridgeAddr
},
},
// Goerli Alpha Testnet
28528
:
{
{
"Standard"
,
"StandardBridge"
,
L2StandardBridgeAddr
},
},
}
var
customBridgeCfgs
=
map
[
uint64
][]
*
implConfig
{
...
...
op-bindings/bindings/weth9.go
View file @
b8d9fa17
This diff is collapsed.
Click to expand it.
op-bindings/bindings/weth9_more.go
View file @
b8d9fa17
...
...
@@ -13,7 +13,7 @@ const WETH9StorageLayoutJSON = "{\"storage\":[{\"astId\":4,\"contract\":\"contra
var
WETH9StorageLayout
=
new
(
solc
.
StorageLayout
)
var
WETH9DeployedBin
=
"0x6080604052600436106100bc5760003560e01c8063313ce56711610074578063a9059cbb1161004e578063a9059cbb146102cb578063d0e30db0146100bc578063dd62ed3e14610311576100bc565b8063313ce5671461024b57806370a082311461027657806395d89b41146102b6576100bc565b806318160ddd116100a557806318160ddd146101aa57806323b872dd146101d15780632e1a7d4d14610221576100bc565b806306fdde03146100c6578063095ea7b314610150575b6100c4610359565b005b3480156100d257600080fd5b506100db6103a8565b6040805160208082528351818301528351919283929083019185019080838360005b838110156101155781810151838201526020016100fd565b50505050905090810190601f1680156101425780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561015c57600080fd5b506101966004803603604081101561017357600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610454565b604080519115158252519081900360200190f35b3480156101b657600080fd5b506101bf6104c7565b60408051918252519081900360200190f35b3480156101dd57600080fd5b50610196600480360360608110156101f457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135811691602081013590911690604001356104cb565b34801561022d57600080fd5b506100c46004803603602081101561024457600080fd5b503561066b565b34801561025757600080fd5b50610260610700565b6040805160ff9092168252519081900360200190f35b34801561028257600080fd5b506101bf6004803603602081101561029957600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610709565b3480156102c257600080fd5b506100db61071b565b3480156102d757600080fd5b50610196600480360360408110156102ee57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610793565b34801561031d57600080fd5b506101bf6004803603604081101561033457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160200135166107a7565b33600081815260036020908152604091829020805434908101909155825190815291517fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9281900390910190a2565b6000805460408051602060026001851615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f8101849004840282018401909252818152929183018282801561044c5780601f106104215761010080835404028352916020019161044c565b820191906000526020600020905b81548152906001019060200180831161042f57829003601f168201915b505050505081565b33600081815260046020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716808552908352818420869055815186815291519394909390927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a350600192915050565b4790565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600360205260408120548211156104fd57600080fd5b73ffffffffffffffffffffffffffffffffffffffff84163314801590610573575073ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff14155b156105ed5773ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020548211156105b557600080fd5b73ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020805483900390555b73ffffffffffffffffffffffffffffffffffffffff808516600081815260036020908152604080832080548890039055938716808352918490208054870190558351868152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a35060019392505050565b3360009081526003602052604090205481111561068757600080fd5b33600081815260036020526040808220805485900390555183156108fc0291849190818181858888f193505050501580156106c6573d6000803e3d6000fd5b5060408051828152905133917f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65919081900360200190a250565b60025460ff1681565b60036020526000908152604090205481565b60018054604080516020600284861615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f8101849004840282018401909252818152929183018282801561044c5780601f106104215761010080835404028352916020019161044c565b60006107a03384846104cb565b9392505050565b60046020908152600092835260408084209091529082529020548156fea265627a7a72315820
b2282f823392ab6b42c17b31235784e88e108cd8d10e77cd732aa3e1e7a88a7d
64736f6c63430005110032"
var
WETH9DeployedBin
=
"0x6080604052600436106100bc5760003560e01c8063313ce56711610074578063a9059cbb1161004e578063a9059cbb146102cb578063d0e30db0146100bc578063dd62ed3e14610311576100bc565b8063313ce5671461024b57806370a082311461027657806395d89b41146102b6576100bc565b806318160ddd116100a557806318160ddd146101aa57806323b872dd146101d15780632e1a7d4d14610221576100bc565b806306fdde03146100c6578063095ea7b314610150575b6100c4610359565b005b3480156100d257600080fd5b506100db6103a8565b6040805160208082528351818301528351919283929083019185019080838360005b838110156101155781810151838201526020016100fd565b50505050905090810190601f1680156101425780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561015c57600080fd5b506101966004803603604081101561017357600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610454565b604080519115158252519081900360200190f35b3480156101b657600080fd5b506101bf6104c7565b60408051918252519081900360200190f35b3480156101dd57600080fd5b50610196600480360360608110156101f457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135811691602081013590911690604001356104cb565b34801561022d57600080fd5b506100c46004803603602081101561024457600080fd5b503561066b565b34801561025757600080fd5b50610260610700565b6040805160ff9092168252519081900360200190f35b34801561028257600080fd5b506101bf6004803603602081101561029957600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610709565b3480156102c257600080fd5b506100db61071b565b3480156102d757600080fd5b50610196600480360360408110156102ee57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610793565b34801561031d57600080fd5b506101bf6004803603604081101561033457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160200135166107a7565b33600081815260036020908152604091829020805434908101909155825190815291517fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9281900390910190a2565b6000805460408051602060026001851615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f8101849004840282018401909252818152929183018282801561044c5780601f106104215761010080835404028352916020019161044c565b820191906000526020600020905b81548152906001019060200180831161042f57829003601f168201915b505050505081565b33600081815260046020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716808552908352818420869055815186815291519394909390927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a350600192915050565b4790565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600360205260408120548211156104fd57600080fd5b73ffffffffffffffffffffffffffffffffffffffff84163314801590610573575073ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff14155b156105ed5773ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020548211156105b557600080fd5b73ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020805483900390555b73ffffffffffffffffffffffffffffffffffffffff808516600081815260036020908152604080832080548890039055938716808352918490208054870190558351868152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a35060019392505050565b3360009081526003602052604090205481111561068757600080fd5b33600081815260036020526040808220805485900390555183156108fc0291849190818181858888f193505050501580156106c6573d6000803e3d6000fd5b5060408051828152905133917f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65919081900360200190a250565b60025460ff1681565b60036020526000908152604090205481565b60018054604080516020600284861615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f8101849004840282018401909252818152929183018282801561044c5780601f106104215761010080835404028352916020019161044c565b60006107a03384846104cb565b9392505050565b60046020908152600092835260408084209091529082529020548156fea265627a7a72315820
92e8fa1999c122c50a7672ead4cd9cdd378070b1e8a202f4537418ba1398d60c
64736f6c63430005110032"
func
init
()
{
if
err
:=
json
.
Unmarshal
([]
byte
(
WETH9StorageLayoutJSON
),
WETH9StorageLayout
);
err
!=
nil
{
...
...
op-chain-ops/crossdomain/encoding.go
0 → 100644
View file @
b8d9fa17
package
crossdomain
import
(
"math/big"
"strings"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/common"
)
var
(
// NonceMask represents a mask used to extract version bytes from the nonce
NonceMask
,
_
=
new
(
big
.
Int
)
.
SetString
(
"0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
,
16
)
// relayMessage0ABI represents the v0 relay message encoding
relayMessage0ABI
=
"[{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
_target
\"
,
\"
type
\"
:
\"
address
\"
},{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
_sender
\"
,
\"
type
\"
:
\"
address
\"
},{
\"
internalType
\"
:
\"
bytes
\"
,
\"
name
\"
:
\"
_message
\"
,
\"
type
\"
:
\"
bytes
\"
},{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
_messageNonce
\"
,
\"
type
\"
:
\"
uint256
\"
}],
\"
name
\"
:
\"
relayMessage
\"
,
\"
outputs
\"
:[],
\"
stateMutability
\"
:
\"
nonpayable
\"
,
\"
type
\"
:
\"
function
\"
}]"
// relayMessage1ABI represents the v1 relay message encoding
relayMessage1ABI
=
"[{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
_nonce
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
_sender
\"
,
\"
type
\"
:
\"
address
\"
},{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
_target
\"
,
\"
type
\"
:
\"
address
\"
},{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
_value
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
_minGasLimit
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
internalType
\"
:
\"
bytes
\"
,
\"
name
\"
:
\"
_message
\"
,
\"
type
\"
:
\"
bytes
\"
}],
\"
name
\"
:
\"
relayMessage
\"
,
\"
outputs
\"
:[],
\"
stateMutability
\"
:
\"
payable
\"
,
\"
type
\"
:
\"
function
\"
}]"
// relayMessage0 represents the ABI of relay message v0
relayMessage0
abi
.
ABI
// relayMessage1 represents the ABI of relay message v1
relayMessage1
abi
.
ABI
)
// Create the required ABIs
func
init
()
{
var
err
error
relayMessage0
,
err
=
abi
.
JSON
(
strings
.
NewReader
(
relayMessage0ABI
))
if
err
!=
nil
{
panic
(
err
)
}
relayMessage1
,
err
=
abi
.
JSON
(
strings
.
NewReader
(
relayMessage1ABI
))
if
err
!=
nil
{
panic
(
err
)
}
}
// EncodeCrossDomainMessageV0 will encode the calldata for
// "relayMessage(address,address,bytes,uint256)",
func
EncodeCrossDomainMessageV0
(
target
*
common
.
Address
,
sender
*
common
.
Address
,
message
[]
byte
,
nonce
*
big
.
Int
,
)
([]
byte
,
error
)
{
return
relayMessage0
.
Pack
(
"relayMessage"
,
target
,
sender
,
message
,
nonce
)
}
// EncodeCrossDomainMessageV1 will encode the calldata for
// "relayMessage(uint256,address,address,uint256,uint256,bytes)",
func
EncodeCrossDomainMessageV1
(
nonce
*
big
.
Int
,
sender
*
common
.
Address
,
target
*
common
.
Address
,
value
*
big
.
Int
,
gasLimit
*
big
.
Int
,
data
[]
byte
,
)
([]
byte
,
error
)
{
return
relayMessage1
.
Pack
(
"relayMessage"
,
nonce
,
sender
,
target
,
value
,
gasLimit
,
data
)
}
// DecodeVersionedNonce will decode the version that is encoded in the nonce
func
DecodeVersionedNonce
(
versioned
*
big
.
Int
)
(
*
big
.
Int
,
*
big
.
Int
)
{
nonce
:=
new
(
big
.
Int
)
.
And
(
versioned
,
NonceMask
)
version
:=
new
(
big
.
Int
)
.
Rsh
(
versioned
,
240
)
return
nonce
,
version
}
// EncodeVersionedNonce will encode the version into the nonce
func
EncodeVersionedNonce
(
nonce
,
version
*
big
.
Int
)
*
big
.
Int
{
shifted
:=
new
(
big
.
Int
)
.
Lsh
(
version
,
240
)
return
new
(
big
.
Int
)
.
Or
(
nonce
,
shifted
)
}
op-chain-ops/crossdomain/encoding_test.go
0 → 100644
View file @
b8d9fa17
package
crossdomain_test
import
(
"math/big"
"testing"
"github.com/ethereum-optimism/optimism/op-chain-ops/crossdomain"
"github.com/stretchr/testify/require"
)
func
FuzzVersionedNonce
(
f
*
testing
.
F
)
{
f
.
Fuzz
(
func
(
t
*
testing
.
T
,
_nonce
[]
byte
,
_version
uint16
)
{
inputNonce
:=
new
(
big
.
Int
)
.
SetBytes
(
_nonce
)
// Clamp nonce to uint240
if
inputNonce
.
Cmp
(
crossdomain
.
NonceMask
)
>
0
{
inputNonce
=
new
(
big
.
Int
)
.
Set
(
crossdomain
.
NonceMask
)
}
// Clamp version to 0 or 1
_version
=
_version
%
2
inputVersion
:=
new
(
big
.
Int
)
.
SetUint64
(
uint64
(
_version
))
encodedNonce
:=
crossdomain
.
EncodeVersionedNonce
(
inputNonce
,
inputVersion
)
decodedNonce
,
decodedVersion
:=
crossdomain
.
DecodeVersionedNonce
(
encodedNonce
)
require
.
Equal
(
t
,
decodedNonce
.
Uint64
(),
inputNonce
.
Uint64
())
require
.
Equal
(
t
,
decodedVersion
.
Uint64
(),
inputVersion
.
Uint64
())
})
}
op-chain-ops/crossdomain/hashing.go
0 → 100644
View file @
b8d9fa17
package
crossdomain
import
(
"math/big"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
)
// HashCrossDomainMessageV0 computes the pre bedrock cross domain messaging
// hashing scheme.
func
HashCrossDomainMessageV0
(
target
*
common
.
Address
,
sender
*
common
.
Address
,
data
[]
byte
,
nonce
*
big
.
Int
,
)
(
common
.
Hash
,
error
)
{
encoded
,
err
:=
EncodeCrossDomainMessageV0
(
target
,
sender
,
data
,
nonce
)
if
err
!=
nil
{
return
common
.
Hash
{},
err
}
hash
:=
crypto
.
Keccak256
(
encoded
)
return
common
.
BytesToHash
(
hash
),
nil
}
// HashCrossDomainMessageV1 computes the first post bedrock cross domain
// messaging hashing scheme.
func
HashCrossDomainMessageV1
(
nonce
*
big
.
Int
,
sender
*
common
.
Address
,
target
*
common
.
Address
,
value
*
big
.
Int
,
gasLimit
*
big
.
Int
,
data
[]
byte
,
)
(
common
.
Hash
,
error
)
{
encoded
,
err
:=
EncodeCrossDomainMessageV1
(
nonce
,
sender
,
target
,
value
,
gasLimit
,
data
)
if
err
!=
nil
{
return
common
.
Hash
{},
err
}
hash
:=
crypto
.
Keccak256
(
encoded
)
return
common
.
BytesToHash
(
hash
),
nil
}
op-chain-ops/crossdomain/message.go
0 → 100644
View file @
b8d9fa17
package
crossdomain
import
(
"fmt"
"math/big"
"github.com/ethereum/go-ethereum/common"
)
// CrossDomainMessage represents a cross domain message
// used by the CrossDomainMessenger. The version is encoded
// in the nonce. Version 0 messages do not have a value,
// version 1 messages have a value and the most significant
// byte of the nonce is a 1
type
CrossDomainMessage
struct
{
Nonce
*
big
.
Int
Sender
*
common
.
Address
Target
*
common
.
Address
Value
*
big
.
Int
GasLimit
*
big
.
Int
Data
[]
byte
}
// NewCrossDomainMessage creates a CrossDomainMessage.
func
NewCrossDomainMessage
(
nonce
*
big
.
Int
,
sender
,
target
*
common
.
Address
,
value
,
gasLimit
*
big
.
Int
,
data
[]
byte
,
)
*
CrossDomainMessage
{
return
&
CrossDomainMessage
{
Nonce
:
nonce
,
Sender
:
sender
,
Target
:
target
,
Value
:
value
,
GasLimit
:
gasLimit
,
Data
:
data
,
}
}
// Version will return the version of the CrossDomainMessage.
// It does this by looking at the first byte of the nonce.
func
(
c
*
CrossDomainMessage
)
Version
()
uint64
{
_
,
version
:=
DecodeVersionedNonce
(
c
.
Nonce
)
return
version
.
Uint64
()
}
// Encode will encode a cross domain message based on the version.
func
(
c
*
CrossDomainMessage
)
Encode
()
([]
byte
,
error
)
{
version
:=
c
.
Version
()
switch
version
{
case
0
:
return
EncodeCrossDomainMessageV0
(
c
.
Target
,
c
.
Sender
,
c
.
Data
,
c
.
Nonce
)
case
1
:
return
EncodeCrossDomainMessageV1
(
c
.
Nonce
,
c
.
Sender
,
c
.
Target
,
c
.
Value
,
c
.
GasLimit
,
c
.
Data
)
default
:
return
nil
,
fmt
.
Errorf
(
"unknown nonce version %d"
,
version
)
}
}
// Hash will compute the hash of the CrossDomainMessage
func
(
c
*
CrossDomainMessage
)
Hash
()
(
common
.
Hash
,
error
)
{
version
:=
c
.
Version
()
switch
version
{
case
0
:
return
HashCrossDomainMessageV0
(
c
.
Target
,
c
.
Sender
,
c
.
Data
,
c
.
Nonce
)
case
1
:
return
HashCrossDomainMessageV1
(
c
.
Nonce
,
c
.
Sender
,
c
.
Target
,
c
.
Value
,
c
.
GasLimit
,
c
.
Data
)
default
:
return
common
.
Hash
{},
fmt
.
Errorf
(
"unknown nonce version %d"
,
version
)
}
}
op-chain-ops/crossdomain/message_test.go
0 → 100644
View file @
b8d9fa17
package
crossdomain_test
import
(
"math/big"
"testing"
"github.com/ethereum-optimism/optimism/op-chain-ops/crossdomain"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/stretchr/testify/require"
)
// TestEncode tests the encoding of a CrossDomainMessage. The assertion was
// created using solidity.
func
TestEncode
(
t
*
testing
.
T
)
{
t
.
Parallel
()
t
.
Run
(
"V0"
,
func
(
t
*
testing
.
T
)
{
msg
:=
crossdomain
.
NewCrossDomainMessage
(
crossdomain
.
EncodeVersionedNonce
(
common
.
Big0
,
common
.
Big0
),
&
common
.
Address
{},
&
common
.
Address
{
19
:
0x01
},
big
.
NewInt
(
0
),
big
.
NewInt
(
5
),
[]
byte
{},
)
require
.
Equal
(
t
,
uint64
(
0
),
msg
.
Version
())
encoded
,
err
:=
msg
.
Encode
()
require
.
Nil
(
t
,
err
)
expect
:=
hexutil
.
MustDecode
(
"0xcbd4ece900000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
)
require
.
Equal
(
t
,
expect
,
encoded
)
})
t
.
Run
(
"V1"
,
func
(
t
*
testing
.
T
)
{
msg
:=
crossdomain
.
NewCrossDomainMessage
(
crossdomain
.
EncodeVersionedNonce
(
common
.
Big1
,
common
.
Big1
),
&
common
.
Address
{
19
:
0x01
},
&
common
.
Address
{
19
:
0x02
},
big
.
NewInt
(
100
),
big
.
NewInt
(
555
),
[]
byte
{},
)
require
.
Equal
(
t
,
uint64
(
1
),
msg
.
Version
())
encoded
,
err
:=
msg
.
Encode
()
require
.
Nil
(
t
,
err
)
expect
:=
hexutil
.
MustDecode
(
"0xd764ad0b0001000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000064000000000000000000000000000000000000000000000000000000000000022b00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000"
)
require
.
Equal
(
t
,
expect
,
encoded
)
})
}
// TestEncode tests the hash of a CrossDomainMessage. The assertion was
// created using solidity.
func
TestHash
(
t
*
testing
.
T
)
{
t
.
Parallel
()
t
.
Run
(
"V0"
,
func
(
t
*
testing
.
T
)
{
msg
:=
crossdomain
.
NewCrossDomainMessage
(
crossdomain
.
EncodeVersionedNonce
(
common
.
Big0
,
common
.
Big0
),
&
common
.
Address
{},
&
common
.
Address
{
19
:
0x01
},
big
.
NewInt
(
10
),
big
.
NewInt
(
5
),
[]
byte
{},
)
require
.
Equal
(
t
,
uint64
(
0
),
msg
.
Version
())
hash
,
err
:=
msg
.
Hash
()
require
.
Nil
(
t
,
err
)
expect
:=
common
.
HexToHash
(
"0x5bb579a193681e7c4d43c8c2e4bc6c2c447d21ef9fa887ca23b2d3f9a0fac065"
)
require
.
Equal
(
t
,
expect
,
hash
)
})
t
.
Run
(
"V1"
,
func
(
t
*
testing
.
T
)
{
msg
:=
crossdomain
.
NewCrossDomainMessage
(
crossdomain
.
EncodeVersionedNonce
(
common
.
Big0
,
common
.
Big1
),
&
common
.
Address
{},
&
common
.
Address
{
19
:
0x01
},
big
.
NewInt
(
0
),
big
.
NewInt
(
5
),
[]
byte
{},
)
require
.
Equal
(
t
,
uint64
(
1
),
msg
.
Version
())
hash
,
err
:=
msg
.
Hash
()
require
.
Nil
(
t
,
err
)
expect
:=
common
.
HexToHash
(
"0x09bbda7f59cdaccab5c41cab4600bd458b2bd7d9f8410f13316fe07e5f4237cc"
)
require
.
Equal
(
t
,
expect
,
hash
)
})
}
packages/contracts-bedrock/.gas-snapshot
View file @
b8d9fa17
...
...
@@ -17,6 +17,10 @@ CrossDomainOwnable2_Test:test_revertNotSetOnlyOwner2() (gas: 14598)
CrossDomainOwnable2_Test:test_revertOnlyOwner() (gas: 63704)
DeployerWhitelist_Test:test_owner() (gas: 7591)
DeployerWhitelist_Test:test_storageSlots() (gas: 33427)
Encoding_Test:test_decodeVersionedNonce_differential(uint240,uint16) (runs: 256, μ: 13329, ~: 13345)
Encoding_Test:test_encodeCrossDomainMessage_differential(uint240,uint8,address,address,uint256,uint256,bytes) (runs: 256, μ: 87650, ~: 91649)
Encoding_Test:test_encodeDepositTransaction_differential(address,address,uint256,uint256,uint64,bool,bytes,uint256) (runs: 256, μ: 106526, ~: 101730)
Encoding_Test:test_nonceVersioning(uint240,uint16) (runs: 256, μ: 652, ~: 652)
GasPriceOracle_Test:test_baseFee() (gas: 8392)
GasPriceOracle_Test:test_gasPrice() (gas: 8381)
GasPriceOracle_Test:test_l1BaseFee() (gas: 10648)
...
...
@@ -30,13 +34,18 @@ GasPriceOracle_Test:test_setL1BaseFeeReverts() (gas: 11739)
GasPriceOracle_Test:test_setOverhead() (gas: 36813)
GasPriceOracle_Test:test_setScalar() (gas: 36820)
GasPriceOracle_Test:test_storageLayout() (gas: 86777)
Hashing_Test:test_hashCrossDomainMessage_differential(uint256,address,address,uint256,uint256,bytes) (runs: 256, μ: 23905, ~: 23788)
Hashing_Test:test_hashDepositSource() (gas: 628)
Hashing_Test:test_hashDepositTransaction_differential(address,address,uint256,uint256,uint64,bytes,uint256) (runs: 256, μ: 66710, ~: 66432)
Hashing_Test:test_hashOutputRootProof_differential(bytes32,bytes32,bytes32,bytes32) (runs: 256, μ: 72062, ~: 93483)
Hashing_Test:test_hashWithdrawal_differential(uint256,address,address,uint256,uint256,bytes) (runs: 256, μ: 23654, ~: 23478)
L1BlockTest:test_basefee() (gas: 7575)
L1BlockTest:test_hash() (gas: 7552)
L1BlockTest:test_number() (gas: 7629)
L1BlockTest:test_sequenceNumber() (gas: 7650)
L1BlockTest:test_timestamp() (gas: 7661)
L1BlockTest:test_updateValues() (gas: 28193)
L1BlockTest:test_updatesValues(uint64,uint64,uint256,bytes32,uint64) (runs: 256, μ: 35307, ~: 35717)
L1BlockNumberTest:test_fallback() (gas: 18677)
L1BlockNumberTest:test_getL1BlockNumber() (gas: 10668)
L1BlockNumberTest:test_receive() (gas: 25340)
...
...
@@ -55,7 +64,7 @@ L1CrossDomainMessenger_Test:test_L1MessengerSendMessage() (gas: 301590)
L1CrossDomainMessenger_Test:test_L1MessengerTwiceSendMessage() (gas: 1492584)
L1CrossDomainMessenger_Test:test_L1MessengerUnpause() (gas: 41003)
L1CrossDomainMessenger_Test:test_L1MessengerXDomainSenderReverts() (gas: 24283)
L1CrossDomainMessenger_Test:test_L1MessengerxDomainMessageSenderResets() (gas: 840
53
)
L1CrossDomainMessenger_Test:test_L1MessengerxDomainMessageSenderResets() (gas: 840
71
)
L1StandardBridge_Test:test_depositERC20() (gas: 574877)
L1StandardBridge_Test:test_depositERC20To() (gas: 577084)
L1StandardBridge_Test:test_depositETH() (gas: 369700)
...
...
@@ -81,7 +90,7 @@ L2CrossDomainMessenger_Test:test_L2MessengerRelayShouldRevertIfPaused() (gas: 41
L2CrossDomainMessenger_Test:test_L2MessengerSendMessage() (gas: 122833)
L2CrossDomainMessenger_Test:test_L2MessengerTwiceSendMessage() (gas: 138556)
L2CrossDomainMessenger_Test:test_L2MessengerXDomainSenderReverts() (gas: 10576)
L2CrossDomainMessenger_Test:test_L2MessengerxDomainMessageSenderResets() (gas: 525
58
)
L2CrossDomainMessenger_Test:test_L2MessengerxDomainMessageSenderResets() (gas: 525
77
)
L2OutputOracleTest:testCannot_ProposeWithUnmatchedBlockhash() (gas: 26829)
L2OutputOracleTest:testCannot_deleteL2Output_ifNotOwner() (gas: 25123)
L2OutputOracleTest:testCannot_deleteL2Output_withWrongRoot() (gas: 91445)
...
...
@@ -92,10 +101,10 @@ L2OutputOracleTest:testCannot_proposeL2OutputIfNotProposer() (gas: 23564)
L2OutputOracleTest:testCannot_proposeOnWrongFork() (gas: 26424)
L2OutputOracleTest:testCannot_proposeUnexpectedBlockNumber() (gas: 25983)
L2OutputOracleTest:test_changeProposer() (gas: 56139)
L2OutputOracleTest:test_computeL2Timestamp() (gas: 30
288
)
L2OutputOracleTest:test_computeL2Timestamp() (gas: 30
307
)
L2OutputOracleTest:test_constructor() (gas: 49046)
L2OutputOracleTest:test_deleteOutput() (gas: 77242)
L2OutputOracleTest:test_getL2Output() (gas: 885
08
)
L2OutputOracleTest:test_getL2Output() (gas: 885
46
)
L2OutputOracleTest:test_latestBlockNumber() (gas: 76284)
L2OutputOracleTest:test_nextBlockNumber() (gas: 15232)
L2OutputOracleTest:test_proposeWithBlockhashAndHeight() (gas: 75046)
...
...
@@ -144,10 +153,11 @@ OptimismPortalUpgradeable_Test:test_cannotInitImpl() (gas: 10813)
OptimismPortalUpgradeable_Test:test_cannotInitProxy() (gas: 15789)
OptimismPortalUpgradeable_Test:test_initValuesOnProxy() (gas: 15967)
OptimismPortalUpgradeable_Test:test_upgrading() (gas: 180632)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_revertsOnInsufficientGas() (gas: 160788)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_differential(address,address,uint256,uint256,bytes) (runs: 256, μ: 265023, ~: 265729)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_revertsOnInsufficientGas() (gas: 158288)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_revertsOnInvalidOutputRootProof() (gas: 81241)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_revertsOnRecentWithdrawal() (gas: 5
30
01)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_revertsOnReentrancy() (gas: 20
53
54)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_revertsOnRecentWithdrawal() (gas: 5
05
01)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_revertsOnReentrancy() (gas: 20
28
54)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_revertsOnReplay() (gas: 278729)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_revertsOnSelfCall() (gas: 50539)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_revertsOninvalidWithdrawalProof() (gas: 148562)
...
...
@@ -164,20 +174,20 @@ OptimismPortal_Test:test_depositTransaction_withEthValueAndContractContractCreat
OptimismPortal_Test:test_depositTransaction_withEthValueAndEOAContractCreation() (gas: 75881)
OptimismPortal_Test:test_depositTransaction_withEthValueFromContract() (gas: 83333)
OptimismPortal_Test:test_depositTransaction_withEthValueFromEOA() (gas: 83993)
OptimismPortal_Test:test_isBlockFinalized() (gas: 1137
25
)
OptimismPortal_Test:test_simple_isBlockFinalized() (gas: 2
66
30)
OptimismPortal_Test:test_isBlockFinalized() (gas: 1137
44
)
OptimismPortal_Test:test_simple_isBlockFinalized() (gas: 2
41
30)
Proxy_Test:test_clashingFunctionSignatures() (gas: 101427)
Proxy_Test:test_implementationKey() (gas: 20942)
Proxy_Test:test_implementationProxyCallIfNotAdmin() (gas: 30021)
Proxy_Test:test_implementationZeroAddress() (gas: 47604)
Proxy_Test:test_itDelegatesToTheImplementation() (gas: 45251)
Proxy_Test:test_ownerKey() (gas: 19091)
Proxy_Test:test_ownerProxyCallIfNotAdmin() (gas: 347
11
)
Proxy_Test:test_ownerProxyCallIfNotAdmin() (gas: 347
29
)
Proxy_Test:test_payableUpgradeToAndCall() (gas: 53865)
Proxy_Test:test_revertUpgradeToAndCall() (gas: 104
654
)
Proxy_Test:test_revertUpgradeToAndCall() (gas: 104
727
)
Proxy_Test:test_upgradeToAndCall() (gas: 125305)
Proxy_Test:test_zeroAddressCaller() (gas: 14825)
ProxyAdmin_Test:test_chugsplashChangeProxyAdmin() (gas: 356
23
)
ProxyAdmin_Test:test_chugsplashChangeProxyAdmin() (gas: 356
42
)
ProxyAdmin_Test:test_chugsplashGetProxyAdmin() (gas: 15683)
ProxyAdmin_Test:test_chugsplashGetProxyImplementation() (gas: 51149)
ProxyAdmin_Test:test_chugsplashUpgrade() (gas: 48960)
...
...
@@ -187,7 +197,7 @@ ProxyAdmin_Test:test_delegateResolvedGetProxyAdmin() (gas: 17699)
ProxyAdmin_Test:test_delegateResolvedGetProxyImplementation() (gas: 62115)
ProxyAdmin_Test:test_delegateResolvedUpgrade() (gas: 58520)
ProxyAdmin_Test:test_delegateResolvedUpgradeAndCall() (gas: 97989)
ProxyAdmin_Test:test_erc1967ChangeProxyAdmin() (gas: 338
51
)
ProxyAdmin_Test:test_erc1967ChangeProxyAdmin() (gas: 338
70
)
ProxyAdmin_Test:test_erc1967GetProxyAdmin() (gas: 15669)
ProxyAdmin_Test:test_erc1967GetProxyImplementation() (gas: 52093)
ProxyAdmin_Test:test_erc1967Upgrade() (gas: 50030)
...
...
@@ -282,6 +292,7 @@ ResourceMetering_Test:test_updateTenEmptyBlocks() (gas: 20571)
ResourceMetering_Test:test_updateTwoEmptyBlocks() (gas: 20594)
ResourceMetering_Test:test_useMaxSucceeds() (gas: 8017134)
ResourceMetering_Test:test_useMoreThanMaxReverts() (gas: 16058)
SafeCall_Test:test_safeCall(address,address,uint256,uint64,bytes) (runs: 256, μ: 43632, ~: 45833)
Semver_Test:test_behindProxy() (gas: 506906)
Semver_Test:test_version() (gas: 9487)
SequencerFeeVault_Test:test_constructor() (gas: 7678)
...
...
packages/contracts-bedrock/contracts/L2/GasPriceOracle.sol
View file @
b8d9fa17
...
...
@@ -21,13 +21,13 @@ contract GasPriceOracle is Ownable, Semver {
* @custom:legacy
* @notice Spacer for backwards compatibility.
*/
uint256
internal
spacer0;
uint256
private
spacer0;
/**
* @custom:legacy
* @notice Spacer for backwards compatibility.
*/
uint256
internal
spacer1;
uint256
private
spacer1;
/**
* @notice Constant L1 gas overhead per transaction.
...
...
packages/contracts-bedrock/contracts/universal/CrossDomainMessenger.sol
View file @
b8d9fa17
...
...
@@ -27,7 +27,7 @@ contract CrossDomainMessengerLegacySpacer {
* @custom:spacer libAddressManager
* @notice Spacer for backwards compatibility.
*/
address
internal
spacer0;
address
private
spacer0;
}
/**
...
...
@@ -91,14 +91,14 @@ abstract contract CrossDomainMessenger is
* @custom:spacer blockedMessages
* @notice Spacer for backwards compatibility.
*/
uint256
internal
spacer1;
uint256
private
spacer1;
/**
* @custom:legacy
* @custom:spacer relayedMessages
* @notice Spacer for backwards compatibility.
*/
uint256
internal
spacer2;
uint256
private
spacer2;
/**
* @notice Mapping of message hashes to boolean receipt values. Note that a message will only
...
...
packages/contracts-bedrock/contracts/universal/StandardBridge.sol
View file @
b8d9fa17
...
...
@@ -36,13 +36,13 @@ abstract contract StandardBridge {
* @custom:legacy
* @notice Spacer for backwards compatibility.
*/
uint256
internal
spacer0;
uint256
private
spacer0;
/**
* @custom:legacy
* @notice Spacer for backwards compatibility.
*/
uint256
internal
spacer1;
uint256
private
spacer1;
/**
* @notice Mapping that stores deposits for a given pair of local and remote tokens.
...
...
proxyd/config.go
View file @
b8d9fa17
...
...
@@ -4,6 +4,7 @@ import (
"fmt"
"os"
"strings"
"time"
)
type
ServerConfig
struct
{
...
...
@@ -40,10 +41,28 @@ type MetricsConfig struct {
}
type
RateLimitConfig
struct
{
RatePerSecond
int
`toml:"rate_per_second"`
ExemptOrigins
[]
string
`toml:"exempt_origins"`
ExemptUserAgents
[]
string
`toml:"exempt_user_agents"`
ErrorMessage
string
`toml:"error_message"`
RatePerSecond
int
`toml:"rate_per_second"`
ExemptOrigins
[]
string
`toml:"exempt_origins"`
ExemptUserAgents
[]
string
`toml:"exempt_user_agents"`
ErrorMessage
string
`toml:"error_message"`
MethodOverrides
map
[
string
]
*
RateLimitMethodOverride
`toml:"method_overrides"`
}
type
RateLimitMethodOverride
struct
{
Limit
int
`toml:"limit"`
Interval
TOMLDuration
`toml:"interval"`
}
type
TOMLDuration
time
.
Duration
func
(
t
*
TOMLDuration
)
UnmarshalText
(
b
[]
byte
)
error
{
d
,
err
:=
time
.
ParseDuration
(
string
(
b
))
if
err
!=
nil
{
return
err
}
*
t
=
TOMLDuration
(
d
)
return
nil
}
type
BackendOptions
struct
{
...
...
proxyd/integration_tests/rate_limit_test.go
View file @
b8d9fa17
package
integration_tests
import
(
"encoding/json"
"net/http"
"os"
"testing"
...
...
@@ -17,6 +18,8 @@ type resWithCode struct {
const
frontendOverLimitResponse
=
`{"error":{"code":-32016,"message":"over rate limit"},"id":null,"jsonrpc":"2.0"}`
var
ethChainID
=
"eth_chainId"
func
TestBackendMaxRPSLimit
(
t
*
testing
.
T
)
{
goodBackend
:=
NewMockBackend
(
BatchedResponseHandler
(
200
,
goodResponse
))
defer
goodBackend
.
Close
()
...
...
@@ -28,8 +31,7 @@ func TestBackendMaxRPSLimit(t *testing.T) {
shutdown
,
err
:=
proxyd
.
Start
(
config
)
require
.
NoError
(
t
,
err
)
defer
shutdown
()
limitedRes
,
codes
:=
spamReqs
(
t
,
client
,
503
)
limitedRes
,
codes
:=
spamReqs
(
t
,
client
,
ethChainID
,
503
)
require
.
Equal
(
t
,
2
,
codes
[
200
])
require
.
Equal
(
t
,
1
,
codes
[
503
])
RequireEqualJSON
(
t
,
[]
byte
(
noBackendsResponse
),
limitedRes
)
...
...
@@ -48,7 +50,7 @@ func TestFrontendMaxRPSLimit(t *testing.T) {
t
.
Run
(
"non-exempt over limit"
,
func
(
t
*
testing
.
T
)
{
client
:=
NewProxydClient
(
"http://127.0.0.1:8545"
)
limitedRes
,
codes
:=
spamReqs
(
t
,
client
,
429
)
limitedRes
,
codes
:=
spamReqs
(
t
,
client
,
ethChainID
,
429
)
require
.
Equal
(
t
,
1
,
codes
[
429
])
require
.
Equal
(
t
,
2
,
codes
[
200
])
RequireEqualJSON
(
t
,
[]
byte
(
frontendOverLimitResponse
),
limitedRes
)
...
...
@@ -58,7 +60,7 @@ func TestFrontendMaxRPSLimit(t *testing.T) {
h
:=
make
(
http
.
Header
)
h
.
Set
(
"User-Agent"
,
"exempt_agent"
)
client
:=
NewProxydClientWithHeaders
(
"http://127.0.0.1:8545"
,
h
)
_
,
codes
:=
spamReqs
(
t
,
client
,
429
)
_
,
codes
:=
spamReqs
(
t
,
client
,
ethChainID
,
429
)
require
.
Equal
(
t
,
3
,
codes
[
200
])
})
...
...
@@ -66,7 +68,7 @@ func TestFrontendMaxRPSLimit(t *testing.T) {
h
:=
make
(
http
.
Header
)
h
.
Set
(
"Origin"
,
"exempt_origin"
)
client
:=
NewProxydClientWithHeaders
(
"http://127.0.0.1:8545"
,
h
)
_
,
codes
:=
spamReqs
(
t
,
client
,
429
)
_
,
codes
:=
spamReqs
(
t
,
client
,
ethChainID
,
429
)
require
.
Equal
(
t
,
3
,
codes
[
200
])
})
...
...
@@ -77,24 +79,72 @@ func TestFrontendMaxRPSLimit(t *testing.T) {
h2
.
Set
(
"X-Forwarded-For"
,
"1.1.1.1"
)
client1
:=
NewProxydClientWithHeaders
(
"http://127.0.0.1:8545"
,
h1
)
client2
:=
NewProxydClientWithHeaders
(
"http://127.0.0.1:8545"
,
h2
)
_
,
codes
:=
spamReqs
(
t
,
client1
,
429
)
_
,
codes
:=
spamReqs
(
t
,
client1
,
ethChainID
,
429
)
require
.
Equal
(
t
,
1
,
codes
[
429
])
require
.
Equal
(
t
,
2
,
codes
[
200
])
_
,
code
,
err
:=
client2
.
SendRPC
(
"eth_chainId"
,
nil
)
_
,
code
,
err
:=
client2
.
SendRPC
(
ethChainID
,
nil
)
require
.
Equal
(
t
,
200
,
code
)
require
.
NoError
(
t
,
err
)
time
.
Sleep
(
time
.
Second
)
_
,
code
,
err
=
client2
.
SendRPC
(
"eth_chainId"
,
nil
)
_
,
code
,
err
=
client2
.
SendRPC
(
ethChainID
,
nil
)
require
.
Equal
(
t
,
200
,
code
)
require
.
NoError
(
t
,
err
)
})
time
.
Sleep
(
time
.
Second
)
t
.
Run
(
"RPC override"
,
func
(
t
*
testing
.
T
)
{
client
:=
NewProxydClient
(
"http://127.0.0.1:8545"
)
limitedRes
,
codes
:=
spamReqs
(
t
,
client
,
"eth_foobar"
,
429
)
// use 2 and 1 here since the limit for eth_foobar is 1
require
.
Equal
(
t
,
2
,
codes
[
429
])
require
.
Equal
(
t
,
1
,
codes
[
200
])
RequireEqualJSON
(
t
,
[]
byte
(
frontendOverLimitResponse
),
limitedRes
)
})
time
.
Sleep
(
time
.
Second
)
t
.
Run
(
"RPC override in batch"
,
func
(
t
*
testing
.
T
)
{
client
:=
NewProxydClient
(
"http://127.0.0.1:8545"
)
req
:=
NewRPCReq
(
"123"
,
"eth_foobar"
,
nil
)
out
,
code
,
err
:=
client
.
SendBatchRPC
(
req
,
req
,
req
)
require
.
NoError
(
t
,
err
)
var
res
[]
proxyd
.
RPCRes
require
.
NoError
(
t
,
json
.
Unmarshal
(
out
,
&
res
))
expCode
:=
proxyd
.
ErrOverRateLimit
.
Code
require
.
Equal
(
t
,
200
,
code
)
require
.
Equal
(
t
,
3
,
len
(
res
))
require
.
Nil
(
t
,
res
[
0
]
.
Error
)
require
.
Equal
(
t
,
expCode
,
res
[
1
]
.
Error
.
Code
)
require
.
Equal
(
t
,
expCode
,
res
[
2
]
.
Error
.
Code
)
})
time
.
Sleep
(
time
.
Second
)
t
.
Run
(
"RPC override in batch exempt"
,
func
(
t
*
testing
.
T
)
{
h
:=
make
(
http
.
Header
)
h
.
Set
(
"User-Agent"
,
"exempt_agent"
)
client
:=
NewProxydClientWithHeaders
(
"http://127.0.0.1:8545"
,
h
)
req
:=
NewRPCReq
(
"123"
,
"eth_foobar"
,
nil
)
out
,
code
,
err
:=
client
.
SendBatchRPC
(
req
,
req
,
req
)
require
.
NoError
(
t
,
err
)
var
res
[]
proxyd
.
RPCRes
require
.
NoError
(
t
,
json
.
Unmarshal
(
out
,
&
res
))
require
.
Equal
(
t
,
200
,
code
)
require
.
Equal
(
t
,
3
,
len
(
res
))
require
.
Nil
(
t
,
res
[
0
]
.
Error
)
require
.
Nil
(
t
,
res
[
1
]
.
Error
)
require
.
Nil
(
t
,
res
[
2
]
.
Error
)
})
}
func
spamReqs
(
t
*
testing
.
T
,
client
*
ProxydHTTPClient
,
limCode
int
)
([]
byte
,
map
[
int
]
int
)
{
func
spamReqs
(
t
*
testing
.
T
,
client
*
ProxydHTTPClient
,
method
string
,
limCode
int
)
([]
byte
,
map
[
int
]
int
)
{
resCh
:=
make
(
chan
*
resWithCode
)
for
i
:=
0
;
i
<
3
;
i
++
{
go
func
()
{
res
,
code
,
err
:=
client
.
SendRPC
(
"eth_chainId"
,
nil
)
res
,
code
,
err
:=
client
.
SendRPC
(
method
,
nil
)
require
.
NoError
(
t
,
err
)
resCh
<-
&
resWithCode
{
code
:
code
,
...
...
proxyd/integration_tests/testdata/frontend_rate_limit.toml
View file @
b8d9fa17
...
...
@@ -15,9 +15,14 @@ backends = ["good"]
[rpc_method_mappings]
eth_chainId
=
"main"
eth_foobar
=
"main"
[rate_limit]
rate_per_second
=
2
exempt_origins
=
["exempt_origin"]
exempt_user_agents
=
["exempt_agent"]
error_message
=
"over rate limit"
[rate_limit.method_overrides.eth_foobar]
limit
=
1
interval
=
"1s"
\ No newline at end of file
proxyd/server.go
View file @
b8d9fa17
...
...
@@ -49,7 +49,8 @@ type Server struct {
timeout
time
.
Duration
maxUpstreamBatchSize
int
upgrader
*
websocket
.
Upgrader
lim
limiter
.
Store
mainLim
limiter
.
Store
overrideLims
map
[
string
]
limiter
.
Store
limConfig
RateLimitConfig
limExemptOrigins
map
[
string
]
bool
limExemptUserAgents
map
[
string
]
bool
...
...
@@ -59,6 +60,8 @@ type Server struct {
srvMu
sync
.
Mutex
}
type
limiterFunc
func
(
method
string
)
bool
func
NewServer
(
backendGroups
map
[
string
]
*
BackendGroup
,
wsBackendGroup
*
BackendGroup
,
...
...
@@ -89,12 +92,12 @@ func NewServer(
maxUpstreamBatchSize
=
defaultMaxUpstreamBatchSize
}
var
l
im
limiter
.
Store
var
mainL
im
limiter
.
Store
limExemptOrigins
:=
make
(
map
[
string
]
bool
)
limExemptUserAgents
:=
make
(
map
[
string
]
bool
)
if
rateLimitConfig
.
RatePerSecond
>
0
{
var
err
error
l
im
,
err
=
memorystore
.
New
(
&
memorystore
.
Config
{
mainL
im
,
err
=
memorystore
.
New
(
&
memorystore
.
Config
{
Tokens
:
uint64
(
rateLimitConfig
.
RatePerSecond
),
Interval
:
time
.
Second
,
})
...
...
@@ -109,7 +112,19 @@ func NewServer(
limExemptUserAgents
[
strings
.
ToLower
(
agent
)]
=
true
}
}
else
{
lim
,
_
=
noopstore
.
New
()
mainLim
,
_
=
noopstore
.
New
()
}
overrideLims
:=
make
(
map
[
string
]
limiter
.
Store
)
for
method
,
override
:=
range
rateLimitConfig
.
MethodOverrides
{
var
err
error
overrideLims
[
method
],
err
=
memorystore
.
New
(
&
memorystore
.
Config
{
Tokens
:
uint64
(
override
.
Limit
),
Interval
:
time
.
Duration
(
override
.
Interval
),
})
if
err
!=
nil
{
return
nil
,
err
}
}
return
&
Server
{
...
...
@@ -127,7 +142,8 @@ func NewServer(
upgrader
:
&
websocket
.
Upgrader
{
HandshakeTimeout
:
5
*
time
.
Second
,
},
lim
:
lim
,
mainLim
:
mainLim
,
overrideLims
:
overrideLims
,
limConfig
:
rateLimitConfig
,
limExemptOrigins
:
limExemptOrigins
,
limExemptUserAgents
:
limExemptUserAgents
,
...
...
@@ -197,22 +213,37 @@ func (s *Server) HandleRPC(w http.ResponseWriter, r *http.Request) {
origin
:=
r
.
Header
.
Get
(
"Origin"
)
userAgent
:=
r
.
Header
.
Get
(
"User-Agent"
)
exemptOrigin
:=
s
.
limExemptOrigins
[
strings
.
ToLower
(
origin
)]
exemptUserAgent
:=
s
.
limExemptUserAgents
[
strings
.
ToLower
(
userAgent
)]
// Use XFF in context since it will automatically be replaced by the remote IP
xff
:=
stripXFF
(
GetXForwardedFor
(
ctx
))
var
ok
bool
if
exemptOrigin
||
exemptUserAgent
{
ok
=
true
}
else
{
if
xff
==
""
{
log
.
Warn
(
"rejecting request without XFF or remote IP"
)
ok
=
false
isUnlimitedOrigin
:=
s
.
isUnlimitedOrigin
(
origin
)
isUnlimitedUserAgent
:=
s
.
isUnlimitedUserAgent
(
userAgent
)
if
xff
==
""
{
writeRPCError
(
ctx
,
w
,
nil
,
ErrInvalidRequest
(
"request does not include a remote IP"
))
return
}
isLimited
:=
func
(
method
string
)
bool
{
if
isUnlimitedOrigin
||
isUnlimitedUserAgent
{
return
false
}
var
lim
limiter
.
Store
if
method
==
""
{
lim
=
s
.
mainLim
}
else
{
_
,
_
,
_
,
ok
,
_
=
s
.
lim
.
Take
(
ctx
,
xff
)
lim
=
s
.
overrideLims
[
method
]
}
if
lim
==
nil
{
return
false
}
_
,
_
,
_
,
ok
,
_
:=
lim
.
Take
(
ctx
,
xff
)
return
!
ok
}
if
!
ok
{
if
isLimited
(
""
)
{
rpcErr
:=
ErrOverRateLimit
.
Clone
()
rpcErr
.
Message
=
s
.
limConfig
.
ErrorMessage
RecordRPCError
(
ctx
,
BackendProxyd
,
"unknown"
,
rpcErr
)
...
...
@@ -271,7 +302,7 @@ func (s *Server) HandleRPC(w http.ResponseWriter, r *http.Request) {
return
}
batchRes
,
batchContainsCached
,
err
:=
s
.
handleBatchRPC
(
ctx
,
reqs
,
true
)
batchRes
,
batchContainsCached
,
err
:=
s
.
handleBatchRPC
(
ctx
,
reqs
,
isLimited
,
true
)
if
err
==
context
.
DeadlineExceeded
{
writeRPCError
(
ctx
,
w
,
nil
,
ErrGatewayTimeout
)
return
...
...
@@ -287,7 +318,7 @@ func (s *Server) HandleRPC(w http.ResponseWriter, r *http.Request) {
}
rawBody
:=
json
.
RawMessage
(
body
)
backendRes
,
cached
,
err
:=
s
.
handleBatchRPC
(
ctx
,
[]
json
.
RawMessage
{
rawBody
},
false
)
backendRes
,
cached
,
err
:=
s
.
handleBatchRPC
(
ctx
,
[]
json
.
RawMessage
{
rawBody
},
isLimited
,
false
)
if
err
!=
nil
{
writeRPCError
(
ctx
,
w
,
nil
,
ErrInternal
)
return
...
...
@@ -296,7 +327,7 @@ func (s *Server) HandleRPC(w http.ResponseWriter, r *http.Request) {
writeRPCRes
(
ctx
,
w
,
backendRes
[
0
])
}
func
(
s
*
Server
)
handleBatchRPC
(
ctx
context
.
Context
,
reqs
[]
json
.
RawMessage
,
isBatch
bool
)
([]
*
RPCRes
,
bool
,
error
)
{
func
(
s
*
Server
)
handleBatchRPC
(
ctx
context
.
Context
,
reqs
[]
json
.
RawMessage
,
is
Limited
limiterFunc
,
is
Batch
bool
)
([]
*
RPCRes
,
bool
,
error
)
{
// A request set is transformed into groups of batches.
// Each batch group maps to a forwarded JSON-RPC batch request (subject to maxUpstreamBatchSize constraints)
// A groupID is used to decouple Requests that have duplicate ID so they're not part of the same batch that's
...
...
@@ -347,6 +378,22 @@ func (s *Server) handleBatchRPC(ctx context.Context, reqs []json.RawMessage, isB
continue
}
// Take rate limit for specific methods.
// NOTE: eventually, this should apply to all batch requests. However,
// since we don't have data right now on the size of each batch, we
// only apply this to the methods that have an additional rate limit.
if
_
,
ok
:=
s
.
overrideLims
[
parsedReq
.
Method
];
ok
&&
isLimited
(
parsedReq
.
Method
)
{
log
.
Info
(
"rate limited specific RPC"
,
"source"
,
"rpc"
,
"req_id"
,
GetReqID
(
ctx
),
"method"
,
parsedReq
.
Method
,
)
RecordRPCError
(
ctx
,
BackendProxyd
,
parsedReq
.
Method
,
ErrOverRateLimit
)
responses
[
i
]
=
NewRPCErrorRes
(
parsedReq
.
ID
,
ErrOverRateLimit
)
continue
}
id
:=
string
(
parsedReq
.
ID
)
// If this is a duplicate Request ID, move the Request to a new batchGroup
ids
[
id
]
++
...
...
@@ -494,6 +541,14 @@ func (s *Server) populateContext(w http.ResponseWriter, r *http.Request) context
)
}
func
(
s
*
Server
)
isUnlimitedOrigin
(
origin
string
)
bool
{
return
s
.
limExemptOrigins
[
strings
.
ToLower
(
origin
)]
}
func
(
s
*
Server
)
isUnlimitedUserAgent
(
origin
string
)
bool
{
return
s
.
limExemptUserAgents
[
strings
.
ToLower
(
origin
)]
}
func
setCacheHeader
(
w
http
.
ResponseWriter
,
cached
bool
)
{
if
cached
{
w
.
Header
()
.
Set
(
cacheStatusHdr
,
"HIT"
)
...
...
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