Skip to content

Commit

Permalink
Merge pull request ethereum#51 from OffchainLabs/arb1-transaction
Browse files Browse the repository at this point in the history
initial arb1 transaction type
  • Loading branch information
PlasmaPower authored Feb 8, 2022
2 parents 558ca7f + 8a0280e commit 3829645
Show file tree
Hide file tree
Showing 4 changed files with 155 additions and 3 deletions.
13 changes: 10 additions & 3 deletions core/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -324,15 +324,22 @@ func (g *Genesis) Commit(db ethdb.Database) (*types.Block, error) {
if config.Clique != nil && len(block.Extra()) == 0 {
return nil, errors.New("can't start clique chain without signers")
}
rawdb.WriteTd(db, block.Hash(), block.NumberU64(), block.Difficulty())
WriteHeadBlock(db, block, nil)
rawdb.WriteChainConfig(db, block.Hash(), config)
return block, nil
}

func WriteHeadBlock(db ethdb.Database, block *types.Block, prevDifficulty *big.Int) {
if prevDifficulty == nil {
prevDifficulty = common.Big0
}
rawdb.WriteTd(db, block.Hash(), block.NumberU64(), new(big.Int).Add(prevDifficulty, block.Difficulty()))
rawdb.WriteBlock(db, block)
rawdb.WriteReceipts(db, block.Hash(), block.NumberU64(), nil)
rawdb.WriteCanonicalHash(db, block.Hash(), block.NumberU64())
rawdb.WriteHeadBlockHash(db, block.Hash())
rawdb.WriteHeadFastBlockHash(db, block.Hash())
rawdb.WriteHeadHeaderHash(db, block.Hash())
rawdb.WriteChainConfig(db, block.Hash(), config)
return block, nil
}

// MustCommit writes the genesis block and state to db, panicking on error.
Expand Down
128 changes: 128 additions & 0 deletions core/types/arbitrum_legacy_tx.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
package types

import (
"math/big"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
)

// Data as received from Arb1 chain
type ArbitrumLegacyTransactionResult struct {
BlockHash *common.Hash `json:"blockHash"`
BlockNumber *hexutil.Big `json:"blockNumber"`
From common.Address `json:"from"`
Gas hexutil.Uint64 `json:"gas"`
GasPrice *hexutil.Big `json:"gasPrice"`
Hash common.Hash `json:"hash"`
Input hexutil.Bytes `json:"input"`
Nonce hexutil.Uint64 `json:"nonce"`
To *common.Address `json:"to"`
TransactionIndex *hexutil.Uint64 `json:"transactionIndex"`
Value *hexutil.Big `json:"value"`
V *hexutil.Big `json:"v"`
R *hexutil.Big `json:"r"`
S *hexutil.Big `json:"s"`

// Arbitrum Specific Fields
L1SeqNum *hexutil.Big `json:"l1SequenceNumber"`
ParentRequestId *common.Hash `json:"parentRequestId"`
IndexInParent *hexutil.Big `json:"indexInParent"`
ArbType hexutil.Uint64 `json:"arbType"`
ArbSubType *hexutil.Uint64 `json:"arbSubType"`
L1BlockNumber *hexutil.Big `json:"l1BlockNumber"`
}

type ArbitrumLegacyTxData struct {
Gas uint64
GasPrice *big.Int
Hash common.Hash // Hash cannot be locally computed from other fields
Data []byte
Nonce uint64
To *common.Address `rlp:"nil"` // nil means contract creation
Value *big.Int
V *big.Int
R *big.Int
S *big.Int
}

func (tx *ArbitrumLegacyTxData) copy() TxData {
cpy := &ArbitrumLegacyTxData{
Nonce: tx.Nonce,
To: copyAddressPtr(tx.To),
Data: common.CopyBytes(tx.Data),
Gas: tx.Gas,
Hash: tx.Hash,
// These are initialized below.
Value: new(big.Int),
GasPrice: new(big.Int),
V: new(big.Int),
R: new(big.Int),
S: new(big.Int),
}
if tx.Value != nil {
cpy.Value.Set(tx.Value)
}
if tx.GasPrice != nil {
cpy.GasPrice.Set(tx.GasPrice)
}
if tx.V != nil {
cpy.V.Set(tx.V)
}
if tx.R != nil {
cpy.R.Set(tx.R)
}
if tx.S != nil {
cpy.S.Set(tx.S)
}
return cpy
}

