Commit 0a99aaac authored by Mark Tyneway's avatar Mark Tyneway Committed by GitHub

Merge pull request #1356 from ethereum-optimism/develop

merge develop into master
parents b9a47cbc 4425e9f5
---
'@eth-optimism/l2geth': patch
---
Reduce the geth diff
......@@ -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
......@@ -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]
......
......@@ -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 }
......
......@@ -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)
......
......@@ -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)
......
......@@ -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,
......
......@@ -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
......
......@@ -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
}
......
......@@ -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 {
......
......@@ -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")
......
......@@ -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
}
......@@ -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")
......
......@@ -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)
......
......@@ -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)
......
......@@ -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)
......
......@@ -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
......
......@@ -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
}
......
......@@ -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 TxByIndexAndPrice // Next transaction for each unique account (price heap)
heads TxByPrice // 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(TxByIndexAndPrice, 0, len(txs))
heads := make(TxByPrice, 0, len(txs))
for from, accTxs := range txs {
// This prevents a panic, not ideal.
if len(accTxs) > 0 {
......
......@@ -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)
......
......@@ -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)
}
......
......@@ -446,25 +446,21 @@ func (pool *TxPool) Add(ctx context.Context, tx *types.Transaction) error {
return nil
}
// AddBatch adds all valid transactions to the pool and passes them to
// AddTransactions 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
......
......@@ -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)
}
......
......@@ -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))
......
......@@ -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: EVM
* Compiler used: optimistic-solc
* Runtime target: OVM
*/
contract OVM_L2ToL1MessagePasser is iOVM_L2ToL1MessagePasser {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment