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

feat: implement handling and execution of oracle data #62

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
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
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,6 @@
[submodule "contracts/astria-bridge-contracts"]
path = contracts/astria-bridge-contracts
url = https://github.com/astriaorg/astria-bridge-contracts.git
[submodule "contracts/astria-oracle-contracts"]
path = contracts/astria-oracle-contracts
url = https://github.com/astriaorg/astria-oracle-contracts.git
1 change: 1 addition & 0 deletions contracts/astria-oracle-contracts
667 changes: 667 additions & 0 deletions contracts/astria_oracle.go

Large diffs are not rendered by default.

12 changes: 12 additions & 0 deletions contracts/generate-bindings-oracle.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
solc --optimize --optimize-runs=200 \
--metadata --metadata-literal \
--base-path "astria-oracle-contracts" \
--abi "astria-oracle-contracts/src/AstriaOracle.sol" \
-o abi/ --overwrite

solc --optimize --optimize-runs=200 \
--base-path "astria-oracle-contracts" \
--bin "astria-oracle-contracts/src/AstriaOracle.sol" \
-o bin/ --overwrite

abigen --abi abi/AstriaOracle.abi --bin bin/AstriaOracle.bin --pkg contracts --type AstriaOracle --out astria_oracle.go
34 changes: 17 additions & 17 deletions core/state_transition.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,9 @@ func (result *ExecutionResult) Revert() []byte {
}

