Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP - L1 events and block processing #2209

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
302 changes: 300 additions & 2 deletions contracts/generated/ManagementContract/ManagementContract.go

Large diffs are not rendered by default.

21 changes: 13 additions & 8 deletions contracts/src/management/ManagementContract.sol
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ contract ManagementContract is Initializable, OwnableUpgradeable {
event SequencerEnclaveGranted(address enclaveID);
event SequencerEnclaveRevoked(address enclaveID);
event RollupAdded(bytes32 rollupHash);
event NetworkSecretRequested(address indexed requester, string requestReport);
event NetworkSecretResponded(address indexed attester, address indexed requester);

// mapping of enclaveID to whether it is attested
mapping(address => bool) private attested;
Expand Down Expand Up @@ -113,13 +115,13 @@ contract ManagementContract is Initializable, OwnableUpgradeable {
}

function addCrossChainMessagesRoot(bytes32 _lastBatchHash, bytes32 blockHash, uint256 blockNum, bytes[] memory crossChainHashes, bytes calldata signature, uint256 rollupNumber, bytes32 forkID) external {
/* if (block.number > blockNum + 255) {
revert("Block binding too old");
}
/* if (block.number > blockNum + 255) {
revert("Block binding too old");
}

if ((blockhash(blockNum) != blockHash)) {
revert(string(abi.encodePacked("Invalid block binding:", Strings.toString(block.number),":", Strings.toString(uint256(blockHash)), ":", Strings.toString(uint256(blockhash(blockNum))))));
} */
if ((blockhash(blockNum) != blockHash)) {
revert(string(abi.encodePacked("Invalid block binding:", Strings.toString(block.number),":", Strings.toString(uint256(blockHash)), ":", Strings.toString(uint256(blockhash(blockNum))))));
} */

if (rollups.toUniqueForkID[rollupNumber] != forkID) {
revert("Invalid forkID");
Expand Down Expand Up @@ -179,6 +181,7 @@ contract ManagementContract is Initializable, OwnableUpgradeable {
// Enclaves can request the Network Secret given an attestation request report
function RequestNetworkSecret(string calldata requestReport) public {
// currently this is a no-op, nodes will monitor for these transactions and respond to them
emit NetworkSecretRequested(msg.sender, requestReport);
}

function ExtractNativeValue(MessageStructs.Structs.ValueTransferMessage calldata _msg, bytes32[] calldata proof, bytes32 root) external {
Expand All @@ -200,7 +203,7 @@ contract ManagementContract is Initializable, OwnableUpgradeable {
require(isEnclAttested, "responding attester is not attested");

if (verifyAttester) {

// the data must be signed with by the correct private key
// signature = f(PubKey, PrivateKey, message)
// address = f(signature, message)
Expand All @@ -213,6 +216,8 @@ contract ManagementContract is Initializable, OwnableUpgradeable {

// mark the requesterID enclave as an attested enclave and store its host address
attested[requesterID] = true;

emit NetworkSecretResponded(attesterID, requesterID);
}


Expand Down Expand Up @@ -263,4 +268,4 @@ contract ManagementContract is Initializable, OwnableUpgradeable {
function GetImportantContractKeys() public view returns(string[] memory) {
return importantContractKeys;
}
}
}
2 changes: 1 addition & 1 deletion go/common/enclave.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ type EnclaveAdmin interface {
// 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(ctx context.Context, blockHeader *types.Header, receipts []*TxAndReceiptAndBlobs) (*BlockSubmissionResponse, SystemError)
SubmitL1Block(ctx context.Context, blockHeader *types.Header, processed *ProcessedL1Data) (*BlockSubmissionResponse, SystemError)

// SubmitBatch submits a batch received from the sequencer for processing.
SubmitBatch(ctx context.Context, batch *ExtBatch) SystemError
Expand Down
7 changes: 3 additions & 4 deletions go/common/host/services.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,8 @@ type L1BlockRepository interface {
// FetchNextBlock returns the next canonical block after a given block hash
// It returns the new block, a bool which is true if the block is the current L1 head and a bool if the block is on a different fork to prevBlock
FetchNextBlock(prevBlock gethcommon.Hash) (*types.Block, bool, error)
// FetchObscuroReceipts returns the receipts for a given L1 block
FetchObscuroReceipts(block *common.L1Block) (types.Receipts, error)
// ExtractTenTransactions returns the events and transactions relevant to Ten
ExtractTenTransactions(block *common.L1Block) (*common.ProcessedL1Data, error)
}

// L1BlockHandler is an interface for receiving new blocks from the repository as they arrive
Expand All @@ -101,8 +101,7 @@ type L1Publisher interface {
InitializeSecret(attestation *common.AttestationReport, encSecret common.EncryptedSharedEnclaveSecret) error
// RequestSecret will send a management contract transaction to request a secret from the enclave, returning the L1 head at time of sending
RequestSecret(report *common.AttestationReport) (gethcommon.Hash, error)
// ExtractRelevantTenTransactions will return all TEN relevant tx from an L1 block
ExtractRelevantTenTransactions(block *types.Block, receipts types.Receipts) ([]*common.TxAndReceiptAndBlobs, []*ethadapter.L1RollupTx, []*ethadapter.L1SetImportantContractsTx)
// FIXME DELETE
// FindSecretResponseTx will return the secret response tx from an L1 block
FindSecretResponseTx(block *types.Block) []*ethadapter.L1RespondSecretTx
// PublishRollup will create and publish a rollup tx to the management contract - fire and forget we don't wait for receipt
Expand Down
92 changes: 92 additions & 0 deletions go/common/l1_transaction.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package common

import (
gethcommon "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto/kzg4844"
)

// L1TxType represents different types of L1 transactions
type L1TxType uint8 // Change to uint8 for RLP serialization

const (
RollupTx L1TxType = iota
InitialiseSecretTx
SecretRequestTx
SecretResponseTx
CrossChainMessageTx
CrossChainValueTranserTx
SequencerAddedTx
SetImportantContractsTx
)

// ProcessedL1Data is submitted to the enclave by the guardian
type ProcessedL1Data struct {
BlockHeader *types.Header
Events []L1Event
}

// L1Event represents a single event type and its associated transactions
type L1Event struct {
Type uint8
Txs []*L1TxData
}

// L1TxData represents an L1 transaction that are relevant to us
type L1TxData struct {
Transaction *types.Transaction
Receipt *types.Receipt
Blobs []*kzg4844.Blob // Only populated for blob transactions
SequencerEnclaveID gethcommon.Address // Only non-zero when a new enclave is added as a sequencer
CrossChainMessages CrossChainMessages // Only populated for xchain messages
ValueTransfers ValueTransferEvents // Only populated for xchain transfers
Proof []byte // Some merkle proof TBC
}

// HasSequencerEnclaveID helper method to check if SequencerEnclaveID is set to avoid custom RLP when we send over grpc
func (tx *L1TxData) HasSequencerEnclaveID() bool {
return tx.SequencerEnclaveID != (gethcommon.Address{})
}

func (p *ProcessedL1Data) AddEvent(txType L1TxType, tx *L1TxData) {
eventType := uint8(txType)

for i := range p.Events {
if p.Events[i].Type != eventType {
continue
}

txHash := tx.Transaction.Hash()

// check for duplicate transaction
for _, existingTx := range p.Events[i].Txs {
if existingTx.Transaction.Hash() == txHash {
return // Skip duplicate transaction
}
}

p.Events[i].Txs = append(p.Events[i].Txs, tx)
return
}

p.Events = append(p.Events, L1Event{
Type: eventType,
Txs: []*L1TxData{tx},
})
}

func (p *ProcessedL1Data) GetEvents(txType L1TxType) []*L1TxData {
if p == nil || len(p.Events) == 0 {
return nil
}

for _, event := range p.Events {
if event.Type == uint8(txType) {
if event.Txs == nil {
return nil
}
return event.Txs
}
}
return nil
}
Loading
Loading