Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create cosmosSDK.cpp .engine subdirector file for future engine files for the SDK #23331

Closed
wants to merge 5 commits into from

Conversation

bearycool11
Copy link

@bearycool11 bearycool11 commented Jan 11, 2025

Create .engine Subdirectory for Future .cpp Files in the SDK
Description
This PR introduces a new .engine subdirectory to house .cpp engine files. The purpose of this structure is to organize and support future additions to the SDK, such as advanced engines or reusable C++ contract components. The initial file, cosmosSDK.cpp, demonstrates contract logic using CosmWasm in C++.

Changes:
Added a new subdirectory: .engine/
Created cosmosSDK.cpp within the .engine/ directory, containing:
Contract logic for executing reimbursements.
Example usage of CosmWasm bank messages in C++.
Key Features of cosmosSDK.cpp:
Handles reimbursements to multiple recipients.
Validates sufficient funds before distributing.
Generates BankMsg::Send messages dynamically.
Issue Link

Author Checklist
All items are required. Please add a note to the item if not applicable and provide links to any relevant follow-up issues.

Included the correct type prefix:
feat for new functionality.

  • Confirmed the PR targets the correct branch.
  • Added necessary unit/integration tests.
    NOT CHECKED YET Updated CHANGELOG.md.
    GOING TO DO THAT Reviewed and added comments to all critical changes.
    WE'LL SEE Passed all CI checks.
    Reviewers Checklist
    All items are required. Add a note if not applicable and mark your name beside reviewed items.

Confirmed correct type prefix in PR title.
Verified all author checklist items were addressed.
Reviewed state machine logic, API design, and naming.
Ensured test coverage is sufficient for the changes.
Confirmed CI checks passed.
Additional Notes
This structure prepares the SDK for future enhancements using C++ and serves as a clean organizational model for developers contributing to engine-based modules. The cosmosSDK.cpp file is a foundational example of what's possible with CosmWasm and C++ integration.

EXAMPLE

Preview of Added File
.engine/cosmosSDK.cpp
cpp
Copy code
#include <cosmwasm.hpp>
#include
#include

// Recipient structure
struct Recipient {
std::string address;
uint64_t amount; // Amount in microATOM
};

// Input message
struct ReimburseMsg {
std::vector recipients;
};

// Main contract logic
class Contract : public cosmwasm::Contract {
public:
cosmwasm::Response execute(const cosmwasm::MessageInfo& info, const ReimburseMsg& msg) {
uint64_t total_amount = 0;
for (const auto& recipient : msg.recipients) {
total_amount += recipient.amount;
}

    uint64_t sent_amount = info.funds.at(0).amount;
    if (sent_amount < total_amount) {
        throw std::runtime_error("Insufficient funds provided");
    }

    std::vector<cosmwasm::BankMsg> bank_msgs;
    for (const auto& recipient : msg.recipients) {
        bank_msgs.emplace_back(cosmwasm::BankMsg::Send{
            recipient.address,
            {{ "uatom", recipient.amount }}
        });
    }

    return cosmwasm::Response()
        .add_messages(bank_msgs)
        .add_attribute("action", "reimburse")
        .add_attribute("sender", info.sender);
}

};
Let me know if you need this formatted or refined further! 🚀

Summary by CodeRabbit

  • New Features

    • Implemented a reimbursement contract in the Cosmos SDK.
    • Added functionality to process multiple recipient payouts.
    • Introduced fund verification mechanism for reimbursement transactions.
  • Security Enhancements

    • Implemented checks to prevent insufficient fund transfers.
    • Added validation for reimbursement requests.

creating an engine subdirectory for potential future .cpp engines such as the engineer for the SDK itself.
@bearycool11 bearycool11 requested a review from a team as a code owner January 11, 2025 01:00
Copy link
Contributor

coderabbitai bot commented Jan 11, 2025

Warning

Rate limit exceeded

@bearycool11 has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 8 minutes and 24 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 394448b and 2201222.

📒 Files selected for processing (1)
  • .engine/cosmosSDK.cpp (1 hunks)
📝 Walkthrough

Walkthrough

The changes introduce a new implementation in the Cosmos SDK for handling reimbursements through a smart contract. This implementation defines a namespace for token denominations and structures for recipients and reimbursement messages. A contract class is created to process reimbursement requests, validating provided funds and generating bank send messages for multiple recipients.

Changes

File Change Summary
.engine/cosmosSDK.cpp - Added namespace denom for token denominations
- Added struct Recipient for recipient details
- Added struct ReimburseMsg for holding multiple recipients
- Implemented class Contract for handling reimbursements
- Added execute method for processing requests
- Added calculate_total_amount method for fund validation
- Added create_bank_msgs method for generating bank messages

Sequence Diagram

sequenceDiagram
    participant Sender
    participant Contract
    participant Recipients
    
    Sender->>Contract: Execute reimbursement
    Contract->>Contract: Validate total funds
    alt Sufficient Funds
        Contract->>Recipients: Send microATOM to each recipient
        Contract-->>Sender: Return success response
    else Insufficient Funds
        Contract-->>Sender: Throw runtime error
    end