// IntrinsicGas computes the 'intrinsic gas' for a message with the given data.
func IntrinsicGas(data []byte, accessList types.AccessList, isContractCreation bool, isHomestead, isEIP2028 bool, isEIP3860 bool, isDepositTx bool) (uint64, error) {
if isDepositTx {
// deposit txs are gasless
func IntrinsicGas(data []byte, accessList types.AccessList, isContractCreation bool, isHomestead, isEIP2028 bool, isEIP3860 bool, isInjectedTx bool) (uint64, error) {
if isInjectedTx {
// injected txs are gasless
return 0, nil
}

Expand Down Expand Up @@ -147,7 +147,7 @@ type Message struct {
AccessList types.AccessList
BlobGasFeeCap *big.Int
BlobHashes []common.Hash
IsDepositTx bool
IsInjectedTx bool

// When SkipAccountChecks is true, the message nonce is not checked against the
// account nonce in state. It also disables checking that the sender is an EOA.
Expand All @@ -157,7 +157,7 @@ type Message struct {

// TransactionToMessage converts a transaction into a Message.
func TransactionToMessage(tx *types.Transaction, s types.Signer, baseFee *big.Int) (*Message, error) {
isDepositTx := tx.Type() == types.DepositTxType
isInjectedTx := tx.Type() == types.InjectedTxType

msg := &Message{
Nonce: tx.Nonce(),
Expand All @@ -172,13 +172,13 @@ func TransactionToMessage(tx *types.Transaction, s types.Signer, baseFee *big.In
SkipAccountChecks: false,
BlobHashes: tx.BlobHashes(),
BlobGasFeeCap: tx.BlobGasFeeCap(),
IsDepositTx: isDepositTx,
IsInjectedTx: isInjectedTx,
}
// If baseFee provided, set gasPrice to effectiveGasPrice.
if baseFee != nil {
msg.GasPrice = cmath.BigMin(msg.GasPrice.Add(msg.GasTipCap, baseFee), msg.GasFeeCap)
}
if isDepositTx {
if isInjectedTx {
msg.From = tx.From()
return msg, nil
}
Expand Down Expand Up @@ -292,8 +292,8 @@ func (st *StateTransition) buyGas() error {
}

func (st *StateTransition) preCheck() error {
if st.msg.IsDepositTx {
// deposit txs do not require checks as they are part of rollup consensus,
if st.msg.IsInjectedTx {
// injected txs do not require checks as they are part of rollup consensus,
// not txs that originate externally.
return nil
}
Expand Down Expand Up @@ -391,18 +391,18 @@ func (st *StateTransition) preCheck() error {
// However if any consensus issue encountered, return the error directly with
// nil evm execution result.
func (st *StateTransition) TransitionDb() (*ExecutionResult, error) {
// if this is a deposit tx, we only need to mint funds and no gas is used.
if st.msg.IsDepositTx && len(st.msg.Data) == 0 {
// if this is a injected tx, we only need to mint funds and no gas is used.
if st.msg.IsInjectedTx && len(st.msg.Data) == 0 {
log.Debug("deposit tx minting funds", "to", *st.msg.To, "value", st.msg.Value)
st.state.AddBalance(*st.msg.To, uint256.MustFromBig(st.msg.Value), tracing.BalanceIncreaseAstriaDepositTx)
st.state.AddBalance(*st.msg.To, uint256.MustFromBig(st.msg.Value), tracing.BalanceIncreaseAstriaInjectedTx)
return &ExecutionResult{
UsedGas: 0,
Err: nil,
ReturnData: nil,
}, nil
}

if st.msg.IsDepositTx {
if st.msg.IsInjectedTx {
st.initialGas = st.msg.GasLimit
st.gasRemaining = st.msg.GasLimit
log.Debug("deposit tx minting erc20", "to", *st.msg.To, "value", st.msg.Value)
Expand Down Expand Up @@ -431,7 +431,7 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) {
)

// Check clauses 4-5, subtract intrinsic gas if everything is correct
gas, err := IntrinsicGas(msg.Data, msg.AccessList, contractCreation, rules.IsHomestead, rules.IsIstanbul, rules.IsShanghai, msg.IsDepositTx)
gas, err := IntrinsicGas(msg.Data, msg.AccessList, contractCreation, rules.IsHomestead, rules.IsIstanbul, rules.IsShanghai, msg.IsInjectedTx)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -474,10 +474,10 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) {
ret, st.gasRemaining, vmerr = st.evm.Call(sender, st.to(), msg.Data, st.gasRemaining, value)
}

// if this is a deposit tx, don't refund gas and also don't pay to the coinbase,
// if this is a injected tx, don't refund gas and also don't pay to the coinbase,
// as no gas was used.
if st.msg.IsDepositTx {
log.Debug("deposit tx executed", "to", *st.msg.To, "value", st.msg.Value, "from", st.msg.From, "gasUsed", st.gasUsed(), "err", vmerr)
if st.msg.IsInjectedTx {
log.Debug("injected tx executed", "to", *st.msg.To, "value", st.msg.Value, "from", st.msg.From, "gasUsed", st.gasUsed(), "err", vmerr)
return &ExecutionResult{
UsedGas: st.gasUsed(),
Err: vmerr,
Expand Down
5 changes: 3 additions & 2 deletions core/tracing/hooks.go
Original file line number Diff line number Diff line change
Expand Up @@ -243,8 +243,9 @@ const (
// Note it doesn't account for a self-destruct which appoints itself as recipient.
BalanceDecreaseSelfdestructBurn BalanceChangeReason = 14

// BalanceIncreaseAstriaDepositTx is ether deposited to the user via an
BalanceIncreaseAstriaDepositTx BalanceChangeReason = 15
// BalanceIncreaseAstriaInjectedTx is ether deposited to the user via an injected transaction
// originating from a sequencer deposit.
BalanceIncreaseAstriaInjectedTx BalanceChangeReason = 15
)

// GasChangeReason is used to indicate the reason for a gas change, useful
Expand Down
2 changes: 1 addition & 1 deletion core/txpool/legacypool/legacypool.go
Original file line number Diff line number Diff line change
Expand Up @@ -699,7 +699,7 @@ func (pool *LegacyPool) validateTxBasics(tx *types.Transaction, local bool) erro
1<<types.LegacyTxType |
1<<types.AccessListTxType |
1<<types.DynamicFeeTxType |
1<<types.DepositTxType,
1<<types.InjectedTxType,
MaxSize: txMaxSize,
MinTip: pool.gasTip.Load().ToBig(),
}
Expand Down
2 changes: 1 addition & 1 deletion core/txpool/validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ func ValidateTransaction(tx *types.Transaction, head *types.Header, signer types
if tx.GasFeeCapIntCmp(tx.GasTipCap()) < 0 {
return core.ErrTipAboveFeeCap
}
if tx.Type() != types.DepositTxType {
if tx.Type() != types.InjectedTxType {
// Make sure the transaction is signed properly
if _, err := types.Sender(signer, tx); err != nil {
return ErrInvalidSender
Expand Down
67 changes: 35 additions & 32 deletions core/types/deposit_tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,47 +4,50 @@ import (
"bytes"
"math/big"

primitivev1 "buf.build/gen/go/astria/primitives/protocolbuffers/go/astria/primitive/v1"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/rlp"
primitivev1 "buf.build/gen/go/astria/primitives/protocolbuffers/go/astria/primitive/v1"
)

var _ TxData = &DepositTx{}
var _ TxData = &InjectedTx{}

type DepositTx struct {
// the bridge sender address set in the genesis file
// ie. the minter or the caller of the ERC20 contract
type InjectedTx struct {
// the caller address set in the genesis file (either bridge or oracle)
// ie. the minter or the caller of the ERC20/oracle contract
From common.Address
// value to be minted to the recipient, if this is a native asset mint
Value *big.Int
// gas limit
Gas uint64
// if this is a native asset mint, this is set to the mint recipient
// if this is an ERC20 mint, this is set to the ERC20 contract address
// if this is an oracle update, this is set to the oracle contract address
To *common.Address
// if this is an ERC20 mint, the following field is set
// to the `mint` function calldata.
// if this is an oracle update, the following field is set to the
// `initializeCurrencyPair` or `updatePriceData` function calldata.
Data []byte
// the transaction ID of the source action for the deposit, consisting
// of the transaction hash.
// the transaction ID of the source action on the sequencer, consisting
// of the transaction hash.
SourceTransactionId primitivev1.TransactionId
// index of the deposit's source action within its transaction
// index of the source action within its sequencer transaction
SourceTransactionIndex uint64
}

func (tx *DepositTx) copy() TxData {
func (tx *InjectedTx) copy() TxData {
to := new(common.Address)
if tx.To != nil {
*to = *tx.To
}

cpy := &DepositTx{
From: tx.From,
Value: new(big.Int),
Gas: tx.Gas,
To: to,
Data: make([]byte, len(tx.Data)),
SourceTransactionId: tx.SourceTransactionId,
cpy := &InjectedTx{
From: tx.From,
Value: new(big.Int),
Gas: tx.Gas,
To: to,
Data: make([]byte, len(tx.Data)),
SourceTransactionId: tx.SourceTransactionId,
SourceTransactionIndex: tx.SourceTransactionIndex,
}

Expand All @@ -55,34 +58,34 @@ func (tx *DepositTx) copy() TxData {
return cpy
}

func (tx *DepositTx) txType() byte { return DepositTxType }
func (tx *DepositTx) chainID() *big.Int { return common.Big0 }
func (tx *DepositTx) accessList() AccessList { return nil }
func (tx *DepositTx) data() []byte { return tx.Data }
func (tx *DepositTx) gas() uint64 { return tx.Gas }
func (tx *DepositTx) gasFeeCap() *big.Int { return new(big.Int) }
func (tx *DepositTx) gasTipCap() *big.Int { return new(big.Int) }
func (tx *DepositTx) gasPrice() *big.Int { return new(big.Int) }
func (tx *DepositTx) value() *big.Int { return tx.Value }
func (tx *DepositTx) nonce() uint64 { return 0 }
func (tx *DepositTx) to() *common.Address { return tx.To }
func (tx *InjectedTx) txType() byte { return InjectedTxType }
func (tx *InjectedTx) chainID() *big.Int { return common.Big0 }
func (tx *InjectedTx) accessList() AccessList { return nil }
func (tx *InjectedTx) data() []byte { return tx.Data }
func (tx *InjectedTx) gas() uint64 { return tx.Gas }
func (tx *InjectedTx) gasFeeCap() *big.Int { return new(big.Int) }
func (tx *InjectedTx) gasTipCap() *big.Int { return new(big.Int) }
func (tx *InjectedTx) gasPrice() *big.Int { return new(big.Int) }
func (tx *InjectedTx) value() *big.Int { return tx.Value }
func (tx *InjectedTx) nonce() uint64 { return 0 }
func (tx *InjectedTx) to() *common.Address { return tx.To }

func (tx *DepositTx) effectiveGasPrice(dst *big.Int, baseFee *big.Int) *big.Int {
func (tx *InjectedTx) effectiveGasPrice(dst *big.Int, baseFee *big.Int) *big.Int {
return dst.Set(new(big.Int))
}

func (tx *DepositTx) rawSignatureValues() (v, r, s *big.Int) {
func (tx *InjectedTx) rawSignatureValues() (v, r, s *big.Int) {
return common.Big0, common.Big0, common.Big0
}

func (tx *DepositTx) setSignatureValues(chainID, v, r, s *big.Int) {
func (tx *InjectedTx) setSignatureValues(chainID, v, r, s *big.Int) {
// noop
}

func (tx *DepositTx) encode(b *bytes.Buffer) error {
func (tx *InjectedTx) encode(b *bytes.Buffer) error {
return rlp.Encode(b, tx)
}

func (tx *DepositTx) decode(input []byte) error {
func (tx *InjectedTx) decode(input []byte) error {
return rlp.DecodeBytes(input, tx)
}
2 changes: 1 addition & 1 deletion core/types/receipt.go
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ func (r *Receipt) decodeTyped(b []byte) error {
return errShortTypedReceipt
}
switch b[0] {
case DynamicFeeTxType, AccessListTxType, BlobTxType, DepositTxType:
case DynamicFeeTxType, AccessListTxType, BlobTxType, InjectedTxType:
var data receiptRLP
err := rlp.DecodeBytes(b[1:], &data)
if err != nil {
Expand Down
16 changes: 8 additions & 8 deletions core/types/transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ const (
AccessListTxType = 0x01
DynamicFeeTxType = 0x02
BlobTxType = 0x03
DepositTxType = 0x04
InjectedTxType = 0x04
)

// Transaction is an Ethereum transaction.
Expand All @@ -72,7 +72,7 @@ func NewTx(inner TxData) *Transaction {

// TxData is the underlying data of a transaction.
//
// This is implemented by DynamicFeeTx, LegacyTx, AccessListTx and DepositTx.
// This is implemented by DynamicFeeTx, LegacyTx, AccessListTx and InjectedTx.
type TxData interface {
txType() byte // returns the type ID
copy() TxData // creates a deep copy and initializes all fields
Expand Down Expand Up @@ -104,14 +104,14 @@ type TxData interface {
}

// From returns the sender of the transaction
// only for deposit transactions.
// only for injected transactions.
func (tx *Transaction) From() common.Address {
if tx.Type() != DepositTxType {
if tx.Type() != InjectedTxType {
return common.Address{}
}

deposit := tx.inner.(*DepositTx)
return deposit.From
injected := tx.inner.(*InjectedTx)
return injected.From
}

// EncodeRLP implements rlp.Encoder
Expand Down Expand Up @@ -218,8 +218,8 @@ func (tx *Transaction) decodeTyped(b []byte) (TxData, error) {
inner = new(DynamicFeeTx)
case BlobTxType:
inner = new(BlobTx)
case DepositTxType:
inner = new(DepositTx)
case InjectedTxType:
inner = new(InjectedTx)
default:
return nil, ErrTxTypeNotSupported
}
Expand Down
7 changes: 4 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ go 1.21
require (
buf.build/gen/go/astria/execution-apis/grpc/go v1.5.1-20241017141511-7e4bcc0ebba5.1
buf.build/gen/go/astria/execution-apis/protocolbuffers/go v1.35.1-20241017141511-7e4bcc0ebba5.1
buf.build/gen/go/astria/primitives/protocolbuffers/go v1.35.1-20240911152449-eeebd3decdce.1
buf.build/gen/go/astria/sequencerblock-apis/protocolbuffers/go v1.35.1-20241017141511-71aab1871615.1
buf.build/gen/go/astria/primitives/protocolbuffers/go v1.35.2-00000000000000-3bfd63a8e304.1
buf.build/gen/go/astria/sequencerblock-apis/protocolbuffers/go v1.35.2-00000000000000-0afe5f04c432.1
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.2.0
github.com/Microsoft/go-winio v0.6.1
github.com/VictoriaMetrics/fastcache v1.12.1
Expand Down Expand Up @@ -79,12 +79,13 @@ require (
golang.org/x/time v0.5.0
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d
google.golang.org/grpc v1.64.1
google.golang.org/protobuf v1.35.1
google.golang.org/protobuf v1.35.2
gopkg.in/natefinch/lumberjack.v2 v2.0.0
gopkg.in/yaml.v3 v3.0.1
)

require (
buf.build/gen/go/astria/vendored/protocolbuffers/go v1.35.2-00000000000000-af6d4456b07b.1 // indirect
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.7.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0 // indirect
github.com/DataDog/zstd v1.4.5 // indirect
Expand Down
14 changes: 8 additions & 6 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ buf.build/gen/go/astria/execution-apis/grpc/go v1.5.1-20241017141511-7e4bcc0ebba
buf.build/gen/go/astria/execution-apis/grpc/go v1.5.1-20241017141511-7e4bcc0ebba5.1/go.mod h1:T5EsLvEE5UMk62gVSwNY/7XlxknAP3sL8tYRsU68b4s=
buf.build/gen/go/astria/execution-apis/protocolbuffers/go v1.35.1-20241017141511-7e4bcc0ebba5.1 h1:3G2O21DuY5Y/G32tP1mAI16AxwDYTscG2YaOb/WQty0=
buf.build/gen/go/astria/execution-apis/protocolbuffers/go v1.35.1-20241017141511-7e4bcc0ebba5.1/go.mod h1:U4LUlabiYNYBd1pqYS9o8SsHjBRoEBysrfRVnebzJH0=
buf.build/gen/go/astria/primitives/protocolbuffers/go v1.35.1-20240911152449-eeebd3decdce.1 h1:kG4riHqlF9X6iZ1Oxs5/6ul6aue7MS+A6DK6HAchuTk=
buf.build/gen/go/astria/primitives/protocolbuffers/go v1.35.1-20240911152449-eeebd3decdce.1/go.mod h1:n9L7X3VAj4od4VHf2ScJuHARUUQTSxJqtRHZk/7Ptt0=
buf.build/gen/go/astria/sequencerblock-apis/protocolbuffers/go v1.35.1-20241017141511-71aab1871615.1 h1:hPMoxTiT7jJjnIbWqneBbL05VeVOTD9UeC/qdvzHL8g=
buf.build/gen/go/astria/sequencerblock-apis/protocolbuffers/go v1.35.1-20241017141511-71aab1871615.1/go.mod h1:2uasRFMH+a3DaF34c1o+w7/YtYnoknmARyYpb9W2QIc=
buf.build/gen/go/astria/primitives/protocolbuffers/go v1.35.2-00000000000000-3bfd63a8e304.1 h1:E1Y+/mSS0HUOJzvgIosnILMJIN5XLQ/tZCnYA9HxNHw=
buf.build/gen/go/astria/primitives/protocolbuffers/go v1.35.2-00000000000000-3bfd63a8e304.1/go.mod h1:I9FcB1oNqT1nI+ny0GD8gF9YrIYrHmczgNu6MTE9fAo=
buf.build/gen/go/astria/sequencerblock-apis/protocolbuffers/go v1.35.2-00000000000000-0afe5f04c432.1 h1:qY1mMo1UCSZLB0kCRLMAppqG81i7ynnBAtWN/uSqNJs=
buf.build/gen/go/astria/sequencerblock-apis/protocolbuffers/go v1.35.2-00000000000000-0afe5f04c432.1/go.mod h1:pWhIvNCTAQCnfu7yiguleI6AApVskVRb8zMqAzbXmyk=
buf.build/gen/go/astria/vendored/protocolbuffers/go v1.35.2-00000000000000-af6d4456b07b.1 h1:u9CKtSqLe8Xhl1oteTmpPN+/tjdoRglIJx2xizAoU5Y=
buf.build/gen/go/astria/vendored/protocolbuffers/go v1.35.2-00000000000000-af6d4456b07b.1/go.mod h1:SrweGbOriTsmWXpeqXdbqCwAs+mohaV0SGtjRjq7mHk=
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
Expand Down Expand Up @@ -895,8 +897,8 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA=
google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
google.golang.org/protobuf v1.35.2 h1:8Ar7bF+apOIoThw1EdZl0p1oWvMqTHmpA2fRTyZO8io=
google.golang.org/protobuf v1.35.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
Expand Down
Loading
Loading