#!/bin/bash # Test SUP-01: Single-Hop Routing # Tests: Builder → Thrower A → Final Relay set -e TEST_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$TEST_DIR/helpers/timing_utils.sh" source "$TEST_DIR/helpers/event_utils.sh" # Load test configuration KEYS_FILE="$TEST_DIR/fixtures/test_keys.json" RELAYS_FILE="$TEST_DIR/fixtures/test_relays.json" # Extract keys BUILDER_PRIVKEY=$(jq -r '.builder.privkey' "$KEYS_FILE") BUILDER_PUBKEY=$(jq -r '.builder.pubkey' "$KEYS_FILE") THROWER_A_PRIVKEY=$(jq -r '.thrower_a.privkey' "$KEYS_FILE") THROWER_A_PUBKEY=$(jq -r '.thrower_a.pubkey' "$KEYS_FILE") # Extract relays THROWER_RELAY=$(jq -r '.test_scenarios.single_hop.thrower_relay' "$RELAYS_FILE") FINAL_RELAY=$(jq -r '.test_scenarios.single_hop.final_relay' "$RELAYS_FILE") echo "=== SUP-01: Single-Hop Routing Test ===" echo "Builder: $BUILDER_PUBKEY" echo "Thrower A: $THROWER_A_PUBKEY" echo "Thrower Relay: $THROWER_RELAY" echo "Final Relay: $FINAL_RELAY" echo "" # Test parameters DELAY=2 AUDIT_TAG="test-single-hop-$(date +%s)" TEST_CONTENT="Single-hop test message at $(date)" echo "Step 1: Create inner kind 1 event" INNER_EVENT=$(create_test_event "$BUILDER_PRIVKEY" "$TEST_CONTENT") INNER_EVENT_ID=$(echo "$INNER_EVENT" | jq -r '.id') echo "Created inner event: $INNER_EVENT_ID" echo "" echo "Step 2: Create routing payload" ROUTING_PAYLOAD=$(create_routing_payload "$INNER_EVENT" "$FINAL_RELAY" "$DELAY" "null" "$AUDIT_TAG") echo "Routing payload created with ${DELAY}s delay" echo "" echo "Step 3: Encrypt routing payload to Thrower A" ENCRYPTED_CONTENT=$(encrypt_payload "$BUILDER_PRIVKEY" "$THROWER_A_PUBKEY" "$ROUTING_PAYLOAD") if [ -z "$ENCRYPTED_CONTENT" ]; then echo "ERROR: Failed to encrypt payload" exit 1 fi echo "Payload encrypted" echo "" echo "Step 4: Create kind 22222 routing event" ROUTING_EVENT=$(create_routing_event "$BUILDER_PRIVKEY" "$THROWER_A_PUBKEY" "$ENCRYPTED_CONTENT") ROUTING_EVENT_ID=$(echo "$ROUTING_EVENT" | jq -r '.id') echo "Created routing event: $ROUTING_EVENT_ID" echo "" echo "Step 5: Publish routing event to Thrower A's relay" PUBLISH_TIME=$(get_timestamp) publish_event "$ROUTING_EVENT" "$THROWER_RELAY" echo "Published at timestamp: $PUBLISH_TIME" echo "" echo "Step 6: Wait for Thrower A to process and forward (delay: ${DELAY}s + processing time)" echo "Monitoring $FINAL_RELAY for inner event $INNER_EVENT_ID..." EXPECTED_TIME=$((PUBLISH_TIME + DELAY)) echo "Expected arrival after: $(date -d @$EXPECTED_TIME)" echo "" # Monitor for the inner event on final relay TIMEOUT=$((DELAY + 30)) # Delay + 30 seconds buffer FOUND=false START_MONITOR=$(get_timestamp) while [ $(($(get_timestamp) - START_MONITOR)) -lt $TIMEOUT ]; do if query_event "$INNER_EVENT_ID" "$FINAL_RELAY" 2 | grep -q "$INNER_EVENT_ID"; then ARRIVAL_TIME=$(get_timestamp) FOUND=true break fi sleep 1 done if [ "$FOUND" = false ]; then echo "ERROR: Inner event not found on final relay within ${TIMEOUT}s" exit 1 fi echo "Step 7: Verify timing" ACTUAL_DELAY=$((ARRIVAL_TIME - PUBLISH_TIME)) echo "Actual delay: ${ACTUAL_DELAY}s" echo "Expected delay: ${DELAY}s (minimum)" if [ $ACTUAL_DELAY -lt $DELAY ]; then echo "ERROR: Event arrived too early! Expected at least ${DELAY}s, got ${ACTUAL_DELAY}s" exit 1 fi # Check if delay is reasonable (not more than 2x expected + 10s buffer) MAX_DELAY=$((DELAY * 2 + 10)) if [ $ACTUAL_DELAY -gt $MAX_DELAY ]; then echo "WARNING: Event took longer than expected (${ACTUAL_DELAY}s > ${MAX_DELAY}s)" fi echo "" echo "Step 8: Verify event content" FINAL_EVENT=$(query_event "$INNER_EVENT_ID" "$FINAL_RELAY" 5) FINAL_CONTENT=$(echo "$FINAL_EVENT" | jq -r '.content') if [ "$FINAL_CONTENT" != "$TEST_CONTENT" ]; then echo "ERROR: Content mismatch!" echo "Expected: $TEST_CONTENT" echo "Got: $FINAL_CONTENT" exit 1 fi echo "Content verified: $FINAL_CONTENT" echo "" echo "=== TEST PASSED ===" echo "✓ Single-hop routing successful" echo "✓ Delay constraint respected (${ACTUAL_DELAY}s >= ${DELAY}s)" echo "✓ Event content preserved" echo "✓ Event published to correct relay" echo "" exit 0