Reddid Technical Architecture Specification - reddcoin-project/reddcoin GitHub Wiki
Version: 1.0
Date: April 2025
Status: Draft
- System Overview
- System Architecture
- Core Components
- Database Schema
- Blockchain Integration
- P2P Protocol Extensions
- API Interfaces
- Security Model
- External Dependencies
- Performance Considerations
- Deployment Requirements
- Implementation Guidelines
The ReddID system provides a comprehensive identity management solution for the Reddcoin blockchain, enabling namespaces, user identifiers, and identity profiles through a hierarchical, market-driven approach to allocation.
The ReddID system encompasses three integrated tiers:
- Namespaces - Top-level domains (.redd, .crypto, etc.) allocated through auctions
- User IDs - Identifiers within namespaces (alice.redd, bob.crypto, etc.) allocated through namespace-specific auctions
- ReddID Profiles - Cross-namespace identities with social and reputation features
- Market-based allocation through auctions with anti-sniping protections
- Hierarchical governance with namespace owners defining rules for user IDs
- Cross-namespace identity resolution with social graph and reputation
- Deflationary economic model with multi-stakeholder revenue distribution
- Efficient P2P synchronization of identity data
- Anti-squatting mechanisms through economic disincentives
The ReddID system extends the Reddcoin Core codebase with new components, database schemas, blockchain operations, P2P messages, and RPC commands, all coordinated through a central ReddIDManager.
graph TD
subgraph ReddID["ReddID System Architecture"]
ReddIDManager["ReddIDManager\n(Central Coordination Component)"]
NamespaceManager["Namespace Manager"]
AuctionManager["Auction Manager"]
ProfileManager["Profile Manager"]
ReddIDP2PManager["ReddIDP2P Manager"]
ReddIDDB["ReddIDDB\n(Database Layer)"]
ReddIDManager --> NamespaceManager
ReddIDManager --> AuctionManager
ReddIDManager --> ProfileManager
ReddIDManager --> ReddIDP2PManager
NamespaceManager --> ReddIDDB
AuctionManager --> ReddIDDB
ProfileManager --> ReddIDDB
ReddIDP2PManager --> ReddIDDB
end
BlockchainIntegration["Blockchain Integration"]
RPCInterface["RPC Interface"]
P2PNetwork["P2P Network"]
ReddIDDB --> BlockchainIntegration
ReddIDDB --> RPCInterface
ReddIDDB --> P2PNetwork
- Modularity - Clear separation of concerns between components
- Hierarchical Structure - Top-down design with well-defined dependencies
- Market-Driven Allocation - Auction mechanisms for efficient resource allocation
- Blockchain Integration - Use of Reddcoin blockchain for immutable state verification
- P2P Synchronization - Efficient distribution of identity data across the network
- Extensibility - Design for future feature additions and improvements
Component | Primary Responsibility |
---|---|
ReddIDManager | Central orchestration of all identity components |
NamespaceManager | Namespace registration, configuration, and governance |
AuctionManager | Auction creation, bidding, and settlement |
ProfileManager | Identity profiles, social connections, and reputation |
ReddIDDB | Persistent storage and retrieval of all identity data |
ReddIDP2PManager | P2P protocol extensions for identity data synchronization |
graph TD
ClientRequest["Client Request"]
RPCInterface["RPC Interface"]
ReddIDManager["ReddIDManager"]
ComponentRouting["Component Routing"]
BlockchainTransaction["Blockchain Transaction"]
ReddIDDBOperations["ReddIDDB Operations"]
P2PMessages["P2P Messages"]
ComponentProcessing["Component-Specific Processing"]
NetworkPropagation["Network Propagation"]
ClientResponse["Client Response"]
ClientRequest --> RPCInterface
RPCInterface --> ReddIDManager
ReddIDManager --> ComponentRouting
ComponentRouting --> BlockchainTransaction
ComponentRouting --> ReddIDDBOperations
ComponentRouting --> P2PMessages
BlockchainTransaction --> NetworkPropagation
ReddIDDBOperations --> ComponentProcessing
P2PMessages --> ComponentProcessing
ReddIDManager --> ComponentProcessing
ComponentProcessing --> ClientResponse
ComponentProcessing --> NetworkPropagation
The ReddIDManager serves as the central coordination component for the entire ReddID system, orchestrating interactions between all subcomponents and providing the primary interface for external systems.
- Initialize and coordinate all ReddID components
- Route operations to appropriate sub-managers
- Maintain system-wide configuration
- Provide validation interface for blockchain integration
- Coordinate transaction creation for on-chain operations
- Expose RPC interfaces for wallet and application integration
class ReddIDManager {
public:
// Initialization and shutdown
bool Initialize();
void Shutdown();
// Component access
NamespaceManager* GetNamespaceManager();
AuctionManager* GetAuctionManager();
ProfileManager* GetProfileManager();
ReddIDDB* GetReddIDDB();
ReddIDP2PManager* GetP2PManager();
// High-level operations
// Namespace operations
bool CreateNamespaceAuction(const std::string& namespaceId, const CKeyID& creator,
CAmount reservePrice, int durationDays,
AuctionType type, uint256& auctionId);
bool FinalizeNamespaceAuction(const uint256& auctionId);
bool CancelNamespaceAuction(const uint256& auctionId, const CKeyID& creator);
// User ID operations
bool CreateUserIDAuction(const std::string& name, const std::string& namespaceId,
const CKeyID& creator, CAmount reservePrice,
int durationDays, AuctionType type, uint256& auctionId);
bool FinalizeUserIDAuction(const uint256& auctionId);
bool CancelUserIDAuction(const uint256& auctionId, const CKeyID& creator);
// ReddID operations
bool RegisterReddID(const std::string& reddId, const CKeyID& owner,
const ReddIDProfile& profile);
bool UpdateProfile(const std::string& reddId, const ReddIDProfile& profile,
const CKeyID& owner);
bool CreateConnection(const ReddIDConnection& connection, const CKeyID& owner);
bool UpdateConnection(const ReddIDConnection& connection, const CKeyID& owner);
bool RemoveConnection(const std::string& fromReddId, const std::string& toReddId,
const CKeyID& owner);
// Transaction fee calculation
CAmount CalculateRenewalFee(const std::string& name, const std::string& namespaceId);
CAmount CalculateRenewalFee(const std::string& namespaceId);
// Blockchain verification
bool ProcessIdTx(const CTransaction& tx, int height);
private:
// Component instances
std::unique_ptr<NamespaceManager> m_namespaceManager;
std::unique_ptr<AuctionManager> m_auctionManager;
std::unique_ptr<ProfileManager> m_profileManager;
std::unique_ptr<ReddIDDB> m_reddidDB;
std::unique_ptr<ReddIDP2PManager> m_p2pManager;
// Helper methods
bool CreateOpReturnTransaction(const std::vector<unsigned char>& data,
CWallet* pwallet, CMutableTransaction& mtx);
};
Parameter | Type | Description | Default |
---|---|---|---|
enableReddID |
bool | Whether the ReddID system is enabled | true |
maxNamespaceLength |
int | Maximum length of namespace identifiers | 15 |
maxUserIdLength |
int | Maximum length of user ID identifiers | 64 |
maxReddIdLength |
int | Maximum length of ReddID identifiers | 32 |
minAuctionDuration |
int | Minimum allowed auction duration (days) | 3 |
maxAuctionDuration |
int | Maximum allowed auction duration (days) | 30 |
developerFundAddress |
string | Address for developer fund revenue | "" |
nodeRewardAddress |
string | Address for node operator rewards | "" |
The NamespaceManager handles the registration, configuration, and governance of namespaces, which serve as top-level domains within the ReddID system.
- Create and manage namespace auctions
- Validate namespace identifiers and configurations
- Enforce namespace governance rules
- Process namespace transfers and renewals
- Maintain namespace pricing tiers
- Calculate namespace fees based on configuration
class NamespaceManager {
public:
// Initialization
NamespaceManager(ReddIDManager* reddIDManager);
bool Initialize();
// Namespace validation
bool ValidateNamespaceID(const std::string& namespaceId);
bool IsNamespaceAvailable(const std::string& namespaceId);
// Namespace auctions
bool CreateNamespaceAuction(const std::string& namespaceId, const CKeyID& creator,
CAmount reservePrice, int durationDays,
AuctionType type, uint256& auctionId);
bool BidOnNamespaceAuction(const uint256& auctionId, const CKeyID& bidder,
CAmount bidAmount, uint256& bidId);
bool FinalizeNamespaceAuction(const uint256& auctionId);
bool CancelNamespaceAuction(const uint256& auctionId, const CKeyID& creator);
// Namespace management
bool UpdateNamespace(const NamespaceInfo& namespaceInfo);
bool RenewNamespace(const std::string& namespaceId, const CKeyID& owner,
int renewalPeriod = 0);
bool TransferNamespace(const std::string& namespaceId, const CKeyID& owner,
const CKeyID& newOwner);
// Namespace pricing
CAmount CalculateMinPrice(const std::string& namespaceId);
CAmount CalculateRenewalFee(const std::string& namespaceId);
// Pricing tiers
bool AddPricingTier(const std::string& namespaceId, int minLength, CAmount minPrice);
bool RemovePricingTier(const std::string& namespaceId, int minLength);
std::vector<PricingTier> GetPricingTiers(const std::string& namespaceId);
// Namespace information
bool GetNamespaceInfo(const std::string& namespaceId, NamespaceInfo& info);
std::vector<NamespaceInfo> GetNamespaces();
std::vector<AuctionInfo> GetActiveAuctions();
bool GetAuctionInfo(const uint256& auctionId, AuctionInfo& auction);
private:
ReddIDManager* m_reddIDManager;
// Default namespace configuration
bool GetDefaultNamespaceConfig(NamespaceInfo& config);
};
- Namespace identifiers must be 1-15 characters
- Valid characters include lowercase letters (a-z), numbers (0-9), and hyphen (-)
- Identifiers cannot start or end with a hyphen
- Identifiers cannot contain consecutive hyphens
Parameter | Default Value |
---|---|
allow_numbers |
true |
allow_hyphens |
true |
allow_underscores |
true |
min_length |
3 |
max_length |
32 |
renewal_period |
365 days |
grace_period |
30 days |
namespace_revenue_pct |
10% |
burn_pct |
70% |
node_pct |
15% |
dev_pct |
5% |
min_auction_duration |
3 days |
max_auction_duration |
7 days |
min_bid_increment |
5.0% |
The AuctionManager handles the creation, bidding, and settlement of auctions for both namespaces and user IDs, implementing the market-driven allocation system.
- Create and validate auction parameters
- Process bids and enforce auction rules
- Implement anti-sniping protections
- Calculate auction settlements and distribute proceeds
- Enforce deposit requirements
- Manage auction state transitions
- Track auction and bid history
class AuctionManager {
public:
// Initialization
AuctionManager(ReddIDManager* reddIDManager);
bool Initialize();
// Auction creation
bool CreateAuction(const std::string& name, const std::string& namespaceId,
const CKeyID& creator, CAmount reservePrice,
int durationDays, AuctionType type, uint256& auctionId);
// Bidding
bool PlaceBid(const uint256& auctionId, const CKeyID& bidder,
CAmount bidAmount, uint256& bidId);
// Auction finalization
bool FinalizeAuction(const uint256& auctionId);
bool CancelAuction(const uint256& auctionId, const CKeyID& creator);
// Refunds
bool ProcessRefund(const uint256& bidId);
bool ProcessAllRefunds(const uint256& auctionId);
// Anti-sniping
bool ExtendAuction(const uint256& auctionId, int extensionMinutes);
// Information retrieval
bool GetAuctionInfo(const uint256& auctionId, AuctionInfo& auction);
bool GetBidInfo(const uint256& bidId, BidInfo& bid);
std::vector<AuctionInfo> GetActiveAuctions();
std::vector<AuctionInfo> GetAuctionsByNamespace(const std::string& namespaceId);
std::vector<BidInfo> GetAuctionBids(const uint256& auctionId);
// Auction validation
bool IsValidMinimumBid(const uint256& auctionId, CAmount bidAmount);
CAmount CalculateMinimumBid(const uint256& auctionId);
CAmount CalculateDepositAmount(CAmount bidAmount, const AuctionInfo& auction);
private:
ReddIDManager* m_reddIDManager;
// Helper methods
bool DistributeAuctionProceeds(const AuctionInfo& auction);
bool ProcessExtensionConditions(const uint256& auctionId, const BidInfo& bid);
};
enum AuctionState {
AUCTION_PENDING = 0, // Auction created but not yet active
AUCTION_ACTIVE = 1, // Auction open for bidding
AUCTION_ENDED = 2, // Auction time elapsed, awaiting finalization
AUCTION_FINALIZED = 3, // Auction settled to winner
AUCTION_CANCELED = 4 // Auction canceled by creator (only if no bids)
};
enum AuctionType {
AUCTION_STANDARD = 0, // Standard auction for most identifiers
AUCTION_PREMIUM = 1, // Premium auction for high-value identifiers
AUCTION_VERIFIED = 2, // Auction requiring identity verification
AUCTION_RENEWAL = 3 // Auction for expired identifiers
};
- If a bid is placed within the final 10% of the auction duration, the auction is extended
- Extension time is 12 hours for namespace auctions and 6 hours for user ID auctions
- Maximum of 3 extensions per auction to prevent indefinite auctions
- Extension information is relayed with high priority through the P2P network
The ProfileManager handles ReddID profiles, social connections, reputation, and cross-namespace identity resolution.
- Manage ReddID registration and profiles
- Process profile updates and verification
- Handle social connections between ReddIDs
- Calculate and update reputation scores
- Provide namespace resolution for ReddIDs
- Maintain cross-namespace identity linking
class ProfileManager {
public:
// Initialization
ProfileManager(ReddIDManager* reddIDManager);
bool Initialize();
// ReddID management
bool RegisterReddID(const std::string& reddId, const CKeyID& owner,
const ReddIDProfile& profile);
bool UpdateProfile(const std::string& reddId, const ReddIDProfile& profile,
const CKeyID& owner);
bool RenewReddID(const std::string& reddId, const CKeyID& owner);
bool DeactivateReddID(const std::string& reddId, const CKeyID& owner);
// Profile retrieval
bool GetProfile(const std::string& reddId, ReddIDProfile& profile);
bool GetProfilesByOwner(const CKeyID& owner, std::vector<std::string>& reddIds);
// Social connections
bool CreateConnection(const ReddIDConnection& connection);
bool UpdateConnection(const ReddIDConnection& connection);
bool RemoveConnection(const std::string& fromReddId, const std::string& toReddId,
const CKeyID& owner);
std::vector<ReddIDConnection> GetConnections(const std::string& reddId);
std::vector<ReddIDConnection> GetIncomingConnections(const std::string& reddId);
// Reputation
bool GetReputation(const std::string& reddId, ReddIDReputation& reputation);
bool UpdateReputation(const ReddIDReputation& reputation);
bool CalculateReputation(const std::string& reddId, ReddIDReputation& reputation);
// Cross-namespace resolution
bool LinkUserID(const std::string& reddId, const std::string& name,
const std::string& namespaceId, bool isPrimary);
bool UnlinkUserID(const std::string& reddId, const std::string& namespaceId);
bool ResolveReddID(const std::string& name, const std::string& namespaceId,
std::string& reddId);
bool GetLinkedUserIDs(const std::string& reddId,
std::vector<ReddIDNamespaceResolution>& resolutions);
// Database access
ReddIDDB* GetDB() { return m_reddIDManager->GetReddIDDB(); }
private:
ReddIDManager* m_reddIDManager;
// Helper methods
bool ValidateReddIDFormat(const std::string& reddId);
bool ValidateProfile(const ReddIDProfile& profile);
bool ValidateConnection(const ReddIDConnection& connection);
};
enum SocialConnectionType {
CONNECTION_FOLLOW = 0, // One-way connection (like Twitter)
CONNECTION_FRIEND = 1, // Two-way, mutual connection
CONNECTION_ENDORSE = 2, // Reputation-affecting positive connection
CONNECTION_BLOCK = 3 // Negative connection for filtering
};
enum PrivacyLevel {
PRIVACY_PUBLIC = 0, // Visible to anyone
PRIVACY_FRIENDS = 1, // Visible to connections only
PRIVACY_PRIVATE = 2 // Visible to owner only
};
enum VerificationLevel {
VERIFICATION_NONE = 0, // No verification
VERIFICATION_SELF = 1, // Self-attested information
VERIFICATION_COMMUNITY = 2, // Peer-verified
VERIFICATION_OFFICIAL = 3 // Officially verified entity
};
The reputation system calculates scores based on several factors:
- Longevity - Account age and stability (20%)
- Transaction - Payment history, volume, and consistency (25%)
- Engagement - Network activity and connections (20%)
- Verification - Identity verification level (15%)
- Auction - Bidding behavior and payment reliability (20%)
The actual calculation applies weighting and normalization to produce a score from 0-100.
The ReddIDDB component provides persistent storage for all identity and auction data, serving as the database layer for the ReddID system.
- Implement database schema for all ReddID data
- Provide CRUD operations for all data types
- Manage database transactions and consistency
- Implement efficient query patterns
- Handle data versioning and migration
- Provide backup and recovery functionality
class ReddIDDB {
public:
// Initialization
ReddIDDB(const fs::path& dataDir);
bool Initialize();
void Shutdown();
// Database transactions
bool BeginTransaction();
bool CommitTransaction();
bool AbortTransaction();
// Namespace operations
bool WriteNamespace(const NamespaceInfo& namespaceInfo);
bool ReadNamespace(const std::string& namespaceId, NamespaceInfo& namespaceInfo);
bool EraseNamespace(const std::string& namespaceId);
bool ListNamespaces(std::vector<std::string>& namespaceIds);
// Pricing tier operations
bool WritePricingTier(const std::string& namespaceId, const PricingTier& tier);
bool ReadPricingTier(const std::string& namespaceId, int minLength, PricingTier& tier);
bool ErasePricingTier(const std::string& namespaceId, int minLength);
bool ListPricingTiers(const std::string& namespaceId, std::vector<PricingTier>& tiers);
// User ID operations
bool WriteUserID(const UserIDInfo& userID);
bool ReadUserID(const std::string& name, const std::string& namespaceId,
UserIDInfo& userID);
bool EraseUserID(const std::string& name, const std::string& namespaceId);
bool ExistsUserID(const std::string& name, const std::string& namespaceId);
bool ListUserIDs(const std::string& namespaceId, std::vector<std::string>& names);
bool ListUserIDsByOwner(const CKeyID& owner, std::vector<UserIDInfo>& userIDs);
// Auction operations
bool WriteAuction(const AuctionInfo& auction);
bool ReadAuction(const uint256& auctionId, AuctionInfo& auction);
bool EraseAuction(const uint256& auctionId);
bool ListAuctions(std::vector<uint256>& auctionIds);
bool ListAuctionsByNamespace(const std::string& namespaceId,
std::vector<uint256>& auctionIds);
bool ListAuctionsByState(AuctionState state, std::vector<uint256>& auctionIds);
// Bid operations
bool WriteBid(const BidInfo& bid);
bool ReadBid(const uint256& bidId, BidInfo& bid);
bool EraseBid(const uint256& bidId);
bool ListBidsByAuction(const uint256& auctionId, std::vector<uint256>& bidIds);
bool ListBidsByBidder(const CKeyID& bidder, std::vector<uint256>& bidIds);
// ReddID profile operations
bool WriteProfile(const ReddIDProfile& profile);
bool ReadProfile(const std::string& reddId, ReddIDProfile& profile);
bool EraseProfile(const std::string& reddId);
bool ListProfiles(std::vector<std::string>& reddIds);
bool ListProfilesByOwner(const CKeyID& owner, std::vector<std::string>& reddIds);
// Reputation operations
bool WriteReputation(const ReddIDReputation& reputation);
bool ReadReputation(const std::string& reddId, ReddIDReputation& reputation);
bool WriteReputationHistory(const ReddIDReputation& reputation);
bool GetReputationHistory(const std::string& reddId,
std::vector<ReddIDReputation>& history,
int64_t startTime = 0, int count = 10);
// Connection operations
bool WriteConnection(const ReddIDConnection& connection);
bool ReadConnection(const std::string& fromReddId, const std::string& toReddId,
ReddIDConnection& connection);
bool EraseConnection(const std::string& fromReddId, const std::string& toReddId);
bool ListConnectionsByFrom(const std::string& fromReddId,
std::vector<ReddIDConnection>& connections);
bool ListConnectionsByTo(const std::string& toReddId,
std::vector<ReddIDConnection>& connections);
// Namespace resolution
bool WriteResolution(const ReddIDNamespaceResolution& resolution);
bool ReadResolution(const std::string& reddId, const std::string& namespaceId,
ReddIDNamespaceResolution& resolution);
bool EraseResolution(const std::string& reddId, const std::string& namespaceId);
bool ListResolutionsByReddID(const std::string& reddId,
std::vector<ReddIDNamespaceResolution>& resolutions);
bool ResolveUserID(const std::string& name, const std::string& namespaceId,
std::string& reddId);
private:
fs::path m_dataDir;
std::unique_ptr<CDBWrapper> m_db;
// Database prefixes for different data types
static const char DB_NAMESPACE = 'n';
static const char DB_PRICING_TIER = 'p';
static const char DB_USER_ID = 'u';
static const char DB_AUCTION = 'a';
static const char DB_BID = 'b';
static const char DB_PROFILE = 'i';
static const char DB_REPUTATION = 'r';
static const char DB_REPUTATION_HISTORY = 'h';
static const char DB_CONNECTION = 'c';
static const char DB_RESOLUTION = 's';
};
The database is organized using LevelDB with custom prefixes for different data types. This supports efficient lookups and range scans while maintaining data integrity.
The ReddIDDB implements atomic transactions to ensure data consistency across related operations:
- Begin transaction with
BeginTransaction()
- Perform multiple write operations
- Commit changes with
CommitTransaction()
or roll back withAbortTransaction()
The ReddIDP2PManager extends the Reddcoin P2P network protocol to support efficient propagation of identity data, auction information, and reputation updates.
- Define and handle new P2P message types
- Propagate auction announcements and bids
- Distribute profile updates and social connections
- Synchronize namespace configurations
- Relay reputation updates
- Implement subscription and filtering mechanisms
- Handle message validation and rate limiting
class ReddIDP2PManager {
public:
// Initialization
ReddIDP2PManager(ReddIDManager* reddIDManager);
bool Initialize();
void Shutdown();
// Message processing
bool ProcessReddIDMessage(CNode* pfrom, const std::string& strCommand,
CDataStream& vRecv, int64_t nTimeReceived,
const CChainParams& chainparams);
// Message sending
bool SendNamespaceAuctionAnnounce(const AuctionInfo& auction);
bool SendNamespaceAuctionBid(const BidInfo& bid);
bool SendNamespaceAuctionFinalize(const uint256& auctionId);
bool SendNamespaceConfigRequest(const std::string& namespaceId, CNode* pnode = nullptr);
bool SendNamespaceConfigResponse(const std::string& namespaceId, CNode* pnode = nullptr);
bool SendUserIDAuctionAnnounce(const AuctionInfo& auction);
bool SendUserIDAuctionBid(const BidInfo& bid);
bool SendUserIDAuctionFinalize(const uint256& auctionId);
bool SendReddIDRegisterAnnounce(const std::string& reddId);
bool SendReddIDProfileUpdate(const std::string& reddId);
bool SendReddIDConnection(const ReddIDConnection& connection);
bool SendReddIDProfileRequest(const std::string& reddId, CNode* pnode = nullptr);
bool SendReddIDProfileResponse(const std::string& reddId, CNode* pnode = nullptr);
bool SendReddIDReputationUpdate(const std::string& reddId);
// Subscription management
bool AddNamespaceSubscription(const std::string& namespaceId, CNode* pnode);
bool RemoveNamespaceSubscription(const std::string& namespaceId, CNode* pnode);
bool AddReddIDSubscription(const std::string& reddId, CNode* pnode);
bool RemoveReddIDSubscription(const std::string& reddId, CNode* pnode);
// Rate limiting
bool CheckMessageRate(CNode* pfrom, const std::string& strCommand);
private:
ReddIDManager* m_reddIDManager;
// Maps to track subscriptions
std::map<std::string, std::set<NodeId>> m_namespaceSubscriptions;
std::map<std::string, std::set<NodeId>> m_reddIDSubscriptions;
// Rate limiting data
std::map<NodeId, std::map<std::string, std::pair<int64_t, int>>> m_messageRateLimits;
// Message handlers
bool HandleNamespaceAuctionAnnounce(CNode* pfrom, CDataStream& vRecv);
bool HandleNamespaceAuctionBid(CNode* pfrom, CDataStream& vRecv);
bool HandleNamespaceAuctionFinalize(CNode* pfrom, CDataStream& vRecv);
bool HandleNamespaceConfigRequest(CNode* pfrom, CDataStream& vRecv);
bool HandleNamespaceConfigResponse(CNode* pfrom, CDataStream& vRecv);
bool HandleUserIDAuctionAnnounce(CNode* pfrom, CDataStream& vRecv);
bool HandleUserIDAuctionBid(CNode* pfrom, CDataStream& vRecv);
bool HandleUserIDAuctionFinalize(CNode* pfrom, CDataStream& vRecv);
bool HandleReddIDRegisterAnnounce(CNode* pfrom, CDataStream& vRecv);
bool HandleReddIDProfileUpdate(CNode* pfrom, CDataStream& vRecv);
bool HandleReddIDConnection(CNode* pfrom, CDataStream& vRecv);
bool HandleReddIDProfileRequest(CNode* pfrom, CDataStream& vRecv);
bool HandleReddIDProfileResponse(CNode* pfrom, CDataStream& vRecv);
bool HandleReddIDReputationUpdate(CNode* pfrom, CDataStream& vRecv);
};
Messages are prioritized for relay based on time sensitivity:
Priority | Message Types | Description |
---|---|---|
High | Auction bids, auction finalization | Time-sensitive information affecting resource allocation |
Medium | Profile updates, connection changes | Identity information with moderate time sensitivity |
Low | Configuration requests, reputation updates | Background information with lower time sensitivity |
To prevent spam and DoS attacks, rate limiting is implemented on a per-node, per-message type basis:
Message Type | Rate Limit |
---|---|
Auction announcements | 10 per minute |
Bids | 20 per minute |
Profile updates | 5 per minute |
Connection operations | 15 per minute |
Configuration requests | 20 per minute |
The following tables define the core data storage for the ReddID system:
Column | Type | Description | Constraints |
---|---|---|---|
id |
VARCHAR(15) | Namespace identifier | PRIMARY KEY |
owner |
BLOB | Owner's address in binary format | NOT NULL |
allow_numbers |
BOOLEAN | Whether numbers are allowed | NOT NULL |
allow_hyphens |
BOOLEAN | Whether hyphens are allowed | NOT NULL |
allow_underscores |
BOOLEAN | Whether underscores are allowed | NOT NULL |
min_length |
INT | Minimum name length | NOT NULL |
max_length |
INT | Maximum name length | NOT NULL |
renewal_period |
INT | Days until renewal required | NOT NULL |
grace_period |
INT | Days in grace period | NOT NULL |
namespace_revenue_pct |
INT | % of auctions going to namespace owner | NOT NULL |
burn_pct |
INT | % of auctions being burned | NOT NULL |
node_pct |
INT | % of auctions going to node operators | NOT NULL |
dev_pct |
INT | % of auctions going to development fund | NOT NULL |
min_auction_duration |
INT | Minimum auction duration in days | NOT NULL |
max_auction_duration |
INT | Maximum auction duration in days | NOT NULL |
min_bid_increment |
REAL | Minimum bid increment percentage | NOT NULL |
config_hash |
BLOB(32) | Hash of this configuration | NOT NULL |
last_updated |
INT64 | When configuration was last updated | NOT NULL |
expiration |
INT64 | When namespace ownership expires | NOT NULL |
Column | Type | Description | Constraints |
---|---|---|---|
namespace_id |
VARCHAR(15) | Namespace identifier | PRIMARY KEY, FOREIGN KEY |
min_length |
INT | Minimum length for this tier | PRIMARY KEY |
min_price |
INT64 | Minimum price for names in this tier | NOT NULL |
Column | Type | Description | Constraints |
---|---|---|---|
name |
VARCHAR(64) | Name portion of the ID | PRIMARY KEY |
namespace_id |
VARCHAR(15) | Namespace portion of the ID | PRIMARY KEY, FOREIGN KEY |
owner |
BLOB | Owner's address in binary format | NOT NULL |
registration_time |
INT64 | When the ID was registered | NOT NULL |
expiration_time |
INT64 | When the ID expires | NOT NULL |
last_transaction |
INT64 | Timestamp of last transaction | NOT NULL |
transaction_count |
INT | Number of transactions | NOT NULL |
metadata_hash |
BLOB(32) | Hash of additional metadata | NULL |
Column | Type | Description | Constraints |
---|---|---|---|
auction_id |
BLOB(32) | Unique identifier for the auction | PRIMARY KEY |
name |
VARCHAR(64) | Name portion of the ID being auctioned | NULL |
namespace_id |
VARCHAR(15) | Namespace portion of the ID | NOT NULL |
creator_address |
BLOB | Creator's address in binary format | NOT NULL |
start_time |
INT64 | Start time (unix timestamp) | NOT NULL |
end_time |
INT64 | End time (unix timestamp) | NOT NULL |
reserve_price |
INT64 | Minimum acceptable bid | NOT NULL |
current_bid |
INT64 | Highest current bid amount | NOT NULL |
current_bidder |
BLOB | Address of highest bidder | NULL |
deposit_amount |
INT64 | Required deposit amount | NOT NULL |
state |
INT | Current auction state | NOT NULL |
type |
INT | Auction type | NOT NULL |
metadata_hash |
BLOB(32) | Hash of additional metadata | NULL |
block_height |
INT | Block height when auction was created | NOT NULL |
txid |
BLOB(32) | Transaction ID of creation transaction | NOT NULL |
Column | Type | Description | Constraints |
---|---|---|---|
bid_id |
BLOB(32) | Unique identifier for the bid | PRIMARY KEY |
auction_id |
BLOB(32) | Reference to the auction | FOREIGN KEY, NOT NULL |
bidder_address |
BLOB | Bidder's address in binary format | NOT NULL |
bidder_reddid |
VARCHAR(32) | Bidder's ReddID (if any) | NULL |
bid_amount |
INT64 | Bid amount | NOT NULL |
deposit_amount |
INT64 | Deposit amount paid | NOT NULL |
bid_time |
INT64 | Time when bid was placed | NOT NULL |
txid |
BLOB(32) | Transaction ID of the bid transaction | NOT NULL |
is_winner |
BOOLEAN | Whether this bid won the auction | NOT NULL |
refunded |
BOOLEAN | Whether the deposit was refunded | NOT NULL |
Column | Type | Description | Constraints |
---|---|---|---|
reddid |
VARCHAR(32) | The ReddID | PRIMARY KEY |
owner |
BLOB | Owner's address in binary format | NOT NULL |
display_name |
VARCHAR(64) | User-selected display name | NOT NULL |
avatar_hash |
BLOB(32) | IPFS hash of avatar image | NULL |
bio |
VARCHAR(256) | Short biography or description | NULL |
email_hash |
BLOB(32) | Hash of verified email | NULL |
social_data |
TEXT | JSON of linked social profiles | NULL |
messaging_pubkey |
BLOB | Public key for encrypted messaging | NULL |
verification_status |
INT | Verification level (0-3) | NOT NULL |
creation_time |
INT64 | When the ReddID was created | NOT NULL |
last_updated |
INT64 | When profile was last updated | NOT NULL |
expiration_time |
INT64 | When the ReddID expires | NOT NULL |
active |
BOOLEAN | Whether the ReddID is currently active | NOT NULL |
flags |
INT | Bitfield of profile flags/settings | NOT NULL |
Column | Type | Description | Constraints |
---|---|---|---|
from_reddid |
VARCHAR(32) | Source ReddID | PRIMARY KEY, FOREIGN KEY |
to_reddid |
VARCHAR(32) | Target ReddID | PRIMARY KEY, FOREIGN KEY |
connection_type |
INT | Type (0=follow, 1=friend, 2=endorse, 3=block) | NOT NULL |
creation_time |
INT64 | When connection was established | NOT NULL |
last_interaction |
INT64 | When last interaction occurred | NOT NULL |
visibility |
INT | Privacy setting (0=public, 1=friends, 2=private) | NOT NULL |
metadata |
TEXT | Additional connection metadata | NULL |
txid |
BLOB(32) | Transaction ID of the connection operation | NOT NULL |
Column | Type | Description | Constraints |
---|---|---|---|
reddid |
VARCHAR(32) | The ReddID | PRIMARY KEY, FOREIGN KEY |
overall_score |
REAL | Aggregate reputation score (0-100) | NOT NULL |
longevity_score |
REAL | Score component for account age | NOT NULL |
transaction_score |
REAL | Score component for transaction history | NOT NULL |
engagement_score |
REAL | Score component for community engagement | NOT NULL |
verification_score |
REAL | Score component for verification depth | NOT NULL |
auction_score |
REAL | Score component for auction behavior | NOT NULL |
last_calculated |
INT64 | When the score was last calculated | NOT NULL |
calculation_proof |
BLOB | Proof of calculation correctness | NULL |
calculator_signatures |
TEXT | JSON of node signatures validating the calculation | NULL |
Column | Type | Description | Constraints |
---|---|---|---|
reddid |
VARCHAR(32) | The ReddID | PRIMARY KEY, FOREIGN KEY |
namespace_id |
VARCHAR(15) | Namespace identifier | PRIMARY KEY, FOREIGN KEY |
user_id |
VARCHAR(64) | User ID within that namespace | NOT NULL |
is_primary |
BOOLEAN | Whether this is the primary namespace for the ReddID | NOT NULL |
auto_update |
BOOLEAN | Whether profile changes propagate to this namespace | NOT NULL |
last_synced |
INT64 | When last synchronized | NOT NULL |
To optimize common query patterns, the following indexes are implemented:
Table | Index | Columns | Purpose |
---|---|---|---|
namespaces |
idx_namespaces_owner |
owner |
Quickly find namespaces by owner |
namespaces |
idx_namespaces_expiration |
expiration |
Find expiring namespaces efficiently |
user_ids |
idx_user_ids_owner |
owner |
Quickly find user IDs by owner |
user_ids |
idx_user_ids_namespace |
namespace_id |
Find all user IDs in a namespace |
user_ids |
idx_user_ids_expiration |
expiration_time |
Find expiring user IDs efficiently |
auctions |
idx_auctions_namespace |
namespace_id |
Find auctions by namespace |
auctions |
idx_auctions_state |
state |
Find auctions by state (e.g., active) |
auctions |
idx_auctions_end_time |
end_time |
Find auctions by end time |
bids |
idx_bids_auction |
auction_id |
Find all bids for an auction |
bids |
idx_bids_bidder |
bidder_address |
Find all bids by a bidder |
reddid_profiles |
idx_profiles_owner |
owner |
Find profiles by owner |
reddid_profiles |
idx_profiles_expiration |
expiration_time |
Find expiring profiles |
reddid_connections |
idx_connections_from |
from_reddid |
Find outgoing connections |
reddid_connections |
idx_connections_to |
to_reddid |
Find incoming connections |
reddid_reputation |
idx_reputation_score |
overall_score |
Find ReddIDs by reputation score |
reddid_namespace_resolution |
idx_resolution_namespace_user |
namespace_id , user_id
|
Resolve from namespace.user to ReddID |
The following diagram illustrates the key relationships between database tables:
erDiagram
namespaces {
VARCHAR(15) id PK
BLOB owner
BOOLEAN allow_numbers
BOOLEAN allow_hyphens
BOOLEAN allow_underscores
INT min_length
INT max_length
INT renewal_period
INT grace_period
INT namespace_revenue_pct
INT burn_pct
INT node_pct
INT dev_pct
INT min_auction_duration
INT max_auction_duration
REAL min_bid_increment
BLOB(32) config_hash
INT64 last_updated
INT64 expiration
}
namespace_pricing_tiers {
VARCHAR(15) namespace_id PK,FK
INT min_length PK
INT64 min_price
}
user_ids {
VARCHAR(64) name PK
VARCHAR(15) namespace_id PK,FK
BLOB owner
INT64 registration_time
INT64 expiration_time
INT64 last_transaction
INT transaction_count
BLOB(32) metadata_hash
}
auctions {
BLOB(32) auction_id PK
VARCHAR(64) name
VARCHAR(15) namespace_id
BLOB creator_address
INT64 start_time
INT64 end_time
INT64 reserve_price
INT64 current_bid
BLOB current_bidder
INT64 deposit_amount
INT state
INT type
BLOB(32) metadata_hash
INT block_height
BLOB(32) txid
}
bids {
BLOB(32) bid_id PK
BLOB(32) auction_id FK
BLOB bidder_address
VARCHAR(32) bidder_reddid
INT64 bid_amount
INT64 deposit_amount
INT64 bid_time
BLOB(32) txid
BOOLEAN is_winner
BOOLEAN refunded
}
reddid_profiles {
VARCHAR(32) reddid PK
BLOB owner
VARCHAR(64) display_name
BLOB(32) avatar_hash
VARCHAR(256) bio
BLOB(32) email_hash
TEXT social_data
BLOB messaging_pubkey
INT verification_status
INT64 creation_time
INT64 last_updated
INT64 expiration_time
BOOLEAN active
INT flags
}
reddid_connections {
VARCHAR(32) from_reddid PK,FK
VARCHAR(32) to_reddid PK,FK
INT connection_type
INT64 creation_time
INT64 last_interaction
INT visibility
TEXT metadata
BLOB(32) txid
}
reddid_reputation {
VARCHAR(32) reddid PK,FK
REAL overall_score
REAL longevity_score
REAL transaction_score
REAL engagement_score
REAL verification_score
REAL auction_score
INT64 last_calculated
BLOB calculation_proof
TEXT calculator_signatures
}
reddid_namespace_resolution {
VARCHAR(32) reddid PK,FK
VARCHAR(15) namespace_id PK,FK
VARCHAR(64) user_id
BOOLEAN is_primary
BOOLEAN auto_update
INT64 last_synced
}
namespaces ||--o{ namespace_pricing_tiers : has
namespaces ||--o{ user_ids : contains
namespaces ||--o{ auctions : hosts
user_ids ||--o{ reddid_namespace_resolution : resolves_to
auctions ||--o{ bids : receives
reddid_profiles ||--o{ reddid_connections : establishes
reddid_profiles ||--o{ reddid_reputation : has
reddid_profiles ||--o{ reddid_namespace_resolution : resolves_to
bids }o--o{ reddid_profiles : placed_by
reddid_connections }o--o{ reddid_profiles : connects_to
- A namespace exists in
namespaces
table - User creates auction in
auctions
table for a new user ID - Other users place bids in
bids
table - Upon auction conclusion, winner is recorded in
auctions
table - New record created in
user_ids
table with winning bidder as owner - Optionally, a
reddid_namespace_resolution
record links the User ID to a ReddID
sequenceDiagram
participant User as User
participant Other Users as Other Users
participant Namespaces as namespaces table
participant Auctions as auctions table
participant Bids as bids table
participant UserIDs as user_ids table
participant Resolution as reddid_namespace_resolution table
Note over Namespaces: 1. Namespace exists
User->>+Auctions: 2. Create auction for new user ID
Auctions-->>-User: Auction created
loop 3. Bidding period
Other Users->>+Bids: Place bids
Bids-->>-Other Users: Bid recorded
end
Note over Auctions: 4. Auction concludes
Auctions->>Auctions: Record winner
Auctions->>+UserIDs: 5. Create user ID record
UserIDs-->>-Auctions: User ID created with winning bidder as owner
opt 6. Optional ReddID linking
User->>+Resolution: Link User ID to ReddID
Resolution-->>-User: Resolution record created
end
- User registers a ReddID in the
reddid_profiles
table - System calculates initial reputation in
reddid_reputation
table - User establishes connections in
reddid_connections
table - User links existing User IDs via
reddid_namespace_resolution
bleta
sequenceDiagram
participant User as User
participant Profiles as reddid_profiles table
participant Reputation as reddid_reputation table
participant Connections as reddid_connections table
participant Resolution as reddid_namespace_resolution table
User->>+Profiles: 1. Register ReddID
Profiles-->>-User: Profile created
Profiles->>+Reputation: 2. Calculate initial reputation
Reputation-->>-Profiles: Reputation record created
User->>+Connections: 3. Establish connections
Connections-->>-User: Connection records created
User->>+Resolution: 4. Link existing User IDs
Resolution-->>-User: Resolution records created
The ReddID system integrates with the Reddcoin blockchain using OP_RETURN operations to record key identity operations. The following transaction types are defined:
Operation | Description | Estimated Size |
---|---|---|
OP_NAMESPACE_AUCTION_CREATE |
Create a namespace auction | ~75 bytes |
OP_NAMESPACE_AUCTION_BID |
Place bid on namespace auction | ~42 bytes |
OP_NAMESPACE_AUCTION_FINALIZE |
Finalize namespace auction | ~42 bytes |
OP_NAMESPACE_CONFIG_UPDATE |
Update namespace configuration | ~70 bytes |
OP_NAMESPACE_TRANSFER |
Transfer namespace ownership | ~55 bytes |
OP_NAMESPACE_RENEW |
Renew namespace registration | ~40 bytes |
Operation | Description | Estimated Size |
---|---|---|
OP_USERID_AUCTION_CREATE |
Create user ID auction | ~60 bytes |
OP_USERID_AUCTION_BID |
Place bid on user ID auction | ~42 bytes |
OP_USERID_AUCTION_FINALIZE |
Finalize user ID auction | ~42 bytes |
OP_USERID_TRANSFER |
Transfer user ID ownership | ~55 bytes |
OP_USERID_RENEW |
Renew user ID registration | ~40 bytes |
Operation | Description | Estimated Size |
---|---|---|
OP_REDDID_REGISTER |
Register a new ReddID | ~75 bytes |
OP_REDDID_UPDATE |
Update ReddID profile | ~50 bytes |
OP_REDDID_CONNECTION |
Create/modify social connection | ~65 bytes |
OP_REDDID_RESOLVE |
Link ReddID to namespace user ID | ~60 bytes |
OP_REDDID_RENEW |
Renew ReddID registration | ~40 bytes |
Each transaction type uses a specialized OP_RETURN format to encode the relevant data compactly:
0 2 3 7 8 16 17 25 26 34 35 39
|-----|--|----------|----|---------|----|-----|-----|------|---------|----|
magic op auctionId type nameHash ns start end reserve depositPct
Where:
-
magic
(2 bytes): Network identifier (0xD4D8 for mainnet) -
op
(1 byte): Operation code (0x7B for namespace auction creation) -
auctionId
(4 bytes): First 4 bytes of auction identifier -
type
(1 byte): Auction type (0=standard, 1=premium) -
nameHash
(8 bytes): First 8 bytes of namespace name hash -
ns
(up to 15 bytes): Namespace identifier string -
start
(8 bytes): Start time as Unix timestamp -
end
(8 bytes): End time as Unix timestamp -
reserve
(8 bytes): Reserve price in satoshis -
depositPct
(1 byte): Deposit percentage (typically 20)
0 2 3 7 8 16 17 25
|-----|--|----------|----|---------|----|-----|
magic op auctionId hash bidAmount time
Where:
-
magic
(2 bytes): Network identifier -
op
(1 byte): Operation code (0x7D for namespace auction bid) -
auctionId
(4 bytes): First 4 bytes of auction identifier -
hash
(8 bytes): Hash of bid data for verification -
bidAmount
(8 bytes): Bid amount in satoshis -
time
(8 bytes): Bid time as Unix timestamp
0 2 3 39
|----|--|-----------------------------|
magic op name.namespace_id (37 bytes)
Where:
-
magic
(2 bytes): Network identifier -
op
(1 byte): Operation code (0x25 for user ID auction creation) -
name.namespace_id
(up to 37 bytes): Combined name and namespace ID
0 2 3 35 36 44 45 109
|----|--|-----------------------------|-----|-----|------------|
magic op reddid_id (32 bytes) time fee profile_hash
Where:
-
magic
(2 bytes): Network identifier -
op
(1 byte): Operation code (0x24 for ReddID registration) -
reddid_id
(up to 32 bytes): ReddID string -
time
(8 bytes): Registration time as Unix timestamp -
fee
(8 bytes): Registration fee in satoshis -
profile_hash
(up to 64 bytes): Hash of full profile data
The system defines the following operation codes for different transaction types:
Hex Value | Symbol | Description | Operation |
---|---|---|---|
0x7B |
{ |
Create namespace auction | OP_NAMESPACE_AUCTION_CREATE |
0x7D |
} |
Bid on namespace auction | OP_NAMESPACE_AUCTION_BID |
0x5B |
[ |
Finalize namespace auction | OP_NAMESPACE_AUCTION_FINALIZE |
0x5D |
] |
Cancel namespace auction | OP_NAMESPACE_AUCTION_CANCEL |
0x3C |
< |
Update namespace configuration | OP_NAMESPACE_CONFIG_UPDATE |
0x3E |
> |
Transfer namespace ownership | OP_NAMESPACE_TRANSFER |
0x5E |
^ |
Renew namespace registration | OP_NAMESPACE_RENEW |
0x25 |
% |
Create user ID auction | OP_USERID_AUCTION_CREATE |
0x7C |
| |
Bid on user ID auction | OP_USERID_AUCTION_BID |
0x22 |
" |
Finalize user ID auction | OP_USERID_AUCTION_FINALIZE |
0x27 |
' |
Cancel user ID auction | OP_USERID_AUCTION_CANCEL |
0x3A |
: |
Transfer user ID ownership | OP_USERID_TRANSFER |
0x3B |
; |
Renew user ID registration | OP_USERID_RENEW |
0x24 |
$ |
Register a new ReddID | OP_REDDID_REGISTER |
0x23 |
# |
Update ReddID profile | OP_REDDID_UPDATE |
0x2B |
+ |
Create/modify social connection | OP_REDDID_CONNECTION |
0x40 |
@ |
Link ReddID to namespace user ID | OP_REDDID_RESOLVE |
0x2A |
* |
Renew ReddID registration | OP_REDDID_RENEW |
The system creates blockchain transactions using the following process:
- Prepare the appropriate OP_RETURN data format for the desired operation
- Create a transaction with at least one input from the user's wallet
- Add normal outputs for payment or change as required
- Add an OP_RETURN output containing the formatted data
- Sign the transaction with the appropriate private key(s)
- Broadcast the transaction to the network
Example transaction creation pseudocode:
bool CreateReddIDTransaction(const std::vector<unsigned char>& data, CAmount feeRate, CMutableTransaction& mtx) {
// Select inputs from wallet to cover the fee
std::vector<COutput> vAvailableCoins;
wallet->AvailableCoins(vAvailableCoins);
// Calculate fee based on transaction size
size_t dataSize = data.size();
size_t txSize = 148 + dataSize + 34; // Input + OP_RETURN + change output
CAmount fee = feeRate * txSize / 1000;
// Find suitable inputs
CAmount totalIn = 0;
std::vector<COutput> selectedCoins;
for (const auto& coin : vAvailableCoins) {
if (coin.nDepth >= MINIMUM_CONFIRMATIONS) {
selectedCoins.push_back(coin);
totalIn += coin.tx->vout[coin.i].nValue;
if (totalIn >= fee) {
break;
}
}
}
if (totalIn < fee) {
return false; // Insufficient funds
}
// Add inputs
for (const auto& coin : selectedCoins) {
mtx.vin.push_back(CTxIn(coin.tx->GetHash(), coin.i));
}
// Add OP_RETURN output
CScript scriptData;
scriptData << OP_RETURN << data;
mtx.vout.push_back(CTxOut(0, scriptData));
// Add change output if necessary
if (totalIn > fee) {
CScript scriptChange = wallet->GetChangeScript();
mtx.vout.push_back(CTxOut(totalIn - fee, scriptChange));
}
return true;
}
The ReddID system extends the Reddcoin consensus rules with the following validations:
- Format Validation: Ensure all OP_RETURN data conforms to the defined formats
- Duplicate Prevention: Prevent duplicate namespace and user ID registrations
- Auction Validation: Enforce auction rules (minimum bids, timing, etc.)
- Authorization Validation: Verify operations are performed by authorized parties
- Economic Rule Enforcement: Enforce revenue distribution as per configuration
Some validation is performed on-chain (enforced by all nodes), while other validation is performed off-chain (by the ReddID system):
Validation | Type | Description |
---|---|---|
Basic format | On-chain | OP_RETURN format, operation codes |
Namespace/ID availability | On-chain | Prevent duplicates |
Authorization | On-chain | Key ownership verification |
Auction state | Off-chain | Current auction state tracking |
Bid validity | Off-chain | Minimum increment rules |
Configuration validity | Off-chain | Namespace configuration rules |
Reputation calculation | Off-chain | Complex reputation formulas |
All ReddID transactions are processed through the chain in the following manner:
- Transaction is included in a block
- During block processing,
ProcessIdTx()
is called for each transaction - OP_RETURN data is extracted and validated
- Valid operations update the ReddID database
- P2P messages are sent to propagate changes
The specific processing function depends on the operation code:
bool ReddIDManager::ProcessIdTx(const CTransaction& tx, int height) {
// Extract OP_RETURN data if present
std::vector<unsigned char> data;
if (!GetOpReturnData(tx, data) || data.size() < 3) {
return false; // Not a ReddID transaction or invalid format
}
// Check magic bytes
if (data[0] != pnetParams->ReddIDMagic[0] || data[1] != pnetParams->ReddIDMagic[1]) {
return false; // Invalid network magic
}
// Process based on operation code
unsigned char opCode = data[2];
switch (opCode) {
case OP_NAMESPACE_AUCTION_CREATE:
return ProcessNamespaceAuctionCreate(tx, data, height);
case OP_NAMESPACE_AUCTION_BID:
return ProcessNamespaceAuctionBid(tx, data, height);
case OP_NAMESPACE_AUCTION_FINALIZE:
return ProcessNamespaceAuctionFinalize(tx, data, height);
// Additional cases for other operations...
default:
return false; // Unknown operation code
}
}
The ReddID system extends the Reddcoin P2P protocol with new message types to facilitate identity data exchange:
Message Type | Command String | Description |
---|---|---|
MSG_NAMESPACE_AUCTION_ANNOUNCE |
nsauc |
Announce a new namespace auction |
MSG_NAMESPACE_AUCTION_BID |
nsbid |
Announce a bid on a namespace auction |
MSG_NAMESPACE_AUCTION_FINALIZE |
nsfin |
Announce namespace auction finalization |
MSG_NAMESPACE_AUCTION_CANCEL |
nscnl |
Announce namespace auction cancellation |
MSG_NAMESPACE_CONFIG_REQUEST |
nsreq |
Request namespace configuration |
MSG_NAMESPACE_CONFIG_RESPONSE |
nsres |
Provide namespace configuration |
Message Type | Command String | Description |
---|---|---|
MSG_USERID_AUCTION_ANNOUNCE |
uidauc |
Announce a new user ID auction |
MSG_USERID_AUCTION_BID |
uidbid |
Announce a bid on a user ID auction |
MSG_USERID_AUCTION_FINALIZE |
uidfin |
Announce user ID auction finalization |
MSG_USERID_AUCTION_CANCEL |
uidcnl |
Announce user ID auction cancellation |
Message Type | Command String | Description |
---|---|---|
MSG_REDDID_REGISTER_ANNOUNCE |
ridreg |
Announce a new ReddID registration |
MSG_REDDID_PROFILE_UPDATE |
ridupd |
Announce profile update |
MSG_REDDID_CONNECTION |
ridcon |
Announce social connection change |
MSG_REDDID_PROFILE_REQUEST |
ridreq |
Request profile data |
MSG_REDDID_PROFILE_RESPONSE |
ridres |
Provide profile data |
MSG_REDDID_REPUTATION_UPDATE |
ridrep |
Update reputation score |
MSG_REDDID_RENEW_ANNOUNCE |
ridrn |
Announce a ReddID renewal |
All ReddID P2P messages follow a standard format:
┌───────────┬───────────┬────────────┬─────────────┐
│ Command │ Length │ Checksum │ Payload │
│ (12 bytes)│ (4 bytes) │ (4 bytes) │ (variable) │
└───────────┴───────────┴────────────┴─────────────┘
The payload format varies depending on the message type. For example, a namespace auction announcement:
┌───────────┬──────────────┬──────────┬───────────┬───────────┬─────────────┐
│ Auction ID│ Namespace ID │ Creator │ Start Time│ End Time │ Reserve │
│ (32 bytes)│ (variable) │ (20 bytes)│ (8 bytes) │ (8 bytes) │ (8 bytes) │
└───────────┴──────────────┴──────────┴───────────┴───────────┴─────────────┘
P2P messages are processed through the following sequence:
- Message received by the node
- Basic validation (format, length, checksum)
- Rate limiting applied to prevent DoS attacks
- Message-specific validation based on type
- Database updated with message information
- Message relayed to other nodes based on relevance
- Node-specific handler called for UI updates
sequenceDiagram
participant Sender as Sending Node
participant Node as Receiving Node
participant Validator as Message Validator
participant RateLimiter as Rate Limiter
participant Database as Database
participant OtherNodes as Other Nodes
participant UI as UI Handler
Sender->>+Node: 1. Message received
Node->>+Validator: 2. Basic validation
Note over Validator: Format, length, checksum
Validator-->>-Node: Validation result
Node->>+RateLimiter: 3. Apply rate limiting
Note over RateLimiter: Prevent DoS attacks
RateLimiter-->>-Node: Rate check result
Node->>Node: 4. Message-specific validation
Note over Node: Based on message type
Node->>+Database: 5. Update database
Database-->>-Node: Update confirmation
Node->>+OtherNodes: 6. Relay to relevant nodes
OtherNodes-->>-Node: Relay acknowledgment
Node->>+UI: 7. Call UI handler
Note over UI: Update user interface
UI-->>-Node: UI update confirmation
Node-->>-Sender: Processing complete
The entry point for message processing is the ProcessReddIDMessage
method:
bool ReddIDP2PManager::ProcessReddIDMessage(CNode* pfrom, const std::string& strCommand,
CDataStream& vRecv, int64_t nTimeReceived,
const CChainParams& chainparams) {
LogPrint(BCLog::REDDID, "ProcessReddIDMessage: %s, %u bytes\n", strCommand, vRecv.size());
// Check rate limits
if (!CheckMessageRate(pfrom, strCommand)) {
LogPrint(BCLog::REDDID, "Rate limit exceeded for %s messages\n", strCommand);
return false;
}
// Process message based on command
if (strCommand == "nsauc")
return HandleNamespaceAuctionAnnounce(pfrom, vRecv);
else if (strCommand == "nsbid")
return HandleNamespaceAuctionBid(pfrom, vRecv);
else if (strCommand == "nsfin")
return HandleNamespaceAuctionFinalize(pfrom, vRecv);
else if (strCommand == "nscnl")
return HandleNamespaceAuctionCancel(pfrom, vRecv);
else if (strCommand == "nsreq")
return HandleNamespaceConfigRequest(pfrom, vRecv);
else if (strCommand == "nsres")
return HandleNamespaceConfigResponse(pfrom, vRecv);
// Additional handlers for other message types...
return false; // Unknown command
}
The P2P network handles synchronization of identity data that is too large to fit in OP_RETURN transactions:
Namespace configurations are synchronized through a request-response pattern:
- Node encounters a namespace reference without local configuration
- Node sends
MSG_NAMESPACE_CONFIG_REQUEST
to peers - Peers with the configuration respond with
MSG_NAMESPACE_CONFIG_RESPONSE
- Node validates the configuration against the on-chain hash
- Configuration is stored in the local database
sequenceDiagram
participant Node as Requesting Node
participant Peers as Network Peers
participant Blockchain as Blockchain
participant DB as Local Database
Note over Node: 1. Encounters namespace without local configuration
Node->>+Peers: 2. Send MSG_NAMESPACE_CONFIG_REQUEST
loop For peers with configuration
Peers-->>-Node: 3. Respond with MSG_NAMESPACE_CONFIG_RESPONSE
end
Node->>+Blockchain: 4. Validate configuration
Note over Node,Blockchain: Check against on-chain hash
Blockchain-->>-Node: Validation result
alt Configuration valid
Node->>+DB: 5. Store configuration
DB-->>-Node: Storage confirmation
else Configuration invalid
Node->>Node: Discard invalid configuration
Note over Node: May blacklist peer if malicious
end
bool ReddIDP2PManager::HandleNamespaceConfigRequest(CNode* pfrom, CDataStream& vRecv) {
std::string namespaceId;
vRecv >> namespaceId;
LogPrint(BCLog::REDDID, "Received namespace config request for %s\n", namespaceId);
NamespaceInfo namespaceInfo;
if (m_reddIDManager->GetNamespaceManager()->GetNamespaceInfo(namespaceId, namespaceInfo)) {
// Send configuration response
SendNamespaceConfigResponse(namespaceId, pfrom);
return true;
}
return false; // We don't have this configuration
}
ReddID profiles are synchronized using a similar pattern:
- Node encounters a ReddID reference without local profile data
- Node sends
MSG_REDDID_PROFILE_REQUEST
to peers - Peers with the profile respond with
MSG_REDDID_PROFILE_RESPONSE
- Node validates the profile against the on-chain hash
- Profile is stored in the local database
sequenceDiagram
participant Node as Requesting Node
participant Peers as Network Peers
participant Blockchain as Blockchain
participant DB as Local Database
Note over Node: 1. Encounters ReddID without local profile data
Node->>+Peers: 2. Send MSG_REDDID_PROFILE_REQUEST
loop For peers with profile
Peers-->>-Node: 3. Respond with MSG_REDDID_PROFILE_RESPONSE
end
Node->>+Blockchain: 4. Validate profile
Note over Node,Blockchain: Check against on-chain hash
Blockchain-->>-Node: Validation result
alt Profile valid
Node->>+DB: 5. Store profile
DB-->>-Node: Storage confirmation
else Profile invalid
Node->>Node: Discard invalid profile
Note over Node: May blacklist peer if malicious
end
Reputation updates are propagated through the network:
- Node calculates a new reputation score for a ReddID
- Node broadcasts
MSG_REDDID_REPUTATION_UPDATE
with the new score - Receiving nodes validate the calculation
- If valid, nodes update their local database
- Nodes may add their signature to the calculation proof
sequenceDiagram
participant CalcNode as Calculating Node
participant Network as Network Nodes
participant Validator as Validation Process
participant DB as Local Database
CalcNode->>CalcNode: 1. Calculate new reputation score
Note over CalcNode: For a specific ReddID
CalcNode->>+Network: 2. Broadcast MSG_REDDID_REPUTATION_UPDATE
Note over CalcNode,Network: Include new score and calculation proof
loop For each receiving node
Network->>+Validator: 3. Validate calculation
Validator-->>-Network: Validation result
alt Calculation is valid
Network->>+DB: 4. Update local database
DB-->>-Network: Update confirmation
Network->>Network: 5. Add signature to calculation proof
Note over Network: Optional step
else Calculation is invalid
Network->>Network: Discard invalid update
Note over Network: May blacklist node if malicious
end
end
Network-->>-CalcNode: Propagation acknowledgment
To optimize network traffic, nodes can subscribe to specific types of updates:
Nodes can subscribe to updates for specific namespaces:
bool ReddIDP2PManager::AddNamespaceSubscription(const std::string& namespaceId, CNode* pnode) {
if (pnode) {
m_namespaceSubscriptions[namespaceId].insert(pnode->GetId());
LogPrint(BCLog::REDDID, "Added namespace subscription for %s from node %d\n",
namespaceId, pnode->GetId());
return true;
}
return false;
}
When sending namespace-related messages, the system prioritizes nodes with relevant subscriptions:
bool ReddIDP2PManager::SendUserIDAuctionAnnounce(const AuctionInfo& auction) {
// Create message payload
CDataStream msg(SER_NETWORK, PROTOCOL_VERSION);
msg << auction.auctionId << auction.name << auction.namespaceId
<< auction.creator << auction.startTime << auction.endTime
<< auction.reservePrice << auction.type;
// Send to subscribed nodes first
bool sent = false;
auto it = m_namespaceSubscriptions.find(auction.namespaceId);
if (it != m_namespaceSubscriptions.end()) {
for (NodeId nodeId : it->second) {
CNode* pnode = g_connman->FindNode(nodeId);
if (pnode) {
g_connman->PushMessage(pnode, CNetMsgMaker(PROTOCOL_VERSION)
.Make(NetMsgType::REDDID, "uidauc", msg));
sent = true;
}
}
}
// Then broadcast to a subset of other nodes
g_connman->ForEachNode([&](CNode* pnode) {
// Only send to a subset of nodes to avoid flooding
if (pnode->nVersion >= MIN_REDDID_PROTO_VERSION && GetRand(4) == 0) {
g_connman->PushMessage(pnode, CNetMsgMaker(PROTOCOL_VERSION)
.Make(NetMsgType::REDDID, "uidauc", msg));
sent = true;
}
});
return sent;
}
Similarly, nodes can subscribe to updates for specific ReddIDs:
bool ReddIDP2PManager::AddReddIDSubscription(const std::string& reddId, CNode* pnode) {
if (pnode) {
m_reddIDSubscriptions[reddId].insert(pnode->GetId());
LogPrint(BCLog::REDDID, "Added ReddID subscription for %s from node %d\n",
reddId, pnode->GetId());
return true;
}
return false;
}
To minimize network overhead, the protocol implements several bandwidth optimizations:
- Compact Formats: Using binary serialization rather than JSON
- Differential Updates: Sending only changed profile fields
- Subscription Filtering: Selective message propagation
- Progressive Resolution: Requesting additional data only when needed
- Caching: Local storage of frequently accessed data
The ReddID system provides comprehensive API access through RPC commands, allowing integration with wallets and third-party applications.
Command | Description |
---|---|
getnamespacelist |
List all registered namespaces |
getnamespaceinfo |
Get detailed information about a namespace |
getnamespaceauctionlist |
List all namespace auctions |
getnamespaceauctioninfo |
Get detailed information about a namespace auction |
createnamespacesauction |
Create a namespace auction |
bidonnamespacesauction |
Place a bid on a namespace auction |
finalizenamespacesauction |
Finalize a namespace auction |
cancelnamespacesauction |
Cancel a namespace auction |
configurenamespaces |
Update namespace configuration |
renewnamespace |
Renew a namespace |
transfernamespace |
Transfer namespace ownership |
Command | Description |
---|---|
getuseridlist |
List user IDs in a namespace |
getuseridinfo |
Get detailed information about a user ID |
getuserauctionlist |
List all user ID auctions |
getuserauctioninfo |
Get detailed information about a user ID auction |
createuseridauction |
Create a user ID auction |
bidonuseridauction |
Place a bid on a user ID auction |
finalizeuseridauction |
Finalize a user ID auction |
canceluseridauction |
Cancel a user ID auction |
renewuserid |
Renew a user ID |
transferuserid |
Transfer user ID ownership |
Command | Description |
---|---|
registerreddid |
Register a new ReddID |
getreddidprofile |
Get profile information for a ReddID |
updatereddidprofile |
Update a ReddID profile |
renewreddid |
Renew a ReddID registration |
deactivatereddid |
Deactivate a ReddID |
Command | Description |
---|---|
getuserconnections |
Get social connections for a ReddID |
createuserconnection |
Create a new social connection |
updateuserconnection |
Update an existing social connection |
removeuserconnection |
Remove a social connection |
Command | Description |
---|---|
getuserreputation |
Get reputation for a ReddID |
calculateuserreputation |
Calculate or recalculate reputation |
getuserreputationhistory |
Get reputation history for a ReddID |
Each RPC command is implemented as a standalone function that interacts with the ReddIDManager and its components:
static UniValue getnamespacelist(const JSONRPCRequest& request)
{
RPCTypeCheck(request.params, {});
NodeContext& node = EnsureAnyNodeContext(request.context);
if (!node.reddid) {
throw JSONRPCError(RPC_INTERNAL_ERROR, "ReddID manager not initialized");
}
ReddIDManager* reddIDManager = node.reddid.get();
NamespaceManager* namespaceManager = reddIDManager->GetNamespaceManager();
if (!namespaceManager) {
throw JSONRPCError(RPC_INTERNAL_ERROR, "Namespace manager not initialized");
}
std::vector<NamespaceInfo> namespaces = namespaceManager->GetNamespaces();
UniValue result(UniValue::VARR);
for (const auto& ns : namespaces) {
UniValue obj(UniValue::VOBJ);
obj.pushKV("id", ns.id);
obj.pushKV("owner", EncodeDestination(PKHash(ns.owner)));
obj.pushKV("allow_numbers", ns.allowNumbers);
obj.pushKV("allow_hyphens", ns.allowHyphens);
obj.pushKV("allow_underscores", ns.allowUnderscores);
obj.pushKV("min_length", ns.minLength);
obj.pushKV("max_length", ns.maxLength);
obj.pushKV("renewal_period", ns.renewalPeriod);
obj.pushKV("grace_period", ns.gracePeriod);
obj.pushKV("namespace_revenue_pct", ns.namespaceRevenuePct);
obj.pushKV("burn_pct", ns.burnPct);
obj.pushKV("node_pct", ns.nodePct);
obj.pushKV("dev_pct", ns.devPct);
obj.pushKV("min_auction_duration", ns.minAuctionDuration);
obj.pushKV("max_auction_duration", ns.maxAuctionDuration);
obj.pushKV("min_bid_increment", ns.minBidIncrement);
obj.pushKV("last_updated", (int64_t)ns.lastUpdated);
obj.pushKV("expiration", (int64_t)ns.expiration);
result.push_back(obj);
}
return result;
}
> reddcoin-cli createnamespacesauction "crypto" 50000 14 0
{
"auction_id": "abcd1234efgh5678ijkl9012mnop3456",
"namespace_id": "crypto",
"start_time": 1617271200,
"end_time": 1618480800,
"reserve_price": 50000.00000000,
"auction_type": 0,
"creator_address": "rBtXp51yUQS7WqBXuFSyoZp9gXtJcnMcbN"
}
> reddcoin-cli bidonuseridauction "abcd1234efgh5678ijkl9012mnop3456" 75000
{
"bid_id": "90ab12cd34ef56gh78ij90kl12mn34op",
"auction_id": "abcd1234efgh5678ijkl9012mnop3456",
"bid_amount": 75000.00000000,
"deposit_amount": 7500.00000000,
"bid_time": 1617352800,
"bidder_address": "rUv2CAYkbuKybe8D7EkHelrSgRKNsZ22vs"
}
> reddcoin-cli getuserconnections "alice" null "both"
{
"reddid": "alice",
"outgoing_connections": [
{
"to_reddid": "bob",
"connection_type": 1,
"type_name": "friend",
"creation_time": 1617271200,
"last_interaction": 1617352800,
"visibility": 0,
"metadata": "Friend from school"
},
{
"to_reddid": "carol",
"connection_type": 0,
"type_name": "follow",
"creation_time": 1617271500,
"last_interaction": 1617271500,
"visibility": 0,
"metadata": ""
}
],
"incoming_connections": [
{
"from_reddid": "dave",
"connection_type": 1,
"type_name": "friend",
"creation_time": 1617281200,
"last_interaction": 1617281200,
"visibility": 0
}
]
}
In addition to the RPC interface, the system provides a WebSocket API for real-time updates:
Subscription | Description |
---|---|
namespace:<id> |
Updates for a specific namespace |
auction:<id> |
Updates for a specific auction |
reddid:<id> |
Updates for a specific ReddID profile |
auctions:active |
All active auction updates |
auctions:ending |
Auctions approaching their end time |
Type | Description |
---|---|
auction_created |
New auction created |
bid_placed |
New bid placed on an auction |
auction_finalized |
Auction has been finalized |
profile_updated |
ReddID profile has been updated |
connection_added |
New social connection created |
reputation_updated |
Reputation score updated |
The system also provides a REST API for integration with web applications:
Endpoint | Method | Description |
---|---|---|
/api/namespaces |
GET | List all namespaces |
/api/namespaces/{id} |
GET | Get namespace details |
/api/auctions/namespaces |
GET | List namespace auctions |
/api/auctions/userids |
GET | List user ID auctions |
/api/reddid/{id} |
GET | Get ReddID profile |
/api/reddid/{id}/connections |
GET | Get ReddID connections |
/api/reddid/{id}/reputation |
GET | Get ReddID reputation |
The ReddID system relies on cryptographic key pairs for authentication and authorization:
Each resource (namespace, user ID, ReddID) is owned by a public-private key pair:
struct ResourceOwnership {
CKeyID ownerKeyID; // Public key hash identifying the owner
int64_t acquiredTimestamp; // When ownership was established
uint256 acquisitionTxid; // Transaction ID that established ownership
};
All management operations require signing with the corresponding private key:
bool AuthorizeOperation(const CKeyID& ownerKeyID, const std::string& operation,
const std::string& resource, const CKey& key,
std::vector<unsigned char>& signature) {
std::string message = operation + ":" + resource + ":" + std::to_string(GetTime());
uint256 messageHash = Hash(message.begin(), message.end());
if (!key.Sign(messageHash, signature)) {
return false;
}
CPubKey pubKey = key.GetPubKey();
CKeyID keyID = pubKey.GetID();
return keyID == ownerKeyID;
}
The system supports key rotation to allow owners to update their keys:
bool ReddIDManager::RotateResourceKey(const std::string& resource, ResourceType type,
const CKeyID& currentOwner, const CKeyID& newOwner,
const CKey& currentKey) {
// Authenticate current owner
std::vector<unsigned char> signature;
std::string operation = "rotate";
if (!AuthorizeOperation(currentOwner, operation, resource, currentKey, signature)) {
return false;
}
// Update ownership records based on resource type
switch (type) {
case RESOURCE_NAMESPACE:
return m_namespaceManager->UpdateOwner(resource, currentOwner, newOwner);
case RESOURCE_USERID:
// Parse resource string to get name and namespace
std::string name, namespaceId;
if (!ParseUserIDString(resource, name, namespaceId)) {
return false;
}
return m_namespaceManager->UpdateUserIDOwner(name, namespaceId,
currentOwner, newOwner);
case RESOURCE_REDDID:
return m_profileManager->UpdateProfileOwner(resource, currentOwner, newOwner);
default:
return false;
}
}
The system uses a multilayered authentication system:
For on-chain operations, authentication is performed through transaction signatures:
- The transaction must be signed by the key corresponding to the input addresses
- For resource management, the input address must match the resource owner
- For auctions, the bidder's address is recorded for future authentication
RPC commands use the Reddcoin Core authentication mechanisms:
- Username/password authentication for the RPC interface
- Authorization verification for wallet operations
- Resource ownership verification for management operations
P2P messages are authenticated through:
- Transaction references for initial operations
- Cryptographic signatures for subsequent operations
- Challenge-response protocols for sensitive operations
The system implements hierarchical access control:
- System-level privileges: Reserved for Reddcoin Core developers
- Namespace owner privileges: Control over namespace configuration
- User ID owner privileges: Control over specific user IDs
- ReddID owner privileges: Control over ReddID profiles and connections
Resource Permissions
├── Namespace
│ ├── Configure (owner only)
│ ├── Transfer (owner only)
│ ├── Renew (owner only)
│ └── View (public)
├── User ID
│ ├── Transfer (owner only)
│ ├── Renew (owner only)
│ ├── Link to ReddID (owner only)
│ └── View (public)
└── ReddID
├── Update Profile (owner only)
├── Manage Connections (owner only)
├── View Profile (public or restricted)
└── View Connections (public or restricted)
The system implements several data protection mechanisms:
Sensitive information can be protected through:
- Data hashing (e.g., email hash rather than plaintext)
- Encryption for private messages
- Visibility controls for social connections
- Permissions for profile information access
For private messages and sensitive data, the system uses:
- Public key cryptography for end-to-end encryption
- AES-256 for symmetric encryption
- Secure key exchange protocols
bool ReddIDManager::SendEncryptedMessage(const std::string& fromReddId,
const std::string& toReddId,
const std::string& message,
const CKey& senderKey) {
// Authenticate sender
ReddIDProfile sender, recipient;
if (!m_profileManager->GetProfile(fromReddId, sender) ||
!m_profileManager->GetProfile(toReddId, recipient)) {
return false;
}
if (sender.owner != senderKey.GetPubKey().GetID()) {
return false; // Not the owner of the sender ReddID
}
if (recipient.messagingPubkey.empty()) {
return false; // Recipient does not have a messaging public key
}
// Encrypt message
CPubKey recipientKey(recipient.messagingPubkey);
if (!recipientKey.IsValid()) {
return false;
}
// Generate one-time ephemeral key
CKey ephemeralKey;
ephemeralKey.MakeNewKey(true);
// ECDH key exchange
std::vector<unsigned char> sharedSecret;
if (!ephemeralKey.ECDH(recipientKey, sharedSecret)) {
return false;
}
// Derive AES key using HKDF
std::vector<unsigned char> aesKey = HKDF(sharedSecret);
// Encrypt message with AES
std::vector<unsigned char> ciphertext;
AES256Encrypt(aesKey, message, ciphertext);
// Create message package
MessagePackage pkg;
pkg.fromReddId = fromReddId;
pkg.toReddId = toReddId;
pkg.ephemeralPubKey = ephemeralKey.GetPubKey();
pkg.ciphertext = ciphertext;
pkg.timestamp = GetTime();
// Sign package
uint256 packageHash = pkg.GetHash();
if (!senderKey.Sign(packageHash, pkg.signature)) {
return false;
}
// Store and relay message
return m_profileManager->StoreMessage(pkg);
}
The system includes comprehensive audit capabilities:
All significant operations are logged with:
- Operation type and parameters
- Timestamp and block height
- Authorizing key identifier
- Resource identifiers
- Transaction references
The system includes verification mechanisms for legal entities:
- Self-Attested Verification: Basic verification with no external proof
- Email Verification: Confirmation through email challenges
- Community Verification: Peer-based verification mechanisms
- Official Verification: Verification for legally registered entities
The system includes mechanisms for resolving disputes:
- Trademark Claims: Process for trademark holders to claim identifiers
- Identity Disputes: Resolution process for impersonation claims
- Operator Intervention: Process for resolving critical issues
The system is developed following secure coding practices:
- Input Validation: All user inputs are validated and sanitized
- Error Handling: Comprehensive error handling to prevent information leakage
- Memory Safety: Buffer overflow protections and memory management
- Cryptographic Standards: Use of well-established cryptographic libraries
- Peer Review: Code review and security auditing processes
The ReddID system depends on several external components:
Component | Usage |
---|---|
Wallet System | Key management, transaction creation |
P2P Network | Message propagation, peer discovery |
Block Validation | Transaction validation, OP_RETURN processing |
RPC Framework | Command interface, authentication |
Database Backend | Storage foundations |
Library | Version | Purpose |
---|---|---|
LevelDB | 1.22+ | Database storage |
OpenSSL | 1.1.1+ | Cryptographic operations |
Boost | 1.70.0+ | Various utilities |
libevent | 2.1.8+ | Networking |
Dependency | Purpose |
---|---|
IPFS (optional) | Decentralized storage for profile images and larger data |
SQLite | Embedded database for efficient querying |
JSON for Modern C++ | JSON parsing and generation |
Google Protocol Buffers | Efficient binary serialization |
Dependency | Purpose |
---|---|
Qt Framework | Cross-platform UI toolkit |
Bootstrap | Web UI styling framework |
React | UI components for web interface |
D3.js | Data visualization for auctions and reputation |
The system uses careful dependency management to minimize security risks:
- Version Pinning: Specific versions of dependencies are specified
- Dependency Auditing: Regular security audits of dependencies
- Minimal Dependencies: Only essential dependencies are included
- Vendoring: Critical dependencies are vendored to prevent supply chain attacks
// Example of dependency version checks
bool CheckDependencies() {
// Check LevelDB version
int major, minor, patch;
leveldb::GetLevelDBVersion(&major, &minor, &patch);
if (major < 1 || (major == 1 && minor < 22)) {
LogPrintf("ERROR: LevelDB version too old: %d.%d.%d, required: 1.22.0+\n",
major, minor, patch);
return false;
}
// Check OpenSSL version
if (SSLeay() < 0x1010100f) {
LogPrintf("ERROR: OpenSSL version too old: %s, required: 1.1.1+\n",
SSLeay_version(SSLEAY_VERSION));
return false;
}
// Check Boost version
if (BOOST_VERSION < 107000) {
LogPrintf("ERROR: Boost version too old: %d, required: 1.70.0+\n",
BOOST_VERSION);
return false;
}
return true;
}
The ReddID system implements several database optimizations:
Carefully designed indexes to optimize common query patterns:
- Primary Key Indexes: For direct lookups by identifier
- Secondary Indexes: For lookups by owner, timestamp, reputation, etc.
- Composite Indexes: For complex queries involving multiple conditions
- Covering Indexes: For queries that can be satisfied entirely from the index
// Example of index creation in database initialization
bool ReddIDDB::CreateIndexes() {
// Create indexes for namespaces
m_db->WriteKey("index:namespaces:owner", std::string());
m_db->WriteKey("index:namespaces:expiration", std::string());
// Create indexes for user IDs
m_db->WriteKey("index:userids:owner", std::string());
m_db->WriteKey("index:userids:namespace", std::string());
m_db->WriteKey("index:userids:expiration", std::string());
// Create indexes for auctions
m_db->WriteKey("index:auctions:namespace", std::string());
m_db->WriteKey("index:auctions:state", std::string());
m_db->WriteKey("index:auctions:end_time", std::string());
// Create indexes for bids
m_db->WriteKey("index:bids:auction", std::string());
m_db->WriteKey("index:bids:bidder", std::string());
// Create indexes for ReddID profiles
m_db->WriteKey("index:profiles:owner", std::string());
m_db->WriteKey("index:profiles:expiration", std::string());
// Create indexes for connections
m_db->WriteKey("index:connections:from", std::string());
m_db->WriteKey("index:connections:to", std::string());
// Create indexes for reputation
m_db->WriteKey("index:reputation:score", std::string());
// Create indexes for namespace resolution
m_db->WriteKey("index:resolution:namespace_user", std::string());
return true;
}
Database operations are batched where possible to minimize I/O overhead:
bool ReddIDDB::UpdateAuctionAndBids(const AuctionInfo& auction,
const std::vector<BidInfo>& bids) {
// Start a database transaction
BeginTransaction();
bool success = true;
// Update the auction
if (!WriteAuction(auction)) {
success = false;
}
// Update all bids in a batch
for (const auto& bid : bids) {
if (!WriteBid(bid)) {
success = false;
break;
}
}
// Commit or abort the transaction
if (success) {
return CommitTransaction();
} else {
AbortTransaction();
return false;
}
}
Careful attention to query patterns to minimize database load:
- Result Limiting: Pagination for large result sets
- Projection: Retrieving only needed fields
- Query Rewriting: Restructuring queries for optimal index usage
- Materialized Views: Precomputed results for complex queries
The system implements multi-level caching to improve performance:
Frequently accessed data is cached in memory:
class NamespaceCache {
public:
NamespaceCache(size_t maxSize = 1000) : m_maxSize(maxSize) {}
bool Get(const std::string& namespaceId, NamespaceInfo& info) {
auto it = m_cache.find(namespaceId);
if (it != m_cache.end()) {
// Check if cached entry is still valid
if (GetTime() - it->second.cacheTime < NAMESPACE_CACHE_TTL) {
info = it->second.info;
return true;
} else {
// Expired entry
m_cache.erase(it);
return false;
}
}
return false;
}
void Put(const std::string& namespaceId, const NamespaceInfo& info) {
// Evict if cache is full
if (m_cache.size() >= m_maxSize) {
// Simple LRU: remove oldest entry
auto oldest = std::min_element(m_cache.begin(), m_cache.end(),
[](const auto& a, const auto& b) {
return a.second.cacheTime < b.second.cacheTime;
});
if (oldest != m_cache.end()) {
m_cache.erase(oldest);
}
}
CachedNamespace cached;
cached.info = info;
cached.cacheTime = GetTime();
m_cache[namespaceId] = cached;
}
void Invalidate(const std::string& namespaceId) {
m_cache.erase(namespaceId);
}
void Clear() {
m_cache.clear();
}
private:
struct CachedNamespace {
NamespaceInfo info;
int64_t cacheTime;
};
std::map<std::string, CachedNamespace> m_cache;
size_t m_maxSize;
static const int64_t NAMESPACE_CACHE_TTL = 3600; // 1 hour
};
Special caching for reputation calculations, which are computationally expensive:
class ReputationCache {
public:
ReputationCache(size_t maxSize = 500) : m_maxSize(maxSize) {}
bool Get(const std::string& reddId, ReddIDReputation& reputation) {
auto it = m_cache.find(reddId);
if (it != m_cache.end()) {
// Reputation cache has a shorter TTL since it changes more frequently
if (GetTime() - it->second.cacheTime < REPUTATION_CACHE_TTL) {
reputation = it->second.reputation;
return true;
} else {
m_cache.erase(it);
return false;
}
}
return false;
}
void Put(const std::string& reddId, const ReddIDReputation& reputation) {
// Eviction policy based on LRU and reputation score
if (m_cache.size() >= m_maxSize) {
// Prefer to keep high-reputation entries in cache
auto evict = std::min_element(m_cache.begin(), m_cache.end(),
[](const auto& a, const auto& b) {
// Score function combining age and reputation
double a_score = a.second.reputation.overallScore *
(GetTime() - a.second.cacheTime);
double b_score = b.second.reputation.overallScore *
(GetTime() - b.second.cacheTime);
return a_score < b_score;
});
if (evict != m_cache.end()) {
m_cache.erase(evict);
}
}
CachedReputation cached;
cached.reputation = reputation;
cached.cacheTime = GetTime();
m_cache[reddId] = cached;
}
void Invalidate(const std::string& reddId) {
m_cache.erase(reddId);
}
private:
struct CachedReputation {
ReddIDReputation reputation;
int64_t cacheTime;
};
std::map<std::string, CachedReputation> m_cache;
size_t m_maxSize;
static const int64_t REPUTATION_CACHE_TTL = 900; // 15 minutes
};
Caching of data distributed through the P2P network:
- Namespace Configurations: Cached locally to avoid repeated requests
- Profile Data: Frequently accessed profiles cached with TTL-based expiration
- Connection Graphs: Caching of social connection data for efficient traversal
- Auction Data: Caching of active auctions for real-time bidding
The system implements several network optimizations:
Messages are prioritized based on time sensitivity:
enum MessagePriority {
PRIORITY_LOW = 0, // Background synchronization, non-urgent updates
PRIORITY_MEDIUM = 1, // Normal updates, profile changes
PRIORITY_HIGH = 2 // Time-sensitive data like auction bids or finalization
};
// When sending messages, priority affects relay behavior
bool ReddIDP2PManager::RelayMessage(CNode* pfrom, const std::string& command,
CDataStream& vMsg, MessagePriority priority) {
int relayChance;
switch (priority) {
case PRIORITY_LOW:
relayChance = 25; // 25% chance to relay to each peer
break;
case PRIORITY_MEDIUM:
relayChance = 50; // 50% chance to relay to each peer
break;
case PRIORITY_HIGH:
relayChance = 100; // Always relay to all peers
break;
default:
relayChance = 25;
}
// Find nodes to relay to
std::vector<CNode*> vNodesCopy;
g_connman->ForEachNode([&vNodesCopy, pfrom, relayChance](CNode* pnode) {
if (pnode->nVersion >= MIN_REDDID_PROTO_VERSION && pnode != pfrom &&
(relayChance == 100 || GetRand(100) < relayChance)) {
vNodesCopy.push_back(pnode);
}
});
// Relay the message
for (auto* pnode : vNodesCopy) {
g_connman->PushMessage(pnode, CNetMsgMaker(PROTOCOL_VERSION).Make(command, vMsg));
}
return !vNodesCopy.empty();
}
Efficient connection management to optimize network resources:
- Connection Prioritization: Prioritize connections to nodes with relevant subscriptions
- Connection Limitation: Limit the number of connections to prevent resource exhaustion
- Bandwidth Management: Control message flow to prevent network congestion
Compression used for larger data transfers:
bool ReddIDP2PManager::SendProfileData(const std::string& reddId, CNode* pnode) {
ReddIDProfile profile;
if (!m_reddIDManager->GetProfileManager()->GetProfile(reddId, profile)) {
return false;
}
// Serialize the profile
CDataStream data(SER_NETWORK, PROTOCOL_VERSION);
data << profile;
// Check if compression is beneficial
if (data.size() > COMPRESSION_THRESHOLD) {
// Compress data
std::vector<unsigned char> compressed;
if (CompressData(data, compressed) && compressed.size() < data.size()) {
// Send compressed data
g_connman->PushMessage(pnode, CNetMsgMaker(PROTOCOL_VERSION)
.Make(NetMsgType::REDDID, "ridres_z", compressed));
return true;
}
}
// Send uncompressed data
g_connman->PushMessage(pnode, CNetMsgMaker(PROTOCOL_VERSION)
.Make(NetMsgType::REDDID, "ridres", data));
return true;
}
bool CompressData(const CDataStream& input, std::vector<unsigned char>& output) {
output.clear();
z_stream strm;
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
// Initialize deflate
if (deflateInit(&strm, Z_DEFAULT_COMPRESSION) != Z_OK) {
return false;
}
// Set input
strm.avail_in = input.size();
strm.next_in = (Bytef*)input.data();
// Prepare output buffer
output.resize(deflateBound(&strm, input.size()));
strm.avail_out = output.size();
strm.next_out = output.data();
// Compress
int ret = deflate(&strm, Z_FINISH);
deflateEnd(&strm);
if (ret != Z_STREAM_END) {
output.clear();
return false;
}
// Resize output to actual compressed size
output.resize(output.size() - strm.avail_out);
return true;
}
The system implements several computational optimizations:
Reputation calculations are optimized to minimize computational overhead:
- Incremental Updates: Reputation is updated incrementally rather than recalculated
- Scheduled Recalculation: Full recalculation performed at scheduled intervals
- Tiered Calculation: Different components calculated at different frequencies
- Parallelization: Reputation calculations parallelized where possible
bool ProfileManager::UpdateReputation(const std::string& reddId,
ReputationUpdateType updateType,
double updateValue) {
ReddIDReputation reputation;
if (!GetReputation(reddId, reputation)) {
// Create default reputation if not exists
reputation.reddId = reddId;
reputation.overallScore = 50.0;
reputation.longevityScore = 0.0;
reputation.transactionScore = 0.0;
reputation.engagementScore = 0.0;
reputation.verificationScore = 0.0;
reputation.auctionScore = 50.0;
reputation.lastCalculated = GetTime();
}
// Update specific component based on update type
switch (updateType) {
case UPDATE_TRANSACTION:
reputation.transactionScore =
(reputation.transactionScore * 0.9) + (updateValue * 0.1);
break;
case UPDATE_ENGAGEMENT:
reputation.engagementScore =
(reputation.engagementScore * 0.8) + (updateValue * 0.2);
break;
case UPDATE_VERIFICATION:
reputation.verificationScore = updateValue;
break;
case UPDATE_AUCTION:
reputation.auctionScore =
(reputation.auctionScore * 0.7) + (updateValue * 0.3);
break;
default:
return false;
}
// Recalculate overall score
const double weights[5] = {0.2, 0.25, 0.2, 0.15, 0.2}; // Component weights
reputation.overallScore =
(reputation.longevityScore * weights[0]) +
(reputation.transactionScore * weights[1]) +
(reputation.engagementScore * weights[2]) +
(reputation.verificationScore * weights[3]) +
(reputation.auctionScore * weights[4]);
// Clamp to valid range
reputation.overallScore = std::max(0.0, std::min(100.0, reputation.overallScore));
// Update timestamp
reputation.lastCalculated = GetTime();
// Save updated reputation
return m_reddIDManager->GetReddIDDB()->WriteReputation(reputation);
}
Auction processing is optimized to handle high transaction volumes:
- Batch Processing: Bids processed in batches
- Priority Queuing: Higher-value auctions processed with priority
- Staged Settlement: Auctions settled in stages to distribute load
- Timelock Management: Efficient handling of time-dependent operations
Social graph operations are optimized for efficient traversal:
- Graph Caching: Frequently traversed paths cached
- Partial Loading: Load only needed portions of the social graph
- Materialized Paths: Precomputed paths for common traversals
- Connection Indexing: Specialized indexes for social graph queries
The system addresses several scalability considerations:
For larger deployments, data can be sharded based on:
- Namespace Sharding: Data partitioned by namespace
- User ID Sharding: User IDs sharded based on hash
- ReddID Sharding: ReddID profiles sharded based on identifier
- Time-Based Sharding: Historical data moved to separate storage
Computational load is distributed based on:
- Node Specialization: Nodes can specialize in different functions
- Workload Partitioning: Divide work based on resource availability
- Task Prioritization: Critical tasks prioritized over background tasks
- Adaptive Scaling: Resource allocation adjusted based on workload
The ReddID system has the following hardware requirements:
Component | Minimum Requirement |
---|---|
CPU | 2 cores, 2.0 GHz |
RAM | 4 GB |
Storage | 50 GB SSD |
Network | 5 Mbps broadband connection |
Component | Recommended Requirement |
---|---|
CPU | 4+ cores, 3.0+ GHz |
RAM | 8+ GB |
Storage | 250+ GB SSD |
Network | 20+ Mbps broadband connection |
Hardware requirements scale based on:
- Transaction Volume: Higher transaction volumes require more CPU and RAM
- Network Size: Larger networks require more bandwidth and connections
- Data Volume: More namespaces and user IDs require more storage
- Query Load: Higher query volumes require more CPU and RAM
The ReddID system has the following software requirements:
OS | Version |
---|---|
Linux | Ubuntu 20.04+, Debian 10+, CentOS 8+ |
Windows | Windows 10, Windows Server 2019+ |
macOS | 10.14 (Mojave)+ |
Software | Version | Purpose |
---|---|---|
Reddcoin Core | 4.0.0+ | Base platform |
GCC/Clang | 9.0+/10.0+ | Compilation |
OpenSSL | 1.1.1+ | Cryptography |
Boost | 1.70.0+ | Utilities |
CMake | 3.16+ | Build system |
Git | 2.25+ | Source control |
Software | Version | Purpose |
---|---|---|
IPFS | 0.8.0+ | Decentralized storage |
Qt | 5.12+ | GUI development |
Docker | 19.03+ | Containerization |
Kubernetes | 1.18+ | Orchestration |
The ReddID system has the following network requirements:
Requirement | Details |
---|---|
Inbound Connections | Port 45444 open for incoming P2P connections |
Outbound Connections | Outbound Internet access on port 45444 |
RPC Access | Port 45443 for local or secured remote access |
WebSocket | Port 45445 for WebSocket API (optional) |
REST API | Port 45446 for REST API (optional) |
Usage Pattern | Inbound | Outbound |
---|---|---|
Light Node | 1-2 GB/day | 500 MB-1 GB/day |
Full Node | 2-3 GB/day | 2-3 GB/day |
Service Node | 5-10 GB/day | 5-10 GB/day |
Recommended network configuration includes:
- Firewall Rules: Allow required ports while blocking unnecessary traffic
- DDoS Protection: Implement rate limiting and flood protection
- Connection Limits: Configure appropriate connection limits based on resources
- Traffic Prioritization: Prioritize critical traffic over less important messages
The installation process consists of the following steps:
# Clone the repository
git clone https://github.com/reddcoin-project/reddcoin-core.git
# Move to the directory
cd reddcoin-core
# Checkout the appropriate branch
git checkout reddid-integration
# Build the software
./autogen.sh
./configure --with-gui=qt5 --enable-reddid
make -j4
# Install (optional)
sudo make install
Basic configuration through reddcoin.conf
:
# ReddID Configuration
reddid=1
reddidindex=1
reddidcache=100
reddidrpc=1
reddidsubscriptions=1
# Network Configuration
listen=1
server=1
rpcuser=username
rpcpassword=password
# P2P Configuration
maxconnections=125
maxuploadtarget=5000
# Initialize the ReddID system (first run)
reddcoind -daemon -reddid -reddidindex -reindex
# Check status
reddcoin-cli reddid-status
Ongoing maintenance requirements include:
Regular backups of:
- Wallet Data: Private keys and transaction data
- ReddID Database: Identity and auction data
- Configuration: System configuration files
- Logs: System logs for audit and troubleshooting
# Backup script example
#!/bin/bash
DATE=$(date +%Y%m%d)
BACKUP_DIR="/backups/reddid/$DATE"
# Create backup directory
mkdir -p $BACKUP_DIR
# Stop the daemon
reddcoin-cli stop
# Wait for shutdown
sleep 10
# Backup wallet
cp -r ~/.reddcoin/wallet.dat $BACKUP_DIR/
# Backup ReddID database
cp -r ~/.reddcoin/reddid/ $BACKUP_DIR/
# Backup configuration
cp ~/.reddcoin/reddcoin.conf $BACKUP_DIR/
# Backup logs
cp ~/.reddcoin/debug.log $BACKUP_DIR/
# Restart the daemon
reddcoind -daemon
Regular monitoring of:
- System Resources: CPU, RAM, disk space
- Network Activity: Connection count, bandwidth usage
- Transaction Volume: Auction activity, bid volume
- Error Rates: Failed operations, connection failures
- Response Times: RPC latency, P2P message propagation
Software updates follow this process:
- Update Announcement: Notification of upcoming updates
- Release Testing: Testing on testnet before mainnet deployment
- Staged Rollout: Gradual rollout to minimize disruption
- Verification: Validate system integrity after update
- Rollback Plan: Procedure for reverting updates if necessary
The ReddID system follows these coding standards:
-
Naming Conventions:
- Classes:
PascalCase
- Functions:
CamelCase
- Variables:
camelCase
- Constants:
UPPER_CASE
- Member variables:
m_camelCase
- Classes:
-
Formatting:
- Indentation: 4 spaces (no tabs)
- Line width: Maximum 100 characters
- Braces: Opening brace on same line, closing brace on new line
- Comments: Above code or at end of line, not exceeding line width
-
Documentation:
- All public functions and classes documented
- Parameter descriptions for all public functions
- Implementation notes for complex algorithms
- Example usage for key functionality
Consistent error handling approach:
bool NamespaceManager::UpdateNamespace(const NamespaceInfo& namespaceInfo) {
// Validate parameters
if (namespaceInfo.id.empty()) {
LogPrintf("ERROR: NamespaceManager::UpdateNamespace: Empty namespace ID\n");
return false;
}
// Check authorization
NamespaceInfo existing;
if (!GetNamespaceInfo(namespaceInfo.id, existing)) {
LogPrintf("ERROR: NamespaceManager::UpdateNamespace: Namespace not found: %s\n",
namespaceInfo.id);
return false;
}
if (existing.owner != namespaceInfo.owner) {
LogPrintf("ERROR: NamespaceManager::UpdateNamespace: Not authorized to update namespace: %s\n",
namespaceInfo.id);
return false;
}
// Validate configuration
if (!ValidateNamespaceConfiguration(namespaceInfo)) {
LogPrintf("ERROR: NamespaceManager::UpdateNamespace: Invalid configuration for namespace: %s\n",
namespaceInfo.id);
return false;
}
// Perform update
try {
if (!m_reddIDManager->GetReddIDDB()->WriteNamespace(namespaceInfo)) {
LogPrintf("ERROR: NamespaceManager::UpdateNamespace: Database write failed for namespace: %s\n",
namespaceInfo.id);
return false;
}
} catch (const std::exception& e) {
LogPrintf("ERROR: NamespaceManager::UpdateNamespace: Exception: %s\n", e.what());
return false;
}
LogPrint(BCLog::REDDID, "Updated namespace: %s\n", namespaceInfo.id);
return true;
}
Comprehensive testing strategy:
- Unit Tests: For individual components and functions
- Integration Tests: For component interactions
- System Tests: For end-to-end functionality
- Stress Tests: For performance under load
- Security Tests: For vulnerability assessment
Example test case:
BOOST_AUTO_TEST_CASE(namespace_validation_test)
{
// Initialize test environment
SetupTestEnvironment();
// Create namespace manager with mock dependencies
MockReddIDManager mockManager;
NamespaceManager namespaceManager(&mockManager);
// Test valid namespace ID
BOOST_CHECK(namespaceManager.ValidateNamespaceID("valid"));
BOOST_CHECK(namespaceManager.ValidateNamespaceID("valid123"));
BOOST_CHECK(namespaceManager.ValidateNamespaceID("v-a-l-i-d"));
// Test invalid namespace ID
BOOST_CHECK(!namespaceManager.ValidateNamespaceID(""));
BOOST_CHECK(!namespaceManager.ValidateNamespaceID("INVALID"));
BOOST_CHECK(!namespaceManager.ValidateNamespaceID("invalid!"));
BOOST_CHECK(!namespaceManager.ValidateNamespaceID("-invalid"));
BOOST_CHECK(!namespaceManager.ValidateNamespaceID("invalid-"));
BOOST_CHECK(!namespaceManager.ValidateNamespaceID("inva--lid"));
BOOST_CHECK(!namespaceManager.ValidateNamespaceID("toolongnamespaceidentifier"));
// Test valid namespace configuration
NamespaceInfo validConfig;
validConfig.id = "valid";
validConfig.allowNumbers = true;
validConfig.allowHyphens = true;
validConfig.allowUnderscores = false;
validConfig.minLength = 3;
validConfig.maxLength = 32;
validConfig.renewalPeriod = 365;
validConfig.gracePeriod = 30;
validConfig.namespaceRevenuePct = 10;
validConfig.burnPct = 70;
validConfig.nodePct = 15;
validConfig.devPct = 5;
validConfig.minAuctionDuration = 3;
validConfig.maxAuctionDuration = 7;
validConfig.minBidIncrement = 5.0;
BOOST_CHECK(namespaceManager.ValidateNamespaceConfiguration(validConfig));
// Test invalid namespace configuration
NamespaceInfo invalidConfig = validConfig;
invalidConfig.minLength = 0; // Invalid: too small
BOOST_CHECK(!namespaceManager.ValidateNamespaceConfiguration(invalidConfig));
invalidConfig = validConfig;
invalidConfig.maxLength = 128; // Invalid: too large
BOOST_CHECK(!namespaceManager.ValidateNamespaceConfiguration(invalidConfig));
invalidConfig = validConfig;
invalidConfig.maxLength = 2; // Invalid: max < min
BOOST_CHECK(!namespaceManager.ValidateNamespaceConfiguration(invalidConfig));
invalidConfig = validConfig;
invalidConfig.namespaceRevenuePct = 20; // Invalid: exceeds limit
BOOST_CHECK(!namespaceManager.ValidateNamespaceConfiguration(invalidConfig));
invalidConfig = validConfig;
// Invalid: percentages don't sum to 100
invalidConfig.namespaceRevenuePct = 10;
invalidConfig.burnPct = 80;
invalidConfig.nodePct = 15;
invalidConfig.devPct = 5;
BOOST_CHECK(!namespaceManager.ValidateNamespaceConfiguration(invalidConfig));
}
Guidelines for implementing specific components:
// ReddIDManager.cpp
#include "reddid/reddidmanager.h"
#include "reddid/namespacemanager.h"
#include "reddid/auctionmanager.h"
#include "reddid/profilemanager.h"
#include "reddid/reddiddb.h"
#include "reddid/reddidp2pmanager.h"
#include "validation.h"
#include "script/script.h"
#include "util/system.h"
#include "logging.h"
ReddIDManager::ReddIDManager(const fs::path& dataDir)
: m_dataDir(dataDir), m_initialized(false)
{
}
bool ReddIDManager::Initialize()
{
// Prevent multiple initialization
if (m_initialized) {
return true;
}
LogPrint(BCLog::REDDID, "Initializing ReddID manager\n");
try {
// Initialize database
m_reddidDB = std::make_unique<ReddIDDB>(m_dataDir);
if (!m_reddidDB->Initialize()) {
LogPrintf("ERROR: Failed to initialize ReddID database\n");
return false;
}
// Initialize component managers
m_namespaceManager = std::make_unique<NamespaceManager>(this);
if (!m_namespaceManager->Initialize()) {
LogPrintf("ERROR: Failed to initialize namespace manager\n");
return false;
}
m_auctionManager = std::make_unique<AuctionManager>(this);
if (!m_auctionManager->Initialize()) {
LogPrintf("ERROR: Failed to initialize auction manager\n");
return false;
}
m_profileManager = std::make_unique<ProfileManager>(this);
if (!m_profileManager->Initialize()) {
LogPrintf("ERROR: Failed to initialize profile manager\n");
return false;
}
m_p2pManager = std::make_unique<ReddIDP2PManager>(this);
if (!m_p2pManager->Initialize()) {
LogPrintf("ERROR: Failed to initialize P2P manager\n");
return false;
}
// Mark as initialized
m_initialized = true;
LogPrint(BCLog::REDDID, "ReddID manager initialized successfully\n");
return true;
}
catch (const std::exception& e) {
LogPrintf("ERROR: Exception during ReddID manager initialization: %s\n", e.what());
return false;
}
}
void ReddIDManager::Shutdown()
{
if (!m_initialized) {
return;
}
LogPrint(BCLog::REDDID, "Shutting down ReddID manager\n");
// Shutdown in reverse order of initialization
if (m_p2pManager) {
m_p2pManager->Shutdown();
}
if (m_profileManager) {
// No specific shutdown needed
}
if (m_auctionManager) {
// No specific shutdown needed
}
if (m_namespaceManager) {
// No specific shutdown needed
}
if (m_reddidDB) {
m_reddidDB->Shutdown();
}
m_initialized = false;
LogPrint(BCLog::REDDID, "ReddID manager shutdown complete\n");
}
// Implementation of CreateNamespaceAuction
bool ReddIDManager::CreateNamespaceAuction(const std::string& namespaceId,
const CKeyID& creator,
CAmount reservePrice, int durationDays,
AuctionType type, uint256& auctionId)
{
if (!m_initialized || !m_namespaceManager) {
LogPrintf("ERROR: ReddID manager not initialized\n");
return false;
}
return m_namespaceManager->CreateNamespaceAuction(namespaceId, creator,
reservePrice, durationDays,
type, auctionId);
}
// ... Additional method implementations ...
bool ReddIDManager::ProcessIdTx(const CTransaction& tx, int height)
{
if (!m_initialized) {
return false;
}
// Extract OP_RETURN data if present
std::vector<unsigned char> data;
if (!GetOpReturnData(tx, data) || data.size() < 3) {
return false; // Not a ReddID transaction or invalid format
}
// Check magic bytes
if (data[0] != 0xD4 || data[1] != 0xD8) {
return false; // Invalid network magic
}
// Process based on operation code
unsigned char opCode = data[2];
switch (opCode) {
case 0x7B: // OP_NAMESPACE_AUCTION_CREATE
return ProcessNamespaceAuctionCreate(tx, data, height);
case 0x7D: // OP_NAMESPACE_AUCTION_BID
return ProcessNamespaceAuctionBid(tx, data, height);
case 0x5B: // OP_NAMESPACE_AUCTION_FINALIZE
return ProcessNamespaceAuctionFinalize(tx, data, height);
// Additional cases for other operations...
default:
return false; // Unknown operation code
}
}
// Helper method to extract OP_RETURN data
bool ReddIDManager::GetOpReturnData(const CTransaction& tx, std::vector<unsigned char>& data)
{
for (const auto& txout : tx.vout) {
if (txout.scriptPubKey.IsUnspendable()) {
CScript::const_iterator pc = txout.scriptPubKey.begin();
opcodetype opcode;
if (txout.scriptPubKey.GetOp(pc, opcode) && opcode == OP_RETURN) {
std::vector<unsigned char> vch;
if (txout.scriptPubKey.GetOp(pc, opcode, vch)) {
data = vch;
return true;
}
}
}
}
return false;
}
// NamespaceManager.cpp
#include "reddid/namespacemanager.h"
#include "reddid/reddidmanager.h"
#include "reddid/reddiddb.h"
#include "validation.h"
#include "util/system.h"
#include "logging.h"
#include <regex>
NamespaceManager::NamespaceManager(ReddIDManager* reddIDManager)
: m_reddIDManager(reddIDManager)
{
}
bool NamespaceManager::Initialize()
{
LogPrint(BCLog::REDDID, "Initializing namespace manager\n");
return true;
}
bool NamespaceManager::ValidateNamespaceID(const std::string& namespaceId)
{
// Check length (1-15 characters)
if (namespaceId.empty() || namespaceId.length() > 15) {
return false;
}
// Check for valid characters (lowercase letters, numbers, hyphens)
std::regex pattern("^[a-z0-9][a-z0-9-]*[a-z0-9]$|^[a-z0-9]$");
if (!std::regex_match(namespaceId, pattern)) {
return false;
}
// Check for consecutive hyphens
if (namespaceId.find("--") != std::string::npos) {
return false;
}
return true;
}
bool NamespaceManager::IsNamespaceAvailable(const std::string& namespaceId)
{
if (!ValidateNamespaceID(namespaceId)) {
return false;
}
// Check if namespace exists
ReddIDDB* db = m_reddIDManager->GetReddIDDB();
if (!db) {
return false;
}
NamespaceInfo info;
if (db->ReadNamespace(namespaceId, info)) {
// Namespace exists, check if it's expired
if (info.expiration > GetTime()) {
return false; // Not expired, not available
}
// Check if it's in grace period
if (info.expiration + (info.gracePeriod * 86400) > GetTime()) {
return false; // In grace period, not available
}
// Expired and past grace period, available
return true;
}
// Namespace doesn't exist, available
return true;
}
bool NamespaceManager::CreateNamespaceAuction(const std::string& namespaceId,
const CKeyID& creator,
CAmount reservePrice, int durationDays,
AuctionType type, uint256& auctionId)
{
// Validate parameters
if (!ValidateNamespaceID(namespaceId)) {
LogPrintf("ERROR: Invalid namespace ID format: %s\n", namespaceId);
return false;
}
if (!IsNamespaceAvailable(namespaceId)) {
LogPrintf("ERROR: Namespace not available: %s\n", namespaceId);
return false;
}
if (durationDays < 14 || durationDays > 30) {
LogPrintf("ERROR: Invalid auction duration: %d days (must be 14-30)\n", durationDays);
return false;
}
CAmount minPrice = CalculateMinPrice(namespaceId);
if (reservePrice < minPrice) {
LogPrintf("ERROR: Reserve price too low: %s (minimum: %s)\n",
FormatMoney(reservePrice), FormatMoney(minPrice));
return false;
}
// Get auction manager
AuctionManager* auctionManager = m_reddIDManager->GetAuctionManager();
if (!auctionManager) {
LogPrintf("ERROR: Auction manager not available\n");
return false;
}
// Create auction
AuctionInfo auction;
auction.namespaceId = namespaceId;
auction.name = ""; // Empty for namespace auctions
auction.creator = creator;
auction.startTime = GetTime();
auction.endTime = auction.startTime + (durationDays * 86400);
auction.reservePrice = reservePrice;
auction.currentBid = 0;
auction.currentBidder = CKeyID();
auction.depositAmount = reservePrice * 0.2; // 20% deposit
auction.state = AUCTION_PENDING;
auction.type = type;
auction.blockHeight = chainActive.Height();
// Generate auction ID
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
ss << auction.namespaceId << auction.creator << auction.startTime << auction.endTime << auction.reservePrice;
auction.auctionId = Hash(ss.begin(), ss.end());
auctionId = auction.auctionId;
// Save auction
ReddIDDB* db = m_reddIDManager->GetReddIDDB();
if (!db) {
LogPrintf("ERROR: Database not available\n");
return false;
}
if (!db->WriteAuction(auction)) {
LogPrintf("ERROR: Failed to write auction to database\n");
return false;
}
// Announce auction via P2P
ReddIDP2PManager* p2pManager = m_reddIDManager->GetP2PManager();
if (p2pManager) {
p2pManager->SendNamespaceAuctionAnnounce(auction);
}
LogPrint(BCLog::REDDID, "Created namespace auction: %s, ID: %s\n", namespaceId, auctionId.ToString());
return true;
}
// ... Additional method implementations ...
CAmount NamespaceManager::CalculateMinPrice(const std::string& namespaceId)
{
// Base minimum prices by length
if (namespaceId.length() == 1) {
return 100000 * COIN; // Single character
} else if (namespaceId.length() == 2) {
return 50000 * COIN; // Two characters
} else if (namespaceId.length() == 3) {
return 25000 * COIN; // Three characters
} else {
return 10000 * COIN; // Four+ characters
}
}
bool NamespaceManager::GetDefaultNamespaceConfig(NamespaceInfo& config)
{
config.allowNumbers = true;
config.allowHyphens = true;
config.allowUnderscores = true;
config.minLength = 3;
config.maxLength = 32;
config.renewalPeriod = 365;
config.gracePeriod = 30;
config.namespaceRevenuePct = 10;
config.burnPct = 70;
config.nodePct = 15;
config.devPct = 5;
config.minAuctionDuration = 3;
config.maxAuctionDuration = 7;
config.minBidIncrement = 5.0;
return true;
}
std::vector<NamespaceInfo> NamespaceManager::GetNamespaces()
{
std::vector<NamespaceInfo> result;
ReddIDDB* db = m_reddIDManager->GetReddIDDB();
if (!db) {
return result;
}
std::vector<std::string> namespaceIds;
if (!db->ListNamespaces(namespaceIds)) {
return result;
}
for (const auto& id : namespaceIds) {
NamespaceInfo info;
if (db->ReadNamespace(id, info)) {
result.push_back(info);
}
}
return result;
}
// reddidtypes.h
#ifndef REDDID_TYPES_H
#define REDDID_TYPES_H
#include <string>
#include <vector>
#include <uint256.h>
#include <key.h>
#include <serialize.h>
/**
* Auction types
*/
enum AuctionType {
AUCTION_STANDARD = 0, // Standard auction for most identifiers
AUCTION_PREMIUM = 1, // Premium auction for high-value identifiers
AUCTION_VERIFIED = 2, // Auction requiring identity verification
AUCTION_RENEWAL = 3 // Auction for expired identifiers
};
/**
* Auction states
*/
enum AuctionState {
AUCTION_PENDING = 0, // Auction created but not yet active
AUCTION_ACTIVE = 1, // Auction open for bidding
AUCTION_ENDED = 2, // Auction time elapsed, awaiting finalization
AUCTION_FINALIZED = 3, // Auction settled to winner
AUCTION_CANCELED = 4 // Auction canceled by creator (only if no bids)
};
/**
* Social connection types
*/
enum SocialConnectionType {
CONNECTION_FOLLOW = 0, // One-way connection (like Twitter)
CONNECTION_FRIEND = 1, // Two-way, mutual connection
CONNECTION_ENDORSE = 2, // Reputation-affecting positive connection
CONNECTION_BLOCK = 3 // Negative connection for filtering
};
/**
* Privacy levels
*/
enum PrivacyLevel {
PRIVACY_PUBLIC = 0, // Visible to anyone
PRIVACY_FRIENDS = 1, // Visible to connections only
PRIVACY_PRIVATE = 2 // Visible to owner only
};
/**
* Verification levels
*/
enum VerificationLevel {
VERIFICATION_NONE = 0, // No verification
VERIFICATION_SELF = 1, // Self-attested information
VERIFICATION_COMMUNITY = 2, // Peer-verified
VERIFICATION_OFFICIAL = 3 // Officially verified entity
};
/**
* Resource types
*/
enum ResourceType {
RESOURCE_NAMESPACE = 0,
RESOURCE_USERID = 1,
RESOURCE_REDDID = 2
};
/**
* Reputation update types
*/
enum ReputationUpdateType {
UPDATE_TRANSACTION = 0,
UPDATE_ENGAGEMENT = 1,
UPDATE_VERIFICATION = 2,
UPDATE_AUCTION = 3
};
/**
* Pricing tier for namespace
*/
struct PricingTier {
int minLength;
CAmount minPrice;
ADD_SERIALIZE_METHODS;
template <typename Stream, typename Operation>
inline void SerializationOp(Stream& s, Operation ser_action) {
READWRITE(minLength);
READWRITE(minPrice);
}
};
/**
* Namespace information
*/
struct NamespaceInfo {
std::string id;
CKeyID owner;
bool allowNumbers;
bool allowHyphens;
bool allowUnderscores;
int minLength;
int maxLength;
int renewalPeriod;
int gracePeriod;
int namespaceRevenuePct;
int burnPct;
int nodePct;
int devPct;
int minAuctionDuration;
int maxAuctionDuration;
double minBidIncrement;
std::vector<unsigned char> configHash;
int64_t lastUpdated;
int64_t expiration;
ADD_SERIALIZE_METHODS;
template <typename Stream, typename Operation>
inline void SerializationOp(Stream& s, Operation ser_action) {
READWRITE(id);
READWRITE(owner);
READWRITE(allowNumbers);
READWRITE(allowHyphens);
READWRITE(allowUnderscores);
READWRITE(minLength);
READWRITE(maxLength);
READWRITE(renewalPeriod);
READWRITE(gracePeriod);
READWRITE(namespaceRevenuePct);
READWRITE(burnPct);
READWRITE(nodePct);
READWRITE(devPct);
READWRITE(minAuctionDuration);
READWRITE(maxAuctionDuration);
READWRITE(minBidIncrement);
READWRITE(configHash);
READWRITE(lastUpdated);
READWRITE(expiration);
}
};
/**
* User ID information
*/
struct UserIDInfo {
std::string name;
std::string namespaceId;
CKeyID owner;
int64_t registrationTime;
int64_t expirationTime;
int64_t lastTransaction;
int transactionCount;
std::vector<unsigned char> metadataHash;
ADD_SERIALIZE_METHODS;
template <typename Stream, typename Operation>
inline void SerializationOp(Stream& s, Operation ser_action) {
READWRITE(name);
READWRITE(namespaceId);
READWRITE(owner);
READWRITE(registrationTime);
READWRITE(expirationTime);
READWRITE(lastTransaction);
READWRITE(transactionCount);
READWRITE(metadataHash);
}
};
/**
* Auction information
*/
struct AuctionInfo {
uint256 auctionId;
std::string name;
std::string namespaceId;
CKeyID creator;
int64_t startTime;
int64_t endTime;
CAmount reservePrice;
CAmount currentBid;
CKeyID currentBidder;
CAmount depositAmount;
AuctionState state;
AuctionType type;
std::vector<unsigned char> metadataHash;
int blockHeight;
uint256 txid;
ADD_SERIALIZE_METHODS;
template <typename Stream, typename Operation>
inline void SerializationOp(Stream& s, Operation ser_action) {
READWRITE(auctionId);
READWRITE(name);
READWRITE(namespaceId);
READWRITE(creator);
READWRITE(startTime);
READWRITE(endTime);
READWRITE(reservePrice);
READWRITE(currentBid);
READWRITE(currentBidder);
READWRITE(depositAmount);
READWRITE(state);
READWRITE(type);
READWRITE(metadataHash);
READWRITE(blockHeight);
READWRITE(txid);
}
};
/**
* Bid information
*/
struct BidInfo {
uint256 bidId;
uint256 auctionId;
CKeyID bidder;
std::string bidderReddId;
CAmount bidAmount;
CAmount depositAmount;
int64_t bidTime;
uint256 txid;
bool isWinner;
bool refunded;
ADD_SERIALIZE_METHODS;
template <typename Stream, typename Operation>
inline void SerializationOp(Stream& s, Operation ser_action) {
READWRITE(bidId);
READWRITE(auctionId);
READWRITE(bidder);
READWRITE(bidderReddId);
READWRITE(bidAmount);
READWRITE(depositAmount);
READWRITE(bidTime);
READWRITE(txid);
READWRITE(isWinner);
READWRITE(refunded);
}
};
/**
* ReddID profile
*/
struct ReddIDProfile {
std::string reddId;
CKeyID owner;
std::string displayName;
std::vector<unsigned char> avatarHash;
std::string bio;
std::vector<unsigned char> emailHash;
std::string socialData;
std::vector<unsigned char> messagingPubkey;
VerificationLevel verificationStatus;
int64_t creationTime;
int64_t lastUpdated;
int64_t expirationTime;
bool active;
int flags;
ADD_SERIALIZE_METHODS;
template <typename Stream, typename Operation>
inline void SerializationOp(Stream& s, Operation ser_action) {
READWRITE(reddId);
READWRITE(owner);
READWRITE(displayName);
READWRITE(avatarHash);
READWRITE(bio);
READWRITE(emailHash);
READWRITE(socialData);
READWRITE(messagingPubkey);
READWRITE(verificationStatus);
READWRITE(creationTime);
READWRITE(lastUpdated);
READWRITE(expirationTime);
READWRITE(active);
READWRITE(flags);
}
};
/**
* ReddID reputation
*/
struct ReddIDReputation {
std::string reddId;
double overallScore;
double longevityScore;
double transactionScore;
double engagementScore;
double verificationScore;
double auctionScore;
int64_t lastCalculated;
std::vector<unsigned char> calculationProof;
std::string calculatorSignatures;
ADD_SERIALIZE_METHODS;
template <typename Stream, typename Operation>
inline void SerializationOp(Stream& s, Operation ser_action) {
READWRITE(reddId);
READWRITE(overallScore);
READWRITE(longevityScore);
READWRITE(transactionScore);
READWRITE(engagementScore);
READWRITE(verificationScore);
READWRITE(auctionScore);
READWRITE(lastCalculated);
READWRITE(calculationProof);
READWRITE(calculatorSignatures);
}
};
/**
* ReddID connection
*/
struct ReddIDConnection {
std::string fromReddId;
std::string toReddId;
SocialConnectionType connectionType;
int64_t creationTime;
int64_t lastInteraction;
int visibility;
std::string metadata;
ADD_SERIALIZE_METHODS;
template <typename Stream, typename Operation>
inline void SerializationOp(Stream& s, Operation ser_action) {
READWRITE(fromReddId);
READWRITE(toReddId);
READWRITE(connectionType);
READWRITE(creationTime);
READWRITE(lastInteraction);
READWRITE(visibility);
READWRITE(metadata);
}
};
/**
* ReddID namespace resolution
*/
struct ReddIDNamespaceResolution {
std::string reddId;
std::string namespaceId;
std::string userId;
bool isPrimary;
bool autoUpdate;
int64_t lastSynced;
ADD_SERIALIZE_METHODS;
template <typename Stream, typename Operation>
inline void SerializationOp(Stream& s, Operation ser_action) {
READWRITE(reddId);
READWRITE(namespaceId);
READWRITE(userId);
READWRITE(isPrimary);
READWRITE(autoUpdate);
READWRITE(lastSynced);
}
};
#endif // REDDID_TYPES_H
sequenceDiagram
participant Client
participant ReddIDManager
participant NamespaceMgr as NamespaceMgr
participant AuctionMgr as AuctionMgr
Client->>+ReddIDManager: CreateNamespaceAuction
ReddIDManager->>+NamespaceMgr: CreateNamespaceAuction
NamespaceMgr->>NamespaceMgr: Validate Parameters
NamespaceMgr->>+AuctionMgr: Create Auction
AuctionMgr->>AuctionMgr: Generate Auction
AuctionMgr->>AuctionMgr: Store Auction
AuctionMgr-->>-NamespaceMgr: Auction Created
NamespaceMgr->>NamespaceMgr: Create TX
NamespaceMgr-->>-ReddIDManager: Creation Complete
ReddIDManager-->>-Client: Return Auction ID
sequenceDiagram
participant Client
participant ReddIDManager
participant AuctionMgr as AuctionMgr
participant ReddIDP2PMgr as ReddIDP2PMgr
Client->>+ReddIDManager: Bid on Auction
ReddIDManager->>+AuctionMgr: Place Bid
AuctionMgr->>AuctionMgr: Validate Auction
AuctionMgr->>AuctionMgr: Check Minimum Bid
AuctionMgr->>AuctionMgr: Create Bid
AuctionMgr->>AuctionMgr: Store Bid
AuctionMgr->>AuctionMgr: Update Auction
AuctionMgr->>AuctionMgr: Create TX
AuctionMgr->>+ReddIDP2PMgr: Announce Bid
ReddIDP2PMgr->>ReddIDP2PMgr: Relay Bid to Network
ReddIDP2PMgr-->>-AuctionMgr: Bid Relayed
AuctionMgr-->>-ReddIDManager: Bid Placed
ReddIDManager-->>-Client: Return Bid ID
sequenceDiagram
participant Client
participant ReddIDManager
participant ProfileMgr as ProfileMgr
participant ReddIDP2PMgr as ReddIDP2PMgr
Client->>+ReddIDManager: Register ReddID
ReddIDManager->>+ProfileMgr: Register ReddID
ProfileMgr->>ProfileMgr: Validate ReddID Format
ProfileMgr->>ProfileMgr: Check Availability
ProfileMgr->>ProfileMgr: Verify Ownership
ProfileMgr->>ProfileMgr: Create Profile
ProfileMgr->>ProfileMgr: Store Profile
ProfileMgr->>ProfileMgr: Create Reputation
ProfileMgr->>ProfileMgr: Create TX
ProfileMgr->>+ReddIDP2PMgr: Announce Profile
ReddIDP2PMgr->>ReddIDP2PMgr: Relay Profile to Network
ReddIDP2PMgr-->>-ProfileMgr: Profile Relayed
ProfileMgr-->>-ReddIDManager: Registration Complete
ReddIDManager-->>-Client: Return Profile Info
To ensure consistent error handling across the codebase, the following guidelines should be followed:
- Methods returning boolean values should return
false
to indicate failure - Failure reasons should be logged using
LogPrintf
orLogPrint
- Complex operations should include detailed error messages
- Functions should validate all inputs before performing operations
bool NamespaceManager::UpdateNamespace(const NamespaceInfo& namespaceInfo) {
// Validate parameters
if (namespaceInfo.id.empty()) {
LogPrintf("ERROR: NamespaceManager::UpdateNamespace: Empty namespace ID\n");
return false;
}
// Check authorization
NamespaceInfo existing;
if (!GetNamespaceInfo(namespaceInfo.id, existing)) {
LogPrintf("ERROR: NamespaceManager::UpdateNamespace: Namespace not found: %s\n",
namespaceInfo.id);
return false;
}
if (existing.owner != namespaceInfo.owner) {
LogPrintf("ERROR: NamespaceManager::UpdateNamespace: Not authorized to update namespace: %s\n",
namespaceInfo.id);
return false;
}
// ... additional validation and operations ...
return true;
}
- Use try-catch blocks for database operations and external calls
- Convert exceptions to simple return values at public API boundaries
- Log detailed exception information for debugging
- Handle specific exception types appropriately
bool ReddIDDB::WriteNamespace(const NamespaceInfo& namespaceInfo) {
try {
// Prepare database key
std::string key = std::string(1, DB_NAMESPACE) + namespaceInfo.id;
// Write to database
return m_db->Write(key, namespaceInfo);
}
catch (const std::exception& e) {
LogPrintf("ERROR: Exception in ReddIDDB::WriteNamespace: %s\n", e.what());
return false;
}
}
For RPC commands, use the standardized error reporting mechanism:
static UniValue createnamespacesauction(const JSONRPCRequest& request)
{
RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VNUM, UniValue::VNUM});
std::string namespaceId = request.params[0].get_str();
CAmount reservePrice = AmountFromValue(request.params[1]);
int durationDays = request.params[2].get_int();
NodeContext& node = EnsureAnyNodeContext(request.context);
if (!node.reddid) {
throw JSONRPCError(RPC_INTERNAL_ERROR, "ReddID manager not initialized");
}
// Validate parameters
if (!node.reddid->GetNamespaceManager()->ValidateNamespaceID(namespaceId)) {
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid namespace ID format");
}
if (!node.reddid->GetNamespaceManager()->IsNamespaceAvailable(namespaceId)) {
throw JSONRPCError(RPC_INVALID_PARAMETER, "Namespace not available");
}
if (durationDays < 14 || durationDays > 30) {
throw JSONRPCError(RPC_INVALID_PARAMETER,
strprintf("Invalid auction duration: %d days (must be 14-30)", durationDays));
}
CAmount minPrice = node.reddid->GetNamespaceManager()->CalculateMinPrice(namespaceId);
if (reservePrice < minPrice) {
throw JSONRPCError(RPC_INVALID_PARAMETER,
strprintf("Reserve price too low: %s (minimum: %s)",
FormatMoney(reservePrice), FormatMoney(minPrice)));
}
// ... additional validation and processing ...
return result;
}
- All public methods should include documentation comments
- Document parameters, return values, and exceptions
- Include examples for complex methods
- Explain non-obvious behavior and edge cases
/**
* Create a namespace auction.
*
* This method creates a new auction for a namespace identifier. The auction
* will run for the specified number of days, with the given reserve price.
*
* @param namespaceId The namespace identifier to auction
* @param creator The key ID of the auction creator
* @param reservePrice The minimum acceptable bid (in satoshis)
* @param durationDays The auction duration (14-30 days)
* @param type The auction type (AUCTION_STANDARD or AUCTION_PREMIUM)
* @param auctionId[out] The resulting auction ID
*
* @return true if the auction was created successfully, false otherwise
*
* @throws None, but logs errors for all failure cases
*
* @note The creator must provide a deposit of 20% of the reserve price.
* @note Premium auctions have longer durations and higher deposits.
*
* Example:
* uint256 auctionId;
* if (CreateNamespaceAuction("redd", creatorKeyId, 50000 * COIN, 14,
* AUCTION_STANDARD, auctionId)) {
* // Auction created successfully
* }
*/
bool NamespaceManager::CreateNamespaceAuction(const std::string& namespaceId,
const CKeyID& creator,
CAmount reservePrice, int durationDays,
AuctionType type, uint256& auctionId);
- Create separate documentation for user-facing functionality
- Document system architecture and interactions
- Create sequence diagrams for complex processes
- Document configuration options and their effects
- Create tests for individual components
- Use mock objects for dependencies
- Test both success and failure paths
- Include edge cases and boundary conditions
BOOST_AUTO_TEST_CASE(namespace_validation_test)
{
// Set up mock ReddIDManager
auto mockManager = std::make_shared<MockReddIDManager>();
NamespaceManager namespaceManager(mockManager.get());
// Test valid namespace IDs
BOOST_CHECK(namespaceManager.ValidateNamespaceID("valid"));
BOOST_CHECK(namespaceManager.ValidateNamespaceID("valid123"));
BOOST_CHECK(namespaceManager.ValidateNamespaceID("v-a-l-i-d"));
// Test invalid namespace IDs
BOOST_CHECK(!namespaceManager.ValidateNamespaceID(""));
BOOST_CHECK(!namespaceManager.ValidateNamespaceID("INVALID"));
BOOST_CHECK(!namespaceManager.ValidateNamespaceID("invalid!"));
BOOST_CHECK(!namespaceManager.ValidateNamespaceID("-invalid"));
BOOST_CHECK(!namespaceManager.ValidateNamespaceID("invalid-"));
BOOST_CHECK(!namespaceManager.ValidateNamespaceID("inva--lid"));
BOOST_CHECK(!namespaceManager.ValidateNamespaceID("toolongnamespaceidentifier"));
}
- Test interactions between components
- Create test fixtures for common setups
- Test complete workflows
- Verify data persistence across operations
BOOST_FIXTURE_TEST_CASE(namespace_auction_workflow_test, ReddIDTestingSetup)
{
// Create namespace auction
uint256 auctionId;
BOOST_CHECK(m_reddIDManager->CreateNamespaceAuction("test", m_keyIds[0],
10000 * COIN, 14,
AUCTION_STANDARD, auctionId));
// Get auction info
AuctionInfo auction;
BOOST_CHECK(m_reddIDManager->GetAuctionManager()->GetAuctionInfo(auctionId, auction));
BOOST_CHECK_EQUAL(auction.namespaceId, "test");
BOOST_CHECK_EQUAL(auction.state, AUCTION_PENDING);
// Place bid
uint256 bidId;
BOOST_CHECK(m_reddIDManager->GetAuctionManager()->PlaceBid(auctionId, m_keyIds[1],
12000 * COIN, bidId));
// Get updated auction
BOOST_CHECK(m_reddIDManager->GetAuctionManager()->GetAuctionInfo(auctionId, auction));
BOOST_CHECK_EQUAL(auction.currentBid, 12000 * COIN);
BOOST_CHECK_EQUAL(auction.currentBidder, m_keyIds[1]);
// Advance time to auction end
SetMockTime(auction.endTime + 1);
// Finalize auction
BOOST_CHECK(m_reddIDManager->FinalizeNamespaceAuction(auctionId));
// Verify namespace creation
NamespaceInfo namespaceInfo;
BOOST_CHECK(m_reddIDManager->GetNamespaceManager()->GetNamespaceInfo("test", namespaceInfo));
BOOST_CHECK_EQUAL(namespaceInfo.owner, m_keyIds[1]);
}
- Test system performance under various loads
- Measure transaction throughput and latency
- Profile resource usage
- Identify bottlenecks and optimization opportunities
BOOST_AUTO_TEST_CASE(auction_performance_test)
{
// Setup test environment
SetupTestEnvironment();
// Measure time to create 100 auctions
auto start = std::chrono::high_resolution_clock::now();
for (int i = 0; i < 100; i++) {
std::string namespaceId = "test" + std::to_string(i);
uint256 auctionId;
BOOST_CHECK(m_reddIDManager->CreateNamespaceAuction(namespaceId, m_keyIds[0],
10000 * COIN, 14,
AUCTION_STANDARD, auctionId));
}
auto end = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
BOOST_TEST_MESSAGE("Time to create 100 auctions: " << duration << "ms");
BOOST_CHECK(duration < 5000); // Should take less than 5 seconds
// Test database query performance
start = std::chrono::high_resolution_clock::now();
std::vector<AuctionInfo> auctions = m_reddIDManager->GetAuctionManager()->GetActiveAuctions();
end = std::chrono::high_resolution_clock::now();
duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
BOOST_TEST_MESSAGE("Time to query 100 auctions: " << duration << "ms");
BOOST_CHECK(duration < 500); // Should take less than 500ms
}
This technical architecture specification provides a comprehensive framework for implementing the ReddID system for Reddcoin. The specification details the core components, their interactions, database schema, blockchain integration, P2P protocol extensions, API interfaces, security model, external dependencies, performance considerations, and deployment requirements.
The system is designed with a focus on modularity, scalability, and extensibility, allowing for future enhancements while maintaining compatibility with the existing Reddcoin ecosystem. By implementing this specification, developers can create a robust identity management solution that provides namespaces, user IDs, and identity profiles with a market-driven allocation mechanism, cross-namespace resolution, and social features.
The document provides clear guidelines for implementation, including coding standards, error handling, documentation, and testing approaches. By following these guidelines, developers can ensure a consistent, maintainable, and high-quality codebase that meets the requirements of the ReddID system.
This specification serves as the primary reference for the development of the ReddID system, providing all necessary details for implementation while allowing for future refinement as development progresses.