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

Allow block processing to continue with failed rollups #2285

Closed
wants to merge 28 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
4f1fa59
Modified how data is passed around.
StefanIliev545 Jan 29, 2025
ff02769
Added acquisition from l1 and processing in the dataservice
StefanIliev545 Jan 29, 2025
2e78d84
Code is in place, but there is a bug with signature verification; Som…
StefanIliev545 Jan 29, 2025
e7b653e
allow block processing to continue
badgersrus Jan 31, 2025
6f9bdde
better comments
badgersrus Jan 31, 2025
f248951
Update
StefanIliev545 Feb 2, 2025
4abe756
Passing no blobhash
StefanIliev545 Feb 2, 2025
9c0e341
Merge branch 'main' of https://github.com/ten-protocol/go-ten into wi…
badgersrus Feb 3, 2025
2981b98
only reject block if we error processing a rollup signed by the enclave
badgersrus Feb 3, 2025
e3124ad
Last 31 bytes only
StefanIliev545 Feb 3, 2025
aec549b
Merge branch 'main' into siliev/update-header-signatures
StefanIliev545 Feb 3, 2025
a323f55
Fix test build
StefanIliev545 Feb 3, 2025
3432f18
Fix linter
StefanIliev545 Feb 3, 2025
3ed1fa9
IT RUN NOW
StefanIliev545 Feb 5, 2025
45411a7
In mem changes
StefanIliev545 Feb 6, 2025
573b474
Merge branch 'main' of https://github.com/ten-protocol/go-ten into si…
badgersrus Feb 6, 2025
0cf527e
fix mock signature crud
badgersrus Feb 6, 2025
e4d8a51
remove function extraction
badgersrus Feb 6, 2025
eebc30a
lint
badgersrus Feb 6, 2025
999874a
Update smartcontracts_test.go
StefanIliev545 Feb 6, 2025
0d96e38
Compile with correct version.
Feb 6, 2025
2dddac3
Updated composite hash
StefanIliev545 Feb 6, 2025
2933b04
Contract bytecode.
Feb 6, 2025
e204351
allow block processing to continue
badgersrus Jan 31, 2025
4ec315f
better comments
badgersrus Jan 31, 2025
2c80436
rebase onto stefans
badgersrus Feb 7, 2025
85b3797
Merge branch 'will/rework-block-rejection' of https://github.com/ten-…
badgersrus Feb 7, 2025
60c821b
stashing:
badgersrus Feb 8, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 20 additions & 20 deletions contracts/generated/ManagementContract/ManagementContract.go

Large diffs are not rendered by default.

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

