Skip to content

Commit

Permalink
misc cleanup (#2232)
Browse files Browse the repository at this point in the history
* misc cleanup

* misc cleanup

* misc cleanup

* misc cleanup

* misc cleanup

* misc cleanup

* address PR comment
  • Loading branch information
tudor-malene authored Jan 6, 2025
1 parent 94e5868 commit 37690af
Show file tree
Hide file tree
Showing 56 changed files with 203 additions and 506 deletions.
1 change: 0 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,6 @@ require (
github.com/gorilla/mux v1.8.1 // indirect
github.com/h2non/filetype v1.1.3 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4 // indirect
github.com/holiman/bloomfilter/v2 v2.0.3 // indirect
github.com/huin/goupnp v1.3.0 // indirect
github.com/jackpal/go-nat-pmp v1.0.2 // indirect
Expand Down
1 change: 0 additions & 1 deletion go/common/batches.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (
)

// ExtBatch is an encrypted form of batch used when passing the batch around outside of an enclave.
// todo (#718) - expand this structure to contain the required fields.
type ExtBatch struct {
Header *BatchHeader
// todo - remove and replace with enclave API
Expand Down
2 changes: 1 addition & 1 deletion go/common/gethencoding/geth_encoding.go
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ func (enc *gethEncodingServiceImpl) CreateEthHeaderForBatch(ctx context.Context,
// wrap in a caching layer
return enc.cachingService.ReadConvertedHeader(ctx, h.Hash(), func() (*types.Header, error) {
// deterministically calculate the private randomness that will be exposed to the EVM
perBatchRandomness := enc.entropyService.BatchEntropy(h.Number)
perBatchRandomness := enc.entropyService.BatchEntropy(h)

// calculate the converted hash of the parent, for a correct converted chain
// default to the genesis
Expand Down
3 changes: 1 addition & 2 deletions go/common/host/identity.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
package host

import (
gethcommon "github.com/ethereum/go-ethereum/common"
"github.com/ten-protocol/go-ten/go/common"
hostconfig "github.com/ten-protocol/go-ten/go/host/config"
)

type Identity struct {
ID gethcommon.Address
ID string
P2PPublicAddress string
IsGenesis bool
IsSequencer bool
Expand Down
3 changes: 0 additions & 3 deletions go/config/defaults/0-base-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,6 @@ enclave:
debug:
enableDebugNamespace: false
enableProfiler: false
l1:
enableBlockValidation: false
#genesisJSON: # json string of L1 genesis block, used for expectation todo: still needed?
log:
level: 1
path: sys_out
Expand Down
10 changes: 0 additions & 10 deletions go/config/enclave.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ type EnclaveConfig struct {

DB *EnclaveDB `mapstructure:"db"`
Debug *EnclaveDebug `mapstructure:"debug"`
L1 *EnclaveL1 `mapstructure:"l1"`
Log *EnclaveLog `mapstructure:"log"`
RPC *EnclaveRPC `mapstructure:"rpc"`
}
Expand All @@ -38,15 +37,6 @@ type EnclaveDebug struct {
EnableProfiler bool `mapstructure:"enableProfiler"`
}

// EnclaveL1 contains the configuration related to the L1 chain.
//
// yaml: `enclave.l1`
type EnclaveL1 struct {
EnableBlockValidation bool `mapstructure:"enableBlockValidation"`
// GenesisJSON is the genesis config for the L1 chain.
GenesisJSON []byte `mapstructure:"genesisJSON"`
}

// EnclaveLog contains the configuration for the enclave logger.
//
// yaml: `enclave.log`
Expand Down
6 changes: 2 additions & 4 deletions go/config/node.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package config

import (
gethcommon "github.com/ethereum/go-ethereum/common"
"github.com/ten-protocol/go-ten/go/common"
)

Expand All @@ -12,9 +11,8 @@ type NodeConfig struct {
NodeType common.NodeType `mapstructure:"nodeType"`
// Name of the node, used by orchestrator to name the containers etc., mostly useful for local testnets
Name string `mapstructure:"name"`
// The host's identity derived from the L1 Private Key
// todo: does node ID still need to exist? Look to remove in favour of enclave IDs
ID gethcommon.Address `mapstructure:"id"`
// Arbitrary identification of the node. Useful for debugging.
ID string `mapstructure:"id"`
// The public peer-to-peer IP address of the host
// todo: does host address still need to exist for the enclave to sign over or does the enclave ID cover the usages?
HostAddress string `mapstructure:"hostAddress"`
Expand Down
2 changes: 1 addition & 1 deletion go/enclave/components/batch_registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ func NewBatchRegistry(storage storage.Storage, config *enclaveconfig.EnclaveConf
lastExecutedBatch: async.NewAsyncTimestamp(time.Now().Add(-time.Minute)),
}

br.ethChainAdapter = NewEthChainAdapter(big.NewInt(config.ObscuroChainID), br, storage, gethEncodingService, *config, logger)
br.ethChainAdapter = NewEthChainAdapter(big.NewInt(config.TenChainID), br, storage, gethEncodingService, *config, logger)
return br
}

Expand Down
20 changes: 12 additions & 8 deletions go/enclave/components/block_processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,20 @@ func NewBlockProcessor(storage storage.Storage, cc *crosschain.Processors, gasOr
}

func (bp *l1BlockProcessor) Process(ctx context.Context, processed *common.ProcessedL1Data) (*BlockIngestionType, error) {
defer core.LogMethodDuration(bp.logger, measure.NewStopwatch(), "L1 block processed", log.BlockHashKey, processed.BlockHeader.Hash())
defer core.LogMethodDuration(bp.logger, measure.NewStopwatch(), "L1 block processed", log.BlockHashKey, processed.BlockHeader.Hash(), log.BlockHeightKey, processed.BlockHeader.Number)

ingestion, err := bp.tryAndInsertBlock(ctx, processed.BlockHeader)
if err != nil {
return nil, err
}

if !ingestion.PreGenesis {
if ingestion.FirstL1Block {
_, err := bp.storage.FetchBatchBySeqNo(ctx, common.L2GenesisSeqNo)
if err == nil {
// the genesis batch was processed already
return nil, fmt.Errorf("invalid state. The ten enclave must start by having access to L1 blocks before it can process batches")
}
} else {
// This requires block to be stored first ... but can permanently fail a block
err = bp.crossChainProcessors.Remote.StoreCrossChainMessages(ctx, processed.BlockHeader, processed)
if err != nil {
Expand Down Expand Up @@ -125,12 +131,10 @@ func (bp *l1BlockProcessor) tryAndInsertBlock(ctx context.Context, block *types.
}

func (bp *l1BlockProcessor) ingestBlock(ctx context.Context, block *types.Header) (*BlockIngestionType, error) {
// todo (#1056) - this is minimal L1 tracking/validation, and should be removed when we are using geth's blockchain or lightchain structures for validation
prevL1Head, err := bp.GetHead(ctx)
if err != nil {
if errors.Is(err, errutil.ErrNotFound) {
// todo (@matt) - we should enforce that this block is a configured hash (e.g. the L1 management contract deployment block)
return &BlockIngestionType{PreGenesis: true}, nil
return &BlockIngestionType{FirstL1Block: true}, nil
}
return nil, fmt.Errorf("could not retrieve head block. Cause: %w", err)
}
Expand All @@ -139,7 +143,7 @@ func (bp *l1BlockProcessor) ingestBlock(ctx context.Context, block *types.Header
return &BlockIngestionType{OldCanonicalBlock: true}, nil
}

// we do a basic sanity check, comparing the received block to the head block on the chain
// we do a basic security check, comparing the received block to the head block on the chain
if block.ParentHash != prevL1Head.Hash() {
isCanon, err := bp.storage.IsBlockCanonical(ctx, block.Hash())
if err != nil {
Expand All @@ -164,10 +168,10 @@ func (bp *l1BlockProcessor) ingestBlock(ctx context.Context, block *types.Header
} else {
bp.logger.Error("Should not happen. Weird Fork detected in the l1 chain", "fork", chainFork)
}
return &BlockIngestionType{ChainFork: chainFork, PreGenesis: false}, nil
return &BlockIngestionType{ChainFork: chainFork, FirstL1Block: false}, nil
}

return &BlockIngestionType{ChainFork: nil, PreGenesis: false}, nil
return &BlockIngestionType{ChainFork: nil, FirstL1Block: false}, nil
}

func (bp *l1BlockProcessor) GetHead(ctx context.Context) (*types.Header, error) {
Expand Down
6 changes: 2 additions & 4 deletions go/enclave/components/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,8 @@ import (
var ErrDuplicateRollup = errors.New("duplicate rollup received")

type BlockIngestionType struct {
// PreGenesis is true if there is no stored L1 head block.
// (L1 head is only stored when there is an L2 state to associate it with. Soon we will start consuming from the
// genesis block and then, we should only see one block ingested in a 'PreGenesis' state)
PreGenesis bool
// FirstL1Block is true if there is no stored L1 head block.
FirstL1Block bool

// ChainFork contains information about the status of the new block in the chain
ChainFork *common.ChainFork
Expand Down
95 changes: 48 additions & 47 deletions go/enclave/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,91 +11,92 @@ import (

// For now, this is the bridge between TenConfig and the config used internally by the enclave service.

// EnclaveConfig contains the full configuration for an Obscuro enclave service.
// EnclaveConfig contains the full configuration for an TEN enclave service.
type EnclaveConfig struct {
// The identity of the host the enclave service is tied to
HostID gethcommon.Address
// The public peer-to-peer IP address of the host the enclave service is tied to
HostAddress string
// The address on which to serve requests
Address string
// The type of the node.
NodeType common.NodeType
// **Consensus configs - must be the same for all nodes. Included in the signed image.
// Whether to produce a verified attestation report
WillAttest bool

// The ID of the L1 chain
L1ChainID int64
// The ID of the Obscuro chain
ObscuroChainID int64
// Whether to produce a verified attestation report
WillAttest bool
// Whether to validate incoming L1 blocks
ValidateL1Blocks bool
// When validating incoming blocks, the genesis config for the L1 chain
GenesisJSON []byte
TenChainID int64

// These L1 contracts must be already deployed before the TEN network is created
// The management contract address on the L1 network
ManagementContractAddress gethcommon.Address
// LogLevel determines the verbosity of output logs
LogLevel int
// The path that the enclave's logs are written to
LogPath string
// Whether the enclave should use in-memory or persistent storage
UseInMemoryDB bool
// host address for the edgeless DB instance (can be empty if using InMemory DB or if attestation is disabled)
EdgelessDBHost string
// filepath for the sqlite DB persistence file (can be empty if a throwaway file in /tmp/ is acceptable or
// if using InMemory DB or if attestation is enabled)
SqliteDBPath string
// ProfilerEnabled starts a profiler instance
ProfilerEnabled bool
// MinGasPrice is the minimum gas price for mining a transaction
MinGasPrice *big.Int
// MessageBus L1 Address
MessageBusAddress gethcommon.Address
// SystemContractOwner is the address that owns the system contracts
SystemContractOwner gethcommon.Address
// P2P address for validators to connect to the sequencer for live batch data
SequencerP2PAddress string
// A json string that specifies the prefunded addresses at the genesis of the TEN network
TenGenesis string
// Whether debug calls are available
DebugNamespaceEnabled bool

// Maximum bytes a batch can be uncompressed.
MaxBatchSize uint64
// MaxRollupSize - configured to be close to what the ethereum clients
// have configured as the maximum size a transaction can have. Note that this isn't
// a protocol limit, but a miner imposed limit and it might be hard to find someone
// to include a transaction if it goes above it
MaxRollupSize uint64
// MinGasPrice is the minimum gas price for mining a transaction
MinGasPrice *big.Int
// A json string that specifies the prefunded addresses at the genesis of the TEN network
TenGenesis string
GasPaymentAddress gethcommon.Address
BaseFee *big.Int
GasBatchExecutionLimit uint64

GasPaymentAddress gethcommon.Address
BaseFee *big.Int
GasBatchExecutionLimit uint64
GasLocalExecutionCapFlag uint64
// **Db configs
// Whether the enclave should use in-memory or persistent storage
UseInMemoryDB bool
// host address for the edgeless DB instance (can be empty if using InMemory DB or if attestation is disabled)
EdgelessDBHost string
// filepath for the sqlite DB persistence file (can be empty if a throwaway file in /tmp/ is acceptable or
// if using InMemory DB or if attestation is enabled)
SqliteDBPath string

// **Networking cfgs
// The address on which to serve requests
RPCAddress string
// RPCTimeout - calls that are longer than this will be cancelled, to prevent resource starvation
// normally, the context is propagated from the host, but in some cases ( like the evm, we have to create a context)
RPCTimeout time.Duration

// **Running config
// Arbitrary identification of the Node. Usually derived from the L1 wallet address. Useful for logging.
NodeID string
// LogLevel determines the verbosity of output logs
LogLevel int
// The path that the enclave's logs are written to
LogPath string
// StoreExecutedTransactions is a flag that instructs the current enclave to store data required to answer RPC queries.
StoreExecutedTransactions bool
// ProfilerEnabled starts a profiler instance
ProfilerEnabled bool
DebugNamespaceEnabled bool
GasLocalExecutionCapFlag uint64

// The type of the node. - todo - remove
NodeType common.NodeType
// The public peer-to-peer IP address of the host the enclave service is tied to
// This is required to advertise for node discovery, and we include it in the attestation
// todo - should we really bind the physical address to the attestation.
HostAddress string
}

func EnclaveConfigFromTenConfig(tenCfg *config.TenConfig) *EnclaveConfig {
return &EnclaveConfig{
HostID: tenCfg.Node.ID,
NodeID: tenCfg.Node.ID,
HostAddress: tenCfg.Node.HostAddress,
NodeType: tenCfg.Node.NodeType,
WillAttest: tenCfg.Enclave.EnableAttestation,
StoreExecutedTransactions: tenCfg.Enclave.StoreExecutedTransactions,

ObscuroChainID: tenCfg.Network.ChainID,
SequencerP2PAddress: tenCfg.Network.Sequencer.P2PAddress,
TenChainID: tenCfg.Network.ChainID,

Address: tenCfg.Enclave.RPC.BindAddress,
RPCAddress: tenCfg.Enclave.RPC.BindAddress,
RPCTimeout: tenCfg.Enclave.RPC.Timeout,

L1ChainID: tenCfg.Network.L1.ChainID,
ValidateL1Blocks: tenCfg.Enclave.L1.EnableBlockValidation,
GenesisJSON: tenCfg.Enclave.L1.GenesisJSON,
ManagementContractAddress: tenCfg.Network.L1.L1Contracts.ManagementContract,
MessageBusAddress: tenCfg.Network.L1.L1Contracts.MessageBusContract,
SystemContractOwner: tenCfg.Network.Sequencer.SystemContractsUpgrader,
Expand Down
11 changes: 2 additions & 9 deletions go/enclave/container/enclave_container.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,6 @@ import (
obscuroGenesis "github.com/ten-protocol/go-ten/go/enclave/genesis"
)

// todo (#1056) - replace with the genesis.json of Obscuro's L1 network.
const hardcodedGenesisJSON = "TODO - REPLACE ME"

type EnclaveContainer struct {
Enclave common.Enclave
RPCServer *enclave.RPCServer
Expand All @@ -44,7 +41,7 @@ func (e *EnclaveContainer) Stop() error {

// NewEnclaveContainerFromConfig wires up the components of the Enclave and its RPC server. Manages their lifecycle/monitors their status
func NewEnclaveContainerFromConfig(config *enclaveconfig.EnclaveConfig) *EnclaveContainer {
logger := log.New(log.EnclaveCmp, config.LogLevel, config.LogPath, log.NodeIDKey, config.HostID)
logger := log.New(log.EnclaveCmp, config.LogLevel, config.LogPath, log.NodeIDKey, config.NodeID)

logger.Info(fmt.Sprintf("Building enclave container with config: %+v", config))

Expand All @@ -56,17 +53,13 @@ func NewEnclaveContainerWithLogger(config *enclaveconfig.EnclaveConfig, logger g
contractAddr := config.ManagementContractAddress
mgmtContractLib := mgmtcontractlib.NewMgmtContractLib(&contractAddr, logger)

if config.ValidateL1Blocks {
config.GenesisJSON = []byte(hardcodedGenesisJSON)
}

genesis, err := obscuroGenesis.New(config.TenGenesis)
if err != nil {
logger.Crit("unable to parse obscuro genesis", log.ErrKey, err)
}

encl := enclave.NewEnclave(config, genesis, mgmtContractLib, logger)
rpcServer := enclave.NewEnclaveRPCServer(config.Address, encl, logger)
rpcServer := enclave.NewEnclaveRPCServer(config.RPCAddress, encl, logger)

return &EnclaveContainer{
Enclave: encl,
Expand Down
14 changes: 8 additions & 6 deletions go/enclave/crypto/evm_entropy_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import (
"fmt"
"math/big"

"github.com/ten-protocol/go-ten/go/common"

gethlog "github.com/ethereum/go-ethereum/log"

gethcommon "github.com/ethereum/go-ethereum/common"
Expand All @@ -23,16 +25,16 @@ func NewEvmEntropyService(sc *SharedSecretService, logger gethlog.Logger) *EvmEn
}

// BatchEntropy - calculates entropy per batch
// In Obscuro, we use a root entropy per batch, which is then used to calculate randomness exposed to individual transactions
// The RootBatchEntropy is calculated based on the shared secret and the batch height
// In Ten, we use a root entropy per batch, which is then used to calculate randomness exposed to individual transactions
// The RootBatchEntropy is calculated based on the shared secret, the batch height and the timestamp
// This ensures that sibling batches will naturally use the same root entropy so that transactions will have the same results
// Note that this formula is vulnerable to the unlikely event of a secret leak.
// todo (crypto) - find a way to hash in timestamp or something else then it would make it harder for attacker, such that sibling batches naturally have the same entropy.
func (ees *EvmEntropyService) BatchEntropy(batchHeight *big.Int) gethcommon.Hash {
func (ees *EvmEntropyService) BatchEntropy(batch *common.BatchHeader) gethcommon.Hash {
if !ees.sharedSecretService.IsInitialised() {
ees.logger.Crit("shared secret service is not initialised")
}
return gethcommon.BytesToHash(ees.sharedSecretService.ExtendEntropy(batchHeight.Bytes()))
extra := batch.Number.Bytes()
extra = append(extra, big.NewInt(int64(batch.Time)).Bytes()...)
return gethcommon.BytesToHash(ees.sharedSecretService.ExtendEntropy(extra))
}

// TxEntropy - calculates the randomness exposed to individual transactions
Expand Down
3 changes: 2 additions & 1 deletion go/enclave/crypto/shared_secret_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ func (sss *SharedSecretService) SetSharedSecret(ss *SharedEnclaveSecret) {

// ExtendEntropy derives more entropy from the shared secret
func (sss *SharedSecretService) ExtendEntropy(extra []byte) []byte {
return crypto.Keccak256(sss.secret[:], extra)
secretHash := crypto.Keccak256(sss.secret[:])
return crypto.Keccak256(secretHash, extra)
}

func (sss *SharedSecretService) EncryptSecretWithKey(pubKey []byte) (common.EncryptedSharedEnclaveSecret, error) {
Expand Down
Loading

0 comments on commit 37690af

Please sign in to comment.