func ArbitrumLegacyFromTransactionResult(result ArbitrumLegacyTransactionResult) *Transaction {
gas := uint64(result.Gas)
nonce := uint64(result.Nonce)
gasPrice := (*big.Int)(result.GasPrice)
value := (*big.Int)(result.Value)
v := (*big.Int)(result.V)
r := (*big.Int)(result.R)
s := (*big.Int)(result.S)
hash := common.Hash(result.Hash)
to := copyAddressPtr(result.To)
var data []byte = result.Input
arblegacy := ArbitrumLegacyTxData{
Gas: gas,
GasPrice: gasPrice,
Hash: hash,
Data: data,
Nonce: nonce,
To: to,
Value: value,
V: v,
R: r,
S: s,
}
return NewTx(&arblegacy)
}

// accessors for innerTx.
func (tx *ArbitrumLegacyTxData) txType() byte { return ArbitrumLegacyTxType }
func (tx *ArbitrumLegacyTxData) chainID() *big.Int { return deriveChainId(tx.V) }
func (tx *ArbitrumLegacyTxData) accessList() AccessList { return nil }
func (tx *ArbitrumLegacyTxData) data() []byte { return tx.Data }
func (tx *ArbitrumLegacyTxData) gas() uint64 { return tx.Gas }
func (tx *ArbitrumLegacyTxData) gasPrice() *big.Int { return tx.GasPrice }
func (tx *ArbitrumLegacyTxData) gasTipCap() *big.Int { return tx.GasPrice }
func (tx *ArbitrumLegacyTxData) gasFeeCap() *big.Int { return tx.GasPrice }
func (tx *ArbitrumLegacyTxData) value() *big.Int { return tx.Value }
func (tx *ArbitrumLegacyTxData) nonce() uint64 { return tx.Nonce }
func (tx *ArbitrumLegacyTxData) to() *common.Address { return tx.To }

func (tx *ArbitrumLegacyTxData) isFake() bool { return false }

func (tx *ArbitrumLegacyTxData) rawSignatureValues() (v, r, s *big.Int) {
return tx.V, tx.R, tx.S
}

func (tx *ArbitrumLegacyTxData) setSignatureValues(chainID, v, r, s *big.Int) {
tx.V, tx.R, tx.S = v, r, s
}
7 changes: 7 additions & 0 deletions core/types/transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ const (
ArbitrumRetryTxType = 104
ArbitrumSubmitRetryableTxType = 105
ArbitrumInternalTxType = 106
ArbitrumLegacyTxType = 120
)

// Transaction is an Ethereum transaction.
Expand Down Expand Up @@ -227,6 +228,10 @@ func (tx *Transaction) decodeTyped(b []byte, arbParsing bool) (TxData, error) {
var inner DynamicFeeTx
err := rlp.DecodeBytes(b[1:], &inner)
return &inner, err
case ArbitrumLegacyTxType:
var inner ArbitrumLegacyTxData
err := rlp.DecodeBytes(b[1:], &inner)
return &inner, err
default:
return nil, ErrTxTypeNotSupported
}
Expand Down Expand Up @@ -423,6 +428,8 @@ func (tx *Transaction) Hash() common.Hash {
h = rlpHash(tx.inner)
} else if tx.Type() == ArbitrumSubmitRetryableTxType {
h = tx.inner.(*ArbitrumSubmitRetryableTx).RequestId // this is required by the retryables API
} else if tx.Type() == ArbitrumLegacyTxType {
h = tx.inner.(*ArbitrumLegacyTxData).Hash
} else {
h = prefixedRlpHash(tx.Type(), tx.inner)
}
Expand Down
10 changes: 10 additions & 0 deletions core/types/transaction_marshalling.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,16 @@ func (t *Transaction) MarshalJSON() ([]byte, error) {
enc.V = (*hexutil.Big)(tx.V)
enc.R = (*hexutil.Big)(tx.R)
enc.S = (*hexutil.Big)(tx.S)
case *ArbitrumLegacyTxData:
enc.Nonce = (*hexutil.Uint64)(&tx.Nonce)
enc.Gas = (*hexutil.Uint64)(&tx.Gas)
enc.GasPrice = (*hexutil.Big)(tx.GasPrice)
enc.Value = (*hexutil.Big)(tx.Value)
enc.Data = (*hexutil.Bytes)(&tx.Data)
enc.To = t.To()
enc.V = (*hexutil.Big)(tx.V)
enc.R = (*hexutil.Big)(tx.R)
enc.S = (*hexutil.Big)(tx.S)
}
return json.Marshal(&enc)
}
Expand Down

0 comments on commit 3829645

Please sign in to comment.