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
0a99aaac
Unverified
Commit
0a99aaac
authored
Aug 19, 2021
by
Mark Tyneway
Committed by
GitHub
Aug 19, 2021
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1356 from ethereum-optimism/develop
merge develop into master
parents
b9a47cbc
4425e9f5
Changes
25
Hide whitespace changes
Inline
Side-by-side
Showing
25 changed files
with
179 additions
and
122 deletions
+179
-122
fast-seas-train.md
.changeset/fast-seas-train.md
+5
-0
release.yml
.github/workflows/release.yml
+25
-25
abi.go
l2geth/accounts/abi/abi.go
+16
-1
simulated.go
l2geth/accounts/abi/bind/backends/simulated.go
+2
-0
keystore.go
l2geth/accounts/keystore/keystore.go
+4
-1
main.go
l2geth/cmd/geth/main.go
+9
-0
usage.go
l2geth/cmd/geth/usage.go
+1
-0
flags.go
l2geth/cmd/utils/flags.go
+7
-0
clique.go
l2geth/consensus/clique/clique.go
+18
-9
consensus.go
l2geth/consensus/ethash/consensus.go
+10
-12
blockchain_test.go
l2geth/core/blockchain_test.go
+1
-0
chain_makers_test.go
l2geth/core/chain_makers_test.go
+5
-8
genesis.go
l2geth/core/genesis.go
+21
-1
accessors_chain.go
l2geth/core/rawdb/accessors_chain.go
+10
-0
accessors_indexes.go
l2geth/core/rawdb/accessors_indexes.go
+4
-0
statedb.go
l2geth/core/state/statedb.go
+5
-0
state_processor.go
l2geth/core/state_processor.go
+10
-0
state_transition.go
l2geth/core/state_transition.go
+16
-6
transaction.go
l2geth/core/types/transaction.go
+2
-34
api.go
l2geth/internal/ethapi/api.go
+0
-12
api_backend.go
l2geth/les/api_backend.go
+0
-4
txpool.go
l2geth/light/txpool.go
+3
-7
worker_test.go
l2geth/miner/worker_test.go
+1
-0
trie.go
l2geth/trie/trie.go
+2
-0
OVM_L2ToL1MessagePasser.sol
...istic-ethereum/OVM/predeploys/OVM_L2ToL1MessagePasser.sol
+2
-2
No files found.
.changeset/fast-seas-train.md
0 → 100644
View file @
0a99aaac
---
'
@eth-optimism/l2geth'
:
patch
---
Reduce the geth diff
.github/workflows/release.yml
View file @
0a99aaac
...
...
@@ -301,28 +301,28 @@ jobs:
push
:
true
tags
:
ethereumoptimism/integration-tests:${{ needs.builder.outputs.integration-tests }},ethereumoptimism/integration-tests:latest
replica-healthcheck
:
name
:
Publish Replica Healthcheck Version ${{ needs.builder.outputs.replica-healthcheck }}
needs
:
builder
if
:
needs.builder.outputs.replica-healthcheck != ''
runs-on
:
ubuntu-latest
steps
:
-
name
:
Checkout
uses
:
actions/checkout@v2
-
name
:
Set up Docker Buildx
uses
:
docker/setup-buildx-action@v1
-
name
:
Login to Docker Hub
uses
:
docker/login-action@v1
with
:
username
:
${{ secrets.DOCKERHUB_ACCESS_TOKEN_USERNAME }}
password
:
${{ secrets.DOCKERHUB_ACCESS_TOKEN_SECRET }}
-
name
:
Build and push
uses
:
docker/build-push-action@v2
with
:
context
:
.
file
:
./ops/docker/Dockerfile.replica-healthcheck
push
:
true
tags
:
ethereumoptimism/replica-healthcheck:${{ needs.builder.outputs.replica-healthcheck }},ethereumoptimism/replica-healthcheck:latest
replica-healthcheck
:
name
:
Publish Replica Healthcheck Version ${{ needs.builder.outputs.replica-healthcheck }}
needs
:
builder
if
:
needs.builder.outputs.replica-healthcheck != ''
runs-on
:
ubuntu-latest
steps
:
-
name
:
Checkout
uses
:
actions/checkout@v2
-
name
:
Set up Docker Buildx
uses
:
docker/setup-buildx-action@v1
-
name
:
Login to Docker Hub
uses
:
docker/login-action@v1
with
:
username
:
${{ secrets.DOCKERHUB_ACCESS_TOKEN_USERNAME }}
password
:
${{ secrets.DOCKERHUB_ACCESS_TOKEN_SECRET }}
-
name
:
Build and push
uses
:
docker/build-push-action@v2
with
:
context
:
.
file
:
./ops/docker/Dockerfile.replica-healthcheck
push
:
true
tags
:
ethereumoptimism/replica-healthcheck:${{ needs.builder.outputs.replica-healthcheck }},ethereumoptimism/replica-healthcheck:latest
l2geth/accounts/abi/abi.go
View file @
0a99aaac
...
...
@@ -123,6 +123,12 @@ func (abi *ABI) UnmarshalJSON(data []byte) error {
return
err
}
abi
.
Methods
=
make
(
map
[
string
]
Method
)
// UsingOVM specific changes
// Create a cache of methods when running under the OVM because
// looking up methods based on the 4 byte selector is part of the hot
// code path. Without this cache, it was observed that 50% of the CPU
// time during syncing was spent hashing the function selectors
// during the call to `abi.MethodsById`
abi
.
MethodsById
=
make
(
map
[[
4
]
byte
]
*
Method
)
abi
.
Events
=
make
(
map
[
string
]
Event
)
for
_
,
field
:=
range
fields
{
...
...
@@ -148,7 +154,8 @@ func (abi *ABI) UnmarshalJSON(data []byte) error {
Outputs
:
field
.
Outputs
,
}
abi
.
Methods
[
name
]
=
method
// add method to the id cache
// UsingOVM specific changes
// Add method to the id cache
sigdata
:=
method
.
ID
()
abi
.
MethodsById
[[
4
]
byte
{
sigdata
[
0
],
sigdata
[
1
],
sigdata
[
2
],
sigdata
[
3
]}]
=
&
method
case
"event"
:
...
...
@@ -177,6 +184,9 @@ func (abi *ABI) MethodById(sigdata []byte) (*Method, error) {
return
nil
,
fmt
.
Errorf
(
"data too short (%d bytes) for abi method lookup"
,
len
(
sigdata
))
}
// UsingOVM specific changes
// Use the method cache to prevent the need to iterate and hash
// each method in the ABI
method
,
exist
:=
abi
.
MethodsById
[[
4
]
byte
{
sigdata
[
0
],
sigdata
[
1
],
sigdata
[
2
],
sigdata
[
3
]}]
if
!
exist
{
return
nil
,
fmt
.
Errorf
(
"no method with id: %#x"
,
sigdata
[
:
4
])
...
...
@@ -195,6 +205,11 @@ func (abi *ABI) EventByID(topic common.Hash) (*Event, error) {
return
nil
,
fmt
.
Errorf
(
"no event with id: %#x"
,
topic
.
Hex
())
}
// UsingOVM
// Both RevertSelector and UnpackRevert were pulled from upstream
// geth as they were not present in the version of geth that this
// codebase was forked from. These are useful for displaying revert
// messages to users when they use `eth_call`
// RevertSelector is a special function selector for revert reason unpacking.
var
RevertSelector
=
crypto
.
Keccak256
([]
byte
(
"Error(string)"
))[
:
4
]
...
...
l2geth/accounts/abi/bind/backends/simulated.go
View file @
0a99aaac
...
...
@@ -601,6 +601,8 @@ func (m callmsg) Gas() uint64 { return m.CallMsg.Gas }
func
(
m
callmsg
)
Value
()
*
big
.
Int
{
return
m
.
CallMsg
.
Value
}
func
(
m
callmsg
)
Data
()
[]
byte
{
return
m
.
CallMsg
.
Data
}
// UsingOVM
// These getters return OVM specific fields
func
(
m
callmsg
)
L1MessageSender
()
*
common
.
Address
{
return
m
.
CallMsg
.
L1MessageSender
}
func
(
m
callmsg
)
L1BlockNumber
()
*
big
.
Int
{
return
m
.
CallMsg
.
L1BlockNumber
}
func
(
m
callmsg
)
QueueOrigin
()
types
.
QueueOrigin
{
return
m
.
CallMsg
.
QueueOrigin
}
...
...
l2geth/accounts/keystore/keystore.go
View file @
0a99aaac
...
...
@@ -85,7 +85,10 @@ func NewKeyStore(keydir string, scryptN, scryptP int) *KeyStore {
ks
.
init
(
keydir
)
if
vm
.
UsingOVM
{
// Add a deterministic key to the key store so that
// all clique blocks are signed with the same key
// all clique blocks are signed with the same key.
// This change will result in deterministic blocks across
// the entire network. This change is necessary due to
// each node running its own single signer clique consensus.
input
:=
make
([]
byte
,
65
)
rng
:=
bytes
.
NewReader
(
input
)
key
,
err
:=
newKey
(
rng
)
...
...
l2geth/cmd/geth/main.go
View file @
0a99aaac
...
...
@@ -149,6 +149,9 @@ var (
configFileFlag
,
}
// UsingOVM
// Optimism specific flags must be added to the application
// flag parsing logic
optimismFlags
=
[]
cli
.
Flag
{
utils
.
Eth1SyncServiceEnable
,
utils
.
Eth1CanonicalTransactionChainDeployHeightFlag
,
...
...
@@ -248,6 +251,7 @@ func init() {
sort
.
Sort
(
cli
.
CommandsByName
(
app
.
Commands
))
app
.
Flags
=
append
(
app
.
Flags
,
nodeFlags
...
)
// UsingOVM
app
.
Flags
=
append
(
app
.
Flags
,
optimismFlags
...
)
app
.
Flags
=
append
(
app
.
Flags
,
rpcFlags
...
)
app
.
Flags
=
append
(
app
.
Flags
,
consoleFlags
...
)
...
...
@@ -454,6 +458,11 @@ func startNode(ctx *cli.Context, stack *node.Node) {
if
err
:=
ethereum
.
StartMining
(
threads
);
err
!=
nil
{
utils
.
Fatalf
(
"Failed to start mining: %v"
,
err
)
}
// UsingOVM
// Can optionally configure the sync service. Turning it off allows
// for statically serving historical data and is also useful for
// local development. When it is turned on, it will attempt to sync
// using the `RollupClient`
if
ctx
.
GlobalBool
(
utils
.
Eth1SyncServiceEnable
.
Name
)
{
if
err
:=
ethereum
.
SyncService
()
.
Start
();
err
!=
nil
{
utils
.
Fatalf
(
"Failed to start syncservice: %v"
,
err
)
...
...
l2geth/cmd/geth/usage.go
View file @
0a99aaac
...
...
@@ -63,6 +63,7 @@ type flagGroup struct {
// AppHelpFlagGroups is the application flags, grouped by functionality.
var
AppHelpFlagGroups
=
[]
flagGroup
{
{
// UsingOVM
Name
:
"OPTIMISM"
,
Flags
:
[]
cli
.
Flag
{
utils
.
Eth1SyncServiceEnable
,
...
...
l2geth/cmd/utils/flags.go
View file @
0a99aaac
...
...
@@ -1130,6 +1130,7 @@ func setIPC(ctx *cli.Context, cfg *node.Config) {
}
}
// UsingOVM
// setEth1 configures the sync service
func
setEth1
(
ctx
*
cli
.
Context
,
cfg
*
rollup
.
Config
)
{
if
ctx
.
GlobalIsSet
(
Eth1CanonicalTransactionChainDeployHeightFlag
.
Name
)
{
...
...
@@ -1159,6 +1160,8 @@ func setEth1(ctx *cli.Context, cfg *rollup.Config) {
}
}
// UsingOVM
// setRollup configures the rollup
func
setRollup
(
ctx
*
cli
.
Context
,
cfg
*
rollup
.
Config
)
{
if
ctx
.
GlobalIsSet
(
RollupAddressManagerOwnerAddressFlag
.
Name
)
{
addr
:=
ctx
.
GlobalString
(
RollupAddressManagerOwnerAddressFlag
.
Name
)
...
...
@@ -1764,6 +1767,10 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *eth.Config) {
chainID
=
new
(
big
.
Int
)
.
SetUint64
(
id
)
}
// UsingOVM
// The genesis block includes state that is set at runtime.
// This allows the statedump to be generic and not created
// specific for each network.
gasLimit
:=
cfg
.
Rollup
.
GasLimit
if
gasLimit
==
0
{
gasLimit
=
params
.
GenesisGasLimit
...
...
l2geth/consensus/clique/clique.go
View file @
0a99aaac
...
...
@@ -324,10 +324,16 @@ func (c *Clique) verifyCascadingFields(chain consensus.ChainReader, header *type
if
parent
==
nil
||
parent
.
Number
.
Uint64
()
!=
number
-
1
||
parent
.
Hash
()
!=
header
.
ParentHash
{
return
consensus
.
ErrUnknownAncestor
}
// [REMOVED] to account for timestamp changes
//if parent.Time+c.config.Period > header.Time {
// return ErrInvalidTimestamp
//}
// Do not account for timestamps in consensus when running the OVM
// changes. The timestamp must be montonic, meaning that it can be the same
// or increase. L1 dictates the timestamp.
if
!
vm
.
UsingOVM
{
if
parent
.
Time
+
c
.
config
.
Period
>
header
.
Time
{
return
ErrInvalidTimestamp
}
}
// Retrieve the snapshot needed to verify this header and cache it
snap
,
err
:=
c
.
snapshot
(
chain
,
number
-
1
,
header
.
ParentHash
,
parents
)
if
err
!=
nil
{
...
...
@@ -547,11 +553,14 @@ func (c *Clique) Prepare(chain consensus.ChainReader, header *types.Header) erro
if
parent
==
nil
{
return
consensus
.
ErrUnknownAncestor
}
// [REMOVED] so we can control timestamps
//header.Time = parent.Time + c.config.Period
//if header.Time < uint64(time.Now().Unix()) {
// header.Time = uint64(time.Now().Unix())
//}
// Do not manipulate the timestamps when running with the OVM
if
!
vm
.
UsingOVM
{
header
.
Time
=
parent
.
Time
+
c
.
config
.
Period
if
header
.
Time
<
uint64
(
time
.
Now
()
.
Unix
())
{
header
.
Time
=
uint64
(
time
.
Now
()
.
Unix
())
}
}
return
nil
}
...
...
l2geth/consensus/ethash/consensus.go
View file @
0a99aaac
...
...
@@ -254,7 +254,7 @@ func (ethash *Ethash) verifyHeader(chain consensus.ChainReader, header, parent *
return
consensus
.
ErrFutureBlock
}
}
if
header
.
Time
<
parent
.
Time
{
if
header
.
Time
<
=
parent
.
Time
{
return
errOlderBlockTime
}
// Verify the block's difficulty based on its timestamp and parent's difficulty
...
...
@@ -273,18 +273,16 @@ func (ethash *Ethash) verifyHeader(chain consensus.ChainReader, header, parent *
return
fmt
.
Errorf
(
"invalid gasUsed: have %d, gasLimit %d"
,
header
.
GasUsed
,
header
.
GasLimit
)
}
// TODO: UNCOMMENT THIS CHECK WHEN WE UNDERSTAND OUR GAS LIMIT REQUIREMENTS
// Verify that the gas limit remains within allowed bounds
//
diff := int64(parent.GasLimit) - int64(header.GasLimit)
//
if diff < 0 {
//
diff *= -1
//
}
//
limit := parent.GasLimit / params.GasLimitBoundDivisor
//
if uint64(diff) >= limit || header.GasLimit < params.MinGasLimit {
//
return fmt.Errorf("invalid gas limit: have %d, want %d += %d", header.GasLimit, parent.GasLimit, limit)
//
}
diff
:=
int64
(
parent
.
GasLimit
)
-
int64
(
header
.
GasLimit
)
if
diff
<
0
{
diff
*=
-
1
}
limit
:=
parent
.
GasLimit
/
params
.
GasLimitBoundDivisor
if
uint64
(
diff
)
>=
limit
||
header
.
GasLimit
<
params
.
MinGasLimit
{
return
fmt
.
Errorf
(
"invalid gas limit: have %d, want %d += %d"
,
header
.
GasLimit
,
parent
.
GasLimit
,
limit
)
}
// Verify that the block number is parent's +1
if
diff
:=
new
(
big
.
Int
)
.
Sub
(
header
.
Number
,
parent
.
Number
);
diff
.
Cmp
(
big
.
NewInt
(
1
))
!=
0
{
...
...
l2geth/core/blockchain_test.go
View file @
0a99aaac
...
...
@@ -816,6 +816,7 @@ func TestLightVsFastVsFullChainHeads(t *testing.T) {
// Tests that chain reorganisations handle transaction removals and reinsertions.
func
TestChainTxReorgs
(
t
*
testing
.
T
)
{
t
.
Skip
(
"UsingOVM"
)
var
(
key1
,
_
=
crypto
.
HexToECDSA
(
"b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291"
)
key2
,
_
=
crypto
.
HexToECDSA
(
"8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a"
)
...
...
l2geth/core/chain_makers_test.go
View file @
0a99aaac
...
...
@@ -29,9 +29,6 @@ import (
)
func
ExampleGenerateChain
()
{
fmt
.
Println
(
"OVM breaks this... SKIPPING: Example Generate Chain fails because of the genesis."
)
return
var
(
key1
,
_
=
crypto
.
HexToECDSA
(
"b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291"
)
key2
,
_
=
crypto
.
HexToECDSA
(
"8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a"
)
...
...
@@ -95,9 +92,9 @@ func ExampleGenerateChain() {
fmt
.
Println
(
"balance of addr1:"
,
state
.
GetBalance
(
addr1
))
fmt
.
Println
(
"balance of addr2:"
,
state
.
GetBalance
(
addr2
))
fmt
.
Println
(
"balance of addr3:"
,
state
.
GetBalance
(
addr3
))
//
//
Output:
//
//
last block: #5
//
//
balance of addr1: 989000
//
//
balance of addr2: 10000
//
//
balance of addr3: 19687500000000001000
// Output:
// last block: #5
// balance of addr1: 989000
// balance of addr2: 10000
// balance of addr3: 19687500000000001000
}
l2geth/core/genesis.go
View file @
0a99aaac
...
...
@@ -267,7 +267,12 @@ func (g *Genesis) configOrDefault(ghash common.Hash) *params.ChainConfig {
}
}
// ApplyOvmStateToState applies the initial OVM state to a state object.
// UsingOVM
// ApplyOvmStateToState applies the initial OVM state to a statedb.
// It inserts a bunch of runtime config into the state.
// It is fragile to storage slots changing as it directly writes to storage
// slots instead of applying messages with well formed calldata.
// This function could be replaced in the future using GenesisAlloc
func
ApplyOvmStateToState
(
statedb
*
state
.
StateDB
,
stateDump
*
dump
.
OvmDump
,
l1XDomainMessengerAddress
,
l1StandardBridgeAddress
,
addrManagerOwnerAddress
,
gpoOwnerAddress
,
l1FeeWalletAddress
common
.
Address
,
chainID
*
big
.
Int
,
gasLimit
uint64
)
{
if
len
(
stateDump
.
Accounts
)
==
0
{
return
...
...
@@ -475,7 +480,11 @@ func DefaultGoerliGenesisBlock() *Genesis {
}
}
// UsingOVM
// DeveloperGenesisBlock returns the 'geth --dev' genesis block.
// Additional runtime parameters are passed through that impact
// the genesis state. An "incompatible genesis block" error means that
// these params were altered since the initial creation of the datadir.
func
DeveloperGenesisBlock
(
period
uint64
,
faucet
,
l1XDomainMessengerAddress
common
.
Address
,
l1StandardBridgeAddress
common
.
Address
,
addrManagerOwnerAddress
,
gpoOwnerAddress
,
l1FeeWalletAddress
common
.
Address
,
stateDumpPath
string
,
chainID
*
big
.
Int
,
gasLimit
uint64
)
*
Genesis
{
// Override the default period to the user requested one
config
:=
*
params
.
AllCliqueProtocolChanges
...
...
@@ -488,6 +497,10 @@ func DeveloperGenesisBlock(period uint64, faucet, l1XDomainMessengerAddress comm
stateDump
:=
dump
.
OvmDump
{}
if
vm
.
UsingOVM
{
// Fetch the state dump from the state dump path
// The system cannot start without a state dump as it depends on
// the ABIs that are included in the state dump. Check that all
// required state dump entries are present to prevent a faulty
// state dump from being used
if
stateDumpPath
==
""
{
panic
(
"Must pass state dump path"
)
}
...
...
@@ -531,6 +544,9 @@ func DeveloperGenesisBlock(period uint64, faucet, l1XDomainMessengerAddress comm
common
.
BytesToAddress
([]
byte
{
7
})
:
{
Balance
:
big
.
NewInt
(
1
)},
// ECScalarMul
common
.
BytesToAddress
([]
byte
{
8
})
:
{
Balance
:
big
.
NewInt
(
1
)},
// ECPairing
},
// UsingOVM
// Add additional properties to the genesis block so that they can
// be added into the initial genesis state at runtime
L1CrossDomainMessengerAddress
:
l1XDomainMessengerAddress
,
L1FeeWalletAddress
:
l1FeeWalletAddress
,
AddressManagerOwnerAddress
:
addrManagerOwnerAddress
,
...
...
@@ -552,6 +568,10 @@ func decodePrealloc(data string) GenesisAlloc {
return
ga
}
// UsingOVM
// fetchStateDump will fetch a state dump from a remote HTTP endpoint.
// This state dump includes the OVM system contracts as well as previous
// user state if the network has previously had a regenesis.
func
fetchStateDump
(
path
string
,
stateDump
*
dump
.
OvmDump
)
error
{
if
stateDump
==
nil
{
return
errors
.
New
(
"Unable to fetch state dump"
)
...
...
l2geth/core/rawdb/accessors_chain.go
View file @
0a99aaac
...
...
@@ -338,6 +338,7 @@ func DeleteBody(db ethdb.KeyValueWriter, hash common.Hash, number uint64) {
}
}
// UsingOVM
// ReadTransactionMeta returns the transaction metadata associated with a
// transaction hash.
func
ReadTransactionMeta
(
db
ethdb
.
Reader
,
number
uint64
)
*
types
.
TransactionMeta
{
...
...
@@ -355,6 +356,7 @@ func ReadTransactionMeta(db ethdb.Reader, number uint64) *types.TransactionMeta
return
meta
}
// UsingOVM
// ReadTransactionMetaRaw returns the raw transaction metadata associated with a
// transaction hash.
func
ReadTransactionMetaRaw
(
db
ethdb
.
Reader
,
number
uint64
)
[]
byte
{
...
...
@@ -365,12 +367,14 @@ func ReadTransactionMetaRaw(db ethdb.Reader, number uint64) []byte {
return
nil
}
// UsingOVM
// WriteTransactionMeta writes the TransactionMeta to disk by hash.
func
WriteTransactionMeta
(
db
ethdb
.
KeyValueWriter
,
number
uint64
,
meta
*
types
.
TransactionMeta
)
{
data
:=
types
.
TxMetaEncode
(
meta
)
WriteTransactionMetaRaw
(
db
,
number
,
data
)
}
// UsingOVM
// WriteTransactionMetaRaw writes the raw transaction metadata bytes to disk.
func
WriteTransactionMetaRaw
(
db
ethdb
.
KeyValueWriter
,
number
uint64
,
data
[]
byte
)
{
if
err
:=
db
.
Put
(
txMetaKey
(
number
),
data
);
err
!=
nil
{
...
...
@@ -378,6 +382,7 @@ func WriteTransactionMetaRaw(db ethdb.KeyValueWriter, number uint64, data []byte
}
}
// UsingOVM
// DeleteTransactionMeta removes the transaction metadata associated with a hash
func
DeleteTransactionMeta
(
db
ethdb
.
KeyValueWriter
,
number
uint64
)
{
if
err
:=
db
.
Delete
(
txMetaKey
(
number
));
err
!=
nil
{
...
...
@@ -577,6 +582,11 @@ func ReadBlock(db ethdb.Reader, hash common.Hash, number uint64) *types.Block {
if
body
==
nil
{
return
nil
}
// UsingOVM
// Read all of the transaction meta from the db when reading a block
// and set the txmeta on each transaction. This is because the tx meta
// is not included as part of the RLP encoding of a transaction to be
// backwards compatible with layer one
for
i
:=
0
;
i
<
len
(
body
.
Transactions
);
i
++
{
meta
:=
ReadTransactionMeta
(
db
,
header
.
Number
.
Uint64
())
body
.
Transactions
[
i
]
.
SetTransactionMeta
(
meta
)
...
...
l2geth/core/rawdb/accessors_indexes.go
View file @
0a99aaac
...
...
@@ -86,6 +86,10 @@ func ReadTransaction(db ethdb.Reader, hash common.Hash) (*types.Transaction, com
}
for
txIndex
,
tx
:=
range
body
.
Transactions
{
if
tx
.
Hash
()
==
hash
{
// UsingOVM
// Read the transaction meta from the database and attach it
// to the transaction. Since there is 1 transaction per block, the
// blocknumber is used as the key.
txMeta
:=
ReadTransactionMeta
(
db
,
*
blockNumber
)
if
txMeta
!=
nil
{
tx
.
SetTransactionMeta
(
txMeta
)
...
...
l2geth/core/state/statedb.go
View file @
0a99aaac
...
...
@@ -232,6 +232,11 @@ func (s *StateDB) GetBalance(addr common.Address) *big.Int {
return
common
.
Big0
}
// UsingOVM
// Read the account's balance from the state. This is used
// because ETH is an ERC20. This function specifically looks
// up the storage slot of the users balance. It is fragile to any
// changes in storage layout.
func
(
s
*
StateDB
)
GetOVMBalance
(
addr
common
.
Address
)
*
big
.
Int
{
eth
:=
common
.
HexToAddress
(
"0x4200000000000000000000000000000000000006"
)
position
:=
big
.
NewInt
(
0
)
...
...
l2geth/core/state_processor.go
View file @
0a99aaac
...
...
@@ -89,6 +89,10 @@ func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *commo
return
nil
,
err
}
}
else
{
// The transaction must be modified when running the OVM. The
// transaction fields that the user signs must be ABI encoded and then
// turned into the calldata of the transaction and the `to` field has to
// be updated to be the sequencer entrypoint.
decompressor
:=
config
.
StateDump
.
Accounts
[
"OVM_SequencerEntrypoint"
]
msg
,
err
=
AsOvmMessage
(
tx
,
types
.
MakeSigner
(
config
,
header
.
Number
),
decompressor
.
Address
,
header
.
GasLimit
)
if
err
!=
nil
{
...
...
@@ -98,6 +102,12 @@ func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *commo
// Create a new context to be used in the EVM environment
context
:=
NewEVMContext
(
msg
,
header
,
bc
,
author
)
if
vm
.
UsingOVM
{
// The `NUMBER` opcode returns the L1 blocknumber instead of the L2
// blocknumber, so set that here. In the future, this should be
// implemented by adding a new property to the EVM struct
// `L1BlockNumber` and updating `opNumber` to return that. This
// will help with keeping the difference in behavior maintainable over
// time
context
.
BlockNumber
=
msg
.
L1BlockNumber
()
}
// Create a new environment which holds all relevant information
...
...
l2geth/core/state_transition.go
View file @
0a99aaac
...
...
@@ -160,6 +160,10 @@ func (st *StateTransition) useGas(amount uint64) error {
func
(
st
*
StateTransition
)
buyGas
()
error
{
mgval
:=
new
(
big
.
Int
)
.
Mul
(
new
(
big
.
Int
)
.
SetUint64
(
st
.
msg
.
Gas
()),
st
.
gasPrice
)
// There is no native ETH, there is OVM_ETH which is an ERC20.
// Sufficient user balance is checked when the user sends the transaction
// via RPC through very similar checks as to when a transaction enters
// the layer one mempool. Deposits skip the check
if
!
vm
.
UsingOVM
{
if
st
.
state
.
GetBalance
(
st
.
msg
.
From
())
.
Cmp
(
mgval
)
<
0
{
return
errInsufficientBalanceForGas
...
...
@@ -171,6 +175,8 @@ func (st *StateTransition) buyGas() error {
st
.
gas
+=
st
.
msg
.
Gas
()
st
.
initialGas
=
st
.
msg
.
Gas
()
// Do not subtract the gas from the user balance when running OVM.
// This is handled in the Solidity contracts to enable to fraud proof
if
!
vm
.
UsingOVM
{
st
.
state
.
SubBalance
(
st
.
msg
.
From
(),
mgval
)
}
...
...
@@ -182,8 +188,10 @@ func (st *StateTransition) preCheck() error {
if
st
.
msg
.
CheckNonce
()
{
nonce
:=
st
.
state
.
GetNonce
(
st
.
msg
.
From
())
if
nonce
<
st
.
msg
.
Nonce
()
{
// Skip the nonce check for L1 to L2 transactions. They do not
// increment a nonce in the state and they also ecrecover to
// `address(0)`
if
vm
.
UsingOVM
{
// The nonce never increments for L1ToL2 txs
if
st
.
msg
.
QueueOrigin
()
==
types
.
QueueOriginL1ToL2
{
return
st
.
buyGas
()
}
...
...
@@ -205,7 +213,9 @@ func (st *StateTransition) TransitionDb() (ret []byte, usedGas uint64, failed bo
}
if
vm
.
UsingOVM
{
// OVM_ENABLED
// When the execution is not an `eth_call`, abi encode the user transaction
// and place it in the calldata of the msg struct so that the user
// transaction can be passed to the system contracts via the calldata
if
st
.
evm
.
EthCallSender
==
nil
{
st
.
msg
,
err
=
toExecutionManagerRun
(
st
.
evm
,
st
.
msg
)
}
...
...
@@ -221,8 +231,6 @@ func (st *StateTransition) TransitionDb() (ret []byte, usedGas uint64, failed bo
istanbul
:=
st
.
evm
.
ChainConfig
()
.
IsIstanbul
(
st
.
evm
.
BlockNumber
)
contractCreation
:=
msg
.
To
()
==
nil
// OVM_ADDITION
// TODO(mark): pay intrinsic gas function needs to be updated
gas
,
err
:=
IntrinsicGas
(
st
.
data
,
contractCreation
,
homestead
,
istanbul
)
if
err
!=
nil
{
return
nil
,
0
,
false
,
err
...
...
@@ -258,7 +266,8 @@ func (st *StateTransition) TransitionDb() (ret []byte, usedGas uint64, failed bo
}
else
{
// Increment the nonce for the next transaction
if
!
vm
.
UsingOVM
{
// OVM_DISABLED
// Do not set the nonce because that is handled in the Solidity
// contracts.
st
.
state
.
SetNonce
(
msg
.
From
(),
st
.
state
.
GetNonce
(
msg
.
From
())
+
1
)
}
...
...
@@ -273,13 +282,14 @@ func (st *StateTransition) TransitionDb() (ret []byte, usedGas uint64, failed bo
st
.
refundGas
()
if
!
vm
.
UsingOVM
{
//
OVM_DISABLED
//
Do not pay the gas to the coinbase address when running the OVM
st
.
state
.
AddBalance
(
evm
.
Coinbase
,
new
(
big
.
Int
)
.
Mul
(
new
(
big
.
Int
)
.
SetUint64
(
st
.
gasUsed
()),
st
.
gasPrice
))
}
return
ret
,
st
.
gasUsed
(),
vmerr
!=
nil
,
err
}
func
(
st
*
StateTransition
)
refundGas
()
{
// Do not refund any gas when running the OVM
if
vm
.
UsingOVM
{
return
}
...
...
l2geth/core/types/transaction.go
View file @
0a99aaac
...
...
@@ -403,44 +403,12 @@ func (s *TxByPrice) Pop() interface{} {
return
x
}
type
TxByIndexAndPrice
Transactions
func
(
s
TxByIndexAndPrice
)
Len
()
int
{
return
len
(
s
)
}
func
(
s
TxByIndexAndPrice
)
Less
(
i
,
j
int
)
bool
{
metai
,
metaj
:=
s
[
i
]
.
GetMeta
(),
s
[
j
]
.
GetMeta
()
// They should never be the same integer but they
// can both be nil. Sort by gasPrice in this case.
if
metai
.
Index
==
nil
&&
metaj
.
Index
==
nil
{
return
s
[
i
]
.
data
.
Price
.
Cmp
(
s
[
j
]
.
data
.
Price
)
>
0
}
// When the index is nil, it means that it is unknown. This
// indicates queue origin sequencer.
if
metai
.
Index
==
nil
&&
metaj
.
Index
!=
nil
{
return
false
}
if
metai
.
Index
!=
nil
&&
metaj
.
Index
==
nil
{
return
true
}
return
*
metai
.
Index
<
*
metaj
.
Index
}
func
(
s
TxByIndexAndPrice
)
Swap
(
i
,
j
int
)
{
s
[
i
],
s
[
j
]
=
s
[
j
],
s
[
i
]
}
func
(
s
*
TxByIndexAndPrice
)
Push
(
x
interface
{})
{
*
s
=
append
(
*
s
,
x
.
(
*
Transaction
))
}
func
(
s
*
TxByIndexAndPrice
)
Pop
()
interface
{}
{
old
:=
*
s
n
:=
len
(
old
)
x
:=
old
[
n
-
1
]
*
s
=
old
[
0
:
n
-
1
]
return
x
}
// TransactionsByPriceAndNonce represents a set of transactions that can return
// transactions in a profit-maximizing sorted order, while supporting removing
// entire batches of transactions for non-executable accounts.
type
TransactionsByPriceAndNonce
struct
{
txs
map
[
common
.
Address
]
Transactions
// Per account nonce-sorted list of transactions
heads
TxBy
IndexAndPrice
// Next transaction for each unique account (price heap)
heads
TxBy
Price
// Next transaction for each unique account (price heap)
signer
Signer
// Signer for the set of transactions
}
...
...
@@ -451,7 +419,7 @@ type TransactionsByPriceAndNonce struct {
// if after providing it to the constructor.
func
NewTransactionsByPriceAndNonce
(
signer
Signer
,
txs
map
[
common
.
Address
]
Transactions
)
*
TransactionsByPriceAndNonce
{
// Initialize a price based heap with the head transactions
heads
:=
make
(
TxBy
IndexAnd
Price
,
0
,
len
(
txs
))
heads
:=
make
(
TxByPrice
,
0
,
len
(
txs
))
for
from
,
accTxs
:=
range
txs
{
// This prevents a panic, not ideal.
if
len
(
accTxs
)
>
0
{
...
...
l2geth/internal/ethapi/api.go
View file @
0a99aaac
...
...
@@ -558,18 +558,6 @@ type StorageResult struct {
Proof
[]
string
`json:"proof"`
}
// Result structs for GetStateDiffProof
type
StateDiffProof
struct
{
Header
*
HeaderMeta
`json:"header"`
Accounts
[]
AccountResult
`json:"accounts"`
}
type
HeaderMeta
struct
{
Number
*
big
.
Int
`json:"number"`
Hash
common
.
Hash
`json:"hash"`
StateRoot
common
.
Hash
`json:"stateRoot"`
Timestamp
uint64
`json:"timestamp"`
}
// GetProof returns the Merkle-proof for a given account and optionally some storage keys.
func
(
s
*
PublicBlockChainAPI
)
GetProof
(
ctx
context
.
Context
,
address
common
.
Address
,
storageKeys
[]
string
,
blockNrOrHash
rpc
.
BlockNumberOrHash
)
(
*
AccountResult
,
error
)
{
state
,
_
,
err
:=
s
.
b
.
StateAndHeaderByNumberOrHash
(
ctx
,
blockNrOrHash
)
...
...
l2geth/les/api_backend.go
View file @
0a99aaac
...
...
@@ -205,10 +205,6 @@ func (b *LesApiBackend) SendTx(ctx context.Context, signedTx *types.Transaction)
return
b
.
eth
.
txPool
.
Add
(
ctx
,
signedTx
)
}
func
(
b
*
LesApiBackend
)
SetTimestamp
(
timestamp
int64
)
{
// Intentionally empty because this is not needed for LightChain
}
func
(
b
*
LesApiBackend
)
RemoveTx
(
txHash
common
.
Hash
)
{
b
.
eth
.
txPool
.
RemoveTx
(
txHash
)
}
...
...
l2geth/light/txpool.go
View file @
0a99aaac
...
...
@@ -446,25 +446,21 @@ func (pool *TxPool) Add(ctx context.Context, tx *types.Transaction) error {
return
nil
}
// Add
Batch
adds all valid transactions to the pool and passes them to
// Add
Transactions
adds all valid transactions to the pool and passes them to
// the tx relay backend
func
(
pool
*
TxPool
)
AddBatch
(
ctx
context
.
Context
,
txs
[]
*
types
.
Transaction
)
[]
error
{
func
(
pool
*
TxPool
)
AddBatch
(
ctx
context
.
Context
,
txs
[]
*
types
.
Transaction
)
{
pool
.
mu
.
Lock
()
defer
pool
.
mu
.
Unlock
()
var
sendTx
types
.
Transactions
errors
:=
make
([]
error
,
len
(
txs
))
for
i
,
tx
:=
range
txs
{
for
_
,
tx
:=
range
txs
{
if
err
:=
pool
.
add
(
ctx
,
tx
);
err
==
nil
{
sendTx
=
append
(
sendTx
,
tx
)
}
else
{
errors
[
i
]
=
err
}
}
if
len
(
sendTx
)
>
0
{
pool
.
relay
.
Send
(
sendTx
)
}
return
errors
}
// GetTransaction returns a transaction if it is contained in the pool
...
...
l2geth/miner/worker_test.go
View file @
0a99aaac
...
...
@@ -192,6 +192,7 @@ func newTestWorker(t *testing.T, chainConfig *params.ChainConfig, engine consens
}
func
TestGenerateBlockAndImportEthash
(
t
*
testing
.
T
)
{
t
.
Skip
(
"OVM"
)
testGenerateBlockAndImport
(
t
,
false
)
}
...
...
l2geth/trie/trie.go
View file @
0a99aaac
...
...
@@ -161,6 +161,8 @@ func (t *Trie) Update(key, value []byte) {
// stored in the trie.
//
// If a node was not found in the database, a MissingNodeError is returned.
// UsingOVM
// Do not delete empty nodes
func
(
t
*
Trie
)
TryUpdate
(
key
,
value
[]
byte
)
error
{
k
:=
keybytesToHex
(
key
)
_
,
n
,
err
:=
t
.
insert
(
t
.
root
,
nil
,
k
,
valueNode
(
value
))
...
...
packages/contracts/contracts/optimistic-ethereum/OVM/predeploys/OVM_L2ToL1MessagePasser.sol
View file @
0a99aaac
...
...
@@ -11,8 +11,8 @@ import { iOVM_L2ToL1MessagePasser } from "../../iOVM/predeploys/iOVM_L2ToL1Messa
* _verifyStorageProof function, which verifies the existence of the transaction hash in this
* contract's `sentMessages` mapping.
*
* Compiler used: solc
* Runtime target:
E
VM
* Compiler used:
optimistic-
solc
* Runtime target:
O
VM
*/
contract OVM_L2ToL1MessagePasser is iOVM_L2ToL1MessagePasser {
...
...
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