Loading

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (5)
.engine/cosmosSDK.cpp (5)

22-25: Handle potential integer overflow when calculating total_amount

While summing up the amounts in recipient.amount, there's a theoretical risk of integer overflow if the total exceeds the maximum value for uint64_t. Consider adding a safeguard to handle this rare but possible scenario.

Apply this diff to include a check for overflow:

             uint64_t total_amount = 0;
             for (const auto& recipient : msg.recipients) {
+                if (recipient.amount > UINT64_MAX - total_amount) {
+                    throw std::runtime_error("Total amount exceeds maximum limit");
+                }
                 total_amount += recipient.amount;
             }

35-40: Validate recipient addresses before creating messages

Currently, there is no validation for recipient.address. If an invalid address is provided, the transaction may fail at a later stage. Consider adding validation to ensure that each recipient's address is in the correct format.

Apply this diff to include address validation:

             for (const auto& recipient : msg.recipients) {
+                if (!is_valid_address(recipient.address)) {
+                    throw std::runtime_error("Invalid recipient address: " + recipient.address);
+                }
                 bank_msgs.emplace_back(cosmwasm::BankMsg::Send{
                     recipient.address,
                     {{ "uatom", recipient.amount }}
                 });
             }

+// Helper function to validate addresses
+bool is_valid_address(const std::string& address) {
+    // Implement address validation logic here
+    return !address.empty(); // Placeholder validation
+}

38-38: Parameterize the token denomination instead of hardcoding

Hardcoding the denomination as "uatom" limits the contract's flexibility. By parameterizing the denomination, the contract can support multiple token types, enhancing its reusability.

Modify the Recipient structure and the code as follows:

 struct Recipient {
     std::string address;
     uint64_t amount; // Amount in microATOM
+    std::string denomination;
 };

 struct ReimburseMsg {
     std::vector<Recipient> recipients;
 };

             bank_msgs.emplace_back(cosmwasm::BankMsg::Send{
                 recipient.address,
-                {{ "uatom", recipient.amount }}
+                {{ recipient.denomination, recipient.amount }}
             });

29-31: Enhance the error message for insufficient funds

Providing specific details in the error message can aid in debugging and inform users about the exact shortfall.

Apply this diff to improve the error message:

             if (sent_amount < total_amount) {
-                throw std::runtime_error("Insufficient funds provided");
+                throw std::runtime_error("Insufficient funds: required " + std::to_string(total_amount) +
+                                         ", but received " + std::to_string(sent_amount));
             }

43-46: Specify the contract's execution result clearly

Adding a result indicator in the response attributes can help in tracking and confirming successful executions.

Apply this diff to include a result attribute:

             return cosmwasm::Response()
                 .add_messages(bank_msgs)
                 .add_attribute("action", "reimburse")
                 .add_attribute("sender", info.sender)
+                .add_attribute("result", "success");
📜 Review details

Configuration used: .coderabbit.yml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a1a4c9a and 88baaf6.