Expand Down Expand Up @@ -110,18 +110,17 @@ contract ManagementContract is Initializable, OwnableUpgradeable {

require(knownBlockHash != 0x0, "Unknown block hash");
require(knownBlockHash == r.BlockBindingHash, "Block binding mismatch");
require(blobhash(0) != bytes32(0), "Blob hash is not set");

bytes32 compositeHash = keccak256(abi.encodePacked(
r.LastSequenceNumber,
r.LastBatchHash,
r.BlockBindingHash,
r.BlockBindingNumber,
r.crossChainRoot,
r.BlobHash
blobhash(0)
));

// Verify the hash matches the one in the rollup
require(compositeHash == r.CompositeHash, "Composite hash mismatch");

// Verify the enclave signature
address enclaveID = ECDSA.recover(compositeHash, r.Signature);
require(attested[enclaveID], "enclaveID not attested");
Expand All @@ -136,9 +135,11 @@ contract ManagementContract is Initializable, OwnableUpgradeable {
if (r.crossChainRoot != bytes32(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)) {
merkleMessageBus.addStateRoot(r.crossChainRoot, block.timestamp);
}
emit RollupAdded(r.Hash);

emit RollupAdded(blobhash(0), r.Signature);
}


// InitializeNetworkSecret kickstarts the network secret, can only be called once
// solc-ignore-next-line unused-param
function InitializeNetworkSecret(address _enclaveID, bytes calldata _initSecret, string calldata _genesisAttestation) public {
Expand Down
5 changes: 2 additions & 3 deletions contracts/src/management/Structs.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,13 @@ import * as MessageBusStructs from "../messaging/Structs.sol";
interface Structs {
struct MetaRollup{
bytes32 Hash;
bytes Signature;
uint256 LastSequenceNumber;

bytes32 BlockBindingHash;
uint256 BlockBindingNumber;
bytes32 crossChainRoot;
bytes32 BlobHash;
bytes32 CompositeHash;
bytes32 LastBatchHash;
bytes Signature;
}

struct RollupStorage {
Expand Down
4 changes: 2 additions & 2 deletions go/common/enclave.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,8 @@ type EnclaveAdmin interface {
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(ctx context.Context, fromSeqNo uint64) (*ExtRollup, []*kzg4844.Blob, SystemError)
// or panic otherwise. Returns the rollup data including signature and blobs.
CreateRollup(ctx context.Context, fromSeqNo uint64) (*CreateRollupResult, SystemError)

// StreamL2Updates - will stream any new batches as they are created/detected
// All will be queued in the channel that has been returned.
Expand Down
16 changes: 7 additions & 9 deletions go/common/errutil/errors_util.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,13 @@ var (

// Standard errors that can be returned from block submission

ErrBlockAlreadyProcessed = errors.New("block already processed")
ErrBlockAncestorNotFound = errors.New("block ancestor not found")
ErrBlockForBatchNotFound = errors.New("block for batch not found")
ErrAncestorBatchNotFound = errors.New("parent for batch not found")
ErrCrossChainBundleRepublished = errors.New("root already added to the message bus")
ErrCrossChainBundleNoBatches = errors.New("no batches for cross chain bundle")
ErrNoNextRollup = errors.New("no next rollup")
ErrRollupForkMismatch = errors.New("rollup fork mismatch")
ErrCrossChainRootMismatch = errors.New("cross chain root mismatch")
ErrBlockAlreadyProcessed = errors.New("block already processed")
ErrBlockAncestorNotFound = errors.New("block ancestor not found")
ErrBlockForBatchNotFound = errors.New("block for batch not found")
ErrAncestorBatchNotFound = errors.New("parent for batch not found")
ErrCrossChainBundleNoBatches = errors.New("no batches for cross chain bundle")
ErrCrossChainRootMismatch = errors.New("cross chain root mismatch")
ErrCriticalRollupProcessing = errors.New("critical error during rollup processing")
)

// BlockRejectError is used as a standard format for error response from enclave for block submission errors
Expand Down
53 changes: 49 additions & 4 deletions go/common/headers.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (

"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto/kzg4844"

"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/rlp"
Expand Down Expand Up @@ -168,10 +169,55 @@ type RollupHeader struct {

CrossChainRoot common.Hash // The root hash of the cross chain tree.
LastBatchSeqNo uint64
BlobHash common.Hash
CompositeHash common.Hash // composite of everything
LastBatchHash common.Hash
}

Signature []byte // The signature of the sequencer enclave over the composite hash
// ComputeCompositeHash creates a composite hash matching the contract's expectations.
// It takes the last batch sequence number, current L1 hash and number, cross-chain root, and blob hash as inputs.
func ComputeCompositeHash(
header *RollupHeader,
blobHash common.Hash,
) common.Hash {
return crypto.Keccak256Hash(
common.LeftPadBytes(new(big.Int).SetUint64(header.LastBatchSeqNo).Bytes(), 32),
header.LastBatchHash.Bytes(),
header.CompressionL1Head.Bytes(),
common.LeftPadBytes(header.CompressionL1Number.Bytes(), 32),
header.CrossChainRoot.Bytes(),
blobHash.Bytes(),
)
}

const BlobVersion byte = 0x01

// DeriveBlobHash computes the versioned blob hash for the given blob.
// If blob is nil (or otherwise considered "non-existent"), it returns the zero hash.
func DeriveBlobHash(blob *kzg4844.Blob) (common.Hash, error) {
// If the blob doesn't exist, return the zero hash.
if blob == nil {
return common.Hash{}, nil
}

// Compute the KZG commitment for the blob.
// Adjust the function name and signature to match your KZG library.
commitment, err := kzg4844.BlobToCommitment(blob)
if err != nil {
return common.Hash{}, fmt.Errorf("failed to compute KZG commitment: %w", err)
}

// Serialize the commitment.
commitmentBytes := commitment[:31] // Expecting, for example, 48 bytes.

// Prepend the version byte.
// Create a new slice with capacity 1 + len(commitmentBytes).
versioned := make([]byte, 0, 1+len(commitmentBytes))
versioned = append(versioned, BlobVersion)
versioned = append(versioned, commitmentBytes...)

// Compute the Keccak-256 hash of the versioned commitment.
blobHash := crypto.Keccak256Hash(versioned)

return blobHash, nil
}

// CalldataRollupHeader contains all information necessary to reconstruct the batches included in the rollup.
Expand Down Expand Up @@ -231,7 +277,6 @@ func (b *BatchHeader) Hash() L2BatchHash {
// RLP encoding excluding the signature.
func (r *RollupHeader) Hash() L2RollupHash {
cp := *r
cp.Signature = nil
hash, err := rlpHash(cp)
if err != nil {
panic("err hashing rollup header")
Expand Down
4 changes: 1 addition & 3 deletions go/common/host/services.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ import (
"context"
"math/big"

"github.com/ethereum/go-ethereum/crypto/kzg4844"

"github.com/ten-protocol/go-ten/go/host/storage"

"github.com/ten-protocol/go-ten/go/responses"
Expand Down Expand Up @@ -109,7 +107,7 @@ type L1Publisher interface {
FindSecretResponseTx(responseTxs []*common.L1TxData) []*common.L1RespondSecretTx
// PublishBlob will create and publish a rollup tx to the management contract - fire and forget we don't wait for receipt
// todo (#1624) - With a single sequencer, it is problematic if rollup publication fails; handle this case better
PublishBlob(producedRollup *common.ExtRollup, blobs []*kzg4844.Blob)
PublishBlob(result common.CreateRollupResult)
// PublishSecretResponse will create and publish a secret response tx to the management contract - fire and forget we don't wait for receipt
PublishSecretResponse(secretResponse *common.ProducedSecretResponse) error

Expand Down
35 changes: 33 additions & 2 deletions go/common/l1_transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,15 +81,32 @@ type L1Event struct {
Txs []*L1TxData
}

type BlobAndSignature struct {
Blob *kzg4844.Blob
Signature RollupSignature
}

type BlobsAndSignatures []BlobAndSignature

func (b *BlobsAndSignatures) ToBlobs() []*kzg4844.Blob {
blobs := make([]*kzg4844.Blob, len(*b))
for i, blob := range *b {
blobs[i] = blob.Blob
}
return blobs
}

// 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
Blobs []*kzg4844.Blob // Only populated for blob transactions
BlobsWithSignature BlobsAndSignatures
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

Proof []byte // Some merkle proof TBC
}

// HasSequencerEnclaveID helper method to check if SequencerEnclaveID is set to avoid custom RLP when we send over grpc
Expand Down Expand Up @@ -139,3 +156,17 @@ func (p *ProcessedL1Data) GetEvents(txType L1TenEventType) []*L1TxData {
}
return nil
}

func (p *ProcessedL1Data) HasEvents(tenEventType L1TenEventType) bool {
if p == nil || len(p.Events) == 0 {
return false
}

for _, event := range p.Events {
if event.Type == uint8(tenEventType) && len(event.Txs) > 0 {
return true
}
}

return false
}
25 changes: 17 additions & 8 deletions go/common/rpc/converters.go
Original file line number Diff line number Diff line change
Expand Up @@ -210,12 +210,10 @@ func ToRollupHeaderMsg(header *common.RollupHeader) *generated.RollupHeaderMsg {
}
headerMsg := generated.RollupHeaderMsg{
CompressionL1Head: header.CompressionL1Head.Bytes(),
Signature: header.Signature,
LastBatchSeqNo: header.LastBatchSeqNo,
CrossChainRoot: header.CrossChainRoot.Bytes(),
CompressionL1Number: header.CompressionL1Number.Bytes(),
BlobHash: header.BlobHash.Bytes(),
CompositeHash: header.CompositeHash.Bytes(),
CrossChainRoot: header.CrossChainRoot.Bytes(),
LastBatchSeqNo: header.LastBatchSeqNo,
LastBatchHash: header.LastBatchHash.Bytes(),
}

return &headerMsg
Expand Down Expand Up @@ -245,9 +243,7 @@ func FromRollupHeaderMsg(header *generated.RollupHeaderMsg) *common.RollupHeader
CompressionL1Number: big.NewInt(0).SetBytes(header.CompressionL1Number),
CrossChainRoot: gethcommon.BytesToHash(header.CrossChainRoot),
LastBatchSeqNo: header.LastBatchSeqNo,
Signature: header.Signature,
BlobHash: gethcommon.BytesToHash(header.BlobHash),
CompositeHash: gethcommon.BytesToHash(header.CompositeHash),
LastBatchHash: gethcommon.BytesToHash(header.LastBatchHash),
}
}

Expand Down Expand Up @@ -289,3 +285,16 @@ func ToBlobMsgs(blobs []*kzg4844.Blob) []*generated.BlobMsg {
}
return msgs
}

func FromBlobMsgs(msgs []*generated.BlobMsg) []*kzg4844.Blob {
if msgs == nil {
return nil
}
blobs := make([]*kzg4844.Blob, len(msgs))
for i, msg := range msgs {
var blob kzg4844.Blob
copy(blob[:], msg.Blob)
blobs[i] = &blob
}
return blobs
}
Loading