Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

wip: separate atomic tx handling #585

Draft
wants to merge 4 commits into
base: coreth-002-pathdb-mem
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions plugin/atx/codec.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package atx

import (
"github.com/ava-labs/avalanchego/codec"
"github.com/ava-labs/avalanchego/codec/linearcodec"
"github.com/ava-labs/avalanchego/utils/wrappers"
"github.com/ava-labs/avalanchego/vms/secp256k1fx"
)

// Codec does serialization and deserialization
var Codec codec.Manager

func init() {
Codec = codec.NewDefaultManager()

var (
lc = linearcodec.NewDefault()
errs = wrappers.Errs{}
)
errs.Add(
lc.RegisterType(&UnsignedImportTx{}),
lc.RegisterType(&UnsignedExportTx{}),
)
lc.SkipRegistrations(3)
errs.Add(
lc.RegisterType(&secp256k1fx.TransferInput{}),
lc.RegisterType(&secp256k1fx.MintOutput{}),
lc.RegisterType(&secp256k1fx.TransferOutput{}),
lc.RegisterType(&secp256k1fx.MintOperation{}),
lc.RegisterType(&secp256k1fx.Credential{}),
lc.RegisterType(&secp256k1fx.Input{}),
lc.RegisterType(&secp256k1fx.OutputOwners{}),
Codec.RegisterCodec(codecVersion, lc),
)
if errs.Errored() {
panic(errs.Err)
}
}
35 changes: 35 additions & 0 deletions plugin/atx/errors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package atx

import "errors"

var (
errEmptyBlock = errors.New("empty block")

Check failure on line 6 in plugin/atx/errors.go

View workflow job for this annotation

GitHub Actions / Lint

var `errEmptyBlock` is unused (unused)
errUnsupportedFXs = errors.New("unsupported feature extensions")

Check failure on line 7 in plugin/atx/errors.go

View workflow job for this annotation

GitHub Actions / Lint

var `errUnsupportedFXs` is unused (unused)
errInvalidBlock = errors.New("invalid block")

Check failure on line 8 in plugin/atx/errors.go

View workflow job for this annotation

GitHub Actions / Lint

var `errInvalidBlock` is unused (unused)
errInvalidAddr = errors.New("invalid hex address")

Check failure on line 9 in plugin/atx/errors.go

View workflow job for this annotation

GitHub Actions / Lint

var `errInvalidAddr` is unused (unused)
errInsufficientAtomicTxFee = errors.New("atomic tx fee too low for atomic mempool")

Check failure on line 10 in plugin/atx/errors.go

View workflow job for this annotation

GitHub Actions / Lint

var `errInsufficientAtomicTxFee` is unused (unused)
errAssetIDMismatch = errors.New("asset IDs in the input don't match the utxo")
errNoImportInputs = errors.New("tx has no imported inputs")
errInputsNotSortedUnique = errors.New("inputs not sorted and unique")
errPublicKeySignatureMismatch = errors.New("signature doesn't match public key")
errWrongChainID = errors.New("tx has wrong chain ID")
errInsufficientFunds = errors.New("insufficient funds")
errNoExportOutputs = errors.New("tx has no export outputs")
errOutputsNotSorted = errors.New("tx outputs not sorted")
errOutputsNotSortedUnique = errors.New("outputs not sorted and unique")
errOverflowExport = errors.New("overflow when computing export amount + txFee")
errInvalidNonce = errors.New("invalid nonce")
errConflictingAtomicInputs = errors.New("invalid block due to conflicting atomic inputs")
errUnclesUnsupported = errors.New("uncles unsupported")

Check failure on line 23 in plugin/atx/errors.go

View workflow job for this annotation

GitHub Actions / Lint

var `errUnclesUnsupported` is unused (unused)
errRejectedParent = errors.New("rejected parent")
errInsufficientFundsForFee = errors.New("insufficient AVAX funds to pay transaction fee")
errNoEVMOutputs = errors.New("tx has no EVM outputs")
errNilBaseFeeApricotPhase3 = errors.New("nil base fee is invalid after apricotPhase3")
errNilExtDataGasUsedApricotPhase4 = errors.New("nil extDataGasUsed is invalid after apricotPhase4")

Check failure on line 28 in plugin/atx/errors.go

View workflow job for this annotation

GitHub Actions / Lint

var `errNilExtDataGasUsedApricotPhase4` is unused (unused)
errNilBlockGasCostApricotPhase4 = errors.New("nil blockGasCost is invalid after apricotPhase4")

Check failure on line 29 in plugin/atx/errors.go

View workflow job for this annotation

GitHub Actions / Lint

var `errNilBlockGasCostApricotPhase4` is unused (unused)
errConflictingAtomicTx = errors.New("conflicting atomic tx present")

Check failure on line 30 in plugin/atx/errors.go

View workflow job for this annotation

GitHub Actions / Lint

var `errConflictingAtomicTx` is unused (unused)
errTooManyAtomicTx = errors.New("too many atomic tx")

Check failure on line 31 in plugin/atx/errors.go

View workflow job for this annotation

GitHub Actions / Lint

var `errTooManyAtomicTx` is unused (unused)
errMissingAtomicTxs = errors.New("cannot build a block with non-empty extra data and zero atomic transactions")
errInvalidHeaderPredicateResults = errors.New("invalid header predicate results")
ErrConflictingAtomicInputs = errConflictingAtomicInputs
)
8 changes: 4 additions & 4 deletions plugin/evm/export_tx.go → plugin/atx/export_tx.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.

package evm
package atx