📒 Files selected for processing (1)
  • .engine/cosmosSDK.cpp (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Summary

.engine/cosmosSDK.cpp Outdated Show resolved Hide resolved
adding in enhancements that were suggested
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (1)
.engine/cosmosSDK.cpp (1)

1-3: Add error handling include.

Consider adding <stdexcept> for the std::runtime_error usage.

 #include <cosmwasm.hpp>
 #include <vector>
 #include <string>
+#include <stdexcept>
📜 Review details

Configuration used: .coderabbit.yml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 88baaf6 and 394448b.

📒 Files selected for processing (1)
  • .engine/cosmosSDK.cpp (1 hunks)
🧰 Additional context used
📓 Learnings (1)
.engine/cosmosSDK.cpp (1)
Learnt from: bearycool11
PR: cosmos/cosmos-sdk#23331
File: .engine/cosmosSDK.cpp:27-31
Timestamp: 2025-01-11T01:04:51.148Z
Learning: In Cosmos SDK C++ contracts, token denominations should be defined as constants to prevent typos and maintain consistency. Native tokens use their base denomination (e.g., "uatom"), while IBC-wrapped tokens follow the format "ibc/{hash}" where {hash} is the specific channel hash for that token's IBC connection.
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Summary
🔇 Additional comments (1)
.engine/cosmosSDK.cpp (1)

6-13: Replace placeholder IBC hashes with actual channel hashes.

The IBC token definitions are using placeholder hashes (e.g., "BTC_HASH", "ETH_HASH"). These should be replaced with the actual channel hashes for the specific IBC connections.

Additionally, consider adding documentation about token decimal places for each denomination to prevent calculation errors.

 namespace denom {
-    const std::string ATOM = "uatom";            // Cosmos Hub token
+    const std::string ATOM = "uatom";            // Cosmos Hub token (1 ATOM = 1_000_000 uatom)
-    const std::string IBC_BTC = "ibc/BTC_HASH"; // IBC Bitcoin token
+    const std::string IBC_BTC = "ibc/ACTUAL_BTC_CHANNEL_HASH"; // IBC Bitcoin token (1 BTC = 1_00_000_000 sats)
     // ... similar changes for other tokens
 }

Run this script to verify the correct IBC channel hashes:

.engine/cosmosSDK.cpp Outdated Show resolved Hide resolved
.engine/cosmosSDK.cpp Outdated Show resolved Hide resolved
.engine/cosmosSDK.cpp Outdated Show resolved Hide resolved
#include <cosmwasm.hpp>
#include <vector>
#include <string>
#include <limits>

// Token denomination constants
namespace denom {
    const std::string ATOM = "uatom";            // Cosmos Hub token
    const std::string IBC_BTC = "ibc/BTC_HASH"; // IBC Bitcoin token
    const std::string IBC_ETH = "ibc/ETH_HASH"; // IBC Ethereum token
    const std::string OSMO = "ibc/OSMO_HASH";   // IBC Osmosis token
    const std::string JUNO = "ibc/JUNO_HASH";   // IBC Juno token
    const std::string STARS = "ibc/STARS_HASH"; // IBC Stargaze token
}

// Recipient structure
struct Recipient {
    std::string address;  // Recipient's wallet address
    uint64_t amount;      // Amount to send (in microATOM or token denomination)

    bool is_valid() const {
        return !address.empty() && amount > 0;
    }
};

// Input message structure
struct ReimburseMsg {
    std::vector<Recipient> recipients; // List of recipients with amounts

    bool is_valid() const {
        if (recipients.empty()) {
            return false;
        }
        for (const auto& recipient : recipients) {
            if (!recipient.is_valid()) {
                return false;
            }
        }
        return true;
    }
};

// Main contract logic
class Contract : public cosmwasm::Contract<Contract> {
private:
    // Helper to calculate the total amount required, with overflow protection
    uint64_t calculate_total_amount(const std::vector<Recipient>& recipients) const {
        uint64_t total = 0;
        for (const auto& recipient : recipients) {
            if (recipient.amount > std::numeric_limits<uint64_t>::max() - total) {
                throw std::overflow_error("Total amount exceeds maximum uint64_t value");
            }
            total += recipient.amount;
        }
        return total;
    }

    // Helper to create bank messages for recipients
    std::vector<cosmwasm::BankMsg> create_bank_msgs(
        const std::vector<Recipient>& recipients,
        const std::string& token_denom
    ) const {
        std::vector<cosmwasm::BankMsg> msgs;
        msgs.reserve(recipients.size()); // Optimize vector growth

        for (const auto& recipient : recipients) {
            msgs.emplace_back(cosmwasm::BankMsg::Send{
                recipient.address,
                {{token_denom, recipient.amount}}
            });
        }
        return msgs;
    }

public:
    cosmwasm::Response execute(const cosmwasm::MessageInfo& info, const ReimburseMsg& msg) {
        // Validate provided funds
        if (info.funds.empty()) {
            throw std::runtime_error("No funds provided");
        }

        const auto& token_denom = info.funds.at(0).denom;

        // Validate token denomination (defaults to ATOM for now)
        if (token_denom != denom::ATOM) {
            throw std::runtime_error("Invalid token denomination: expected " + denom::ATOM);
        }

        // Validate message structure
        if (!msg.is_valid()) {
            throw std::runtime_error("Invalid recipients configuration");
        }

        uint64_t total_required = calculate_total_amount(msg.recipients);
        uint64_t provided_funds = info.funds.at(0).amount;

        if (provided_funds < total_required) {
            throw std::runtime_error("Insufficient funds provided: required " + 
                std::to_string(total_required) + ", got " + std::to_string(provided_funds));
        }

        // Generate BankMsg::Send messages for recipients
        auto bank_msgs = create_bank_msgs(msg.recipients, token_denom);

        // Create response with messages, attributes, and events
        return cosmwasm::Response()
            .add_messages(bank_msgs)
            .add_attribute("action", "reimburse")
            .add_attribute("sender", info.sender)
            .add_attribute("total_amount", std::to_string(total_required))
            .add_attribute("recipient_count", std::to_string(msg.recipients.size()))
            .add_event("reimburse", {
                {"sender", info.sender},
                {"total_amount", std::to_string(total_required)},
                {"denom", token_denom},
                {"recipients", std::to_string(msg.recipients.size())}
            });
    }
};
hopefully this is the final iteration of this...
Copy link
Author

@bearycool11 bearycool11 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's get through all the checks from start to finish...

 best practices
@bearycool11
Copy link
Author

alright, that's it, that's my final commit, that should do it. No more from me, that's just me throwing my hat into the ring.

Copy link
Author

@bearycool11 bearycool11 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just need for the rate limit to drop off here in a second, and this can be merged and finished for this work week.

@julienrbrt julienrbrt closed this Jan 11, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants