- Introduced Aggregator.sol for Chainlink-compatible oracle functionality, including round-based updates and access control. - Added OracleWithCCIP.sol to extend Aggregator with CCIP cross-chain messaging capabilities. - Created .gitmodules to include OpenZeppelin contracts as a submodule. - Developed a comprehensive deployment guide in NEXT_STEPS_COMPLETE_GUIDE.md for Phase 2 and smart contract deployment. - Implemented Vite configuration for the orchestration portal, supporting both Vue and React frameworks. - Added server-side logic for the Multi-Cloud Orchestration Portal, including API endpoints for environment management and monitoring. - Created scripts for resource import and usage validation across non-US regions. - Added tests for CCIP error handling and integration to ensure robust functionality. - Included various new files and directories for the orchestration portal and deployment scripts.
158 lines
5.7 KiB
Solidity
158 lines
5.7 KiB
Solidity
// SPDX-License-Identifier: MIT
|
|
pragma solidity ^0.8.19;
|
|
|
|
import "@openzeppelin/contracts/access/AccessControl.sol";
|
|
import "./interfaces/IPacketRegistry.sol";
|
|
|
|
/**
|
|
* @title PacketRegistry
|
|
* @notice Records packet lifecycle events for non-scheme participants
|
|
* @dev Tracks packet generation, dispatch, and acknowledgment linked to ChainID 138 triggers
|
|
* Provides tamper-evident audit trail for instruction packets sent via secure email, AS4, or PDF
|
|
*/
|
|
contract PacketRegistry is IPacketRegistry, AccessControl {
|
|
bytes32 public constant PACKET_OPERATOR_ROLE = keccak256("PACKET_OPERATOR_ROLE");
|
|
|
|
// triggerId => latest packet info
|
|
mapping(uint256 => PacketInfo) private _packets;
|
|
|
|
struct PacketInfo {
|
|
bytes32 payloadHash;
|
|
bytes32 mode;
|
|
bytes32 channel;
|
|
bytes32 messageRef;
|
|
bytes32 receiptRef;
|
|
bytes32 status;
|
|
bool generated;
|
|
bool dispatched;
|
|
bool acknowledged;
|
|
}
|
|
|
|
/**
|
|
* @notice Initializes the registry with an admin address
|
|
* @param admin Address that will receive DEFAULT_ADMIN_ROLE
|
|
*/
|
|
constructor(address admin) {
|
|
_grantRole(DEFAULT_ADMIN_ROLE, admin);
|
|
}
|
|
|
|
/**
|
|
* @notice Records that a packet has been generated
|
|
* @dev Requires PACKET_OPERATOR_ROLE
|
|
* @param triggerId The trigger ID from RailTriggerRegistry
|
|
* @param payloadHash SHA-256 hash of the packet payload
|
|
* @param mode Transmission mode (e.g., "PDF", "EMAIL", "AS4")
|
|
*/
|
|
function recordGenerated(
|
|
uint256 triggerId,
|
|
bytes32 payloadHash,
|
|
bytes32 mode
|
|
) external override onlyRole(PACKET_OPERATOR_ROLE) {
|
|
require(triggerId > 0, "PacketRegistry: zero triggerId");
|
|
require(payloadHash != bytes32(0), "PacketRegistry: zero payloadHash");
|
|
require(mode != bytes32(0), "PacketRegistry: zero mode");
|
|
require(!_packets[triggerId].generated, "PacketRegistry: already generated");
|
|
|
|
_packets[triggerId].payloadHash = payloadHash;
|
|
_packets[triggerId].mode = mode;
|
|
_packets[triggerId].generated = true;
|
|
|
|
emit PacketGenerated(triggerId, payloadHash, mode);
|
|
}
|
|
|
|
/**
|
|
* @notice Records that a packet has been dispatched via a channel
|
|
* @dev Requires PACKET_OPERATOR_ROLE. Packet must have been generated first.
|
|
* @param triggerId The trigger ID from RailTriggerRegistry
|
|
* @param channel The dispatch channel (e.g., "EMAIL", "AS4", "PORTAL")
|
|
* @param messageRef The message reference ID from the transport layer
|
|
*/
|
|
function recordDispatched(
|
|
uint256 triggerId,
|
|
bytes32 channel,
|
|
bytes32 messageRef
|
|
) external override onlyRole(PACKET_OPERATOR_ROLE) {
|
|
require(triggerId > 0, "PacketRegistry: zero triggerId");
|
|
require(channel != bytes32(0), "PacketRegistry: zero channel");
|
|
require(messageRef != bytes32(0), "PacketRegistry: zero messageRef");
|
|
require(_packets[triggerId].generated, "PacketRegistry: not generated");
|
|
require(!_packets[triggerId].dispatched, "PacketRegistry: already dispatched");
|
|
|
|
_packets[triggerId].channel = channel;
|
|
_packets[triggerId].messageRef = messageRef;
|
|
_packets[triggerId].dispatched = true;
|
|
|
|
emit PacketDispatched(triggerId, channel, messageRef);
|
|
}
|
|
|
|
/**
|
|
* @notice Records that a packet has been acknowledged by the recipient
|
|
* @dev Requires PACKET_OPERATOR_ROLE. Packet must have been dispatched first.
|
|
* @param triggerId The trigger ID from RailTriggerRegistry
|
|
* @param receiptRef The receipt reference ID from the recipient
|
|
* @param status The acknowledgment status (e.g., "RECEIVED", "ACCEPTED", "REJECTED")
|
|
*/
|
|
function recordAcknowledged(
|
|
uint256 triggerId,
|
|
bytes32 receiptRef,
|
|
bytes32 status
|
|
) external override onlyRole(PACKET_OPERATOR_ROLE) {
|
|
require(triggerId > 0, "PacketRegistry: zero triggerId");
|
|
require(receiptRef != bytes32(0), "PacketRegistry: zero receiptRef");
|
|
require(status != bytes32(0), "PacketRegistry: zero status");
|
|
require(_packets[triggerId].dispatched, "PacketRegistry: not dispatched");
|
|
require(!_packets[triggerId].acknowledged, "PacketRegistry: already acknowledged");
|
|
|
|
_packets[triggerId].receiptRef = receiptRef;
|
|
_packets[triggerId].status = status;
|
|
_packets[triggerId].acknowledged = true;
|
|
|
|
emit PacketAcknowledged(triggerId, receiptRef, status);
|
|
}
|
|
|
|
/**
|
|
* @notice Returns packet information for a trigger
|
|
* @param triggerId The trigger ID
|
|
* @return payloadHash The payload hash
|
|
* @return mode The transmission mode
|
|
* @return channel The dispatch channel
|
|
* @return messageRef The message reference
|
|
* @return receiptRef The receipt reference
|
|
* @return status The acknowledgment status
|
|
* @return generated Whether packet was generated
|
|
* @return dispatched Whether packet was dispatched
|
|
* @return acknowledged Whether packet was acknowledged
|
|
*/
|
|
function getPacketInfo(
|
|
uint256 triggerId
|
|
)
|
|
external
|
|
view
|
|
returns (
|
|
bytes32 payloadHash,
|
|
bytes32 mode,
|
|
bytes32 channel,
|
|
bytes32 messageRef,
|
|
bytes32 receiptRef,
|
|
bytes32 status,
|
|
bool generated,
|
|
bool dispatched,
|
|
bool acknowledged
|
|
)
|
|
{
|
|
PacketInfo memory info = _packets[triggerId];
|
|
return (
|
|
info.payloadHash,
|
|
info.mode,
|
|
info.channel,
|
|
info.messageRef,
|
|
info.receiptRef,
|
|
info.status,
|
|
info.generated,
|
|
info.dispatched,
|
|
info.acknowledged
|
|
);
|
|
}
|
|
}
|
|
|