Skip to content

Commit

Permalink
l1 meta: timestamp and blocknumber (ethereum#114)
Browse files Browse the repository at this point in the history
* l1 meta: timestamp and blocknumber

* internal: remove dead test

* api: return the last l1 timestamp

* tx: add l1 timestamp getter/setter

* ethapi: remove dead code

* sync service: handle timestamp setting

* miner: set timestamp right before execution

* syncservice: set timestamp correctly

* sync service: handle l1blocknumber

* test: test for correct timestamp

* tx: remove newline

* rollup api: add rollup_getLatestCrossDomainInfo

* timestamp: use max(5 mins ago, last l1 timestamp

* miner: properly set l1 timestamp

* miner: remove timestamp loop

* lint: fix

* api: fix spelling, return hex for consistency

* sync service: update the timestamp if too old

* rollup: clean up struct comment

* txmeta: fix comment

* txmeta: fix json struct tag

* timestamps: move closer to the source

* rollup: sequencer batch append bugfixes

* miner: clean up logic

* rollup: more determism

* miner: clean up

* verifier: use nil as l1txorigin

* rollup: simplify confirmation depth logic

* api: don't set the l1blocknumber or l1timestamp

* syncservice: clean up applylogs

* miner: hide functionality behind using_ovm

* rollup: add ethsign ctc parsing

* comments: clean up

* sync service:  clean up test

* sync service: initialize latest eth1 data

* sync service: protection for verifier

* rollup: safely set the timestamp, log if unexpected result

* api-backend: don't allow txs to 0 address
  • Loading branch information
tynes authored Nov 25, 2020
1 parent 931ec90 commit 08903b8
Show file tree
Hide file tree
Showing 14 changed files with 367 additions and 685 deletions.
29 changes: 13 additions & 16 deletions core/types/transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ package types
import (
"container/heap"
"errors"
"fmt"
"io"
"math/big"
"sync/atomic"
Expand Down Expand Up @@ -144,27 +143,25 @@ func (t *Transaction) SetIndex(index uint64) {
t.meta.Index = &index
}

// Appends the provided 64-bit nonce to this Transaction's calldata as the last 4 bytes
func (t *Transaction) AddNonceToWrappedTransaction(nonce uint64) {
bytes := make([]byte, 8)
for i := range bytes {
bytes[i] = 0xFF & byte(nonce>>(56-i))
func (t *Transaction) SetL1Timestamp(ts uint64) {
if &t.meta == nil {
return
}
t.data.Payload = append(t.data.Payload, bytes...)
t.meta.L1Timestamp = ts
}

// Parses the encoded nonce from this Transaction's calldata and returns it as well as the calldata without the encoded nonce.
func (t *Transaction) GetNonceAndCalldataFromWrappedTransaction() (uint64, []byte, error) {
if len(t.data.Payload) < 8 {
return 0, nil, fmt.Errorf("Cannot parse encoded nonce out of calldata of less than 8 bytes in length. Calldata: %x", t.data.Payload)
func (t *Transaction) L1Timestamp() uint64 {
if &t.meta == nil {
return 0
}
return t.meta.L1Timestamp
}

nonceBytes := t.data.Payload[len(t.data.Payload)-8:]
nonce := uint64(0)
for i := range nonceBytes {
nonce += uint64(nonceBytes[i] << (56 - i))
func (t *Transaction) SetL1BlockNumber(bn uint64) {
if &t.meta == nil {
return
}
return nonce, t.data.Payload[:len(t.data.Payload)-8], nil
t.meta.L1BlockNumber = new(big.Int).SetUint64(bn)
}

// ChainId returns which chain id this transaction was signed for (if at all)
Expand Down
20 changes: 17 additions & 3 deletions core/types/transaction_meta.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,18 @@ const (

type TransactionMeta struct {
L1BlockNumber *big.Int `json:"l1BlockNumber"`
L1Timestamp uint64 `json:"l1Timestamp"`
L1MessageSender *common.Address `json:"l1MessageSender" gencodec:"required"`
SignatureHashType SignatureHashType `json:"signatureHashType" gencodec:"required"`
QueueOrigin *big.Int `json:"queueOrigin" gencodec:"required"`
Index *uint64 `json:"index" gencodec:"required"`
}

// NewTransactionMeta creates a TransactionMeta
func NewTransactionMeta(l1BlockNumber *big.Int, l1MessageSender *common.Address, sighashType SignatureHashType, queueOrigin QueueOrigin) *TransactionMeta {
func NewTransactionMeta(l1BlockNumber *big.Int, l1timestamp uint64, l1MessageSender *common.Address, sighashType SignatureHashType, queueOrigin QueueOrigin) *TransactionMeta {
return &TransactionMeta{
L1BlockNumber: l1BlockNumber,
L1Timestamp: l1timestamp,
L1MessageSender: l1MessageSender,
SignatureHashType: sighashType,
QueueOrigin: big.NewInt(int64(queueOrigin)),
Expand All @@ -45,7 +47,8 @@ func NewTransactionMeta(l1BlockNumber *big.Int, l1MessageSender *common.Address,
// varbytes(SignatureHashType) ||
// varbytes(L1BlockNumber) ||
// varbytes(L1MessageSender) ||
// varbytes(QueueOrigin)
// varbytes(QueueOrigin) ||
// varbytes(L1Timestamp)
func TxMetaDecode(input []byte) (*TransactionMeta, error) {
var err error
meta := TransactionMeta{}
Expand All @@ -55,7 +58,6 @@ func TxMetaDecode(input []byte) (*TransactionMeta, error) {
if err != nil {
return nil, err
}

var sighashType SignatureHashType
binary.Read(bytes.NewReader(sb), binary.LittleEndian, &sighashType)
meta.SignatureHashType = sighashType
Expand Down Expand Up @@ -88,6 +90,14 @@ func TxMetaDecode(input []byte) (*TransactionMeta, error) {
meta.QueueOrigin = queueOrigin
}

l, err := common.ReadVarBytes(b, 0, 1024, "L1Timestamp")
if err != nil {
return nil, err
}
var l1Timestamp uint64
binary.Read(bytes.NewReader(l), binary.LittleEndian, &l1Timestamp)
meta.L1Timestamp = l1Timestamp

return &meta, nil
}

Expand Down Expand Up @@ -126,6 +136,10 @@ func TxMetaEncode(meta *TransactionMeta) []byte {
common.WriteVarBytes(b, 0, q.Bytes())
}

l := new(bytes.Buffer)
binary.Write(l, binary.LittleEndian, &meta.L1Timestamp)
common.WriteVarBytes(b, 0, l.Bytes())

return b.Bytes()
}

Expand Down
15 changes: 13 additions & 2 deletions core/types/transaction_meta_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,42 +15,49 @@ var (

txMetaSerializationTests = []struct {
l1BlockNumber *big.Int
l1Timestamp uint64
msgSender *common.Address
sighashType SignatureHashType
queueOrigin QueueOrigin
}{
{
l1BlockNumber: l1BlockNumber,
l1Timestamp: 100,
msgSender: &addr,
sighashType: SighashEthSign,
queueOrigin: QueueOriginL1ToL2,
},
{
l1BlockNumber: nil,
l1Timestamp: 45,
msgSender: &addr,
sighashType: SighashEthSign,
queueOrigin: QueueOriginL1ToL2,
},
{
l1BlockNumber: l1BlockNumber,
l1Timestamp: 0,
msgSender: nil,
sighashType: SighashEthSign,
queueOrigin: QueueOriginSequencer,
},
{
l1BlockNumber: l1BlockNumber,
l1Timestamp: 0,
msgSender: &addr,
sighashType: SighashEthSign,
queueOrigin: QueueOriginSequencer,
},
{
l1BlockNumber: nil,
l1Timestamp: 0,
msgSender: nil,
sighashType: SighashEthSign,
queueOrigin: QueueOriginL1ToL2,
},
{
l1BlockNumber: l1BlockNumber,
l1Timestamp: 0,
msgSender: &addr,
sighashType: SighashEthSign,
queueOrigin: QueueOriginL1ToL2,
Expand All @@ -74,7 +81,7 @@ var (

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

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

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

Expand All @@ -111,6 +118,10 @@ func isTxMetaEqual(meta1 *TransactionMeta, meta2 *TransactionMeta) bool {
return false
}

if meta1.L1Timestamp != meta2.L1Timestamp {
return false
}

if meta1.L1MessageSender == nil || meta2.L1MessageSender == nil {
if meta1.L1MessageSender != meta2.L1MessageSender {
return false
Expand Down
30 changes: 30 additions & 0 deletions eth/api_backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,11 @@
package eth

import (
"bytes"
"context"
"errors"
"math/big"
"os"

"github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/common"
Expand Down Expand Up @@ -76,6 +78,14 @@ func (b *EthAPIBackend) GetRollupContractAddresses() map[string]*common.Address
}
}

func (b *EthAPIBackend) GetLatestL1BlockNumber() uint64 {
return b.eth.syncService.GetLatestL1BlockNumber()
}

func (b *EthAPIBackend) GetLatestL1Timestamp() uint64 {
return b.eth.syncService.GetLatestL1Timestamp()
}

// ChainConfig returns the active chain configuration.
func (b *EthAPIBackend) ChainConfig() *params.ChainConfig {
return b.eth.blockchain.Config()
Expand Down Expand Up @@ -256,10 +266,30 @@ func (b *EthAPIBackend) SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscri
// Transactions originating from the RPC endpoints are added to remotes so that
// a lock can be used around the remotes for when the sequencer is reorganizing.
func (b *EthAPIBackend) SendTx(ctx context.Context, signedTx *types.Transaction) error {
if os.Getenv("USING_OVM") == "true" {
to := signedTx.To()
if to != nil && bytes.Equal(to.Bytes(), common.Address{}.Bytes()) {
return errors.New("Cannot send transaction to zero address")
}
}
return b.eth.txPool.AddRemote(signedTx)
}

func (b *EthAPIBackend) SendTxs(ctx context.Context, signedTxs []*types.Transaction) []error {
if os.Getenv("USING_OVM") == "true" {
errs := make([]error, len(signedTxs))
err := false
for i, tx := range signedTxs {
to := tx.To()
if to != nil && bytes.Equal(to.Bytes(), common.Address{}.Bytes()) {
err = true
errs[i] = errors.New("Cannot send transaction to zero address")
}
}
if err {
return errs
}
}
return b.eth.txPool.AddRemotes(signedTxs)
}

Expand Down
1 change: 1 addition & 0 deletions eth/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -509,6 +509,7 @@ func (s *Ethereum) Miner() *miner.Miner { return s.miner }
func (s *Ethereum) AccountManager() *accounts.Manager { return s.accountManager }
func (s *Ethereum) BlockChain() *core.BlockChain { return s.blockchain }
func (s *Ethereum) TxPool() *core.TxPool { return s.txPool }
func (s *Ethereum) SyncService() *rollup.SyncService { return s.syncService }
func (s *Ethereum) EventMux() *event.TypeMux { return s.eventMux }
func (s *Ethereum) Engine() consensus.Engine { return s.engine }
func (s *Ethereum) ChainDb() ethdb.Database { return s.chainDb }
Expand Down
Loading

0 comments on commit 08903b8

Please sign in to comment.