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
084269f0
Unverified
Commit
084269f0
authored
Sep 08, 2023
by
mergify[bot]
Committed by
GitHub
Sep 08, 2023
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'develop' into aj/invalid-root-docs
parents
a49ff03f
4cc0f7bf
Changes
12
Show whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
236 additions
and
176 deletions
+236
-176
__init__.py
bedrock-devnet/devnet/__init__.py
+17
-9
faultproof_test.go
op-e2e/faultproof_test.go
+0
-67
Dockerfile
op-ufm/Dockerfile
+2
-1
example.config.toml
op-ufm/example.config.toml
+16
-18
config.go
op-ufm/pkg/config/config.go
+5
-10
eth.go
op-ufm/pkg/metrics/clients/eth.go
+39
-5
signer.go
op-ufm/pkg/metrics/clients/signer.go
+2
-2
roundtrip.go
op-ufm/pkg/provider/roundtrip.go
+117
-37
tx_pool.go
op-ufm/pkg/provider/tx_pool.go
+5
-1
.gitignore
packages/contracts-bedrock/.gitignore
+3
-0
devnetL1-template.json
...es/contracts-bedrock/deploy-config/devnetL1-template.json
+0
-0
pnpm-lock.yaml
pnpm-lock.yaml
+30
-26
No files found.
bedrock-devnet/devnet/__init__.py
View file @
084269f0
...
...
@@ -56,8 +56,9 @@ def main():
deployment_dir
=
pjoin
(
contracts_bedrock_dir
,
'deployments'
,
'devnetL1'
)
op_node_dir
=
pjoin
(
args
.
monorepo_dir
,
'op-node'
)
ops_bedrock_dir
=
pjoin
(
monorepo_dir
,
'ops-bedrock'
)
deploy_config_dir
=
pjoin
(
contracts_bedrock_dir
,
'deploy-config'
),
devnet_config_path
=
pjoin
(
contracts_bedrock_dir
,
'deploy-config'
,
'devnetL1.json'
)
deploy_config_dir
=
pjoin
(
contracts_bedrock_dir
,
'deploy-config'
)
devnet_config_path
=
pjoin
(
deploy_config_dir
,
'devnetL1.json'
)
devnet_config_template_path
=
pjoin
(
deploy_config_dir
,
'devnetL1-template.json'
)
ops_chain_ops
=
pjoin
(
monorepo_dir
,
'op-chain-ops'
)
sdk_dir
=
pjoin
(
monorepo_dir
,
'packages'
,
'sdk'
)
...
...
@@ -69,6 +70,7 @@ def main():
l1_deployments_path
=
pjoin
(
deployment_dir
,
'.deploy'
),
deploy_config_dir
=
deploy_config_dir
,
devnet_config_path
=
devnet_config_path
,
devnet_config_template_path
=
devnet_config_template_path
,
op_node_dir
=
op_node_dir
,
ops_bedrock_dir
=
ops_bedrock_dir
,
ops_chain_ops
=
ops_chain_ops
,
...
...
@@ -124,10 +126,16 @@ def deploy_contracts(paths):
'--rpc-url'
,
'http://127.0.0.1:8545'
],
env
=
{},
cwd
=
paths
.
contracts_bedrock_dir
)
def
init_devnet_l1_deploy_config
(
paths
,
update_timestamp
=
False
):
deploy_config
=
read_json
(
paths
.
devnet_config_template_path
)
if
update_timestamp
:
deploy_config
[
'l1GenesisBlockTimestamp'
]
=
'{:#x}'
.
format
(
int
(
time
.
time
()))
write_json
(
paths
.
devnet_config_path
,
deploy_config
)
def
devnet_l1_genesis
(
paths
):
log
.
info
(
'Generating L1 genesis state'
)
init_devnet_l1_deploy_config
(
paths
)
geth
=
subprocess
.
Popen
([
'geth'
,
'--dev'
,
'--http'
,
'--http.api'
,
'eth,debug'
,
'--verbosity'
,
'4'
,
'--gcmode'
,
'archive'
,
'--dev.gaslimit'
,
'30000000'
...
...
@@ -157,13 +165,13 @@ def devnet_deploy(paths):
if
os
.
path
.
exists
(
paths
.
allocs_path
)
==
False
:
devnet_l1_genesis
(
paths
)
devnet_config_backup
=
pjoin
(
paths
.
devnet_dir
,
'devnetL1.json.bak'
)
shutil
.
copy
(
paths
.
devnet_config_path
,
devnet_config_backup
)
deploy_config
=
read_json
(
paths
.
devnet_config_path
)
deploy_config
[
'l1GenesisBlockTimestamp'
]
=
'{:#x}'
.
format
(
int
(
time
.
time
()))
write_json
(
paths
.
devnet_config_path
,
deploy_config
)
# It's odd that we want to regenerate the devnetL1.json file with
# an updated timestamp different than the one used in the devnet_l1_genesis
# function. But, without it, CI flakes on this test rather consistently.
# If someone reads this comment and understands why this is being done, please
# update this comment to explain.
init_devnet_l1_deploy_config
(
paths
,
update_timestamp
=
True
)
outfile_l1
=
pjoin
(
paths
.
devnet_dir
,
'genesis-l1.json'
)
run_command
([
'go'
,
'run'
,
'cmd/main.go'
,
'genesis'
,
'l1'
,
'--deploy-config'
,
paths
.
devnet_config_path
,
...
...
op-e2e/faultproof_test.go
View file @
084269f0
...
...
@@ -13,43 +13,6 @@ import (
"github.com/stretchr/testify/require"
)
func
TestMultipleAlphabetGames
(
t
*
testing
.
T
)
{
InitParallel
(
t
)
ctx
:=
context
.
Background
()
sys
,
l1Client
:=
startFaultDisputeSystem
(
t
)
t
.
Cleanup
(
sys
.
Close
)
gameFactory
:=
disputegame
.
NewFactoryHelper
(
t
,
ctx
,
sys
.
cfg
.
L1Deployments
,
l1Client
)
// Start a challenger with the correct alphabet trace
gameFactory
.
StartChallenger
(
ctx
,
sys
.
NodeEndpoint
(
"l1"
),
"TowerDefense"
,
challenger
.
WithAlphabet
(
"abcdefg"
),
challenger
.
WithPrivKey
(
sys
.
cfg
.
Secrets
.
Alice
),
challenger
.
WithAgreeProposedOutput
(
true
),
)
game1
:=
gameFactory
.
StartAlphabetGame
(
ctx
,
"abcxyz"
)
// Wait for the challenger to respond to the first game
game1
.
WaitForClaimCount
(
ctx
,
2
)
game2
:=
gameFactory
.
StartAlphabetGame
(
ctx
,
"zyxabc"
)
// Wait for the challenger to respond to the second game
game2
.
WaitForClaimCount
(
ctx
,
2
)
// Challenger should respond to new claims
game2
.
Attack
(
ctx
,
1
,
common
.
Hash
{
0xaa
})
game2
.
WaitForClaimCount
(
ctx
,
4
)
game1
.
Defend
(
ctx
,
1
,
common
.
Hash
{
0xaa
})
game1
.
WaitForClaimCount
(
ctx
,
4
)
gameDuration
:=
game1
.
GameDuration
(
ctx
)
sys
.
TimeTravelClock
.
AdvanceTime
(
gameDuration
)
require
.
NoError
(
t
,
wait
.
ForNextBlock
(
ctx
,
l1Client
))
game1
.
WaitForGameStatus
(
ctx
,
disputegame
.
StatusChallengerWins
)
game2
.
WaitForGameStatus
(
ctx
,
disputegame
.
StatusChallengerWins
)
}
func
TestMultipleCannonGames
(
t
*
testing
.
T
)
{
InitParallel
(
t
)
...
...
@@ -106,36 +69,6 @@ func TestMultipleCannonGames(t *testing.T) {
challenger
.
WaitForGameDataDeletion
(
ctx
,
game1
,
game2
)
}
func
TestResolveDisputeGame
(
t
*
testing
.
T
)
{
InitParallel
(
t
)
ctx
:=
context
.
Background
()
sys
,
l1Client
:=
startFaultDisputeSystem
(
t
)
t
.
Cleanup
(
sys
.
Close
)
disputeGameFactory
:=
disputegame
.
NewFactoryHelper
(
t
,
ctx
,
sys
.
cfg
.
L1Deployments
,
l1Client
)
game
:=
disputeGameFactory
.
StartAlphabetGame
(
ctx
,
"zyxwvut"
)
require
.
NotNil
(
t
,
game
)
gameDuration
:=
game
.
GameDuration
(
ctx
)
game
.
WaitForGameStatus
(
ctx
,
disputegame
.
StatusInProgress
)
game
.
StartChallenger
(
ctx
,
sys
.
NodeEndpoint
(
"l1"
),
"HonestAlice"
,
challenger
.
WithAgreeProposedOutput
(
true
),
challenger
.
WithAlphabet
(
"abcdefg"
),
challenger
.
WithPrivKey
(
sys
.
cfg
.
Secrets
.
Alice
),
)
game
.
WaitForClaimCount
(
ctx
,
2
)
sys
.
TimeTravelClock
.
AdvanceTime
(
gameDuration
)
require
.
NoError
(
t
,
wait
.
ForNextBlock
(
ctx
,
l1Client
))
// Challenger should resolve the game now that the clocks have expired.
game
.
WaitForGameStatus
(
ctx
,
disputegame
.
StatusChallengerWins
)
}
func
TestChallengerCompleteDisputeGame
(
t
*
testing
.
T
)
{
InitParallel
(
t
)
...
...
op-ufm/Dockerfile
View file @
084269f0
...
...
@@ -18,9 +18,10 @@ COPY --from=builder /app/entrypoint.sh /bin/entrypoint.sh
COPY
--from=builder /app/bin/ufm /bin/ufm
RUN
apk update
&&
\
apk add ca-certificates
&&
\
chmod
+x /bin/entrypoint.sh
RUN
apk add ca-certificates jq curl bind-tools
VOLUME
/etc/ufm
EXPOSE
8080
...
...
op-ufm/example.config.toml
View file @
084269f0
...
...
@@ -39,12 +39,6 @@ address = "0x0000000000000000000000000000000000000000"
private_key
=
"0000000000000000000000000000000000000000000000000000000000000000"
# Transaction value in wei
tx_value
=
100000000000000
# Gas limit
gas_limit
=
21000
# Gas tip cap
gas_tip_cap
=
2000000000
# Fee cap
gas_fee_cap
=
20000000000
[providers.p1]
# URL to the RPC provider
...
...
@@ -52,13 +46,15 @@ url = "http://localhost:8551"
# Read only providers are only used to check for transactions
read_only
=
true
# Interval to poll the provider for expected transactions
read_interval
=
"1s"
read_interval
=
"1
0
s"
# Interval to submit new transactions to the provider
send_interval
=
"5s"
# Wallet to be used for sending transactions
wallet
=
"default"
# Network to pool transactions, i.e. providers in the same network will check transactions from each other
network
=
"op-goerli"
send_interval
=
"30s"
# Interval between send transaction when we get "already known" txpool err
send_transaction_retry_interval
=
"100ms"
# Max time to retry
send_transaction_retry_timeout
=
"5s"
# Interval between each send transaction to the same network
send_transaction_cool_down
=
"30s"
# Interval between receipt retrieval
receipt_retrieval_interval
=
"500ms"
# Max time to check for receipt
...
...
@@ -72,13 +68,15 @@ url = "http://localhost:8552"
# Read only providers are only used to check for transactions
read_only
=
false
# Interval to poll the provider for expected transactions
read_interval
=
"
2
s"
read_interval
=
"
10
s"
# Interval to submit new transactions to the provider
send_interval
=
"3s"
# Wallet to be used for sending transactions
wallet
=
"default"
# Network to pool transactions, i.e. providers in the same network will check transactions from each other
network
=
"op-goerli"
send_interval
=
"30s"
# Interval between send transaction when we get "already known" txpool err
send_transaction_retry_interval
=
"100ms"
# Max time to retry
send_transaction_retry_timeout
=
"5s"
# Interval between each send transaction to the same network
send_transaction_cool_down
=
"30s"
# Interval between receipt retrieval
receipt_retrieval_interval
=
"500ms"
# Max time to check for receipt
...
...
op-ufm/pkg/config/config.go
View file @
084269f0
...
...
@@ -49,9 +49,6 @@ type WalletConfig struct {
// transaction parameters
TxValue
big
.
Int
`toml:"tx_value"`
GasLimit
uint64
`toml:"gas_limit"`
GasTipCap
big
.
Int
`toml:"gas_tip_cap"`
GasFeeCap
big
.
Int
`toml:"gas_fee_cap"`
}
type
ProviderConfig
struct
{
...
...
@@ -64,6 +61,7 @@ type ProviderConfig struct {
SendInterval
TOMLDuration
`toml:"send_interval"`
SendTransactionRetryInterval
TOMLDuration
`toml:"send_transaction_retry_interval"`
SendTransactionRetryTimeout
TOMLDuration
`toml:"send_transaction_retry_timeout"`
SendTransactionCoolDown
TOMLDuration
`toml:"send_transaction_cool_down"`
ReceiptRetrievalInterval
TOMLDuration
`toml:"receipt_retrieval_interval"`
ReceiptRetrievalTimeout
TOMLDuration
`toml:"receipt_retrieval_timeout"`
...
...
@@ -130,12 +128,6 @@ func (c *Config) Validate() error {
if
wallet
.
TxValue
.
BitLen
()
==
0
{
return
errors
.
Errorf
(
"wallet [%s] tx_value is missing"
,
name
)
}
if
wallet
.
GasLimit
==
0
{
return
errors
.
Errorf
(
"wallet [%s] gas_limit is missing"
,
name
)
}
if
wallet
.
GasFeeCap
.
BitLen
()
==
0
{
return
errors
.
Errorf
(
"wallet [%s] gas_fee_cap is missing"
,
name
)
}
}
for
name
,
provider
:=
range
c
.
Providers
{
...
...
@@ -154,6 +146,9 @@ func (c *Config) Validate() error {
if
provider
.
SendTransactionRetryTimeout
==
0
{
return
errors
.
Errorf
(
"provider [%s] send_transaction_retry_timeout is missing"
,
name
)
}
if
provider
.
SendTransactionCoolDown
==
0
{
return
errors
.
Errorf
(
"provider [%s] send_transaction_cool_down is missing"
,
name
)
}
if
provider
.
ReceiptRetrievalInterval
==
0
{
return
errors
.
Errorf
(
"provider [%s] receipt_retrieval_interval is missing"
,
name
)
}
...
...
op-ufm/pkg/metrics/clients/eth.go
View file @
084269f0
...
...
@@ -2,6 +2,7 @@ package clients
import
(
"context"
"math/big"
"time"
"github.com/ethereum-optimism/optimism/op-ufm/pkg/metrics"
...
...
@@ -22,7 +23,7 @@ func Dial(providerName string, url string) (*InstrumentedEthClient, error) {
start
:=
time
.
Now
()
c
,
err
:=
ethclient
.
Dial
(
url
)
if
err
!=
nil
{
metrics
.
RecordError
(
providerName
,
"ethclient.Dial"
)
metrics
.
RecordError
Details
(
providerName
,
"ethclient.Dial"
,
err
)
return
nil
,
err
}
metrics
.
RecordRPCLatency
(
providerName
,
"ethclient"
,
"Dial"
,
time
.
Since
(
start
))
...
...
@@ -34,7 +35,7 @@ func (i *InstrumentedEthClient) TransactionByHash(ctx context.Context, hash comm
tx
,
isPending
,
err
:=
i
.
c
.
TransactionByHash
(
ctx
,
hash
)
if
err
!=
nil
{
if
!
i
.
ignorableErrors
(
err
)
{
metrics
.
RecordError
(
i
.
providerName
,
"ethclient.TransactionByHash"
)
metrics
.
RecordError
Details
(
i
.
providerName
,
"ethclient.TransactionByHash"
,
err
)
}
return
nil
,
false
,
err
}
...
...
@@ -46,7 +47,7 @@ func (i *InstrumentedEthClient) PendingNonceAt(ctx context.Context, address stri
start
:=
time
.
Now
()
nonce
,
err
:=
i
.
c
.
PendingNonceAt
(
ctx
,
common
.
HexToAddress
(
address
))
if
err
!=
nil
{
metrics
.
RecordError
(
i
.
providerName
,
"ethclient.PendingNonceAt"
)
metrics
.
RecordError
Details
(
i
.
providerName
,
"ethclient.PendingNonceAt"
,
err
)
return
0
,
err
}
metrics
.
RecordRPCLatency
(
i
.
providerName
,
"ethclient"
,
"PendingNonceAt"
,
time
.
Since
(
start
))
...
...
@@ -58,7 +59,7 @@ func (i *InstrumentedEthClient) TransactionReceipt(ctx context.Context, txHash c
receipt
,
err
:=
i
.
c
.
TransactionReceipt
(
ctx
,
txHash
)
if
err
!=
nil
{
if
!
i
.
ignorableErrors
(
err
)
{
metrics
.
RecordError
(
i
.
providerName
,
"ethclient.TransactionReceipt"
)
metrics
.
RecordError
Details
(
i
.
providerName
,
"ethclient.TransactionReceipt"
,
err
)
}
return
nil
,
err
}
...
...
@@ -71,7 +72,7 @@ func (i *InstrumentedEthClient) SendTransaction(ctx context.Context, tx *types.T
err
:=
i
.
c
.
SendTransaction
(
ctx
,
tx
)
if
err
!=
nil
{
if
!
i
.
ignorableErrors
(
err
)
{
metrics
.
RecordError
(
i
.
providerName
,
"ethclient.SendTransaction"
)
metrics
.
RecordError
Details
(
i
.
providerName
,
"ethclient.SendTransaction"
,
err
)
}
return
err
}
...
...
@@ -79,6 +80,39 @@ func (i *InstrumentedEthClient) SendTransaction(ctx context.Context, tx *types.T
return
err
}
func
(
i
*
InstrumentedEthClient
)
EstimateGas
(
ctx
context
.
Context
,
msg
ethereum
.
CallMsg
)
(
uint64
,
error
)
{
start
:=
time
.
Now
()
gas
,
err
:=
i
.
c
.
EstimateGas
(
ctx
,
msg
)
if
err
!=
nil
{
metrics
.
RecordErrorDetails
(
i
.
providerName
,
"ethclient.EstimateGas"
,
err
)
return
0
,
err
}
metrics
.
RecordRPCLatency
(
i
.
providerName
,
"ethclient"
,
"EstimateGas"
,
time
.
Since
(
start
))
return
gas
,
err
}
func
(
i
*
InstrumentedEthClient
)
SuggestGasTipCap
(
ctx
context
.
Context
)
(
*
big
.
Int
,
error
)
{
start
:=
time
.
Now
()
gasTipCap
,
err
:=
i
.
c
.
SuggestGasTipCap
(
ctx
)
if
err
!=
nil
{
metrics
.
RecordErrorDetails
(
i
.
providerName
,
"ethclient.SuggestGasTipCap"
,
err
)
return
nil
,
err
}
metrics
.
RecordRPCLatency
(
i
.
providerName
,
"ethclient"
,
"SuggestGasTipCap"
,
time
.
Since
(
start
))
return
gasTipCap
,
err
}
func
(
i
*
InstrumentedEthClient
)
HeaderByNumber
(
ctx
context
.
Context
,
number
*
big
.
Int
)
(
*
types
.
Header
,
error
)
{
start
:=
time
.
Now
()
header
,
err
:=
i
.
c
.
HeaderByNumber
(
ctx
,
number
)
if
err
!=
nil
{
metrics
.
RecordErrorDetails
(
i
.
providerName
,
"ethclient.HeaderByNumber"
,
err
)
return
nil
,
err
}
metrics
.
RecordRPCLatency
(
i
.
providerName
,
"ethclient"
,
"HeaderByNumber"
,
time
.
Since
(
start
))
return
header
,
err
}
func
(
i
*
InstrumentedEthClient
)
ignorableErrors
(
err
error
)
bool
{
msg
:=
err
.
Error
()
// we dont use errors.Is because eth client actually uses errors.New,
...
...
op-ufm/pkg/metrics/clients/signer.go
View file @
084269f0
...
...
@@ -22,7 +22,7 @@ func NewSignerClient(providerName string, logger log.Logger, endpoint string, tl
start
:=
time
.
Now
()
c
,
err
:=
signer
.
NewSignerClient
(
logger
,
endpoint
,
tlsConfig
)
if
err
!=
nil
{
metrics
.
RecordError
(
providerName
,
"signer.NewSignerClient"
)
metrics
.
RecordError
Details
(
providerName
,
"signer.NewSignerClient"
,
err
)
return
nil
,
err
}
metrics
.
RecordRPCLatency
(
providerName
,
"signer"
,
"NewSignerClient"
,
time
.
Since
(
start
))
...
...
@@ -33,7 +33,7 @@ func (i *InstrumentedSignerClient) SignTransaction(ctx context.Context, chainId
start
:=
time
.
Now
()
tx
,
err
:=
i
.
c
.
SignTransaction
(
ctx
,
chainId
,
tx
)
if
err
!=
nil
{
metrics
.
RecordError
(
i
.
providerName
,
"signer.SignTransaction"
)
metrics
.
RecordError
Details
(
i
.
providerName
,
"signer.SignTransaction"
,
err
)
return
nil
,
err
}
metrics
.
RecordRPCLatency
(
i
.
providerName
,
"signer"
,
"SignTransaction"
,
time
.
Since
(
start
))
...
...
op-ufm/pkg/provider/roundtrip.go
View file @
084269f0
...
...
@@ -2,6 +2,7 @@ package provider
import
(
"context"
"math/big"
"time"
"github.com/ethereum-optimism/optimism/op-ufm/pkg/metrics"
...
...
@@ -21,7 +22,7 @@ import (
// RoundTrip send a new transaction to measure round trip latency
func
(
p
*
Provider
)
RoundTrip
(
ctx
context
.
Context
)
{
log
.
Debug
(
"
roundTripLatency
"
,
log
.
Debug
(
"
RoundTrip
"
,
"provider"
,
p
.
name
)
client
,
err
:=
iclients
.
Dial
(
p
.
name
,
p
.
config
.
URL
)
...
...
@@ -33,33 +34,38 @@ func (p *Provider) RoundTrip(ctx context.Context) {
return
}
var
nonce
uint64
p
.
txPool
.
M
.
Lock
()
if
p
.
txPool
.
Nonce
==
uint64
(
0
)
{
nonce
,
err
=
client
.
PendingNonceAt
(
ctx
,
p
.
walletConfig
.
Address
)
if
err
!=
nil
{
log
.
Error
(
"cant get nounce"
,
"provider"
,
p
.
name
,
"err"
,
err
)
p
.
txPool
.
M
.
Unlock
()
return
}
p
.
txPool
.
Nonce
=
nonce
}
else
{
p
.
txPool
.
Nonce
++
nonce
=
p
.
txPool
.
Nonce
}
p
.
txPool
.
M
.
Unlock
()
p
.
txPool
.
ExclusiveSend
.
Lock
()
defer
p
.
txPool
.
ExclusiveSend
.
Unlock
()
txHash
:=
common
.
Hash
{}
attempt
:=
0
nonce
:=
uint64
(
0
)
// used for timeout
firstAttemptAt
:=
time
.
Now
()
// used for actual round trip time (disregard retry time)
roundTripStartedAt
:=
time
.
Now
()
var
roundTripStartedAt
time
.
Time
for
{
// sleep until we get a clear to send
for
{
tx
:=
p
.
createTx
(
nonce
)
txHash
=
tx
.
Hash
()
coolDown
:=
time
.
Duration
(
p
.
config
.
SendTransactionCoolDown
)
-
time
.
Since
(
p
.
txPool
.
LastSend
)
if
coolDown
>
0
{
time
.
Sleep
(
coolDown
)
}
else
{
break
}
}
tx
,
err
:=
p
.
createTx
(
ctx
,
client
,
nonce
)
nonce
=
tx
.
Nonce
()
if
err
!=
nil
{
log
.
Error
(
"cant create tx"
,
"provider"
,
p
.
name
,
"nonce"
,
nonce
,
"err"
,
err
)
return
}
signedTx
,
err
:=
p
.
sign
(
ctx
,
tx
)
if
err
!=
nil
{
...
...
@@ -69,7 +75,6 @@ func (p *Provider) RoundTrip(ctx context.Context) {
"err"
,
err
)
return
}
txHash
=
signedTx
.
Hash
()
roundTripStartedAt
=
time
.
Now
()
...
...
@@ -78,25 +83,29 @@ func (p *Provider) RoundTrip(ctx context.Context) {
if
err
.
Error
()
==
txpool
.
ErrAlreadyKnown
.
Error
()
||
err
.
Error
()
==
txpool
.
ErrReplaceUnderpriced
.
Error
()
||
err
.
Error
()
==
core
.
ErrNonceTooLow
.
Error
()
{
log
.
Warn
(
"cant send transaction (retryable)"
,
"provider"
,
p
.
name
,
"err"
,
err
,
"nonce"
,
nonce
)
if
time
.
Since
(
firstAttemptAt
)
>=
time
.
Duration
(
p
.
config
.
SendTransactionRetryTimeout
)
{
log
.
Error
(
"send transaction timed out (known already)"
,
"provider"
,
p
.
name
,
"hash"
,
txHash
.
Hex
(),
"nonce"
,
nonce
,
"elapsed"
,
time
.
Since
(
firstAttemptAt
),
"attempt"
,
attempt
,
"nonce"
,
nonce
)
metrics
.
RecordError
(
p
.
name
,
"ethclient.SendTransaction.nonce"
)
"attempt"
,
attempt
)
metrics
.
RecordErrorDetails
(
p
.
name
,
"send.timeout"
,
err
)
return
}
log
.
Warn
(
"tx already known, incrementing nonce and trying again"
,
"provider"
,
p
.
name
,
"nonce"
,
nonce
)
time
.
Sleep
(
time
.
Duration
(
p
.
config
.
SendTransactionRetryInterval
))
p
.
txPool
.
M
.
Lock
()
p
.
txPool
.
Nonce
++
nonce
=
p
.
txPool
.
Nonce
p
.
txPool
.
M
.
Unlock
()
nonce
++
attempt
++
if
attempt
%
10
==
0
{
log
.
Debug
(
"retrying send transaction..."
,
...
...
@@ -108,6 +117,7 @@ func (p *Provider) RoundTrip(ctx context.Context) {
}
else
{
log
.
Error
(
"cant send transaction"
,
"provider"
,
p
.
name
,
"nonce"
,
nonce
,
"err"
,
err
)
metrics
.
RecordErrorDetails
(
p
.
name
,
"ethclient.SendTransaction"
,
err
)
return
...
...
@@ -131,6 +141,7 @@ func (p *Provider) RoundTrip(ctx context.Context) {
SentAt
:
sentAt
,
SeenBy
:
make
(
map
[
string
]
time
.
Time
),
}
p
.
txPool
.
LastSend
=
sentAt
p
.
txPool
.
M
.
Unlock
()
var
receipt
*
types
.
Receipt
...
...
@@ -140,13 +151,17 @@ func (p *Provider) RoundTrip(ctx context.Context) {
log
.
Error
(
"receipt retrieval timed out"
,
"provider"
,
p
.
name
,
"hash"
,
txHash
,
"nonce"
,
nonce
,
"elapsed"
,
time
.
Since
(
sentAt
))
metrics
.
RecordErrorDetails
(
p
.
name
,
"receipt.timeout"
,
err
)
return
}
time
.
Sleep
(
time
.
Duration
(
p
.
config
.
ReceiptRetrievalInterval
))
if
attempt
%
10
==
0
{
log
.
Debug
(
"checking for receipt..."
,
"provider"
,
p
.
name
,
"hash"
,
txHash
,
"nonce"
,
nonce
,
"attempt"
,
attempt
,
"elapsed"
,
time
.
Since
(
sentAt
))
}
...
...
@@ -155,6 +170,7 @@ func (p *Provider) RoundTrip(ctx context.Context) {
log
.
Error
(
"cant get receipt for transaction"
,
"provider"
,
p
.
name
,
"hash"
,
txHash
.
Hex
(),
"nonce"
,
nonce
,
"err"
,
err
)
return
}
...
...
@@ -168,6 +184,7 @@ func (p *Provider) RoundTrip(ctx context.Context) {
log
.
Info
(
"got transaction receipt"
,
"hash"
,
txHash
.
Hex
(),
"nonce"
,
nonce
,
"roundTripLatency"
,
roundTripLatency
,
"provider"
,
p
.
name
,
"blockNumber"
,
receipt
.
BlockNumber
,
...
...
@@ -175,20 +192,83 @@ func (p *Provider) RoundTrip(ctx context.Context) {
"gasUsed"
,
receipt
.
GasUsed
)
}
func
(
p
*
Provider
)
createTx
(
nonce
uint64
)
*
types
.
Transaction
{
toAddress
:=
common
.
HexToAddress
(
p
.
walletConfig
.
Address
)
func
(
p
*
Provider
)
createTx
(
ctx
context
.
Context
,
client
*
iclients
.
InstrumentedEthClient
,
nonce
uint64
)
(
*
types
.
Transaction
,
error
)
{
var
err
error
if
nonce
==
0
{
nonce
,
err
=
client
.
PendingNonceAt
(
ctx
,
p
.
walletConfig
.
Address
)
if
err
!=
nil
{
log
.
Error
(
"cant get nounce"
,
"provider"
,
p
.
name
,
"nonce"
,
nonce
,
"err"
,
err
)
return
nil
,
err
}
}
gasTipCap
,
err
:=
client
.
SuggestGasTipCap
(
ctx
)
if
err
!=
nil
{
log
.
Error
(
"cant get gas tip cap"
,
"provider"
,
p
.
name
,
"err"
,
err
)
return
nil
,
err
}
gasTipCap
=
new
(
big
.
Int
)
.
Mul
(
gasTipCap
,
big
.
NewInt
(
110
))
gasTipCap
=
new
(
big
.
Int
)
.
Div
(
gasTipCap
,
big
.
NewInt
(
100
))
head
,
err
:=
client
.
HeaderByNumber
(
ctx
,
nil
)
if
err
!=
nil
{
log
.
Error
(
"cant get base fee from head"
,
"provider"
,
p
.
name
,
"err"
,
err
)
return
nil
,
err
}
baseFee
:=
head
.
BaseFee
gasFeeCap
:=
new
(
big
.
Int
)
.
Add
(
gasTipCap
,
new
(
big
.
Int
)
.
Mul
(
baseFee
,
big
.
NewInt
(
2
)))
addr
:=
common
.
HexToAddress
(
p
.
walletConfig
.
Address
)
var
data
[]
byte
tx
:=
types
.
NewTx
(
&
types
.
DynamicFeeTx
{
dynamicTx
:=
&
types
.
DynamicFeeTx
{
ChainID
:
&
p
.
walletConfig
.
ChainID
,
Nonce
:
nonce
,
GasFeeCap
:
&
p
.
walletConfig
.
GasFeeCap
,
GasTipCap
:
&
p
.
walletConfig
.
GasTipCap
,
Gas
:
p
.
walletConfig
.
GasLimit
,
To
:
&
toAddress
,
GasFeeCap
:
gasFeeCap
,
GasTipCap
:
gasTipCap
,
To
:
&
addr
,
Value
:
&
p
.
walletConfig
.
TxValue
,
Data
:
data
,
}
gas
,
err
:=
client
.
EstimateGas
(
ctx
,
ethereum
.
CallMsg
{
From
:
addr
,
To
:
&
addr
,
GasFeeCap
:
gasFeeCap
,
GasTipCap
:
gasTipCap
,
Data
:
dynamicTx
.
Data
,
Value
:
dynamicTx
.
Value
,
})
return
tx
if
err
!=
nil
{
log
.
Error
(
"cant estimate gas"
,
"provider"
,
p
.
name
,
"err"
,
err
)
return
nil
,
err
}
dynamicTx
.
Gas
=
gas
tx
:=
types
.
NewTx
(
dynamicTx
)
log
.
Info
(
"tx created"
,
"provider"
,
p
.
name
,
"from"
,
addr
,
"to"
,
dynamicTx
.
To
,
"nonce"
,
dynamicTx
.
Nonce
,
"value"
,
dynamicTx
.
Value
,
"gas"
,
dynamicTx
.
Gas
,
"gasTipCap"
,
dynamicTx
.
GasTipCap
,
"gasFeeCap"
,
dynamicTx
.
GasFeeCap
,
)
return
tx
,
nil
}
func
(
p
*
Provider
)
sign
(
ctx
context
.
Context
,
tx
*
types
.
Transaction
)
(
*
types
.
Transaction
,
error
)
{
...
...
op-ufm/pkg/provider/tx_pool.go
View file @
084269f0
...
...
@@ -15,7 +15,11 @@ type NetworkTransactionPool struct {
M
sync
.
Mutex
Transactions
map
[
string
]
*
TransactionState
Expected
int
Nonce
uint64
// Last time a transaction was sent
LastSend
time
.
Time
// Prevents concurrent transaction send
ExclusiveSend
sync
.
Mutex
}
type
TransactionState
struct
{
...
...
packages/contracts-bedrock/.gitignore
View file @
084269f0
...
...
@@ -26,3 +26,6 @@ deployments/hardhat
deployments/getting-started
deployments/*/.deploy
deployments/1337
# Devnet config which changes with each 'make devnet-up'
deploy-config/devnetL1.json
packages/contracts-bedrock/deploy-config/devnetL1.json
→
packages/contracts-bedrock/deploy-config/devnetL1
-template
.json
View file @
084269f0
File moved
pnpm-lock.yaml
View file @
084269f0
...
...
@@ -23,7 +23,7 @@ importers:
version
:
0.4.8
'
@nrwl/nx-cloud'
:
specifier
:
latest
version
:
16.
3
.0
version
:
16.
4
.0
'
@types/chai'
:
specifier
:
^4.2.18
version
:
4.2.21
...
...
@@ -2534,6 +2534,10 @@ packages:
resolution
:
{
integrity
:
sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA==
}
engines
:
{
node
:
'
>=
16'
}
/@noble/hashes@1.3.2
:
resolution
:
{
integrity
:
sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==
}
engines
:
{
node
:
'
>=
16'
}
/@nodelib/fs.scandir@2.1.5
:
resolution
:
{
integrity
:
sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==
}
engines
:
{
node
:
'
>=
8'
}
...
...
@@ -2669,10 +2673,10 @@ packages:
-
nx
dev
:
true
/@nrwl/nx-cloud@16.
3
.0
:
resolution
:
{
integrity
:
sha512-
nJrGsVufhY74KcP7kM7BqFOGAoO5OEF6+wfiM295DgmEG9c1yW+x5QiQaC42K9SWYn/eKQa1X7466ZA5lynXoQ
==
}
/@nrwl/nx-cloud@16.
4
.0
:
resolution
:
{
integrity
:
sha512-
QitrYK6z9ceagetBlgLMZnC0T85k2JTk+oK0MxZ5p/woclqeYN7SiGNZgMzDq8TjJwt8Fm/MDnsSo3xtufmLBg
==
}
dependencies
:
nx-cloud
:
16.
3
.0
nx-cloud
:
16.
4
.0
transitivePeerDependencies
:
-
debug
dev
:
true
...
...
@@ -3071,7 +3075,7 @@ packages:
/@scure/bip39@1.2.1
:
resolution
:
{
integrity
:
sha512-Z3/Fsz1yr904dduJD0NpiyRHhRYHdcnyh73FZWiV+/qhWi83wNJ3NWolYqCEN+ZWsUz2TWwajJggcRE9r1zUYg==
}
dependencies
:
'
@noble/hashes'
:
1.3.
1
'
@noble/hashes'
:
1.3.
2
'
@scure/base'
:
1.1.1
/@sentry-internal/tracing@7.64.0
:
...
...
@@ -3713,20 +3717,20 @@ packages:
/@types/bn.js@4.11.6
:
resolution
:
{
integrity
:
sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==
}
dependencies
:
'
@types/node'
:
20.5.
0
'
@types/node'
:
20.5.
3
dev
:
true
/@types/bn.js@5.1.0
:
resolution
:
{
integrity
:
sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA==
}
dependencies
:
'
@types/node'
:
20.5.
0
'
@types/node'
:
20.5.
3
dev
:
true
/@types/body-parser@1.19.1
:
resolution
:
{
integrity
:
sha512-a6bTJ21vFOGIkwM0kzh9Yr89ziVxq4vYH2fQ6N8AeipEzai/cFK6aGMArIkUeIdRIgpwQa+2bXiLuUJCpSf2Cg==
}
dependencies
:
'
@types/connect'
:
3.4.35
'
@types/node'
:
20.5.
0
'
@types/node'
:
20.5.
3
dev
:
true
/@types/chai-as-promised@7.1.5
:
...
...
@@ -3752,7 +3756,7 @@ packages:
/@types/connect@3.4.35
:
resolution
:
{
integrity
:
sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==
}
dependencies
:
'
@types/node'
:
20.5.
0
'
@types/node'
:
20.5.
3
/@types/dateformat@5.0.0
:
resolution
:
{
integrity
:
sha512-SZg4JdHIWHQGEokbYGZSDvo5wA4TLYPXaqhigs/wH+REDOejcJzgH+qyY+HtEUtWOZxEUkbhbdYPqQDiEgrXeA==
}
...
...
@@ -3766,7 +3770,7 @@ packages:
/@types/express-serve-static-core@4.17.35
:
resolution
:
{
integrity
:
sha512-wALWQwrgiB2AWTT91CB62b6Yt0sNHpznUXeZEcnPU3DRdlDIz74x8Qg1UUYKSVFi+va5vKOLYRBI1bRKiLLKIg==
}
dependencies
:
'
@types/node'
:
20.5.
0
'
@types/node'
:
20.5.
3
'
@types/qs'
:
6.9.7
'
@types/range-parser'
:
1.2.4
'
@types/send'
:
0.17.1
...
...
@@ -3812,7 +3816,7 @@ packages:
dependencies
:
'
@types/abstract-leveldown'
:
5.0.2
'
@types/level-errors'
:
3.0.0
'
@types/node'
:
20.5.
0
'
@types/node'
:
20.5.
3
dev
:
true
/@types/lru-cache@5.1.1
:
...
...
@@ -3843,7 +3847,7 @@ packages:
/@types/mkdirp@0.5.2
:
resolution
:
{
integrity
:
sha512-U5icWpv7YnZYGsN4/cmh3WD2onMY0aJIiTE6+51TwJCttdHvtCYmkBNOobHlXwrJRL0nkH9jH4kD+1FAdMN4Tg==
}
dependencies
:
'
@types/node'
:
20.5.
0
'
@types/node'
:
20.5.
3
dev
:
true
/@types/mocha@10.0.1
:
...
...
@@ -3862,7 +3866,7 @@ packages:
/@types/node-fetch@2.6.4
:
resolution
:
{
integrity
:
sha512-1ZX9fcN4Rvkvgv4E6PAY5WXUFWFcRWxZa3EW83UjycOB9ljJCedb2CupIP4RZMEwF/M3eTcCihbBRgwtGbg5Rg==
}
dependencies
:
'
@types/node'
:
20.5.
0
'
@types/node'
:
20.5.
3
form-data
:
3.0.1
dev
:
true
...
...
@@ -3875,10 +3879,10 @@ packages:
/@types/node@20.5.0
:
resolution
:
{
integrity
:
sha512-Mgq7eCtoTjT89FqNoTzzXg2XvCi5VMhRV6+I2aYanc6kQCBImeNaAYRs/DyoVqk1YEUJK5gN9VO7HRIdz4Wo3Q==
}
dev
:
true
/@types/node@20.5.3
:
resolution
:
{
integrity
:
sha512-ITI7rbWczR8a/S6qjAW7DMqxqFMjjTo61qZVWJ1ubPvbIQsL5D/TvwjYEalM8Kthpe3hTzOGrF2TGbAu2uyqeA==
}
dev
:
true
/@types/normalize-package-data@2.4.1
:
resolution
:
{
integrity
:
sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==
}
...
...
@@ -3890,7 +3894,7 @@ packages:
/@types/pbkdf2@3.1.0
:
resolution
:
{
integrity
:
sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ==
}
dependencies
:
'
@types/node'
:
20.5.
0
'
@types/node'
:
20.5.
3
dev
:
true
/@types/pino-multi-stream@5.1.3
:
...
...
@@ -3908,13 +3912,13 @@ packages:
/@types/pino-std-serializers@2.4.1
:
resolution
:
{
integrity
:
sha512-17XcksO47M24IVTVKPeAByWUd3Oez7EbIjXpSbzMPhXVzgjGtrOa49gKBwxH9hb8dKv58OelsWQ+A1G1l9S3wQ==
}
dependencies
:
'
@types/node'
:
20.5.
0
'
@types/node'
:
20.5.
3
dev
:
true
/@types/pino@6.3.11
:
resolution
:
{
integrity
:
sha512-S7+fLONqSpHeW9d7TApUqO6VN47KYgOXhCNKwGBVLHObq8HhaAYlVqUNdfnvoXjCMiwE5xcPm/5R2ZUh8bgaXQ==
}
dependencies
:
'
@types/node'
:
20.5.
0
'
@types/node'
:
20.5.
3
'
@types/pino-pretty'
:
4.7.1
'
@types/pino-std-serializers'
:
2.4.1
sonic-boom
:
2.8.0
...
...
@@ -3964,7 +3968,7 @@ packages:
/@types/secp256k1@4.0.3
:
resolution
:
{
integrity
:
sha512-Da66lEIFeIz9ltsdMZcpQvmrmmoqrfju8pm1BH8WbYjZSwUgCwXLb9C+9XYogwBITnbsSaMdVPb2ekf7TV+03w==
}
dependencies
:
'
@types/node'
:
20.5.
0
'
@types/node'
:
20.5.
3
dev
:
true
/@types/seedrandom@3.0.1
:
...
...
@@ -3983,14 +3987,14 @@ packages:
resolution
:
{
integrity
:
sha512-Cwo8LE/0rnvX7kIIa3QHCkcuF21c05Ayb0ZfxPiv0W8VRiZiNW/WuRupHKpqqGVGf7SUA44QSOUKaEd9lIrd/Q==
}
dependencies
:
'
@types/mime'
:
1.3.2
'
@types/node'
:
20.5.
0
'
@types/node'
:
20.5.
3
dev
:
true
/@types/serve-static@1.13.10
:
resolution
:
{
integrity
:
sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ==
}
dependencies
:
'
@types/mime'
:
1.3.2
'
@types/node'
:
20.5.
0
'
@types/node'
:
20.5.
3
dev
:
true
/@types/sinon-chai@3.2.5
:
...
...
@@ -4027,18 +4031,18 @@ packages:
/@types/ws@7.4.7
:
resolution
:
{
integrity
:
sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==
}
dependencies
:
'
@types/node'
:
20.5.
0
'
@types/node'
:
20.5.
3
/@types/ws@8.5.3
:
resolution
:
{
integrity
:
sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w==
}
dependencies
:
'
@types/node'
:
20.5.
0
'
@types/node'
:
20.5.
3
dev
:
false
/@types/ws@8.5.5
:
resolution
:
{
integrity
:
sha512-lwhs8hktwxSjf9UaZ9tG5M03PGogvFaH8gUgLNbN9HKIg0dvv6q+gkSuJ8HN4/VbyxkuLzCjlN7GquQ0gUJfIg==
}
dependencies
:
'
@types/node'
:
20.5.
0
'
@types/node'
:
20.5.
3
dev
:
true
/@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.60.1)(eslint@8.47.0)(typescript@5.1.6)
:
...
...
@@ -12293,11 +12297,11 @@ packages:
resolution
:
{
integrity
:
sha512-ub5E4+FBPKwAZx0UwIQOjYWGHTEq5sPqHQNRN8Z9e4A7u3Tj1weLJsL59yH9vmvqEtBHaOmT6cYQKIZOxp35FQ==
}
dev
:
true
/nx-cloud@16.
3
.0
:
resolution
:
{
integrity
:
sha512-
hmNgpeLO4v4WDSWa8YhwX+q+9ohIyY8iqxlWyIKixWzQH2XfRgYFjOLH4IDLGOlKa3hg7MB6+4+75cK9CfSmKw
==
}
/nx-cloud@16.
4
.0
:
resolution
:
{
integrity
:
sha512-
jbq4hWvDwRlJVpxgMgbmNSkue+6XZSn53R6Vo6qmCAWODJ9KY1BZdZ/9VRL8IX/BRKebVFiXp3SapFB1qPhH8A
==
}
hasBin
:
true
dependencies
:
'
@nrwl/nx-cloud'
:
16.
3
.0
'
@nrwl/nx-cloud'
:
16.
4
.0
axios
:
1.1.3
chalk
:
4.1.2
dotenv
:
10.0.0
...
...
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