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

Protocol: attest against EnclaveID rather than HostID #1831

Merged
merged 9 commits into from
Mar 18, 2024
42 changes: 21 additions & 21 deletions contracts/generated/ManagementContract/ManagementContract.go

Large diffs are not rendered by default.

40 changes: 19 additions & 21 deletions contracts/src/management/ManagementContract.sol
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ contract ManagementContract is Initializable, OwnableUpgradeable {
// Event to log changes to important contract addresses
event ImportantContractAddressUpdated(string key, address newAddress);

mapping(address => string) private attestationRequests;
// mapping of enclaveID to whether it is attested
mapping(address => bool) private attested;
// TODO - Revisit the decision to store the host addresses in the smart contract.
string[] private hostAddresses; // The addresses of all the Obscuro hosts on the network.
string[] private hostAddresses; // The addresses of all the Ten hosts on the network.

// In the near-term it is convenient to have an accessible source of truth for important contract addresses
// TODO - this is probably not appropriate long term but currently useful for testnets. Look to remove.
Expand Down Expand Up @@ -77,45 +77,43 @@ contract ManagementContract is Initializable, OwnableUpgradeable {

// solc-ignore-next-line unused-param
function AddRollup(Structs.MetaRollup calldata r, string calldata _rollupData, Structs.HeaderCrossChainData calldata crossChainData) public {
// TODO How to ensure the sender without hashing the calldata ?
// bytes32 derp = keccak256(abi.encodePacked(ParentHash, AggregatorID, L1Block, Number, rollupData));

// TODO: Add a check that ensures the cross messages are coming from the correct fork using block hashes.

// revert if the AggregatorID is not attested
require(attested[r.AggregatorID], "aggregator not attested");
// todo: verify this enclaveID is a permissioned Sequencer enclaveID
address enclaveID = ECDSA.recover(r.Hash, r.Signature);
// revert if the EnclaveID is not attested
require(attested[enclaveID], "enclaveID not attested");

AppendRollup(r);
pushCrossChainMessages(crossChainData);
}

// InitializeNetworkSecret kickstarts the network secret, can only be called once
// solc-ignore-next-line unused-param
function InitializeNetworkSecret(address _aggregatorID, bytes calldata _initSecret, string memory _hostAddress, string calldata _genesisAttestation) public {
require(!networkSecretInitialized);
function InitializeNetworkSecret(address _enclaveID, bytes calldata _initSecret, string memory _hostAddress, string calldata _genesisAttestation) public {
require(!networkSecretInitialized, "network secret already initialized");

// network can no longer be initialized
networkSecretInitialized = true;

// aggregator is now on the list of attested aggregators and its host address is available
attested[_aggregatorID] = true;
// enclave is now on the list of attested enclaves (and its host address is published for p2p)
attested[_enclaveID] = true;
hostAddresses.push(_hostAddress);
}

// Aggregators can request the Network Secret given an attestation request report
// Enclaves can request the Network Secret given an attestation request report
function RequestNetworkSecret(string calldata requestReport) public {
// Attestations should only be allowed to produce once ?
attestationRequests[msg.sender] = requestReport;
// currently this is a no-op, nodes will monitor for these transactions and respond to them
}

// Attested node will pickup on Network Secret Request
// and if valid will respond with the Network Secret
// An attested enclave will pickup the Network Secret Request
// and, if valid, will respond with the Network Secret
// and mark the requesterID as attested
// @param verifyAttester Whether to ask the attester to complete a challenge (signing a hash) to prove their identity.
function RespondNetworkSecret(address attesterID, address requesterID, bytes memory attesterSig, bytes memory responseSecret, string memory hostAddress, bool verifyAttester) public {
// only attested aggregators can respond to Network Secret Requests
bool isAggAttested = attested[attesterID];
require(isAggAttested);
// only attested enclaves can respond to Network Secret Requests
bool isEnclAttested = attested[attesterID];
require(isEnclAttested, "responding attester is not attested");

if (verifyAttester) {

Expand All @@ -127,9 +125,9 @@ contract ManagementContract is Initializable, OwnableUpgradeable {
address recoveredAddrSignedCalculated = ECDSA.recover(calculatedHashSigned, attesterSig);

require(recoveredAddrSignedCalculated == attesterID, "calculated address and attesterID dont match");
}
}

// mark the requesterID aggregator as an attested aggregator and store its host address
// mark the requesterID enclave as an attested enclave and store its host address
attested[requesterID] = true;
// TODO - Consider whether to remove duplicates.
hostAddresses.push(hostAddress);
Expand Down
2 changes: 1 addition & 1 deletion contracts/src/management/Structs.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import * as MessageBusStructs from "../messaging/Structs.sol";
interface Structs {
struct MetaRollup{
bytes32 Hash;
address AggregatorID;
bytes Signature;
uint256 LastSequenceNumber;
}

Expand Down
3 changes: 2 additions & 1 deletion go/common/enclave.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,8 @@ type BlockSubmissionResponse struct {
// ProducedSecretResponse contains the data to publish to L1 in response to a secret request discovered while processing an L1 block
type ProducedSecretResponse struct {
Secret []byte
RequesterID gethcommon.Address
RequesterID gethcommon.Address // enclaveID of the enclave that requested the secret
AttesterID gethcommon.Address // enclaveID of the enclave that produced the secret
HostAddress string
}

Expand Down
3 changes: 1 addition & 2 deletions go/common/headers.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,13 +126,12 @@ func (b *BatchHeader) UnmarshalJSON(data []byte) error {
// RollupHeader is a public / plaintext struct that holds common properties of rollups.
// All these fields are processed by the Management contract
type RollupHeader struct {
Coinbase common.Address
CompressionL1Head L1BlockHash // the l1 block that the sequencer considers canonical at the time when this rollup is created

CrossChainMessages []MessageBus.StructsCrossChainMessage `json:"crossChainMessages"`

PayloadHash common.Hash // The hash of the compressed batches. TODO
Signature []byte // The signature of the sequencer on the payload hash
Signature []byte // The signature of the sequencer enclave on the payload hash

LastBatchSeqNo uint64
}
Expand Down
8 changes: 4 additions & 4 deletions go/common/rpc/converters.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,14 @@ import (
// Protobuf message classes.

func ToAttestationReportMsg(report *common.AttestationReport) generated.AttestationReportMsg {
return generated.AttestationReportMsg{Report: report.Report, PubKey: report.PubKey, Owner: report.Owner.Bytes(), HostAddress: report.HostAddress}
return generated.AttestationReportMsg{Report: report.Report, PubKey: report.PubKey, EnclaveID: report.EnclaveID.Bytes(), HostAddress: report.HostAddress}
}

func FromAttestationReportMsg(msg *generated.AttestationReportMsg) *common.AttestationReport {
return &common.AttestationReport{
Report: msg.Report,
PubKey: msg.PubKey,
Owner: gethcommon.BytesToAddress(msg.Owner),
EnclaveID: gethcommon.BytesToAddress(msg.EnclaveID),
HostAddress: msg.HostAddress,
}
}
Expand All @@ -46,6 +46,7 @@ func ToSecretRespMsg(responses []*common.ProducedSecretResponse) []*generated.Se
msg := generated.SecretResponseMsg{
Secret: resp.Secret,
RequesterID: resp.RequesterID.Bytes(),
AttesterID: resp.AttesterID.Bytes(),
HostAddress: resp.HostAddress,
}
respMsgs[i] = &msg
Expand All @@ -61,6 +62,7 @@ func FromSecretRespMsg(secretResponses []*generated.SecretResponseMsg) []*common
r := common.ProducedSecretResponse{
Secret: msgResp.Secret,
RequesterID: gethcommon.BytesToAddress(msgResp.RequesterID),
AttesterID: gethcommon.BytesToAddress(msgResp.AttesterID),
HostAddress: msgResp.HostAddress,
}
respList[i] = &r
Expand Down Expand Up @@ -218,7 +220,6 @@ func ToRollupHeaderMsg(header *common.RollupHeader) *generated.RollupHeaderMsg {
headerMsg := generated.RollupHeaderMsg{
CompressionL1Head: header.CompressionL1Head.Bytes(),
Signature: header.Signature,
Coinbase: header.Coinbase.Bytes(),
CrossChainMessages: ToCrossChainMsgs(header.CrossChainMessages),
LastBatchSeqNo: header.LastBatchSeqNo,
}
Expand Down Expand Up @@ -248,7 +249,6 @@ func FromRollupHeaderMsg(header *generated.RollupHeaderMsg) *common.RollupHeader
return &common.RollupHeader{
CompressionL1Head: gethcommon.BytesToHash(header.CompressionL1Head),
Signature: header.Signature,
Coinbase: gethcommon.BytesToAddress(header.Coinbase),
CrossChainMessages: FromCrossChainMsgs(header.CrossChainMessages),
LastBatchSeqNo: header.LastBatchSeqNo,
}
Expand Down
Loading
Loading