Skip to content
This repository was archived by the owner on Apr 11, 2021. It is now read-only.

feat: raw tx #255

Merged
merged 10 commits into from
Mar 9, 2021
Merged
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
4 changes: 2 additions & 2 deletions core/rawdb/accessors_chain_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -430,7 +430,7 @@ func TestBlockMetaStorage(t *testing.T) {

index1 := uint64(1)
tx1 := types.NewTransaction(1, common.HexToAddress("0x1"), big.NewInt(1), 1, big.NewInt(1), nil)
tx1Meta := types.NewTransactionMeta(nil, 0, nil, types.SighashEIP155, types.QueueOriginSequencer, &index1, nil)
tx1Meta := types.NewTransactionMeta(nil, 0, nil, types.SighashEIP155, types.QueueOriginSequencer, &index1, nil, nil)
tx1.SetTransactionMeta(tx1Meta)

WriteTransactionMeta(db, index1, tx1.GetMeta())
Expand Down Expand Up @@ -464,7 +464,7 @@ func TestBlockMetaStorage(t *testing.T) {

index2 := uint64(2)
tx2 := types.NewTransaction(2, common.HexToAddress("0x02"), big.NewInt(2), 2, big.NewInt(2), nil)
tx2Meta := types.NewTransactionMeta(l1BlockNumber, 0, &addr, types.SighashEthSign, types.QueueOriginSequencer, nil, nil)
tx2Meta := types.NewTransactionMeta(l1BlockNumber, 0, &addr, types.SighashEthSign, types.QueueOriginSequencer, nil, nil, nil)
tx2.SetTransactionMeta(tx2Meta)

WriteTransactionMeta(db, index2, tx2.GetMeta())
Expand Down
6 changes: 3 additions & 3 deletions core/rawdb/accessors_indexes_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,15 +73,15 @@ func TestLookupStorage(t *testing.T) {
l1BlockNumber2 := big.NewInt(2)

tx1 := types.NewTransaction(1, common.BytesToAddress([]byte{0x11}), big.NewInt(111), 1111, big.NewInt(11111), []byte{0x11, 0x11, 0x11})
tx1Meta := types.NewTransactionMeta(l1BlockNumber1, 0, &sender1, types.SighashEIP155, types.QueueOriginSequencer, nil, nil)
tx1Meta := types.NewTransactionMeta(l1BlockNumber1, 0, &sender1, types.SighashEIP155, types.QueueOriginSequencer, nil, nil, nil)
tx1.SetTransactionMeta(tx1Meta)

tx2 := types.NewTransaction(2, common.BytesToAddress([]byte{0x22}), big.NewInt(222), 2222, big.NewInt(22222), []byte{0x22, 0x22, 0x22})
tx2Meta := types.NewTransactionMeta(l1BlockNumber2, 0, &sender2, types.SighashEIP155, types.QueueOriginSequencer, nil, nil)
tx2Meta := types.NewTransactionMeta(l1BlockNumber2, 0, &sender2, types.SighashEIP155, types.QueueOriginSequencer, nil, nil, nil)
tx2.SetTransactionMeta(tx2Meta)

tx3 := types.NewTransaction(3, common.BytesToAddress([]byte{0x33}), big.NewInt(333), 3333, big.NewInt(33333), []byte{0x33, 0x33, 0x33})
tx3Meta := types.NewTransactionMeta(l1BlockNumber1, 0, nil, types.SighashEIP155, types.QueueOriginSequencer, nil, nil)
tx3Meta := types.NewTransactionMeta(l1BlockNumber1, 0, nil, types.SighashEIP155, types.QueueOriginSequencer, nil, nil, nil)
tx3.SetTransactionMeta(tx3Meta)

txs := []*types.Transaction{tx1, tx2, tx3}
Expand Down
72 changes: 1 addition & 71 deletions core/state_transition_ovm.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package core

import (
"bytes"
"fmt"
"math/big"

Expand Down Expand Up @@ -79,56 +78,13 @@ func AsOvmMessage(tx *types.Transaction, signer types.Signer, decompressor commo
return msg, nil
}

v, r, s := tx.RawSignatureValues()

// V parameter here will include the chain ID, so we need to recover the original V. If the V
// does not equal zero or one, we have an invalid parameter and need to throw an error.
// This is technically a duplicate check because it happens inside of
// `tx.AsMessage` as well.
v = new(big.Int).SetUint64(v.Uint64() - 35 - 2*tx.ChainId().Uint64())
if v.Uint64() != 0 && v.Uint64() != 1 {
index := tx.GetMeta().Index
if index == nil {
return msg, fmt.Errorf("invalid signature v parameter: %d", v.Uint64())
}
}

// Since we use a fixed encoding, we need to insert some placeholder address to represent that
// the user wants to create a contract (in this case, the zero address).
var target common.Address
if tx.To() == nil {
target = ZeroAddress
} else {
target = *tx.To()
}

// Divide the gas price by one million to compress it
// before it is send to the sequencer entrypoint. This is to save
// space on calldata.
gasPrice := new(big.Int).Div(msg.GasPrice(), new(big.Int).SetUint64(1000000))

// Sequencer uses a custom encoding structure --
// We originally receive sequencer transactions encoded in this way, but we decode them before
// inserting into Geth so we can make transactions easily parseable. However, this means that
// we need to re-encode the transactions before executing them.
var data = new(bytes.Buffer)
data.WriteByte(getSignatureType(msg)) // 1 byte: 00 == EIP 155, 02 == ETH Sign Message
data.Write(fillBytes(r, 32)) // 32 bytes: Signature `r` parameter
data.Write(fillBytes(s, 32)) // 32 bytes: Signature `s` parameter
data.Write(fillBytes(v, 1)) // 1 byte: Signature `v` parameter
data.Write(fillBytes(big.NewInt(int64(msg.Gas())), 3)) // 3 bytes: Gas limit
data.Write(fillBytes(gasPrice, 3)) // 3 bytes: Gas price
data.Write(fillBytes(big.NewInt(int64(msg.Nonce())), 3)) // 3 bytes: Nonce
data.Write(target.Bytes()) // 20 bytes: Target address
data.Write(msg.Data()) // ?? bytes: Transaction data

// Sequencer transactions get sent to the "sequencer entrypoint," a contract that decompresses
// the incoming transaction data.
outmsg, err := modMessage(
msg,
msg.From(),
&decompressor,
data.Bytes(),
tx.GetMeta().RawTransaction,
msg.Gas(),
)

Expand Down Expand Up @@ -201,18 +157,6 @@ func modMessage(
return outmsg, nil
}

func getSignatureType(
msg Message,
) uint8 {
if msg.SignatureHashType() == 0 {
return 0
} else if msg.SignatureHashType() == 1 {
return 2
} else {
return 1
}
}

func getQueueOrigin(
queueOrigin *big.Int,
) (types.QueueOrigin, error) {
Expand All @@ -226,17 +170,3 @@ func getQueueOrigin(
return types.QueueOriginSequencer, fmt.Errorf("invalid queue origin: %d", queueOrigin)
}
}

func fillBytes(x *big.Int, size int) []byte {
b := x.Bytes()
switch {
case len(b) > size:
panic("math/big: value won't fit requested size")
case len(b) == size:
return b
default:
buf := make([]byte, size)
copy(buf[size-len(b):], b)
return buf
}
}
2 changes: 1 addition & 1 deletion core/types/transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ func newTransaction(nonce uint64, to *common.Address, amount *big.Int, gasLimit
data = common.CopyBytes(data)
}

meta := NewTransactionMeta(nil, 0, nil, SighashEIP155, QueueOriginSequencer, nil, nil)
meta := NewTransactionMeta(nil, 0, nil, SighashEIP155, QueueOriginSequencer, nil, nil, nil)

d := txdata{
AccountNonce: nonce,
Expand Down
21 changes: 19 additions & 2 deletions core/types/transaction_meta.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,12 @@ type TransactionMeta struct {
// The canonical transaction chain index
Index *uint64 `json:"index" gencodec:"required"`
// The queue index, nil for queue origin sequencer transactions
QueueIndex *uint64 `json:"queueIndex" gencodec:"required"`
QueueIndex *uint64 `json:"queueIndex" gencodec:"required"`
RawTransaction []byte `json:"rawTransaction" gencodec:"required"`
}

// NewTransactionMeta creates a TransactionMeta
func NewTransactionMeta(l1BlockNumber *big.Int, l1timestamp uint64, l1MessageSender *common.Address, sighashType SignatureHashType, queueOrigin QueueOrigin, index *uint64, queueIndex *uint64) *TransactionMeta {
func NewTransactionMeta(l1BlockNumber *big.Int, l1timestamp uint64, l1MessageSender *common.Address, sighashType SignatureHashType, queueOrigin QueueOrigin, index *uint64, queueIndex *uint64, rawTransaction []byte) *TransactionMeta {
return &TransactionMeta{
L1BlockNumber: l1BlockNumber,
L1Timestamp: l1timestamp,
Expand All @@ -44,6 +45,7 @@ func NewTransactionMeta(l1BlockNumber *big.Int, l1timestamp uint64, l1MessageSen
QueueOrigin: big.NewInt(int64(queueOrigin)),
Index: index,
QueueIndex: queueIndex,
RawTransaction: rawTransaction,
}
}

Expand Down Expand Up @@ -121,6 +123,14 @@ func TxMetaDecode(input []byte) (*TransactionMeta, error) {
meta.QueueIndex = &queueIndex
}

raw, err := common.ReadVarBytes(b, 0, 130000, "RawTransaction")
if err != nil {
return nil, err
}
if !isNullValue(raw) {
meta.RawTransaction = raw
}

return &meta, nil
}

Expand Down Expand Up @@ -181,6 +191,13 @@ func TxMetaEncode(meta *TransactionMeta) []byte {
common.WriteVarBytes(b, 0, qi.Bytes())
}

rawTransaction := meta.RawTransaction
if rawTransaction == nil {
common.WriteVarBytes(b, 0, getNullValue())
} else {
common.WriteVarBytes(b, 0, rawTransaction)
}

return b.Bytes()
}

Expand Down
81 changes: 44 additions & 37 deletions core/types/transaction_meta_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,53 +14,60 @@ var (
l1BlockNumber = big.NewInt(0)

txMetaSerializationTests = []struct {
l1BlockNumber *big.Int
l1Timestamp uint64
msgSender *common.Address
sighashType SignatureHashType
queueOrigin QueueOrigin
l1BlockNumber *big.Int
l1Timestamp uint64
msgSender *common.Address
sighashType SignatureHashType
queueOrigin QueueOrigin
rawTransaction []byte
}{
{
l1BlockNumber: l1BlockNumber,
l1Timestamp: 100,
msgSender: &addr,
sighashType: SighashEthSign,
queueOrigin: QueueOriginL1ToL2,
l1BlockNumber: l1BlockNumber,
l1Timestamp: 100,
msgSender: &addr,
sighashType: SighashEthSign,
queueOrigin: QueueOriginL1ToL2,
rawTransaction: []byte{255, 255, 255, 255},
},
{
l1BlockNumber: nil,
l1Timestamp: 45,
msgSender: &addr,
sighashType: SighashEthSign,
queueOrigin: QueueOriginL1ToL2,
l1BlockNumber: nil,
l1Timestamp: 45,
msgSender: &addr,
sighashType: SighashEthSign,
queueOrigin: QueueOriginL1ToL2,
rawTransaction: []byte{42, 69, 42, 69},
},
{
l1BlockNumber: l1BlockNumber,
l1Timestamp: 0,
msgSender: nil,
sighashType: SighashEthSign,
queueOrigin: QueueOriginSequencer,
l1BlockNumber: l1BlockNumber,
l1Timestamp: 0,
msgSender: nil,
sighashType: SighashEthSign,
queueOrigin: QueueOriginSequencer,
rawTransaction: []byte{0, 0, 0, 0},
},
{
l1BlockNumber: l1BlockNumber,
l1Timestamp: 0,
msgSender: &addr,
sighashType: SighashEthSign,
queueOrigin: QueueOriginSequencer,
l1BlockNumber: l1BlockNumber,
l1Timestamp: 0,
msgSender: &addr,
sighashType: SighashEthSign,
queueOrigin: QueueOriginSequencer,
rawTransaction: []byte{0, 0, 0, 0},
},
{
l1BlockNumber: nil,
l1Timestamp: 0,
msgSender: nil,
sighashType: SighashEthSign,
queueOrigin: QueueOriginL1ToL2,
l1BlockNumber: nil,
l1Timestamp: 0,
msgSender: nil,
sighashType: SighashEthSign,
queueOrigin: QueueOriginL1ToL2,
rawTransaction: []byte{0, 0, 0, 0},
},
{
l1BlockNumber: l1BlockNumber,
l1Timestamp: 0,
msgSender: &addr,
sighashType: SighashEthSign,
queueOrigin: QueueOriginL1ToL2,
l1BlockNumber: l1BlockNumber,
l1Timestamp: 0,
msgSender: &addr,
sighashType: SighashEthSign,
queueOrigin: QueueOriginL1ToL2,
rawTransaction: []byte{0, 0, 0, 0},
},
}

Expand All @@ -81,7 +88,7 @@ var (

func TestTransactionMetaEncode(t *testing.T) {
for _, test := range txMetaSerializationTests {
txmeta := NewTransactionMeta(test.l1BlockNumber, test.l1Timestamp, test.msgSender, test.sighashType, test.queueOrigin, nil, nil)
txmeta := NewTransactionMeta(test.l1BlockNumber, test.l1Timestamp, test.msgSender, test.sighashType, test.queueOrigin, nil, nil, test.rawTransaction)

encoded := TxMetaEncode(txmeta)
decoded, err := TxMetaDecode(encoded)
Expand All @@ -98,7 +105,7 @@ func TestTransactionMetaEncode(t *testing.T) {

func TestTransactionSighashEncode(t *testing.T) {
for _, test := range txMetaSighashEncodeTests {
txmeta := NewTransactionMeta(l1BlockNumber, 0, &addr, test.input, QueueOriginSequencer, nil, nil)
txmeta := NewTransactionMeta(l1BlockNumber, 0, &addr, test.input, QueueOriginSequencer, nil, nil, nil)
encoded := TxMetaEncode(txmeta)
decoded, err := TxMetaDecode(encoded)

Expand Down
6 changes: 3 additions & 3 deletions core/types/transaction_signing_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ func TestOVMSigner(t *testing.T) {
key, _ := defaultTestKey()

tx := NewTransaction(0, common.Address{}, new(big.Int), 0, new(big.Int), nil)
txMeta := NewTransactionMeta(nil, 0, nil, SighashEthSign, QueueOriginSequencer, nil, nil)
txMeta := NewTransactionMeta(nil, 0, nil, SighashEthSign, QueueOriginSequencer, nil, nil, nil)
tx.SetTransactionMeta(txMeta)

var err error
Expand Down Expand Up @@ -175,7 +175,7 @@ func TestOVMSignerHash(t *testing.T) {

// The signature hash should be different when using `SighashEthSign`
txEthSign := NewTransaction(0, common.Address{}, new(big.Int), 0, new(big.Int), nil)
txMeta := NewTransactionMeta(nil, 0, nil, SighashEthSign, QueueOriginSequencer, nil, nil)
txMeta := NewTransactionMeta(nil, 0, nil, SighashEthSign, QueueOriginSequencer, nil, nil, nil)
txEthSign.SetTransactionMeta(txMeta)

hashEthSign := signer.Hash(txEthSign)
Expand Down Expand Up @@ -216,7 +216,7 @@ func TestOVMSignerSender(t *testing.T) {
// Create a transaction with EthSign signature hash, sign the transaction,
// recover the address and assert that the address matches the key.
txEthSign := NewTransaction(0, addr, new(big.Int), 0, new(big.Int), nil)
txMeta := NewTransactionMeta(nil, 0, nil, SighashEthSign, QueueOriginSequencer, nil, nil)
txMeta := NewTransactionMeta(nil, 0, nil, SighashEthSign, QueueOriginSequencer, nil, nil, nil)
txEthSign.SetTransactionMeta(txMeta)

txEthSign, err = SignTx(txEthSign, signer, key)
Expand Down
10 changes: 6 additions & 4 deletions internal/ethapi/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -1177,6 +1177,7 @@ type RPCTransaction struct {
L1Timestamp hexutil.Uint64 `json:"l1Timestamp"`
Index *hexutil.Uint64 `json:"index"`
QueueIndex *hexutil.Uint64 `json:"queueIndex"`
RawTransaction hexutil.Bytes `json:"rawTransaction"`
}

// newRPCTransaction returns a transaction that will serialize to the RPC
Expand Down Expand Up @@ -1210,6 +1211,7 @@ func newRPCTransaction(tx *types.Transaction, blockHash common.Hash, blockNumber
}

if meta := tx.GetMeta(); meta != nil {
result.RawTransaction = meta.RawTransaction
result.L1TxOrigin = meta.L1MessageSender
result.L1Timestamp = (hexutil.Uint64)(meta.L1Timestamp)
if meta.L1BlockNumber != nil {
Expand Down Expand Up @@ -1547,12 +1549,12 @@ func (args *SendTxArgs) toTransaction() *types.Transaction {
}
if args.To == nil {
tx := types.NewContractCreation(uint64(*args.Nonce), (*big.Int)(args.Value), uint64(*args.Gas), (*big.Int)(args.GasPrice), input)
txMeta := types.NewTransactionMeta(args.L1BlockNumber, 0, nil, types.SighashEIP155, types.QueueOriginSequencer, nil, nil)
txMeta := types.NewTransactionMeta(args.L1BlockNumber, 0, nil, types.SighashEIP155, types.QueueOriginSequencer, nil, nil, nil)
tx.SetTransactionMeta(txMeta)
return tx
}
tx := types.NewTransaction(uint64(*args.Nonce), *args.To, (*big.Int)(args.Value), uint64(*args.Gas), (*big.Int)(args.GasPrice), input)
txMeta := types.NewTransactionMeta(args.L1BlockNumber, 0, args.L1MessageSender, args.SignatureHashType, types.QueueOriginSequencer, nil, nil)
txMeta := types.NewTransactionMeta(args.L1BlockNumber, 0, args.L1MessageSender, args.SignatureHashType, types.QueueOriginSequencer, nil, nil, nil)
tx.SetTransactionMeta(txMeta)
return tx
}
Expand Down Expand Up @@ -1651,7 +1653,7 @@ func (s *PublicTransactionPoolAPI) SendRawTransaction(ctx context.Context, encod
return common.Hash{}, errors.New("Gas price must be a multiple of 1,000,000 wei")
}
// L1Timestamp and L1BlockNumber will be set by the miner
txMeta := types.NewTransactionMeta(nil, 0, nil, types.SighashEIP155, types.QueueOriginSequencer, nil, nil)
txMeta := types.NewTransactionMeta(nil, 0, nil, types.SighashEIP155, types.QueueOriginSequencer, nil, nil, nil)
tx.SetTransactionMeta(txMeta)
return SubmitTransaction(ctx, s.b, tx)
}
Expand All @@ -1678,7 +1680,7 @@ func (s *PublicTransactionPoolAPI) SendRawEthSignTransaction(ctx context.Context
return common.Hash{}, errors.New("Gas price must be a multiple of 1,000,000 wei")
}
// L1Timestamp and L1BlockNumber will be set by the miner
txMeta := types.NewTransactionMeta(nil, 0, nil, types.SighashEthSign, types.QueueOriginSequencer, nil, nil)
txMeta := types.NewTransactionMeta(nil, 0, nil, types.SighashEthSign, types.QueueOriginSequencer, nil, nil, nil)
tx.SetTransactionMeta(txMeta)
return SubmitTransaction(ctx, s.b, tx)
}
Expand Down
Loading