import (
"context"
Expand Down Expand Up @@ -176,7 +176,7 @@ func (utx *UnsignedExportTx) Burned(assetID ids.ID) (uint64, error) {
func (utx *UnsignedExportTx) SemanticVerify(
vm *VM,
stx *Tx,
_ *Block,
_ ids.ID,
baseFee *big.Int,
rules params.Rules,
) error {
Expand Down Expand Up @@ -275,8 +275,8 @@ func (utx *UnsignedExportTx) AtomicOps() (ids.ID, *atomic.Requests, error) {
return utx.DestinationChain, &atomic.Requests{PutRequests: elems}, nil
}

// newExportTx returns a new ExportTx
func (vm *VM) newExportTx(
// NewExportTx returns a new ExportTx
func (vm *VM) NewExportTx(
assetID ids.ID, // AssetID of the tokens to export
amount uint64, // Amount of tokens to export
chainID ids.ID, // Chain to send the UTXOs to
Expand Down
17 changes: 17 additions & 0 deletions plugin/atx/formatting.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package atx

import (
"github.com/ava-labs/avalanchego/utils/crypto/secp256k1"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
)

// GetEthAddress returns the ethereum address derived from [privKey]
func GetEthAddress(privKey *secp256k1.PrivateKey) common.Address {
return PublicKeyToEthAddress(privKey.PublicKey())
}

// PublicKeyToEthAddress returns the ethereum address derived from [pubKey]
func PublicKeyToEthAddress(pubKey *secp256k1.PublicKey) common.Address {
return crypto.PubkeyToAddress(*(pubKey.ToECDSA()))
}
12 changes: 6 additions & 6 deletions plugin/evm/import_tx.go → plugin/atx/import_tx.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.

package evm
package atx

import (
"context"
Expand Down Expand Up @@ -177,7 +177,7 @@ func (utx *UnsignedImportTx) Burned(assetID ids.ID) (uint64, error) {
func (utx *UnsignedImportTx) SemanticVerify(
vm *VM,
stx *Tx,
parent *Block,
parent ids.ID,
baseFee *big.Int,
rules params.Rules,
) error {
Expand Down Expand Up @@ -273,8 +273,8 @@ func (utx *UnsignedImportTx) AtomicOps() (ids.ID, *atomic.Requests, error) {
return utx.SourceChain, &atomic.Requests{RemoveRequests: utxoIDs}, nil
}

// newImportTx returns a new ImportTx
func (vm *VM) newImportTx(
// NewImportTx returns a new ImportTx
func (vm *VM) NewImportTx(
chainID ids.ID, // chain to import from
to common.Address, // Address of recipient
baseFee *big.Int, // fee to use post-AP3
Expand All @@ -290,11 +290,11 @@ func (vm *VM) newImportTx(
return nil, fmt.Errorf("problem retrieving atomic UTXOs: %w", err)
}

return vm.newImportTxWithUTXOs(chainID, to, baseFee, kc, atomicUTXOs)
return vm.NewImportTxWithUTXOs(chainID, to, baseFee, kc, atomicUTXOs)
}

// newImportTx returns a new ImportTx
func (vm *VM) newImportTxWithUTXOs(
func (vm *VM) NewImportTxWithUTXOs(
chainID ids.ID, // chain to import from
to common.Address, // Address of recipient
baseFee *big.Int, // fee to use post-AP3
Expand Down
32 changes: 32 additions & 0 deletions plugin/atx/interfaces.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package atx

import (
"math/big"

"github.com/ava-labs/avalanchego/ids"
"github.com/ava-labs/avalanchego/snow/choices"
"github.com/ava-labs/coreth/core/types"
"github.com/ethereum/go-ethereum/common"
)

type StateDB interface {
SubBalance(common.Address, *big.Int)
AddBalance(common.Address, *big.Int)
GetBalance(common.Address) *big.Int

GetBalanceMultiCoin(common.Address, common.Hash) *big.Int
SubBalanceMultiCoin(common.Address, common.Hash, *big.Int)
AddBalanceMultiCoin(common.Address, common.Hash, *big.Int)

GetNonce(common.Address) uint64
SetNonce(common.Address, uint64)
}

type BlockChain interface {
State() (StateDB, error)
CurrentHeader() *types.Header
}

type BlockGetter interface {
GetBlockAndAtomicTxs(ids.ID) ([]*Tx, choices.Status, ids.ID, error)
}
2 changes: 1 addition & 1 deletion plugin/evm/metadata.go → plugin/atx/metadata.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.

package evm
package atx

import (
"github.com/ava-labs/avalanchego/ids"
Expand Down
6 changes: 4 additions & 2 deletions plugin/evm/tx.go → plugin/atx/tx.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.

package evm
package atx

import (
"bytes"
Expand Down Expand Up @@ -123,7 +123,7 @@ type UnsignedAtomicTx interface {
// Verify attempts to verify that the transaction is well formed
Verify(ctx *snow.Context, rules params.Rules) error
// Attempts to verify this transaction with the provided state.
SemanticVerify(vm *VM, stx *Tx, parent *Block, baseFee *big.Int, rules params.Rules) error
SemanticVerify(vm *VM, stx *Tx, parent ids.ID, baseFee *big.Int, rules params.Rules) error
// AtomicOps returns the blockchainID and set of atomic requests that
// must be applied to shared memory for this transaction to be accepted.
// The set of atomic requests must be returned in a consistent order.
Expand Down Expand Up @@ -287,3 +287,5 @@ func mergeAtomicOps(txs []*Tx) (map[ids.ID]*atomic.Requests, error) {
}
return output, nil
}

var MergeAtomicOps = mergeAtomicOps
Loading
Loading