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
e9fa6f37
Unverified
Commit
e9fa6f37
authored
Mar 27, 2023
by
mergify[bot]
Committed by
GitHub
Mar 27, 2023
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'develop' into sc/ci-release-error-1
parents
d77aefb9
2a201dce
Changes
11
Show whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
303 additions
and
16 deletions
+303
-16
flags.go
op-node/flags/flags.go
+8
-0
ConnectionGater.go
op-node/p2p/mocks/ConnectionGater.go
+14
-0
PeerGater.go
op-node/p2p/mocks/PeerGater.go
+14
-0
peer_gater.go
op-node/p2p/peer_gater.go
+21
-3
peer_gater_test.go
op-node/p2p/peer_gater_test.go
+33
-4
system_config_test.go
op-node/rollup/derive/system_config_test.go
+170
-0
config.go
op-node/rollup/driver/config.go
+4
-0
state.go
op-node/rollup/driver/state.go
+16
-2
service.go
op-node/service.go
+5
-4
021-SystemDictatorSteps-2.ts
...ges/contracts-bedrock/deploy/021-SystemDictatorSteps-2.ts
+16
-1
devnet.md
specs/meta/devnet.md
+2
-2
No files found.
op-node/flags/flags.go
View file @
e9fa6f37
...
...
@@ -118,6 +118,13 @@ var (
Usage
:
"Initialize the sequencer in a stopped state. The sequencer can be started using the admin_startSequencer RPC"
,
EnvVar
:
prefixEnvVar
(
"SEQUENCER_STOPPED"
),
}
SequencerMaxSafeLagFlag
=
cli
.
Uint64Flag
{
Name
:
"sequencer.max-safe-lag"
,
Usage
:
"Maximum number of L2 blocks for restricting the distance between L2 safe and unsafe. Disabled if 0."
,
EnvVar
:
prefixEnvVar
(
"SEQUENCER_MAX_SAFE_LAG"
),
Required
:
false
,
Value
:
0
,
}
SequencerL1Confs
=
cli
.
Uint64Flag
{
Name
:
"sequencer.l1-confs"
,
Usage
:
"Number of L1 blocks to keep distance from the L1 head as a sequencer for picking an L1 origin."
,
...
...
@@ -221,6 +228,7 @@ var optionalFlags = []cli.Flag{
VerifierL1Confs
,
SequencerEnabledFlag
,
SequencerStoppedFlag
,
SequencerMaxSafeLagFlag
,
SequencerL1Confs
,
L1EpochPollIntervalFlag
,
RPCEnableAdmin
,
...
...
op-node/p2p/mocks/ConnectionGater.go
View file @
e9fa6f37
...
...
@@ -142,6 +142,20 @@ func (_m *ConnectionGater) InterceptUpgraded(_a0 network.Conn) (bool, control.Di
return
r0
,
r1
}
// IsBlocked provides a mock function with given fields: p
func
(
_m
*
ConnectionGater
)
IsBlocked
(
p
peer
.
ID
)
bool
{
ret
:=
_m
.
Called
(
p
)
var
r0
bool
if
rf
,
ok
:=
ret
.
Get
(
0
)
.
(
func
(
peer
.
ID
)
bool
);
ok
{
r0
=
rf
(
p
)
}
else
{
r0
=
ret
.
Get
(
0
)
.
(
bool
)
}
return
r0
}
// ListBlockedAddrs provides a mock function with given fields:
func
(
_m
*
ConnectionGater
)
ListBlockedAddrs
()
[]
net
.
IP
{
ret
:=
_m
.
Called
()
...
...
op-node/p2p/mocks/PeerGater.go
View file @
e9fa6f37
...
...
@@ -13,6 +13,20 @@ type PeerGater struct {
mock
.
Mock
}
// IsBlocked provides a mock function with given fields: _a0
func
(
_m
*
PeerGater
)
IsBlocked
(
_a0
peer
.
ID
)
bool
{
ret
:=
_m
.
Called
(
_a0
)
var
r0
bool
if
rf
,
ok
:=
ret
.
Get
(
0
)
.
(
func
(
peer
.
ID
)
bool
);
ok
{
r0
=
rf
(
_a0
)
}
else
{
r0
=
ret
.
Get
(
0
)
.
(
bool
)
}
return
r0
}
// Update provides a mock function with given fields: _a0, _a1
func
(
_m
*
PeerGater
)
Update
(
_a0
peer
.
ID
,
_a1
float64
)
{
_m
.
Called
(
_a0
,
_a1
)
...
...
op-node/p2p/peer_gater.go
View file @
e9fa6f37
...
...
@@ -3,7 +3,6 @@ package p2p
import
(
log
"github.com/ethereum/go-ethereum/log"
peer
"github.com/libp2p/go-libp2p/core/peer"
slices
"golang.org/x/exp/slices"
)
// ConnectionFactor is the factor by which we multiply the connection score.
...
...
@@ -15,6 +14,7 @@ const PeerScoreThreshold = -100
// gater is an internal implementation of the [PeerGater] interface.
type
gater
struct
{
connGater
ConnectionGater
blockedMap
map
[
peer
.
ID
]
bool
log
log
.
Logger
banEnabled
bool
}
...
...
@@ -25,33 +25,51 @@ type gater struct {
type
PeerGater
interface
{
// Update handles a peer score update and blocks/unblocks the peer if necessary.
Update
(
peer
.
ID
,
float64
)
// IsBlocked returns true if the given [peer.ID] is blocked.
IsBlocked
(
peer
.
ID
)
bool
}
// NewPeerGater returns a new peer gater.
func
NewPeerGater
(
connGater
ConnectionGater
,
log
log
.
Logger
,
banEnabled
bool
)
PeerGater
{
return
&
gater
{
connGater
:
connGater
,
blockedMap
:
make
(
map
[
peer
.
ID
]
bool
),
log
:
log
,
banEnabled
:
banEnabled
,
}
}
// IsBlocked returns true if the given [peer.ID] is blocked.
func
(
s
*
gater
)
IsBlocked
(
peerID
peer
.
ID
)
bool
{
return
s
.
blockedMap
[
peerID
]
}
// setBlocked sets the blocked status of the given [peer.ID].
func
(
s
*
gater
)
setBlocked
(
peerID
peer
.
ID
,
blocked
bool
)
{
s
.
blockedMap
[
peerID
]
=
blocked
}
// Update handles a peer score update and blocks/unblocks the peer if necessary.
func
(
s
*
gater
)
Update
(
id
peer
.
ID
,
score
float64
)
{
// Check if the peer score is below the threshold
// If so, we need to block the peer
if
score
<
PeerScoreThreshold
&&
s
.
banEnabled
{
isAlreadyBlocked
:=
s
.
IsBlocked
(
id
)
if
score
<
PeerScoreThreshold
&&
s
.
banEnabled
&&
!
isAlreadyBlocked
{
s
.
log
.
Warn
(
"peer blocking enabled, blocking peer"
,
"id"
,
id
.
String
(),
"score"
,
score
)
err
:=
s
.
connGater
.
BlockPeer
(
id
)
if
err
!=
nil
{
s
.
log
.
Warn
(
"connection gater failed to block peer"
,
"id"
,
id
.
String
(),
"err"
,
err
)
}
// Set the peer as blocked in the blocked map
s
.
setBlocked
(
id
,
true
)
}
// Unblock peers whose score has recovered to an acceptable level
if
(
score
>
PeerScoreThreshold
)
&&
slices
.
Contains
(
s
.
connGater
.
ListBlockedPeers
(),
id
)
{
if
(
score
>
PeerScoreThreshold
)
&&
isAlreadyBlocked
{
err
:=
s
.
connGater
.
UnblockPeer
(
id
)
if
err
!=
nil
{
s
.
log
.
Warn
(
"connection gater failed to unblock peer"
,
"id"
,
id
.
String
(),
"err"
,
err
)
}
// Set the peer as unblocked in the blocked map
s
.
setBlocked
(
id
,
false
)
}
}
op-node/p2p/peer_gater_test.go
View file @
e9fa6f37
...
...
@@ -37,30 +37,59 @@ func (testSuite *PeerGaterTestSuite) TestPeerScoreConstants() {
}
// TestPeerGaterUpdate tests the peer gater update hook.
func
(
testSuite
*
PeerGaterTestSuite
)
TestPeerGater
Update
()
{
func
(
testSuite
*
PeerGaterTestSuite
)
TestPeerGater
_UpdateBansPeers
()
{
gater
:=
p2p
.
NewPeerGater
(
testSuite
.
mockGater
,
testSuite
.
logger
,
true
,
)
// Return an empty list of already blocked peers
testSuite
.
mockGater
.
On
(
"ListBlockedPeers"
)
.
Return
([]
peer
.
ID
{})
.
Once
()
// Mock a connection gater peer block call
// Since the peer score is below the [PeerScoreThreshold] of -100,
// the [BlockPeer] method should be called
testSuite
.
mockGater
.
On
(
"BlockPeer"
,
peer
.
ID
(
"peer1"
))
.
Return
(
nil
)
testSuite
.
mockGater
.
On
(
"BlockPeer"
,
peer
.
ID
(
"peer1"
))
.
Return
(
nil
)
.
Once
()
// The peer should initially be unblocked
testSuite
.
False
(
gater
.
IsBlocked
(
peer
.
ID
(
"peer1"
)))
// Apply the peer gater update
gater
.
Update
(
peer
.
ID
(
"peer1"
),
float64
(
-
100
))
gater
.
Update
(
peer
.
ID
(
"peer1"
),
float64
(
-
101
))
// The peer should be considered blocked
testSuite
.
True
(
gater
.
IsBlocked
(
peer
.
ID
(
"peer1"
)))
// Now let's unblock the peer
testSuite
.
mockGater
.
On
(
"UnblockPeer"
,
peer
.
ID
(
"peer1"
))
.
Return
(
nil
)
.
Once
()
gater
.
Update
(
peer
.
ID
(
"peer1"
),
float64
(
0
))
// The peer should be considered unblocked
testSuite
.
False
(
gater
.
IsBlocked
(
peer
.
ID
(
"peer1"
)))
}
// TestPeerGaterUpdateNoBanning tests the peer gater update hook without banning set
func
(
testSuite
*
PeerGaterTestSuite
)
TestPeerGaterUpdateNoBanning
()
{
func
(
testSuite
*
PeerGaterTestSuite
)
TestPeerGater
_
UpdateNoBanning
()
{
gater
:=
p2p
.
NewPeerGater
(
testSuite
.
mockGater
,
testSuite
.
logger
,
false
,
)
// Return an empty list of already blocked peers
testSuite
.
mockGater
.
On
(
"ListBlockedPeers"
)
.
Return
([]
peer
.
ID
{})
// Notice: [BlockPeer] should not be called since banning is not enabled
// even though the peer score is way below the [PeerScoreThreshold] of -100
gater
.
Update
(
peer
.
ID
(
"peer1"
),
float64
(
-
100000
))
// The peer should be unblocked
testSuite
.
False
(
gater
.
IsBlocked
(
peer
.
ID
(
"peer1"
)))
// Make sure that if we then "unblock" the peer, nothing happens
gater
.
Update
(
peer
.
ID
(
"peer1"
),
float64
(
0
))
// The peer should still be unblocked
testSuite
.
False
(
gater
.
IsBlocked
(
peer
.
ID
(
"peer1"
)))
}
op-node/rollup/derive/system_config_test.go
0 → 100644
View file @
e9fa6f37
package
derive
import
(
"math/big"
"testing"
"github.com/ethereum-optimism/optimism/op-node/eth"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/stretchr/testify/require"
)
var
(
// ABI encoding helpers
dynBytes
,
_
=
abi
.
NewType
(
"bytes"
,
""
,
nil
)
address
,
_
=
abi
.
NewType
(
"address"
,
""
,
nil
)
uint256T
,
_
=
abi
.
NewType
(
"uint256"
,
""
,
nil
)
addressArgs
=
abi
.
Arguments
{
{
Type
:
address
},
}
bytesArgs
=
abi
.
Arguments
{
{
Type
:
dynBytes
},
}
twoUint256
=
abi
.
Arguments
{
{
Type
:
uint256T
},
{
Type
:
uint256T
},
}
oneUint256
=
abi
.
Arguments
{
{
Type
:
uint256T
},
}
)
// TestProcessSystemConfigUpdateLogEvent tests the parsing of an event and mutating the
// SystemConfig. The hook will build the ABI encoded data dynamically. All tests create
// a new SystemConfig and apply a log against it and then assert that the mutated system
// config is equal to the defined system config in the test.
func
TestProcessSystemConfigUpdateLogEvent
(
t
*
testing
.
T
)
{
tests
:=
[]
struct
{
name
string
log
*
types
.
Log
config
eth
.
SystemConfig
hook
func
(
*
testing
.
T
,
*
types
.
Log
)
*
types
.
Log
err
bool
}{
{
// The log data is ignored by consensus and no modifications to the
// system config occur.
name
:
"SystemConfigUpdateUnsafeBlockSigner"
,
log
:
&
types
.
Log
{
Topics
:
[]
common
.
Hash
{
ConfigUpdateEventABIHash
,
ConfigUpdateEventVersion0
,
SystemConfigUpdateUnsafeBlockSigner
,
},
},
hook
:
func
(
t
*
testing
.
T
,
log
*
types
.
Log
)
*
types
.
Log
{
addr
:=
common
.
Address
{}
data
,
err
:=
addressArgs
.
Pack
(
&
addr
)
require
.
NoError
(
t
,
err
)
log
.
Data
=
data
return
log
},
config
:
eth
.
SystemConfig
{},
err
:
false
,
},
{
// The batcher address should be updated.
name
:
"SystemConfigUpdateBatcher"
,
log
:
&
types
.
Log
{
Topics
:
[]
common
.
Hash
{
ConfigUpdateEventABIHash
,
ConfigUpdateEventVersion0
,
SystemConfigUpdateBatcher
,
},
},
hook
:
func
(
t
*
testing
.
T
,
log
*
types
.
Log
)
*
types
.
Log
{
addr
:=
common
.
Address
{
19
:
0xaa
}
addrData
,
err
:=
addressArgs
.
Pack
(
&
addr
)
require
.
NoError
(
t
,
err
)
data
,
err
:=
bytesArgs
.
Pack
(
addrData
)
require
.
NoError
(
t
,
err
)
log
.
Data
=
data
return
log
},
config
:
eth
.
SystemConfig
{
BatcherAddr
:
common
.
Address
{
19
:
0xaa
},
},
err
:
false
,
},
{
// The overhead and the scalar should be updated.
name
:
"SystemConfigUpdateGasConfig"
,
log
:
&
types
.
Log
{
Topics
:
[]
common
.
Hash
{
ConfigUpdateEventABIHash
,
ConfigUpdateEventVersion0
,
SystemConfigUpdateGasConfig
,
},
},
hook
:
func
(
t
*
testing
.
T
,
log
*
types
.
Log
)
*
types
.
Log
{
overhead
:=
big
.
NewInt
(
0xff
)
scalar
:=
big
.
NewInt
(
0xaa
)
numberData
,
err
:=
twoUint256
.
Pack
(
overhead
,
scalar
)
require
.
NoError
(
t
,
err
)
data
,
err
:=
bytesArgs
.
Pack
(
numberData
)
require
.
NoError
(
t
,
err
)
log
.
Data
=
data
return
log
},
config
:
eth
.
SystemConfig
{
Overhead
:
eth
.
Bytes32
{
31
:
0xff
},
Scalar
:
eth
.
Bytes32
{
31
:
0xaa
},
},
err
:
false
,
},
{
// The gas limit should be updated.
name
:
"SystemConfigUpdateGasLimit"
,
log
:
&
types
.
Log
{
Topics
:
[]
common
.
Hash
{
ConfigUpdateEventABIHash
,
ConfigUpdateEventVersion0
,
SystemConfigUpdateGasLimit
,
},
},
hook
:
func
(
t
*
testing
.
T
,
log
*
types
.
Log
)
*
types
.
Log
{
gasLimit
:=
big
.
NewInt
(
0xbb
)
numberData
,
err
:=
oneUint256
.
Pack
(
gasLimit
)
require
.
NoError
(
t
,
err
)
data
,
err
:=
bytesArgs
.
Pack
(
numberData
)
require
.
NoError
(
t
,
err
)
log
.
Data
=
data
return
log
},
config
:
eth
.
SystemConfig
{
GasLimit
:
0xbb
,
},
err
:
false
,
},
{
name
:
"SystemConfigOneTopic"
,
log
:
&
types
.
Log
{
Topics
:
[]
common
.
Hash
{
ConfigUpdateEventABIHash
,
},
},
hook
:
func
(
t
*
testing
.
T
,
log
*
types
.
Log
)
*
types
.
Log
{
return
log
},
config
:
eth
.
SystemConfig
{},
err
:
true
,
},
}
for
_
,
test
:=
range
tests
{
test
:=
test
t
.
Run
(
test
.
name
,
func
(
t
*
testing
.
T
)
{
config
:=
eth
.
SystemConfig
{}
err
:=
ProcessSystemConfigUpdateLogEvent
(
&
config
,
test
.
hook
(
t
,
test
.
log
))
if
test
.
err
{
require
.
Error
(
t
,
err
)
}
else
{
require
.
NoError
(
t
,
err
)
}
require
.
Equal
(
t
,
config
,
test
.
config
)
})
}
}
op-node/rollup/driver/config.go
View file @
e9fa6f37
...
...
@@ -16,4 +16,8 @@ type Config struct {
// SequencerStopped is false when the driver should sequence new blocks.
SequencerStopped
bool
`json:"sequencer_stopped"`
// SequencerMaxSafeLag is the maximum number of L2 blocks for restricting the distance between L2 safe and unsafe.
// Disabled if 0.
SequencerMaxSafeLag
uint64
`json:"sequencer_max_safe_lag"`
}
op-node/rollup/driver/state.go
View file @
e9fa6f37
...
...
@@ -212,8 +212,22 @@ func (s *Driver) eventLoop() {
// And avoid sequencing if the derivation pipeline indicates the engine is not ready.
if
s
.
driverConfig
.
SequencerEnabled
&&
!
s
.
driverConfig
.
SequencerStopped
&&
s
.
l1State
.
L1Head
()
!=
(
eth
.
L1BlockRef
{})
&&
s
.
derivation
.
EngineReady
()
{
if
s
.
driverConfig
.
SequencerMaxSafeLag
>
0
&&
s
.
derivation
.
SafeL2Head
()
.
Number
+
s
.
driverConfig
.
SequencerMaxSafeLag
<=
s
.
derivation
.
UnsafeL2Head
()
.
Number
{
// If the safe head has fallen behind by a significant number of blocks, delay creating new blocks
// until the safe lag is below SequencerMaxSafeLag.
if
sequencerCh
!=
nil
{
s
.
log
.
Warn
(
"Delay creating new block since safe lag exceeds limit"
,
"safe_l2"
,
s
.
derivation
.
SafeL2Head
(),
"unsafe_l2"
,
s
.
derivation
.
UnsafeL2Head
(),
)
sequencerCh
=
nil
}
}
else
if
s
.
sequencer
.
BuildingOnto
()
.
ID
()
!=
s
.
derivation
.
UnsafeL2Head
()
.
ID
()
{
// If we are sequencing, and the L1 state is ready, update the trigger for the next sequencer action.
// This may adjust at any time based on fork-choice changes or previous errors.
//
// update sequencer time if the head changed
if
s
.
sequencer
.
BuildingOnto
()
.
ID
()
!=
s
.
derivation
.
UnsafeL2Head
()
.
ID
()
{
planSequencerAction
()
}
}
else
{
...
...
op-node/service.go
View file @
e9fa6f37
...
...
@@ -149,6 +149,7 @@ func NewDriverConfig(ctx *cli.Context) *driver.Config {
SequencerConfDepth
:
ctx
.
GlobalUint64
(
flags
.
SequencerL1Confs
.
Name
),
SequencerEnabled
:
ctx
.
GlobalBool
(
flags
.
SequencerEnabledFlag
.
Name
),
SequencerStopped
:
ctx
.
GlobalBool
(
flags
.
SequencerStoppedFlag
.
Name
),
SequencerMaxSafeLag
:
ctx
.
GlobalUint64
(
flags
.
SequencerMaxSafeLagFlag
.
Name
),
}
}
...
...
packages/contracts-bedrock/deploy/021-SystemDictatorSteps-2.ts
View file @
e9fa6f37
...
...
@@ -182,6 +182,8 @@ const deployFn: DeployFunction = async (hre) => {
false
// do not pause the the OptimismPortal when initializing
)
}
else
{
// pause the OptimismPortal when initializing
const
optimismPortalPaused
=
true
const
tx
=
await
SystemDictator
.
populateTransaction
.
updateDynamicConfig
(
{
l2OutputOracleStartingBlockNumber
:
...
...
@@ -189,9 +191,22 @@ const deployFn: DeployFunction = async (hre) => {
l2OutputOracleStartingTimestamp
:
hre
.
deployConfig
.
l2OutputOracleStartingTimestamp
,
},
true
optimismPortalPaused
)
console
.
log
(
`Please update dynamic oracle config...`
)
console
.
log
(
JSON
.
stringify
(
{
l2OutputOracleStartingBlockNumber
:
hre
.
deployConfig
.
l2OutputOracleStartingBlockNumber
,
l2OutputOracleStartingTimestamp
:
hre
.
deployConfig
.
l2OutputOracleStartingTimestamp
,
optimismPortalPaused
,
},
null
,
2
)
)
console
.
log
(
`MSD address:
${
SystemDictator
.
address
}
`
)
console
.
log
(
`JSON:`
)
console
.
log
(
jsonifyTransaction
(
tx
))
...
...
specs/meta/devnet.md
View file @
e9fa6f37
...
...
@@ -23,7 +23,7 @@ make devnet-down # stops the devnet
make devnet-clean
# removes the devnet by deleting images and persistent volumes
```
L1 is accessible at
`http://localhost:8545`
, and L2 is accessible at
`http://localhost:
8546
`
.
L1 is accessible at
`http://localhost:8545`
, and L2 is accessible at
`http://localhost:
9545
`
.
Any Ethereum tool - Metamask,
`seth`
, etc. - can use these endpoints.
Note that you will need to specify the L2 chain ID manually if you use Metamask. The devnet's L2 chain ID is 901.
...
...
@@ -43,7 +43,7 @@ You'll need a `.env` with the following contents:
```bash
L1_PROVIDER_URL=http://localhost:8545
L2_PROVIDER_URL=http://localhost:
8546
L2_PROVIDER_URL=http://localhost:
9545
PRIVATE_KEY=bf7604d9d3a1c7748642b1b7b05c2bd219c9faa91458b370f85e5a40f3b03af7
```
...
...
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