Skip to content

Commit

Permalink
more perf fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
tudor-malene committed Sep 19, 2023
1 parent 8ae0747 commit 62ae6e8
Show file tree
Hide file tree
Showing 10 changed files with 52 additions and 31 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/manual-deploy-testnet-l2.yml
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,8 @@ jobs:
echo "RESOURCE_TESTNET_NAME=devtestnet" >> $GITHUB_ENV
echo "L1_WS_URL=ws://dev-testnet-eth2network.uksouth.cloudapp.azure.com:9000" >> $GITHUB_ENV
echo "L1_HTTP_URL=http://dev-testnet-eth2network.uksouth.cloudapp.azure.com:8025" >> $GITHUB_ENV
echo "BATCH_INTERVAL=1s" >> $GITHUB_ENV
echo "ROLLUP_INTERVAL=10s" >> $GITHUB_ENV
echo "BATCH_INTERVAL=50ms" >> $GITHUB_ENV
echo "ROLLUP_INTERVAL=5s" >> $GITHUB_ENV
- name: 'Output env vars'
id: outputVars
Expand Down
29 changes: 25 additions & 4 deletions go/enclave/components/batch_registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@ package components
import (
"errors"
"fmt"
"math/big"
"sync"

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

"github.com/ethereum/go-ethereum/core/types"

"github.com/obscuronet/go-obscuro/go/enclave/storage"
Expand All @@ -20,20 +23,37 @@ import (
)

type batchRegistry struct {
storage storage.Storage
logger gethlog.Logger
storage storage.Storage
logger gethlog.Logger
headBatchSeq *big.Int // keep track of the last executed batch to optimise db access

batchesCallback func(*core.Batch, types.Receipts)
callbackMutex sync.RWMutex
}

func NewBatchRegistry(storage storage.Storage, logger gethlog.Logger) BatchRegistry {
var headBatchSeq *big.Int
headBatch, err := storage.FetchHeadBatch()
if err != nil {
if errors.Is(err, errutil.ErrNotFound) {
headBatchSeq = big.NewInt(int64(common.L2GenesisSeqNo))
} else {
return nil
}
} else {
headBatchSeq = headBatch.SeqNo()
}
return &batchRegistry{
storage: storage,
logger: logger,
storage: storage,
headBatchSeq: headBatchSeq,
logger: logger,
}
}

func (br *batchRegistry) HeadBatchSeq() *big.Int {
return br.headBatchSeq
}

func (br *batchRegistry) SubscribeForExecutedBatches(callback func(*core.Batch, types.Receipts)) {
br.callbackMutex.Lock()
defer br.callbackMutex.Unlock()
Expand All @@ -53,6 +73,7 @@ func (br *batchRegistry) OnBatchExecuted(batch *core.Batch, receipts types.Recei

defer br.logger.Debug("Sending batch and events", log.BatchHashKey, batch.Hash(), log.DurationKey, measure.NewStopwatch())

br.headBatchSeq = batch.SeqNo()
if br.batchesCallback != nil {
br.batchesCallback(batch, receipts)
}
Expand Down
2 changes: 2 additions & 0 deletions go/enclave/components/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ type BatchRegistry interface {
// HasGenesisBatch - returns if genesis batch is available yet or not, or error in case
// the function is unable to determine.
HasGenesisBatch() (bool, error)

HeadBatchSeq() *big.Int
}

type RollupProducer interface {
Expand Down
2 changes: 1 addition & 1 deletion go/enclave/nodetype/validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ func (val *obsValidator) VerifySequencerSignature(*core.Batch) error {
}

func (val *obsValidator) ExecuteStoredBatches() error {
batches, err := val.storage.FetchCanonicalUnexecutedBatches()
batches, err := val.storage.FetchCanonicalUnexecutedBatches(val.batchRegistry.HeadBatchSeq())
if err != nil {
if errors.Is(err, errutil.ErrNotFound) {
return nil
Expand Down
15 changes: 8 additions & 7 deletions go/enclave/storage/enclavedb/batch.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ const (
bInsert = "insert into batch values (?,?,?,?,?,?,?,?,?,?)"
updateBatchExecuted = "update batch set is_executed=true where sequence=?"

selectBatch = "select b.header, bb.content from batch b join batch_body bb on b.body=bb.hash"
selectBatch = "select b.header, bb.content from batch b join batch_body bb on b.body=bb.id"
selectHeader = "select b.header from batch b"

txExecInsert = "insert into exec_tx values "
Expand All @@ -50,7 +50,8 @@ const (

// WriteBatchAndTransactions - persists the batch and the transactions
func WriteBatchAndTransactions(dbtx DBTransaction, batch *core.Batch) error {
bodyHash := truncTo16(batch.Header.TxHash)
// todo - optimize for reorgs
batchBodyID := batch.SeqNo().Uint64()

body, err := rlp.EncodeToBytes(batch.Transactions)
if err != nil {
Expand All @@ -61,7 +62,7 @@ func WriteBatchAndTransactions(dbtx DBTransaction, batch *core.Batch) error {
return fmt.Errorf("could not encode batch header. Cause: %w", err)
}

dbtx.ExecuteSQL(bodyInsert, bodyHash, body)
dbtx.ExecuteSQL(bodyInsert, batchBodyID, body)

var parentBytes []byte
if batch.Number().Uint64() > 0 {
Expand All @@ -84,7 +85,7 @@ func WriteBatchAndTransactions(dbtx DBTransaction, batch *core.Batch) error {
batch.Header.Number.Uint64(), // height
isCanon, // is_canonical
header, // header blob
bodyHash, // reference to the batch body
batchBodyID, // reference to the batch body
truncTo16(batch.Header.L1Proof), // l1_proof
false, // executed
)
Expand Down Expand Up @@ -112,7 +113,7 @@ func WriteBatchAndTransactions(dbtx DBTransaction, batch *core.Batch) error {
args = append(args, from.Bytes()) // sender_address
args = append(args, transaction.Nonce()) // nonce
args = append(args, i) // idx
args = append(args, bodyHash) // the batch body which contained it
args = append(args, batchBodyID) // the batch body which contained it
}
dbtx.ExecuteSQL(insert, args...)
}
Expand Down Expand Up @@ -449,8 +450,8 @@ func ReadContractCreationCount(db *sql.DB) (*big.Int, error) {
return big.NewInt(count), nil
}

func ReadUnexecutedBatches(db *sql.DB) ([]*core.Batch, error) {
return fetchBatches(db, "where is_executed=false and is_canonical=true order by b.sequence")
func ReadUnexecutedBatches(db *sql.DB, from *big.Int) ([]*core.Batch, error) {
return fetchBatches(db, "where is_executed=false and is_canonical=true and sequence >= ? order by b.sequence", from.Uint64())
}

func BatchWasExecuted(db *sql.DB, hash common.L2BatchHash) (bool, error) {
Expand Down
2 changes: 1 addition & 1 deletion go/enclave/storage/enclavedb/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import (

const (
baseEventsQuerySelect = "select full_topic0, full_topic1, full_topic2, full_topic3, full_topic4, datablob, b.full_hash, b.height, tx.full_hash, tx.idx, log_idx, address"
baseDebugEventsQuerySelect = "select rel_address1, rel_address2, rel_address3, rel_address4, lifecycle_event, topic0, topic1, topic2, topic3, topic4, datablob, b.full_hash, b.height, tx.full_hash, tx.idx, log_idx, address"
baseDebugEventsQuerySelect = "select rel_address1, rel_address2, rel_address3, rel_address4, lifecycle_event, full_topic0, full_topic1, full_topic2, full_topic3, full_topic4, datablob, b.full_hash, b.height, tx.full_hash, tx.idx, log_idx, address"
baseEventsJoin = "from events e join exec_tx extx on e.exec_tx_id=extx.id join tx on extx.tx=tx.hash join batch b on extx.batch=b.sequence where b.is_canonical=true "
insertEvent = "insert into events values "
insertEventValues = "(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"
Expand Down
13 changes: 5 additions & 8 deletions go/enclave/storage/init/edgelessdb/001_init.sql
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ create table if not exists obsdb.block
header blob NOT NULL,
height int NOT NULL,
primary key (hash),
INDEX (is_canonical),
INDEX (height)
);
GRANT ALL ON obsdb.block TO obscuro;
Expand Down Expand Up @@ -64,9 +63,9 @@ GRANT ALL ON obsdb.rollup TO obscuro;

create table if not exists obsdb.batch_body
(
hash binary(16),
id int NOT NULL,
content mediumblob NOT NULL,
primary key (hash)
primary key (id)
);
GRANT ALL ON obsdb.batch_body TO obscuro;

Expand All @@ -79,15 +78,13 @@ create table if not exists obsdb.batch
height int NOT NULL,
is_canonical boolean NOT NULL,
header blob NOT NULL,
body binary(16) NOT NULL,
body int NOT NULL,
l1_proof binary(16) NOT NULL,
is_executed boolean NOT NULL,
primary key (sequence),
INDEX (hash),
INDEX (body),
INDEX (height),
INDEX (is_canonical),
INDEX (is_executed),
INDEX (height, is_canonical),
INDEX (l1_proof)
);
GRANT ALL ON obsdb.batch TO obscuro;
Expand All @@ -100,7 +97,7 @@ create table if not exists obsdb.tx
sender_address binary(20) NOT NULL,
nonce int NOT NULL,
idx int NOT NULL,
body binary(16) NOT NULL,
body int NOT NULL,
INDEX (body),
primary key (hash)
);
Expand Down
10 changes: 5 additions & 5 deletions go/enclave/storage/init/sqlite/001_init.sql
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,12 @@ create table if not exists rollup
start_seq int NOT NULL,
end_seq int NOT NULL,
header blob NOT NULL,
compression_block binary(16) NOT NULL
compression_block binary(16) NOT NULL REFERENCES block
);

create table if not exists batch_body
(
hash binary(16) primary key,
id int NOT NULL primary key,
content mediumblob NOT NULL
);

Expand All @@ -63,14 +63,14 @@ create table if not exists batch
height int NOT NULL,
is_canonical boolean NOT NULL,
header blob NOT NULL,
body binary(16) NOT NULL REFERENCES batch_body,
body int NOT NULL REFERENCES batch_body,
l1_proof binary(16) NOT NULL, -- normally this would be a FK, but there is a weird edge case where an L2 node might not have the block used to create this batch
is_executed boolean NOT NULL
-- the unique constraint is commented for now because there might be multiple non-canonical batches for the same height
-- unique (height, is_canonical, is_executed)
);
create index IDX_BATCH_HEIGHT on batch (height);
create index IDX_BATCH_HASH on batch (hash);
create index IDX_BATCH_HEIGHT on batch (height, is_canonical);
create index IDX_BATCH_Block on batch (l1_proof);

create table if not exists tx
Expand All @@ -81,7 +81,7 @@ create table if not exists tx
sender_address binary(20) NOT NULL,
nonce int NOT NULL,
idx int NOT NULL,
body binary(16) REFERENCES batch_body
body int REFERENCES batch_body
);

create table if not exists exec_tx
Expand Down
2 changes: 1 addition & 1 deletion go/enclave/storage/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ type BatchResolver interface {
FetchBatchesByBlock(common.L1BlockHash) ([]*core.Batch, error)

// FetchCanonicalUnexecutedBatches - return the list of the unexecuted batches that are canonical
FetchCanonicalUnexecutedBatches() ([]*core.Batch, error)
FetchCanonicalUnexecutedBatches(*big.Int) ([]*core.Batch, error)

// BatchWasExecuted - return true if the batch was executed
BatchWasExecuted(hash common.L2BatchHash) (bool, error)
Expand Down
4 changes: 2 additions & 2 deletions go/enclave/storage/storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -505,10 +505,10 @@ func (s *storageImpl) GetContractCount() (*big.Int, error) {
return enclavedb.ReadContractCreationCount(s.db.GetSQLDB())
}

func (s *storageImpl) FetchCanonicalUnexecutedBatches() ([]*core.Batch, error) {
func (s *storageImpl) FetchCanonicalUnexecutedBatches(from *big.Int) ([]*core.Batch, error) {
callStart := time.Now()
defer s.logDuration("FetchCanonicalUnexecutedBatches", callStart)
return enclavedb.ReadUnexecutedBatches(s.db.GetSQLDB())
return enclavedb.ReadUnexecutedBatches(s.db.GetSQLDB(), from)
}

func (s *storageImpl) BatchWasExecuted(hash common.L2BatchHash) (bool, error) {
Expand Down

0 comments on commit 62ae6e8

Please sign in to comment.