-
Notifications
You must be signed in to change notification settings - Fork 39
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
L1 events and block processing (#2209)
* homogenise l1 events into singular block processing
- Loading branch information
1 parent
a12a05d
commit 514417e
Showing
48 changed files
with
1,832 additions
and
1,255 deletions.
There are no files selected for viewing
302 changes: 300 additions & 2 deletions
302
contracts/generated/ManagementContract/ManagementContract.go
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
# Standardizing L1 Data Processing | ||
|
||
## Requirements | ||
|
||
1. Standardise the way in which we process l1 blocks to find the relevant data needed for processing on the L2 | ||
2. Reduce the processing load on the enclave | ||
|
||
## Current Problems | ||
* Multiple redundant loops through L1 block data | ||
* Inconsistent processing patterns | ||
* Unnecessary load on the enclave | ||
* Scattered responsibility for L1 data extraction | ||
|
||
## Proposed Solution | ||
|
||
Filter logs from blocks using the Management Contract and MessageBus Contract address. Build a map of emitted event types | ||
against the transactions that created them. The events we care about: | ||
|
||
* Initialize secret | ||
* Request Secret | ||
* Secret Response | ||
* Rollup | ||
* Cross chain messages | ||
* Value transfers | ||
* Enclave granted sequencer | ||
* Enclave sequencer revoked | ||
|
||
```go | ||
const ( | ||
RollupTx L1TxType = iota | ||
InitialiseSecretTx | ||
SecretRequestTx | ||
SecretResponseTx | ||
CrossChainMessageTx | ||
CrossChainValueTranserTx | ||
SequencerAddedTx | ||
SequencerRevokedTx | ||
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 | ||
} | ||
``` | ||
## Guardian | ||
In the guardian we do all the transaction extraction to look for the event types we care about and then submit a | ||
`ProcessedL1Data` object to the enclave via gRPC in the `SubmitL1Block` function. | ||
|
||
`TODO` what proof to submit? | ||
|
||
## Enclave side | ||
|
||
On the enclave side we handle each of the `processedData.GetEvents[L1TxType]` individually and don't have duplicate loops | ||
through the transactions. | ||
|
||
Correct ordering of these event processing is going to be the biggest pain point I suspect. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -55,5 +55,5 @@ type P2PHostService interface { | |
|
||
type L1RepoService interface { | ||
Service | ||
L1BlockRepository | ||
L1DataService | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
package common | ||
|
||
import ( | ||
"math/big" | ||
|
||
gethcommon "github.com/ethereum/go-ethereum/common" | ||
"github.com/ethereum/go-ethereum/core/types" | ||
"github.com/ethereum/go-ethereum/crypto/kzg4844" | ||
) | ||
|
||
// L1TenTransaction is an abstraction that transforms an Ethereum transaction into a format that can be consumed more | ||
// easily by TEN. | ||
type L1TenTransaction interface{} | ||
|
||
type L1RollupTx struct { | ||
Rollup EncodedRollup | ||
} | ||
|
||
type L1RollupHashes struct { | ||
BlobHashes []gethcommon.Hash | ||
} | ||
|
||
type L1DepositTx struct { | ||
Amount *big.Int // Amount to be deposited | ||
To *gethcommon.Address // Address the ERC20 Transfer was made to (always be the Management Contract Addr) | ||
Sender *gethcommon.Address // Address that issued the ERC20, the token holder or tx.origin | ||
TokenContract *gethcommon.Address // Address of the ERC20 Contract address that was executed | ||
} | ||
|
||
type L1RespondSecretTx struct { | ||
Secret []byte | ||
RequesterID gethcommon.Address | ||
AttesterID gethcommon.Address | ||
AttesterSig []byte | ||
} | ||
|
||
type L1SetImportantContractsTx struct { | ||
Key string | ||
NewAddress gethcommon.Address | ||
} | ||
|
||
type L1RequestSecretTx struct { | ||
Attestation EncodedAttestationReport | ||
} | ||
|
||
type L1InitializeSecretTx struct { | ||
EnclaveID *gethcommon.Address | ||
InitialSecret []byte | ||
Attestation EncodedAttestationReport | ||
} | ||
|
||
// The following types and structs are used for processing the l1 blocks and categorising the transactions to be processed | ||
// by the enclave. | ||
|
||
// L1TenEventType represents different types of L1 transactions we monitor for | ||
type L1TenEventType uint8 // Change to uint8 for RLP serialization | ||
|
||
const ( | ||
RollupTx L1TenEventType = iota | ||
InitialiseSecretTx | ||
SecretRequestTx | ||
SecretResponseTx | ||
CrossChainMessageTx | ||
CrossChainValueTranserTx | ||
SequencerAddedTx | ||
SequencerRevokedTx | ||
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(tenEventType L1TenEventType, tx *L1TxData) { | ||
eventType := uint8(tenEventType) | ||
|
||
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 L1TenEventType) []*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 | ||
} |
Oops, something went wrong.