-
Notifications
You must be signed in to change notification settings - Fork 28
Conversation
core/state_transition.go
Outdated
return nil, 0, false, err | ||
} | ||
|
||
evm.Context.Origin = msg.From() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hopefully this will be made unnecessary by a change @K-Ho is making to the OVM_ExecutionManager
. Basically needed so I can get msg.sender == ovmStateManager.owner()
to return true.
core/state_transition.go
Outdated
} | ||
} else { | ||
// OVM_ENABLED | ||
st.buyGas() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the only part of the preCheck
that we actually care about.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is it safe to skip the nonce check?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It wasn't :-( I added the nonce check again.
if contractCreation { | ||
// Here we are going to call the EM directly |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All of this is now handled in toExecutionManagerRun
, so not needed here anymore.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
awesome refactor
|
||
// If the tx fails we won't have incremented the nonce. In this case, increment it manually | ||
log.Debug("Incrementing nonce due to transaction failure") | ||
st.state.SetNonce(msg.From(), st.state.GetNonce(sender.Address())+1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to figure out the best way to handle this nonce eviction thing. @karlfloersch should we just go ahead and update the eviction logic?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Once we've stabilized Synthetix running in Contracts v2, and have deployed Mintr to this Geth & have it work, that seems to me to be the next highest priority
log.Debug("return data", "data", hexutil.Encode(ret)) | ||
if !vm.UsingOVM { | ||
// OVM_DISABLED | ||
st.state.AddBalance(st.evm.Coinbase, new(big.Int).Mul(new(big.Int).SetUint64(st.gasUsed()), st.gasPrice)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No balances in the OVM.
} | ||
|
||
if caller.Address() == OvmExecutionManager.Address && | ||
!strings.HasPrefix(strings.ToLower(addr.Hex()), "0xdeaddeaddeaddeaddeaddeaddeaddeaddead") && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
0xdead
and 0x0000
addresses can't be the target.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why? What do these mean? Could we use a variable instead of hardcoded addrs?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
0xdead
addresses are used for all of the OVM contracts that run in L2 (so the execution manager, state manager, etc.) Users aren't allowed to call these addresses via ovmCALLs & similar opcodes. We could probably use a variable but we need to coordinate this variable across everything.
if !UsingOVM { | ||
// OVM_DISABLED | ||
// Fail if we're trying to transfer more than the available balance | ||
if !evm.Context.CanTransfer(evm.StateDB, caller.Address(), value) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Breaks things in the OVM (don't need it anyway).
core/vm/evm.go
Outdated
if UsingOVM { | ||
// OVM_ENABLED | ||
if isTarget { | ||
evm.OriginalTargetResult = ret[96:] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ignore the first 96 bytes (the return status and ABI encoding parameters).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there any chance len(ret) < 96
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes -- fixed to address this.
@@ -124,6 +124,8 @@ func NewEVMInterpreter(evm *EVM, cfg Config) *EVMInterpreter { | |||
} | |||
} | |||
|
|||
var returnDataCopy string |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the hack that bypasses an apparent bug
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Curious, what was the bug - also why do we need to do this manually? Isin.returnData
not always set correctly?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a pretty crazy bug 😮
Has to do with internal Geth memory management... we gotta look into it further
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@gakonst unclear what the bug is. It appears that some combination of RETURNDATACOPY
and other opcodes results in MSTORE
overwriting in.returnData
. Very strange.
@@ -806,7 +806,7 @@ func DoCall(ctx context.Context, b Backend, args CallArgs, blockNrOrHash rpc.Blo | |||
} | |||
} | |||
// Set default gas & gas price if none were set | |||
gas := uint64(math.MaxUint64 / 2) | |||
gas := uint64(10000000) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will break with max gas because EM asserts that gas is < maxGasPerQueuePerEpoch
(not sure what the right value is to put here -- block gas limit?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm using ExecutionManager.GetMaxTransactionGasLimit
var ZeroAddress = common.HexToAddress("0x0000000000000000000000000000000000000000") | ||
|
||
type ovmTransaction struct { | ||
Timestamp *big.Int "json:\"timestamp\"" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why the escaped "
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Took this from another part of geth where it used the escaped "
.
core/state_transition_ovm.go
Outdated
} | ||
|
||
// Signature type | ||
data.WriteByte(byte(sigtype)) // 1 byte: 00 == EOACreate, 01 == EIP 155, 02 == ETH Sign Message |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've played with a few different styles of serialization, using bytes.Buffer
, io.Writer
and []byte
. Curious if you have any preferences.
My favorite so far has been using []byte
directly, see
Line 382 in b2e6790
func (c *CTCTxEIP155) Encode(b []byte) error { |
} | ||
} | ||
|
||
func getQueueOrigin( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm sorry about this
@@ -69,6 +88,7 @@ func run(evm *EVM, contract *Contract, input []byte, readOnly bool) ([]byte, err | |||
return RunPrecompiledContract(p, input, contract) | |||
} | |||
} | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe no need to add extra whitelines for minimal diff?
|
||
OvmStateManager = OvmStateDump.Accounts["OVM_StateManager"] | ||
OvmExecutionManager = OvmStateDump.Accounts["OVM_ExecutionManager"] | ||
UsingOVM = os.Getenv("USING_OVM") == "true" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Noted that this will be added to deploy config
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Got part of the way through & will finish shortly but so far it's looking great!
|
||
// If the tx fails we won't have incremented the nonce. In this case, increment it manually | ||
log.Debug("Incrementing nonce due to transaction failure") | ||
st.state.SetNonce(msg.From(), st.state.GetNonce(sender.Address())+1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Once we've stabilized Synthetix running in Contracts v2, and have deployed Mintr to this Geth & have it work, that seems to me to be the next highest priority
@@ -326,6 +326,13 @@ func (tx *Transaction) AsMessage(s Signer) (Message, error) { | |||
|
|||
var err error | |||
msg.from, err = Sender(s, tx) | |||
|
|||
if tx.meta.L1MessageSender != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not entirely sure but I think it looks about right tbh.
Also, right here you should add:
if tx.meta.lastL1BlockNumber != nil {
msg.l1BlockNumber = tx.meta.lastL1BlockNumber
}
Oh though I forgot -- we have to rename txId
here - https://github.com/ethereum-optimism/go-ethereum/pull/67/files#diff-5500355cc4409489bee920d34f30a486e081409325cc12793ea7895fb64ac7daR605 to lastL1BlockNumber
func toExecutionManagerRun(evm *vm.EVM, msg Message) (Message, error) { | ||
tx := ovmTransaction{ | ||
evm.Context.Time, | ||
evm.Context.BlockNumber, // TODO (what's the correct block number?) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For an L1 to L2 transaction, is block.number supposed to be the L1 block number?
Yep
@karlfloersch @tynes what's the correct value for this?
Ah so we've got to set it in the same way you set the L1MessageSender from the meta. I wrote up how that works below
core/state_transition_ovm.go
Outdated
} | ||
|
||
v, r, s := tx.RawSignatureValues() | ||
v = big.NewInt(int64(v.Uint64() - 35 - 2*420)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
v = big.NewInt(int64(v.Uint64() - 35 - 2*420)) | |
v = big.NewInt(int64(v.Uint64() - 35 - 2* CHAIN_ID)) |
Could refactor this out to a CHAIN_ID constant, maybe also add a comment that this is EIP-155?
core/state_transition.go
Outdated
} | ||
} else { | ||
// OVM_ENABLED | ||
st.buyGas() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is it safe to skip the nonce check?
if contractCreation { | ||
// Here we are going to call the EM directly |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
awesome refactor
var isUnknown = true | ||
for name, account := range OvmStateDump.Accounts { | ||
if contract.Address() == account.Address { | ||
isUnknown = false | ||
abi := &(account.ABI) | ||
method, err := abi.MethodById(input) | ||
if err != nil { | ||
log.Debug("Calling Known Contract", "Name", name, "ERROR", err) | ||
} else { | ||
log.Debug("Calling Known Contract", "Name", name, "Method", method.RawName) | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OvmStateDump.Accounts
is already a map, can't you just do account, ok := OvmStateDumpAccounts[name]
?
// ovmADDRESS will be set by the execution manager to the target address whenever it's | ||
// about to create a new contract. This value is currently stored at the [15] storage slot. | ||
// Can pull this specific storage slot to get the address that the execution manager is | ||
// trying to create to, and create to it. | ||
slot := common.HexToHash(strconv.FormatInt(15, 16)) | ||
contractAddr = common.BytesToAddress(evm.StateDB.GetState(OvmExecutionManager.Address, slot).Bytes()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this referring to this? This is maybe a footgun in case the layout of the ExecutionManager changes, maybe consider adding a big big warning to this and the contracts?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, consider refactoring the else
branch to a helper function?
@@ -124,6 +124,8 @@ func NewEVMInterpreter(evm *EVM, cfg Config) *EVMInterpreter { | |||
} | |||
} | |||
|
|||
var returnDataCopy string |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Curious, what was the bug - also why do we need to do this manually? Isin.returnData
not always set correctly?
internal/ethapi/api.go
Outdated
@@ -859,7 +863,10 @@ func DoCall(ctx context.Context, b Backend, args CallArgs, blockNrOrHash rpc.Blo | |||
// Setup the gas pool (also for unmetered requests) | |||
// and apply the message. | |||
gp := new(core.GasPool).AddGas(math.MaxUint64) | |||
res, gas, failed, err := core.ApplyMessage(evm, msg, gp) | |||
log.Debug(">>>>>> Serving an eth_call <<<<<<", "From", addr.Hex(), "To", args.To.Hex()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
log.Debug(">>>>>> Serving an eth_call <<<<<<", "From", addr.Hex(), "To", args.To.Hex()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Definitely should remove this logline, there will be tons of these
internal/ethapi/api.go
Outdated
log.Debug(">>>>>> Serving an eth_call <<<<<<", "From", addr.Hex(), "To", args.To.Hex()) | ||
evm.Context.EthCallSender = &addr | ||
res, gas, failed, err := core.ApplyMessage(evm, outmsg, gp) | ||
log.Debug("<<<<<< Served an eth_call >>>>>>", "From", addr.Hex(), "To", args.To.Hex()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
log.Debug("<<<<<< Served an eth_call >>>>>>", "From", addr.Hex(), "To", args.To.Hex()) |
(just a reminder to remove once done debugging)
@@ -266,6 +356,65 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas | |||
contract.UseGas(contract.Gas) | |||
} | |||
} | |||
|
|||
if UsingOVM { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the rationale behind the whole isTarget/OriginalTarget logic? What can go wrong here?
…-ethereum into dev/contracts-v2-v2
…o dev/contracts-v2-v2
core/state_processor.go
Outdated
|
||
if vm.UsingOVM { | ||
// OVM_ENABLED | ||
log.Debug("<<<<<< Served an OVM transaction >>>>>>") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know if we need these loglines anymore, but it probably isn't a bad idea to log something along the lines of ovm enabled
once at startup if the env var that turns on ovm is set
core/state_processor.go
Outdated
if err != nil { | ||
return nil, err | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we need to add extra newlines as it just creates a bigger diff from upstream. Go code generally has less newlines between blocks of code compared to JS based on reading a bunch of Go codebases 🤷
|
||
func getQueueOrigin( | ||
queueOrigin *big.Int, | ||
) (types.QueueOrigin, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm confused about this because there should only be 2 queue origins?
ethereum-optimism/optimism#358 must be merged at the same time |
|
||
if len(address) == 0 { | ||
log.Warn("No TX_INGESTION_SIGNER_ADDRESS supplied. Using ZERO_ADDRESS default.") | ||
address = "0000000000000000000000000000000000000000" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This always breaks in this code path because address len is 40
* Works, but need to figure out this bug * Remove unnecessary log statements * Finalizing integration * Small code cleanups * Added a few more comments * Various bugfixes * Works, but need to figure out this bug * Remove unnecessary log statements * Finalizing integration * Small code cleanups * Added a few more comments * Various bugfixes * Added custom fillbytes function * Removed old test file for now * Fix linting errors * Fix linting errors * Reduce gas limit again * Various fixes! * Minor updates to get l1 ingestion address * Fix remaining bugs * Fix lint errors * Fix broken tests. WARN I skipped some * loglines: remove before deployment * core: less diff by removing newlines * core: less diff by removing newlines * rollup: remove logline in signtx * core/ovm: handle errors when type casting * ovm: log applying message Co-authored-by: Karl Floersch <karl@karlfloersch.com> Co-authored-by: Mark Tyneway <mark.tyneway@gmail.com>
* Works, but need to figure out this bug * Remove unnecessary log statements * Finalizing integration * Small code cleanups * Added a few more comments * Various bugfixes * Works, but need to figure out this bug * Remove unnecessary log statements * Finalizing integration * Small code cleanups * Added a few more comments * Various bugfixes * Added custom fillbytes function * Removed old test file for now * Fix linting errors * Fix linting errors * Reduce gas limit again * Various fixes! * Minor updates to get l1 ingestion address * Fix remaining bugs * Fix lint errors * Fix broken tests. WARN I skipped some * loglines: remove before deployment * core: less diff by removing newlines * core: less diff by removing newlines * rollup: remove logline in signtx * core/ovm: handle errors when type casting * ovm: log applying message Co-authored-by: Karl Floersch <karl@karlfloersch.com> Co-authored-by: Mark Tyneway <mark.tyneway@gmail.com>
Description
Lots of changes, but the primary ones are:
state_manager.go
with the new APIContributing Agreement