Skip to content

Commit

Permalink
Pass Context from enclave rpc to database (#1882)
Browse files Browse the repository at this point in the history
* pass Context to reach the database interactions

* pass Context to reach the database interactions

* pr comment
  • Loading branch information
tudor-malene authored Apr 23, 2024
1 parent 3e566ff commit 7ca4364
Show file tree
Hide file tree
Showing 84 changed files with 1,135 additions and 969 deletions.
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,14 @@ require (
github.com/hashicorp/golang-lru/v2 v2.0.7
github.com/holiman/uint256 v1.2.4
github.com/jolestar/go-commons-pool/v2 v2.1.2
github.com/lib/pq v1.10.9
github.com/mattn/go-sqlite3 v1.14.22
github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416
github.com/pkg/errors v0.9.1
github.com/rs/cors v1.10.1
github.com/sanity-io/litter v1.5.5
github.com/status-im/keycard-go v0.3.2
github.com/stretchr/testify v1.9.0
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7
github.com/tidwall/gjson v1.17.1
github.com/valyala/fasthttp v1.52.0
gitlab.com/NebulousLabs/fastrand v0.0.0-20181126182046-603482d69e40
Expand Down Expand Up @@ -107,7 +107,6 @@ require (
github.com/kr/pretty v0.3.1 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/leodido/go-urn v1.4.0 // indirect
github.com/lib/pq v1.10.9 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-runewidth v0.0.15 // indirect
github.com/mmcloughlin/addchain v0.4.0 // indirect
Expand All @@ -131,6 +130,7 @@ require (
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/stretchr/objx v0.5.2 // indirect
github.com/supranational/blst v0.3.11 // indirect
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect
github.com/tidwall/match v1.1.1 // indirect
github.com/tidwall/pretty v1.2.1 // indirect
github.com/tklauser/go-sysconf v0.3.13 // indirect
Expand Down
10 changes: 5 additions & 5 deletions go/common/cache_util.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import (

// GetCachedValue - returns the cached value for the provided key. If the key is not found, then invoke the 'onFailed' function
// which returns the value, and cache it
func GetCachedValue[V any](cache *cache.Cache[*V], logger gethlog.Logger, key any, onCacheMiss func(any) (*V, error)) (*V, error) {
value, err := cache.Get(context.Background(), key)
func GetCachedValue[V any](ctx context.Context, cache *cache.Cache[*V], logger gethlog.Logger, key any, onCacheMiss func(any) (*V, error)) (*V, error) {
value, err := cache.Get(ctx, key)
if err != nil || value == nil {
// todo metrics for cache misses
v, err := onCacheMiss(key)
Expand All @@ -21,18 +21,18 @@ func GetCachedValue[V any](cache *cache.Cache[*V], logger gethlog.Logger, key an
if v == nil {
logger.Crit("Returned a nil value from the onCacheMiss function. Should not happen.")
}
CacheValue(cache, logger, key, v)
CacheValue(ctx, cache, logger, key, v)
return v, nil
}

return value, err
}

func CacheValue[V any](cache *cache.Cache[*V], logger gethlog.Logger, key any, v *V) {
func CacheValue[V any](ctx context.Context, cache *cache.Cache[*V], logger gethlog.Logger, key any, v *V) {
if v == nil {
return
}
err := cache.Set(context.Background(), key, v)
err := cache.Set(ctx, key, v)
if err != nil {
logger.Error("Could not store value in cache", log.ErrKey, err)
}
Expand Down
59 changes: 30 additions & 29 deletions go/common/enclave.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package common

import (
"context"
"encoding/json"
"math/big"

Expand Down Expand Up @@ -34,61 +35,61 @@ type Enclave interface {
EnclaveScan

// Status checks whether the enclave is ready to process requests - only implemented by the RPC layer
Status() (Status, SystemError)
Status(context.Context) (Status, SystemError)

// Attestation - Produces an attestation report which will be used to request the shared secret from another enclave.
Attestation() (*AttestationReport, SystemError)
Attestation(context.Context) (*AttestationReport, SystemError)

// GenerateSecret - the genesis enclave is responsible with generating the secret entropy
GenerateSecret() (EncryptedSharedEnclaveSecret, SystemError)
GenerateSecret(context.Context) (EncryptedSharedEnclaveSecret, SystemError)

// InitEnclave - initialise an enclave with a seed received by another enclave
InitEnclave(secret EncryptedSharedEnclaveSecret) SystemError
InitEnclave(ctx context.Context, secret EncryptedSharedEnclaveSecret) SystemError

// EnclaveID - returns the enclave's ID
EnclaveID() (EnclaveID, SystemError)
EnclaveID(context.Context) (EnclaveID, SystemError)

// SubmitL1Block - Used for the host to submit L1 blocks to the enclave, these may be:
// a. historic block - if the enclave is behind and in the process of catching up with the L1 state
// b. the latest block published by the L1, to which the enclave should respond with a rollup
// It is the responsibility of the host to gossip the returned rollup
// For good functioning the caller should always submit blocks ordered by height
// submitting a block before receiving ancestors of it, will result in it being ignored
SubmitL1Block(block L1Block, receipts L1Receipts, isLatest bool) (*BlockSubmissionResponse, SystemError)
SubmitL1Block(ctx context.Context, block L1Block, receipts L1Receipts, isLatest bool) (*BlockSubmissionResponse, SystemError)

// SubmitTx - user transactions
SubmitTx(tx EncryptedTx) (*responses.RawTx, SystemError)
SubmitTx(ctx context.Context, tx EncryptedTx) (*responses.RawTx, SystemError)

// SubmitBatch submits a batch received from the sequencer for processing.
SubmitBatch(batch *ExtBatch) SystemError
SubmitBatch(ctx context.Context, batch *ExtBatch) SystemError

// ObsCall - Execute a smart contract to retrieve data. The equivalent of "Eth_call"
// Todo - return the result with a block delay. To prevent frontrunning.
ObsCall(encryptedParams EncryptedParamsCall) (*responses.Call, SystemError)
ObsCall(ctx context.Context, encryptedParams EncryptedParamsCall) (*responses.Call, SystemError)

// GetTransactionCount returns the nonce of the wallet with the given address (encrypted with the acc viewing key)
GetTransactionCount(encryptedParams EncryptedParamsGetTxCount) (*responses.TxCount, SystemError)
GetTransactionCount(ctx context.Context, encryptedParams EncryptedParamsGetTxCount) (*responses.TxCount, SystemError)

// Stop gracefully stops the enclave
Stop() SystemError

// GetTransaction returns a transaction in JSON format, encrypted with the viewing key for the transaction's `from` field.
GetTransaction(encryptedParams EncryptedParamsGetTxByHash) (*responses.TxByHash, SystemError)
GetTransaction(ctx context.Context, encryptedParams EncryptedParamsGetTxByHash) (*responses.TxByHash, SystemError)

// GetTransactionReceipt returns a transaction receipt given its signed hash, or nil if the transaction is unknown
GetTransactionReceipt(encryptedParams EncryptedParamsGetTxReceipt) (*responses.TxReceipt, SystemError)
GetTransactionReceipt(ctx context.Context, encryptedParams EncryptedParamsGetTxReceipt) (*responses.TxReceipt, SystemError)

// GetBalance returns the balance of the address on the Obscuro network, encrypted with the viewing key for the
// address.
GetBalance(encryptedParams EncryptedParamsGetBalance) (*responses.Balance, SystemError)
GetBalance(ctx context.Context, encryptedParams EncryptedParamsGetBalance) (*responses.Balance, SystemError)

// GetCode returns the code stored at the given address in the state for the given rollup hash.
GetCode(address gethcommon.Address, rollupHash *gethcommon.Hash) ([]byte, SystemError)
GetCode(ctx context.Context, address gethcommon.Address, rollupHash *gethcommon.Hash) ([]byte, SystemError)

// Subscribe adds a log subscription to the enclave under the given ID, provided the request is authenticated
// correctly. The events will be populated in the BlockSubmissionResponse. If there is an existing subscription
// with the given ID, it is overwritten.
Subscribe(id rpc.ID, encryptedParams EncryptedParamsLogSubscription) SystemError
Subscribe(ctx context.Context, id rpc.ID, encryptedParams EncryptedParamsLogSubscription) SystemError

// Unsubscribe removes the log subscription with the given ID from the enclave. If there is no subscription with
// the given ID, nothing is deleted.
Expand All @@ -98,54 +99,54 @@ type Enclave interface {
StopClient() SystemError

// EstimateGas tries to estimate the gas needed to execute a specific transaction based on the pending state.
EstimateGas(encryptedParams EncryptedParamsEstimateGas) (*responses.Gas, SystemError)
EstimateGas(ctx context.Context, encryptedParams EncryptedParamsEstimateGas) (*responses.Gas, SystemError)

// GetLogs returns all the logs matching the filter.
GetLogs(encryptedParams EncryptedParamsGetLogs) (*responses.Logs, SystemError)
GetLogs(ctx context.Context, encryptedParams EncryptedParamsGetLogs) (*responses.Logs, SystemError)

// HealthCheck returns whether the enclave is in a healthy state
HealthCheck() (bool, SystemError)
HealthCheck(context.Context) (bool, SystemError)

// GetBatch - retrieve a batch if existing within the enclave db.
GetBatch(hash L2BatchHash) (*ExtBatch, SystemError)
GetBatch(ctx context.Context, hash L2BatchHash) (*ExtBatch, SystemError)

// GetBatchBySeqNo - retrieve batch by sequencer number if it's in the db.
GetBatchBySeqNo(seqNo uint64) (*ExtBatch, SystemError)
GetBatchBySeqNo(ctx context.Context, seqNo uint64) (*ExtBatch, SystemError)

// GetRollupData - retrieve the first batch sequence and start time for a given rollup.
GetRollupData(hash L2RollupHash) (*PublicRollupMetadata, SystemError)
GetRollupData(ctx context.Context, hash L2RollupHash) (*PublicRollupMetadata, SystemError)

// CreateBatch - creates a new head batch extending the previous one for the latest known L1 head if the node is
// a sequencer. Will panic otherwise.
CreateBatch(skipIfEmpty bool) SystemError
CreateBatch(ctx context.Context, skipIfEmpty bool) SystemError

// CreateRollup - will create a new rollup by going through the sequencer if the node is a sequencer
// or panic otherwise.
CreateRollup(fromSeqNo uint64) (*ExtRollup, SystemError)
CreateRollup(ctx context.Context, fromSeqNo uint64) (*ExtRollup, SystemError)

// DebugTraceTransaction returns the trace of a transaction
DebugTraceTransaction(hash gethcommon.Hash, config *tracers.TraceConfig) (json.RawMessage, SystemError)
DebugTraceTransaction(ctx context.Context, hash gethcommon.Hash, config *tracers.TraceConfig) (json.RawMessage, SystemError)

// StreamL2Updates - will stream any new batches as they are created/detected
// All will be queued in the channel that has been returned.
StreamL2Updates() (chan StreamL2UpdatesResponse, func())
// DebugEventLogRelevancy returns the logs of a transaction
DebugEventLogRelevancy(hash gethcommon.Hash) (json.RawMessage, SystemError)
DebugEventLogRelevancy(ctx context.Context, hash gethcommon.Hash) (json.RawMessage, SystemError)
}

// EnclaveScan represents the methods that are used for data scanning in the enclave
type EnclaveScan interface {
// GetTotalContractCount returns the total number of contracts that have been deployed
GetTotalContractCount() (*big.Int, SystemError)
GetTotalContractCount(context.Context) (*big.Int, SystemError)

// GetCustomQuery returns the data of a custom query
GetCustomQuery(encryptedParams EncryptedParamsGetStorageAt) (*responses.PrivateQueryResponse, SystemError)
GetCustomQuery(ctx context.Context, encryptedParams EncryptedParamsGetStorageAt) (*responses.PrivateQueryResponse, SystemError)

// GetPublicTransactionData returns a list of public transaction data
GetPublicTransactionData(pagination *QueryPagination) (*TransactionListingResponse, SystemError)
GetPublicTransactionData(ctx context.Context, pagination *QueryPagination) (*TransactionListingResponse, SystemError)

// EnclavePublicConfig returns network data that is known to the enclave but can be shared publicly
EnclavePublicConfig() (*EnclavePublicConfig, SystemError)
EnclavePublicConfig(context.Context) (*EnclavePublicConfig, SystemError)
}

// BlockSubmissionResponse is the response sent from the enclave back to the node after ingesting a block
Expand Down
17 changes: 9 additions & 8 deletions go/common/gethencoding/geth_encoding.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package gethencoding

import (
"context"
"encoding/json"
"fmt"
"math/big"
Expand Down Expand Up @@ -45,8 +46,8 @@ const (

// EncodingService handles conversion to Geth data structures
type EncodingService interface {
CreateEthHeaderForBatch(h *common.BatchHeader) (*types.Header, error)
CreateEthBlockFromBatch(b *core.Batch) (*types.Block, error)
CreateEthHeaderForBatch(ctx context.Context, h *common.BatchHeader) (*types.Header, error)
CreateEthBlockFromBatch(ctx context.Context, b *core.Batch) (*types.Block, error)
}

type gethEncodingServiceImpl struct {
Expand Down Expand Up @@ -307,11 +308,11 @@ func ExtractEthCall(param interface{}) (*gethapi.TransactionArgs, error) {
// CreateEthHeaderForBatch - the EVM requires an Ethereum header.
// We convert the Batch headers to Ethereum headers to be able to use the Geth EVM.
// Special care must be taken to maintain a valid chain of these converted headers.
func (enc *gethEncodingServiceImpl) CreateEthHeaderForBatch(h *common.BatchHeader) (*types.Header, error) {
func (enc *gethEncodingServiceImpl) CreateEthHeaderForBatch(ctx context.Context, h *common.BatchHeader) (*types.Header, error) {
// wrap in a caching layer
return common.GetCachedValue(enc.gethHeaderCache, enc.logger, h.Hash(), func(a any) (*types.Header, error) {
return common.GetCachedValue(ctx, enc.gethHeaderCache, enc.logger, h.Hash(), func(a any) (*types.Header, error) {
// deterministically calculate the private randomness that will be exposed to the EVM
secret, err := enc.storage.FetchSecret()
secret, err := enc.storage.FetchSecret(ctx)
if err != nil {
enc.logger.Crit("Could not fetch shared secret. Exiting.", log.ErrKey, err)
}
Expand All @@ -322,7 +323,7 @@ func (enc *gethEncodingServiceImpl) CreateEthHeaderForBatch(h *common.BatchHeade
convertedParentHash := common.GethGenesisParentHash

if h.SequencerOrderNo.Uint64() > common.L2GenesisSeqNo {
convertedParentHash, err = enc.storage.FetchConvertedHash(h.ParentHash)
convertedParentHash, err = enc.storage.FetchConvertedHash(ctx, h.ParentHash)
if err != nil {
enc.logger.Error("Cannot find the converted value for the parent of", log.BatchSeqNoKey, h.SequencerOrderNo)
return nil, err
Expand Down Expand Up @@ -377,8 +378,8 @@ type localBlock struct {
ReceivedFrom interface{}
}

func (enc *gethEncodingServiceImpl) CreateEthBlockFromBatch(b *core.Batch) (*types.Block, error) {
blockHeader, err := enc.CreateEthHeaderForBatch(b.Header)
func (enc *gethEncodingServiceImpl) CreateEthBlockFromBatch(ctx context.Context, b *core.Batch) (*types.Block, error) {
blockHeader, err := enc.CreateEthHeaderForBatch(ctx, b.Header)
if err != nil {
return nil, fmt.Errorf("unable to create eth block from batch - %w", err)
}
Expand Down
21 changes: 11 additions & 10 deletions go/common/gethutil/gethutil.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package gethutil

import (
"bytes"
"context"
"fmt"

"github.com/ten-protocol/go-ten/go/enclave/storage"
Expand All @@ -18,8 +19,8 @@ var EmptyHash = gethcommon.Hash{}

// LCA - returns the latest common ancestor of the 2 blocks or an error if no common ancestor is found
// it also returns the blocks that became canonincal, and the once that are now the fork
func LCA(newCanonical *types.Block, oldCanonical *types.Block, resolver storage.BlockResolver) (*common.ChainFork, error) {
b, cp, ncp, err := internalLCA(newCanonical, oldCanonical, resolver, []common.L1BlockHash{}, []common.L1BlockHash{oldCanonical.Hash()})
func LCA(ctx context.Context, newCanonical *types.Block, oldCanonical *types.Block, resolver storage.BlockResolver) (*common.ChainFork, error) {
b, cp, ncp, err := internalLCA(ctx, newCanonical, oldCanonical, resolver, []common.L1BlockHash{}, []common.L1BlockHash{oldCanonical.Hash()})
// remove the common ancestor
if len(cp) > 0 {
cp = cp[0 : len(cp)-1]
Expand All @@ -36,37 +37,37 @@ func LCA(newCanonical *types.Block, oldCanonical *types.Block, resolver storage.
}, err
}

func internalLCA(newCanonical *types.Block, oldCanonical *types.Block, resolver storage.BlockResolver, canonicalPath []common.L1BlockHash, nonCanonicalPath []common.L1BlockHash) (*types.Block, []common.L1BlockHash, []common.L1BlockHash, error) {
func internalLCA(ctx context.Context, newCanonical *types.Block, oldCanonical *types.Block, resolver storage.BlockResolver, canonicalPath []common.L1BlockHash, nonCanonicalPath []common.L1BlockHash) (*types.Block, []common.L1BlockHash, []common.L1BlockHash, error) {
if newCanonical.NumberU64() == common.L1GenesisHeight || oldCanonical.NumberU64() == common.L1GenesisHeight {
return newCanonical, canonicalPath, nonCanonicalPath, nil
}
if bytes.Equal(newCanonical.Hash().Bytes(), oldCanonical.Hash().Bytes()) {
return newCanonical, canonicalPath, nonCanonicalPath, nil
}
if newCanonical.NumberU64() > oldCanonical.NumberU64() {
p, err := resolver.FetchBlock(newCanonical.ParentHash())
p, err := resolver.FetchBlock(ctx, newCanonical.ParentHash())
if err != nil {
return nil, nil, nil, fmt.Errorf("could not retrieve parent block. Cause: %w", err)
}

return internalLCA(p, oldCanonical, resolver, append(canonicalPath, p.Hash()), nonCanonicalPath)
return internalLCA(ctx, p, oldCanonical, resolver, append(canonicalPath, p.Hash()), nonCanonicalPath)
}
if oldCanonical.NumberU64() > newCanonical.NumberU64() {
p, err := resolver.FetchBlock(oldCanonical.ParentHash())
p, err := resolver.FetchBlock(ctx, oldCanonical.ParentHash())
if err != nil {
return nil, nil, nil, fmt.Errorf("could not retrieve parent block. Cause: %w", err)
}

return internalLCA(newCanonical, p, resolver, canonicalPath, append(nonCanonicalPath, p.Hash()))
return internalLCA(ctx, newCanonical, p, resolver, canonicalPath, append(nonCanonicalPath, p.Hash()))
}
parentBlockA, err := resolver.FetchBlock(newCanonical.ParentHash())
parentBlockA, err := resolver.FetchBlock(ctx, newCanonical.ParentHash())
if err != nil {
return nil, nil, nil, fmt.Errorf("could not retrieve parent block. Cause: %w", err)
}
parentBlockB, err := resolver.FetchBlock(oldCanonical.ParentHash())
parentBlockB, err := resolver.FetchBlock(ctx, oldCanonical.ParentHash())
if err != nil {
return nil, nil, nil, fmt.Errorf("could not retrieve parent block. Cause: %w", err)
}

return internalLCA(parentBlockA, parentBlockB, resolver, append(canonicalPath, parentBlockA.Hash()), append(nonCanonicalPath, parentBlockB.Hash()))
return internalLCA(ctx, parentBlockA, parentBlockB, resolver, append(canonicalPath, parentBlockA.Hash()), append(nonCanonicalPath, parentBlockB.Hash()))
}
6 changes: 4 additions & 2 deletions go/common/host/host.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package host

import (
"context"

"github.com/ethereum/go-ethereum/core/types"
"github.com/ten-protocol/go-ten/go/common"
"github.com/ten-protocol/go-ten/go/config"
Expand All @@ -17,7 +19,7 @@ type Host interface {
// Start initializes the main loop of the host.
Start() error
// SubmitAndBroadcastTx submits an encrypted transaction to the enclave, and broadcasts it to the other hosts on the network.
SubmitAndBroadcastTx(encryptedParams common.EncryptedParamsSendRawTx) (*responses.RawTx, error)
SubmitAndBroadcastTx(ctx context.Context, encryptedParams common.EncryptedParamsSendRawTx) (*responses.RawTx, error)
// SubscribeLogs feeds logs matching the encrypted log subscription to the matchedLogs channel.
SubscribeLogs(id rpc.ID, encryptedLogSubscription common.EncryptedParamsLogSubscription, matchedLogs chan []byte) error
// UnsubscribeLogs terminates a log subscription between the host and the enclave.
Expand All @@ -26,7 +28,7 @@ type Host interface {
Stop() error

// HealthCheck returns the health status of the host + enclave + db
HealthCheck() (*HealthCheck, error)
HealthCheck(context.Context) (*HealthCheck, error)

// ObscuroConfig returns the info of the Obscuro network
ObscuroConfig() (*common.ObscuroNetworkInfo, error)
Expand Down
Loading

0 comments on commit 7ca4364

Please sign in to comment.