Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
99 changes: 85 additions & 14 deletions crates/dashboard/src/dashboard.html
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,17 @@
font-size: 13px;
outline: none;
}
input[type="text"]:focus { border-color: var(--accent); }
input[type="text"]:focus, select:focus { border-color: var(--accent); }
select {
background: var(--bg);
border: 1px solid var(--border);
border-radius: 6px;
padding: 6px 12px;
color: var(--text);
font-size: 13px;
outline: none;
cursor: pointer;
}
button {
background: var(--accent);
color: #fff;
Expand Down Expand Up @@ -170,6 +180,9 @@
.badge-green { background: rgba(74,222,128,0.15); color: var(--green); }
.badge-red { background: rgba(248,113,113,0.15); color: var(--red); }
.badge-yellow { background: rgba(251,191,36,0.15); color: var(--yellow); }
tr.evt-error td { border-left: 3px solid var(--red); }
tr.evt-warn td { border-left: 3px solid var(--yellow); }
tr.evt-state td { border-left: 3px solid var(--green); }
</style>
</head>
<body>
Expand Down Expand Up @@ -206,6 +219,26 @@ <h2>Noir Prover</h2>
<div class="panel" id="panel-events">
<div class="controls">
<input type="text" id="evt-filter" placeholder="Filter by type...">
<input type="text" id="evt-e3-filter" placeholder="Filter by E3 ID...">
<select id="evt-source-filter">
<option value="">All sources</option>
<option value="Local">Local</option>
<option value="Net">Net</option>
<option value="Evm">Evm</option>
</select>
<select id="evt-severity-filter">
<option value="">All events</option>
<option value="error">Errors only</option>
<option value="warning">Warnings</option>
<option value="state">State changes</option>
</select>
Comment thread
ctrlc03 marked this conversation as resolved.
<select id="evt-sort">
<option value="seq-desc">Newest first</option>
<option value="seq-asc">Oldest first</option>
<option value="type-asc">Type A-Z</option>
<option value="type-desc">Type Z-A</option>
<option value="source-asc">Source A-Z</option>
</select>
<button id="evt-refresh" onclick="loadEvents()">Refresh</button>
<label><input type="checkbox" id="evt-auto"> Auto-refresh</label>
</div>
Expand Down Expand Up @@ -322,7 +355,7 @@ <h2>Wallet</h2>
async function loadEvents(since, append) {
try {
const s = since !== undefined ? since : 0;
const text = await api('/api/events?since=' + s + '&limit=50');
const text = await api('/api/events?since=' + s + '&limit=500');
Comment thread
ctrlc03 marked this conversation as resolved.
// Split on newlines first; if a line fails to parse, try splitting on }{ boundaries
const lines = text.trim().split('\n').filter(function(l) { return l.trim().length > 0; });
if (!append) allEvents = [];
Expand Down Expand Up @@ -366,21 +399,49 @@ <h2>Wallet</h2>
if (eventCursor !== null) loadEvents(eventCursor, true);
}

var ERROR_TYPES = ['EnclaveError','E3Failed','ProofVerificationFailed','SignedProofFailed','ThresholdShareCollectionFailed','EncryptionKeyCollectionFailed'];
var WARNING_TYPES = ['AccusationVote','ProofFailureAccusation','CommitmentMismatch'];
var STATE_TYPES = ['E3Requested','CiphernodeSelected','CommitteePublished','CommitteeFinalized','CiphertextOutputPublished','PlaintextOutputPublished','PlaintextAggregated','E3StageChanged'];

function renderEvents() {
const filter = document.getElementById('evt-filter').value.toLowerCase();
const tbody = document.getElementById('evt-body');
const rows = [];
for (const evt of allEvents) {
const ctx = evt.ctx || {};
const type = extractType(evt);
var filter = document.getElementById('evt-filter').value.toLowerCase();
var e3Filter = document.getElementById('evt-e3-filter').value.toLowerCase();
var sourceFilter = document.getElementById('evt-source-filter').value;
var severityFilter = document.getElementById('evt-severity-filter').value;
var sortKey = document.getElementById('evt-sort').value;
var sorted = allEvents.slice();
sorted.sort(function(a, b) {
var seqA = (a.ctx || {}).seq || 0;
var seqB = (b.ctx || {}).seq || 0;
if (sortKey === 'seq-asc') return seqA - seqB;
if (sortKey === 'seq-desc') return seqB - seqA;
var typeA = extractType(a);
var typeB = extractType(b);
if (sortKey === 'type-asc') return typeA.localeCompare(typeB);
if (sortKey === 'type-desc') return typeB.localeCompare(typeA);
if (sortKey === 'source-asc') return ((a.ctx || {}).source || '').localeCompare((b.ctx || {}).source || '');
return seqB - seqA;
});
var tbody = document.getElementById('evt-body');
var rows = [];
for (var i = 0; i < sorted.length; i++) {
var evt = sorted[i];
var ctx = evt.ctx || {};
var type = extractType(evt);
if (filter && !type.toLowerCase().includes(filter)) continue;
const seq = ctx.seq !== undefined ? ctx.seq : '-';
const e3id = extractE3Id(evt);
const src = ctx.source || '-';
var e3id = extractE3Id(evt);
if (e3Filter && !String(e3id).toLowerCase().includes(e3Filter)) continue;
if (sourceFilter && ctx.source !== sourceFilter) continue;
if (severityFilter === 'error' && !ERROR_TYPES.some(function(t) { return type === t; })) continue;
if (severityFilter === 'warning' && !WARNING_TYPES.some(function(t) { return type === t; })) continue;
if (severityFilter === 'state' && !STATE_TYPES.some(function(t) { return type === t; })) continue;
var seq = ctx.seq !== undefined ? ctx.seq : '-';
var src = ctx.source || '-';
const id = 'evt-' + rows.length;
var ts = hlcToTime(ctx.ts);
var rowClass = ERROR_TYPES.indexOf(type) >= 0 ? 'evt-error' : WARNING_TYPES.indexOf(type) >= 0 ? 'evt-warn' : STATE_TYPES.indexOf(type) >= 0 ? 'evt-state' : '';
rows.push(
'<tr onclick="toggleDetail(\'' + id + '\')" style="cursor:pointer">' +
'<tr class="' + rowClass + '" onclick="toggleDetail(\'' + id + '\')" style="cursor:pointer">' +
'<td>' + esc(String(seq)) + '</td>' +
'<td>' + esc(ts) + '</td>' +
'<td>' + esc(type) + '</td>' +
Expand All @@ -391,6 +452,7 @@ <h2>Wallet</h2>
);
}
tbody.innerHTML = rows.length ? rows.join('') : '<tr><td colspan="5" class="loading">No events</td></tr>';
document.getElementById('evt-refresh').textContent = 'Refresh (' + allEvents.length + ' total, ' + rows.length + ' shown)';
}

function extractType(evt) {
Expand All @@ -402,9 +464,14 @@ <h2>Wallet</h2>

function extractE3Id(evt) {
if (!evt.payload) return '-';
const data = Object.values(evt.payload)[0];
var data = Object.values(evt.payload)[0];
if (!data || typeof data !== 'object') return '-';
return data.e3_id || data.e3Id || '-';
var eid = data.e3_id !== undefined ? data.e3_id : data.e3Id;
if (eid == null) return '-';
if (typeof eid === 'object' && eid.id !== undefined) {
return eid.chain_id !== undefined ? eid.chain_id + ':' + eid.id : String(eid.id);
}
return String(eid);
}

function toggleDetail(id) {
Expand All @@ -413,6 +480,10 @@ <h2>Wallet</h2>
}

document.getElementById('evt-filter').addEventListener('input', renderEvents);
document.getElementById('evt-e3-filter').addEventListener('input', renderEvents);
document.getElementById('evt-source-filter').addEventListener('change', renderEvents);
document.getElementById('evt-severity-filter').addEventListener('change', renderEvents);
document.getElementById('evt-sort').addEventListener('change', renderEvents);

// Auto-refresh for events
document.getElementById('evt-auto').addEventListener('change', function() {
Expand Down
2 changes: 1 addition & 1 deletion crates/keyshare/src/decryption_key_shared_collector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use tracing::{info, warn};

use crate::ThresholdKeyshare;

const DEFAULT_COLLECTION_TIMEOUT: Duration = Duration::from_secs(1200);
const DEFAULT_COLLECTION_TIMEOUT: Duration = Duration::from_secs(3600);

enum CollectorState {
Collecting,
Expand Down
2 changes: 1 addition & 1 deletion crates/keyshare/src/encryption_key_collector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use e3_trbfv::PartyId;
use e3_utils::MAILBOX_LIMIT;
use tracing::{info, warn};

const DEFAULT_COLLECTION_TIMEOUT: Duration = Duration::from_secs(60);
const DEFAULT_COLLECTION_TIMEOUT: Duration = Duration::from_secs(600);

use crate::ThresholdKeyshare;

Expand Down
2 changes: 1 addition & 1 deletion crates/keyshare/src/threshold_share_collector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ pub struct ReceivedShareProofs {
pub signed_c3b_proofs: Vec<SignedProofPayload>,
}

const DEFAULT_COLLECTION_TIMEOUT: Duration = Duration::from_secs(800);
const DEFAULT_COLLECTION_TIMEOUT: Duration = Duration::from_secs(3600);

pub(crate) enum CollectorState {
Collecting,
Expand Down
7 changes: 4 additions & 3 deletions crates/net/src/net_interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,10 @@ use tokio::{
use tracing::{debug, error, info, trace, warn};

const PROTOCOL_NAME: StreamProtocol = StreamProtocol::new("/enclave/kad/1.0.0");
const MAX_KADEMLIA_PAYLOAD_MB: usize = 10;
const MAX_KADEMLIA_PAYLOAD_MB: usize = 100;
const MAX_KADEMLIA_RECORD_MB: usize = 25; // Largest record: ~21MB ThresholdShare with prod params
const DHT_MAX_RECORDS: usize = 4096;
const MAX_GOSSIP_MSG_SIZE_KB: usize = 700;
const MAX_GOSSIP_MSG_SIZE_KB: usize = 10240; // 10MB — prod params C6 proofs are ~4.6MB
Comment thread
ctrlc03 marked this conversation as resolved.
const MAX_CONSECUTIVE_DIAL_FAILURES: u32 = 40;
const EVENT_CHANNEL_SIZE: usize = 1000;
const CMD_CHANNEL_SIZE: usize = 1000;
Expand Down Expand Up @@ -308,7 +309,7 @@ fn create_behaviour(
.set_query_timeout(Duration::from_secs(30));
let store_config = MemoryStoreConfig {
max_records: DHT_MAX_RECORDS,
max_value_bytes: MAX_KADEMLIA_PAYLOAD_MB * 1024 * 1024,
max_value_bytes: MAX_KADEMLIA_RECORD_MB * 1024 * 1024,
max_providers_per_key: usize::MAX,
max_provided_keys: DHT_MAX_RECORDS,
};
Expand Down
1 change: 1 addition & 0 deletions crates/program-server/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ impl E3ProgramServer {
let server = HttpServer::new(move || {
App::new()
.app_data(web::Data::new(config.clone()))
.app_data(web::JsonConfig::default().limit(10 * 1024 * 1024)) // 10MB for prod params
.wrap(Logger::default())
.route("/run_compute", web::post().to(handle_compute))
.route("/health", web::get().to(handle_health_check))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ use super::commitment_links;
use anyhow::Result;
use async_trait::async_trait;
use e3_events::{BusHandle, EnclaveEvent, EnclaveEventData, Event};
use e3_request::{E3Context, E3ContextSnapshot, E3Extension};
use tracing::info;
use e3_request::{E3Context, E3ContextSnapshot, E3Extension, META_KEY};
use tracing::{error, info};

pub struct CommitmentConsistencyCheckerExtension {
bus: BusHandle,
Expand Down Expand Up @@ -46,9 +46,14 @@ impl E3Extension for CommitmentConsistencyCheckerExtension {

let e3_id = data.e3_id.clone();

let Some(meta) = ctx.get_dependency(META_KEY) else {
error!("E3Meta not available — cannot start CommitmentConsistencyChecker");
return;
};

info!("Starting CommitmentConsistencyChecker for E3 {}", e3_id);

let links = commitment_links::default_links();
let links = commitment_links::default_links(meta.params_preset);
let addr = CommitmentConsistencyChecker::setup(&self.bus, e3_id, links);

ctx.set_event_recipient("commitment_consistency_checker", Some(addr.into()));
Expand Down
6 changes: 3 additions & 3 deletions crates/zk-prover/src/actors/commitment_links/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ pub mod c4b_to_c6;
pub mod c6_to_c7;

use e3_events::ProofType;
use e3_fhe_params::DEFAULT_BFV_PRESET;
use e3_fhe_params::BfvPreset;

/// A 32-byte BN254 field element extracted from public signals.
pub type FieldValue = [u8; 32];
Expand Down Expand Up @@ -104,8 +104,8 @@ pub trait CommitmentLink: Send + Sync {
/// that C4 consumes as `expected_commitments`. Since C2→C3 already ensures
/// C3 encrypts the correct share, C2→C4 closes the remaining gap (preventing
/// a party from using different commitments in C4 than they computed in C2).
pub fn default_links() -> Vec<Box<dyn CommitmentLink>> {
let l = DEFAULT_BFV_PRESET.metadata().num_moduli;
pub fn default_links(preset: BfvPreset) -> Vec<Box<dyn CommitmentLink>> {
let l = preset.metadata().num_moduli;
vec![
Box::new(c0_to_c3::C3aToC0PkCommitmentLink),
Box::new(c0_to_c3::C3bToC0PkCommitmentLink),
Expand Down
2 changes: 1 addition & 1 deletion examples/CRISP/enclave.config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ chains:
rpc_url: ws://localhost:8545
contracts:
e3_program:
address: "0x809d550fca64d94Bd9F66E60752A544199cfAC3D"
address: "0x4c5859f0F772848b2D91F1D83E2Fe57935348029"
deploy_block: 31
enclave:
address: "0xB7f8BC63BbcaD18155201308C8f3540b07f84F5e"
Expand Down
Loading
Loading