Skip to content

Commit

Permalink
add Sequencer number field , plus some renaming (#1347)
Browse files Browse the repository at this point in the history
* add Sequencer number field , plus some renaming

* fix bug

* fix test
  • Loading branch information
tudor-malene authored Jun 22, 2023
1 parent e49bd32 commit 473b109
Show file tree
Hide file tree
Showing 26 changed files with 322 additions and 263 deletions.
21 changes: 11 additions & 10 deletions go/common/headers.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,17 @@ var hasherPool = sync.Pool{
// BatchHeader is a public / plaintext struct that holds common properties of batches.
// Making changes to this struct will require GRPC + GRPC Converters regen
type BatchHeader struct {
ParentHash L2BatchHash
Root StateRoot `json:"stateRoot"`
TxHash common.Hash `json:"transactionsRoot"` // todo (#1545) - include the synthetic deposits
ReceiptHash common.Hash `json:"receiptsRoot"`
Number *big.Int
GasLimit uint64
GasUsed uint64
Time uint64 `json:"timestamp"`
Extra []byte `json:"extraData"`
BaseFee *big.Int
ParentHash L2BatchHash
Root StateRoot `json:"stateRoot"`
TxHash common.Hash `json:"transactionsRoot"` // todo (#1545) - include the synthetic deposits
ReceiptHash common.Hash `json:"receiptsRoot"`
Number *big.Int // height of the batch
SequencerOrderNo *big.Int // multiple batches can be created with the same height in case of L1 reorgs. The sequencer is responsible for including all of them in the rollups.
GasLimit uint64
GasUsed uint64
Time uint64 `json:"timestamp"`
Extra []byte `json:"extraData"`
BaseFee *big.Int

// The custom Obscuro fields.
L1Proof L1BlockHash // the L1 block used by the enclave to generate the current batch
Expand Down
2 changes: 2 additions & 0 deletions go/common/rpc/converters.go
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ func ToBatchHeaderMsg(header *common.BatchHeader) *generated.BatchHeaderMsg {
Root: header.Root.Bytes(),
TxHash: header.TxHash.Bytes(),
Number: header.Number.Uint64(),
SequencerOrderNo: header.SequencerOrderNo.Uint64(),
ReceiptHash: header.ReceiptHash.Bytes(),
Extra: header.Extra,
R: header.R.Bytes(),
Expand Down Expand Up @@ -223,6 +224,7 @@ func FromBatchHeaderMsg(header *generated.BatchHeaderMsg) *common.BatchHeader {
Root: gethcommon.BytesToHash(header.Root),
TxHash: gethcommon.BytesToHash(header.TxHash),
Number: big.NewInt(int64(header.Number)),
SequencerOrderNo: big.NewInt(int64(header.SequencerOrderNo)),
ReceiptHash: gethcommon.BytesToHash(header.ReceiptHash),
Extra: header.Extra,
R: r.SetBytes(header.R),
Expand Down
361 changes: 186 additions & 175 deletions go/common/rpc/generated/enclave.pb.go

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions go/common/rpc/generated/enclave.proto
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,7 @@ message BatchHeaderMsg {
bytes LatestInboundCrossChainHeight = 14;
bytes LatestInboundCrossChainHash = 15;
repeated CrossChainMsg CrossChainMessages = 16;
uint64 SequencerOrderNo = 17;
}

message ExtRollupMsg {
Expand Down
17 changes: 9 additions & 8 deletions go/enclave/components/batch_producer.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ func (bp *batchProducerImpl) ComputeBatch(context *BatchExecutionContext) (*Comp
}

// Create a new batch based on the fromBlock of inclusion of the previous, including all new transactions
batch := core.DeterministicEmptyBatch(parent, block, context.AtTime)
batch := core.DeterministicEmptyBatch(parent, block, context.AtTime, context.SequencerNo)

stateDB, err := bp.storage.CreateStateDB(batch.Header.ParentHash)
if err != nil {
Expand Down Expand Up @@ -120,13 +120,14 @@ func (bp *batchProducerImpl) CreateGenesisState(blkHash common.L1BlockHash, time

genesisBatch := &core.Batch{
Header: &common.BatchHeader{
ParentHash: common.L2BatchHash{},
L1Proof: blkHash,
Root: *preFundGenesisState,
TxHash: types.EmptyRootHash,
Number: big.NewInt(int64(0)),
ReceiptHash: types.EmptyRootHash,
Time: timeNow,
ParentHash: common.L2BatchHash{},
L1Proof: blkHash,
Root: *preFundGenesisState,
TxHash: types.EmptyRootHash,
Number: big.NewInt(int64(0)),
SequencerOrderNo: big.NewInt(int64(0)),
ReceiptHash: types.EmptyRootHash,
Time: timeNow,
},
Transactions: []*common.L2Tx{},
}
Expand Down
4 changes: 3 additions & 1 deletion go/enclave/components/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package components

import (
"errors"
"math/big"

gethcommon "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/state"
Expand Down Expand Up @@ -40,14 +41,15 @@ type L1BlockProcessor interface {
GetCrossChainContractAddress() *gethcommon.Address
}

// Contains all of the data that each batch depends on
// BatchExecutionContext - Contains all of the data that each batch depends on
type BatchExecutionContext struct {
BlockPtr common.L1BlockHash // Block is needed for the cross chain messages
ParentPtr common.L2BatchHash
Transactions common.L2Transactions
AtTime uint64
Creator gethcommon.Address
ChainConfig *params.ChainConfig
SequencerNo *big.Int
}

// ComputedBatch - a structure representing the result of a batch
Expand Down
9 changes: 5 additions & 4 deletions go/enclave/core/batch.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import (
)

// Batch Data structure only for the internal use of the enclave since transactions are in clear
// Making changes to this struct will require GRPC + GRPC Converters regen
type Batch struct {
Header *common.BatchHeader
hash atomic.Value
Expand Down Expand Up @@ -93,11 +92,13 @@ func DeterministicEmptyBatch(
parent *common.BatchHeader,
block *types.Block,
time uint64,
sequencerNo *big.Int,
) *Batch {
h := common.BatchHeader{
ParentHash: parent.Hash(),
L1Proof: block.Hash(),
Number: big.NewInt(0).Add(parent.Number, big.NewInt(1)),
ParentHash: parent.Hash(),
L1Proof: block.Hash(),
Number: big.NewInt(0).Add(parent.Number, big.NewInt(1)),
SequencerOrderNo: sequencerNo,
// todo (#1548) - Consider how this time should align with the time of the L1 block used as proof.
Time: time,
}
Expand Down
2 changes: 2 additions & 0 deletions go/enclave/db/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ type BatchResolver interface {
FetchBatchByHeight(height uint64) (*core.Batch, error)
// FetchHeadBatch returns the current head batch of the canonical chain.
FetchHeadBatch() (*core.Batch, error)
// FetchCurrentSequencerNo returns the sequencer number
FetchCurrentSequencerNo() (*big.Int, error)
}

type RollupResolver interface {
Expand Down
13 changes: 13 additions & 0 deletions go/enclave/db/rawdb/accessors_receipts.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package rawdb
import (
"bytes"
"fmt"
"math/big"

common2 "github.com/obscuronet/go-obscuro/go/common"

Expand Down Expand Up @@ -98,6 +99,18 @@ func WriteContractCreationTxs(db ethdb.KeyValueWriter, receipts types.Receipts)
return nil
}

func WriteCurrentBatchSequenceNumber(db ethdb.KeyValueWriter, sequenceNo *big.Int) error {
return db.Put(sequenceNumber, sequenceNo.Bytes())
}

func ReadBatchSequenceNumber(db ethdb.KeyValueReader) (*big.Int, error) {
value, err := db.Get(sequenceNumber)
if err != nil {
return nil, err
}
return big.NewInt(0).SetBytes(value), nil
}

// ReadContractTransaction - returns the tx that created a contract
func ReadContractTransaction(db ethdb.Reader, address common.Address) (*common.Hash, error) {
value, err := db.Get(contractReceiptKey(address))
Expand Down
5 changes: 3 additions & 2 deletions go/enclave/db/rawdb/schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ import (
)

var (
sharedSecret = []byte("SharedSecret")
headBatchHash = []byte("HeadBatch") // headBatchHashPrefix -> curr L2 head batch hash
sharedSecret = []byte("SharedSecret")
sequenceNumber = []byte("SequenceNo")
headBatchHash = []byte("HeadBatch") // headBatchHashPrefix -> curr L2 head batch hash

attestationKeyPrefix = []byte("oAK") // attestationKeyPrefix + address -> key
syntheticTransactionsKeyPrefix = []byte("oSTX") // attestationKeyPrefix + address -> key
Expand Down
7 changes: 7 additions & 0 deletions go/enclave/db/storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,10 @@ func (s *storageImpl) FetchHeadBatch() (*core.Batch, error) {
return s.FetchBatch(*headHash)
}

func (s *storageImpl) FetchCurrentSequencerNo() (*big.Int, error) {
return obscurorawdb.ReadBatchSequenceNumber(s.db)
}

func (s *storageImpl) FetchBatch(hash common.L2BatchHash) (*core.Batch, error) {
batch, err := obscurorawdb.ReadBatch(s.db, hash)
if err != nil {
Expand Down Expand Up @@ -471,6 +475,9 @@ func (s *storageImpl) StoreBatch(batch *core.Batch, receipts []*types.Receipt, d
if err := obscurorawdb.WriteContractCreationTxs(dbBatch, receipts); err != nil {
return fmt.Errorf("could not save contract creation transaction. Cause: %w", err)
}
if err := obscurorawdb.WriteCurrentBatchSequenceNumber(dbBatch, batch.Header.SequencerOrderNo); err != nil {
return fmt.Errorf("could not save the current seqencer number. Cause: %w", err)
}
return nil
}

Expand Down
1 change: 1 addition & 0 deletions go/enclave/enclave.go
Original file line number Diff line number Diff line change
Expand Up @@ -1649,6 +1649,7 @@ func calculateAndStoreStateDB(batch *core.Batch, producer components.BatchProduc
Transactions: batch.Transactions,
AtTime: batch.Header.Time,
ChainConfig: chainConfig,
SequencerNo: batch.Header.SequencerOrderNo,
})
if err != nil {
return err
Expand Down
13 changes: 7 additions & 6 deletions go/enclave/enclave_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -621,12 +621,13 @@ func checkExpectedBalance(enclave common.Enclave, blkNumber gethrpc.BlockNumber,

func dummyBatch(blkHash gethcommon.Hash, height uint64, state *state.StateDB) *core.Batch {
h := common.BatchHeader{
ParentHash: common.L1BlockHash{},
L1Proof: blkHash,
Root: state.IntermediateRoot(true),
Number: big.NewInt(int64(height)),
ReceiptHash: types.EmptyRootHash,
Time: uint64(time.Now().Unix()),
ParentHash: common.L1BlockHash{},
L1Proof: blkHash,
Root: state.IntermediateRoot(true),
Number: big.NewInt(int64(height)),
SequencerOrderNo: big.NewInt(int64(height)),
ReceiptHash: types.EmptyRootHash,
Time: uint64(time.Now().Unix()),
}
return &core.Batch{
Header: &h,
Expand Down
12 changes: 12 additions & 0 deletions go/enclave/nodetype/sequencer.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"crypto/rand"
"errors"
"fmt"
"math/big"
"sync"
"time"

Expand Down Expand Up @@ -178,13 +179,18 @@ func (s *sequencer) createNewHeadBatch(l1HeadBlock *common.L1Block) error {
return err
}

sequencerNo, err := s.storage.FetchCurrentSequencerNo()
if err != nil {
return err
}
cb, err := s.batchProducer.ComputeBatch(&components.BatchExecutionContext{
BlockPtr: l1HeadBlock.Hash(),
ParentPtr: headBatch.Hash(),
Transactions: transactions,
AtTime: uint64(time.Now().Unix()), // todo - time is set only here; take from l1 block?
Creator: s.hostID,
ChainConfig: s.chainConfig,
SequencerNo: sequencerNo.Add(sequencerNo, big.NewInt(1)),
})
if err != nil {
return fmt.Errorf("failed computing batch. Cause: %w", err)
Expand Down Expand Up @@ -277,6 +283,11 @@ func (s *sequencer) handleFork(block *common.L1Block, ancestralBatch *core.Batch
for i := len(orphanedBatches) - 1; i >= 0; i-- {
orphan := orphanedBatches[i]

sequencerNo, err := s.storage.FetchCurrentSequencerNo()
if err != nil {
return err
}

// Extend the chain with identical cousin batches
cb, err := s.batchProducer.ComputeBatch(&components.BatchExecutionContext{
BlockPtr: block.Hash(),
Expand All @@ -285,6 +296,7 @@ func (s *sequencer) handleFork(block *common.L1Block, ancestralBatch *core.Batch
AtTime: orphan.Header.Time,
Creator: s.hostID,
ChainConfig: s.chainConfig,
SequencerNo: sequencerNo.Add(sequencerNo, big.NewInt(1)),
})
if err != nil {
s.logger.Crit("Error recalculating l2chain for forked block", log.ErrKey, err)
Expand Down
1 change: 1 addition & 0 deletions go/enclave/nodetype/validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ func (val *obsValidator) ValidateAndStoreBatch(incomingBatch *core.Batch) error
Transactions: incomingBatch.Transactions,
AtTime: incomingBatch.Header.Time,
ChainConfig: val.chainConfig,
SequencerNo: incomingBatch.Header.SequencerOrderNo,
})
if err != nil {
return fmt.Errorf("failed recomputing batch %s. Cause: %w", incomingBatch.Hash(), err)
Expand Down
1 change: 1 addition & 0 deletions go/host/rpc/clientapi/client_api_eth.go
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ func headerToMap(header *common.BatchHeader) map[string]interface{} {
"logsBloom": nil,
"difficulty": nil,
"number": header.Number,
"sequencerOrderNo": header.SequencerOrderNo,
"gasLimit": header.GasLimit,
"gasUsed": header.GasUsed,
"timestamp": header.Time,
Expand Down
18 changes: 9 additions & 9 deletions go/obsclient/obsclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,27 +47,27 @@ func (oc *ObsClient) ChainID() (*big.Int, error) {
return (*big.Int)(&result), err
}

// RollupNumber returns the height of the head rollup
func (oc *ObsClient) RollupNumber() (uint64, error) {
// BatchNumber returns the height of the head rollup
func (oc *ObsClient) BatchNumber() (uint64, error) {
var result hexutil.Uint64
err := oc.rpcClient.Call(&result, rpc.RollupNumber)
err := oc.rpcClient.Call(&result, rpc.BatchNumber)
return uint64(result), err
}

// RollupHeaderByNumber returns the header of the rollup with the given number
func (oc *ObsClient) RollupHeaderByNumber(number *big.Int) (*common.BatchHeader, error) {
// BatchHeaderByNumber returns the header of the rollup with the given number
func (oc *ObsClient) BatchHeaderByNumber(number *big.Int) (*common.BatchHeader, error) {
var batchHeader *common.BatchHeader
err := oc.rpcClient.Call(&batchHeader, rpc.GetRollupByNumber, toBlockNumArg(number), false)
err := oc.rpcClient.Call(&batchHeader, rpc.GetBatchByNumber, toBlockNumArg(number), false)
if err == nil && batchHeader == nil {
err = ethereum.NotFound
}
return batchHeader, err
}

// RollupHeaderByHash returns the block header with the given hash.
func (oc *ObsClient) RollupHeaderByHash(hash gethcommon.Hash) (*common.BatchHeader, error) {
// BatchHeaderByHash returns the block header with the given hash.
func (oc *ObsClient) BatchHeaderByHash(hash gethcommon.Hash) (*common.BatchHeader, error) {
var batchHeader *common.BatchHeader
err := oc.rpcClient.Call(&batchHeader, rpc.GetRollupByHash, hash, false)
err := oc.rpcClient.Call(&batchHeader, rpc.GetBatchByHash, hash, false)
if err == nil && batchHeader == nil {
err = ethereum.NotFound
}
Expand Down
6 changes: 3 additions & 3 deletions go/rpc/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ import (
)

const (
RollupNumber = "eth_blockNumber"
BatchNumber = "eth_blockNumber"
Call = "eth_call"
ChainID = "eth_chainId"
GetBalance = "eth_getBalance"
GetRollupByHash = "eth_getBlockByHash"
GetRollupByNumber = "eth_getBlockByNumber"
GetBatchByHash = "eth_getBlockByHash"
GetBatchByNumber = "eth_getBlockByNumber"
GetCode = "eth_getCode"
GetTransactionByHash = "eth_getTransactionByHash"
GetTransactionCount = "eth_getTransactionCount"
Expand Down
9 changes: 5 additions & 4 deletions integration/datagenerator/batch.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,11 @@ import (
func RandomBatch(block *types.Block) common.ExtBatch {
extBatch := common.ExtBatch{
Header: &common.BatchHeader{
ParentHash: randomHash(),
L1Proof: randomHash(),
Root: randomHash(),
Number: big.NewInt(int64(RandomUInt64())),
ParentHash: randomHash(),
L1Proof: randomHash(),
Root: randomHash(),
Number: big.NewInt(int64(RandomUInt64())),
SequencerOrderNo: big.NewInt(int64(RandomUInt64())),
},
TxHashes: []gethcommon.Hash{randomHash()},
EncryptedTxBlob: RandomBytes(10),
Expand Down
2 changes: 1 addition & 1 deletion integration/manualtests/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ func TestClientGetRollup(t *testing.T) {

obsClient := obsclient.NewObsClient(client)

rollupHeader, err := obsClient.RollupHeaderByNumber(big.NewInt(4392))
rollupHeader, err := obsClient.BatchHeaderByNumber(big.NewInt(4392))
assert.Nil(t, err)

var rollup *common.ExtRollup
Expand Down
2 changes: 1 addition & 1 deletion integration/noderunner/noderunner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ func TestCanStartStandaloneObscuroHostAndEnclave(t *testing.T) {
time.Sleep(time.Second)

var rollupNumber hexutil.Uint64
err = obscuroClient.Call(&rollupNumber, rpc.RollupNumber)
err = obscuroClient.Call(&rollupNumber, rpc.BatchNumber)
if err == nil && rollupNumber > 0 {
return
}
Expand Down
Loading

0 comments on commit 473b109

Please sign in to comment.