Skip to content

Commit

Permalink
Merge pull request #240 from bubafistah/swap_rpc
Browse files Browse the repository at this point in the history
Swap mvp
  • Loading branch information
bubafistah authored Oct 2, 2022
2 parents b3f28db + cd85407 commit 01b5fa7
Show file tree
Hide file tree
Showing 8 changed files with 287 additions and 31 deletions.
1 change: 1 addition & 0 deletions src/cryptonote_basic/cryptonote_basic_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,7 @@ namespace cryptonote {
else if (swap_address_prefix == prefix || integrated_swap_address_prefix == prefix) {
// Identify addr as swap addr
adr.is_swap_addr = true;
has_payment_id = false;
}
else
{
Expand Down
14 changes: 7 additions & 7 deletions src/cryptonote_core/blockchain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,14 +114,14 @@ static const struct {
} testnet_hard_forks[] = {
// version 1 from the start of the blockchain
{ 1, 1, 0, config::testnet::GENESIS_TIMESTAMP },
{ 2, 101, 0, 1518115575 },
{ 3, 201, 0, 1518117468 },
{ 4, 301, 0, 1518118888 },
{ 5, 401, 0, 1539941268 },
{ 6, 501, 0, 1551264860 },
{ 7, 901, 0, 1551264860 + 1000 } // Give it some time offset
{ 2, 11, 0, 1518115575 },
{ 3, 21, 0, 1518117468 },
{ 4, 31, 0, 1518118888 },
{ 5, 41, 0, 1539941268 },
{ 6, 51, 0, 1551264860 },
{ 7, 71, 0, 1551264860 + 1000 } // Give it some time offset
};
static const uint64_t testnet_hard_fork_version_1_till = 100;
static const uint64_t testnet_hard_fork_version_1_till = 10;

//------------------------------------------------------------------
Blockchain::Blockchain(tx_memory_pool& tx_pool) :
Expand Down
18 changes: 7 additions & 11 deletions src/cryptonote_core/cryptonote_tx_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ using namespace epee;
#include "crypto/crypto.h"
#include "crypto/hash.h"
#include "ringct/rctSigs.h"
#include "cryptonote_core/swap_address.h"

namespace cryptonote
{
Expand Down Expand Up @@ -279,6 +280,7 @@ namespace cryptonote
for(const tx_destination_entry& dst_entr: shuffled_dsts)
{
CHECK_AND_ASSERT_MES(dst_entr.amount > 0 || tx.version > 1, false, "Destination with wrong amount: " << dst_entr.amount);

crypto::key_derivation derivation;
crypto::public_key out_eph_public_key;
bool r = crypto::generate_key_derivation(dst_entr.addr.m_view_public_key, txkey.sec, derivation);
Expand All @@ -298,13 +300,7 @@ namespace cryptonote

txout_to_key tk = AUTO_VAL_INIT(tk);

if (dst_entr.addr.is_swap_addr) {
// Zero key for swap txs
// TODO Should probably do all address math only when neccessary
} else {
tk.key = out_eph_public_key;
}

tk.key = out_eph_public_key;

out.target = tk;
tx.vout.push_back(out);
Expand Down Expand Up @@ -514,7 +510,7 @@ namespace cryptonote
//---------------------------------------------------------------
bool is_swap_tx(const transaction& tx, const std::vector<tx_destination_entry>& destinations)
{
// a tx is a swap tx if it has at least one swap destination address (null_pkey output) AND swap info in extra.userdata
// a tx is a swap tx if it has at least one swap destination address (null_pkey output)(not true anymore) AND swap info in extra.userdata
bool has_swap_destinations = false;

if (!destinations.empty())
Expand All @@ -540,9 +536,9 @@ namespace cryptonote
}
}
}

if (!has_swap_destinations)
return false; // No swap destinations
// Ignore, we are using regular swap wallet
//if (!has_swap_destinations)
// return false; // No swap destinations

std::vector<cryptonote::tx_extra_field> extra_fields;

Expand Down
16 changes: 16 additions & 0 deletions src/cryptonote_core/swap_address.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,26 @@
#define SWAP_PUBLIC_ADDRESS_BASE58_PREFIX 0x73f7 // 'iT'
#define SWAP_PUBLIC_INTEG_ADDRESS_BASE58_PREFIX 0x6af7 // 'iTH'

#define SWAP_ENABLED 0

#if SWAP_ENABLED

#define SWAP_ADDRESS_ENCRYPTION_PUB_KEY ""
#define SWAP_ADDRESS_ENCRYPTION_SEC_KEY ""

#define SWAP_WALLET ""

#else

// Just for testing
#define SWAP_ADDRESS_ENCRYPTION_PUB_KEY "f2de2998375bd562ca98a2f9b576fa0f659651fc15b557c4d411e0004a47df24"
#define SWAP_ADDRESS_ENCRYPTION_SEC_KEY "72ae3e7de47bbb5af78ed6608a1eabe77a2429c385d28e708c01afaa82737900"

#define SWAP_WALLET "TixxsGTkkhyKydNiptoWW8fNkoHiwfvQDPbqPxWwt6VVKJnu59mmSAEGh2ezTLfXZhVAfrJwV7AT3YGXtzTf7H8r9p32qm7UZP"

#endif


namespace cryptonote {
#pragma pack(push, 1)

Expand Down
149 changes: 149 additions & 0 deletions src/rpc/core_rpc_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ using namespace epee;
#include "crypto/hash.h"
#include "rpc/rpc_args.h"
#include "core_rpc_server_error_codes.h"
#include "cryptonote_core/swap_address.h"
#include "ringct/rctSigs.h"

#undef MONERO_DEFAULT_LOG_CATEGORY
#define MONERO_DEFAULT_LOG_CATEGORY "daemon.rpc"
Expand Down Expand Up @@ -1765,7 +1767,154 @@ namespace cryptonote
return true;
}
//------------------------------------------------------------------------------------------------------------------------------
uint64_t decodeRctHelper(const rct::rctSig & rv, const crypto::public_key &pub, const crypto::secret_key &sec, unsigned int i, rct::key & mask)
{
crypto::key_derivation derivation;
bool r = crypto::generate_key_derivation(pub, sec, derivation);
if (!r)
{
LOG_ERROR("Failed to generate key derivation to decode rct output " << i);
return 0;
}
crypto::secret_key scalar1;
crypto::derivation_to_scalar(derivation, i, scalar1);
try
{
switch (rv.type)
{
case rct::RCTTypeSimple:
return rct::decodeRctSimple(rv, rct::sk2rct(scalar1), i, mask);
case rct::RCTTypeFull:
return rct::decodeRct(rv, rct::sk2rct(scalar1), i, mask);
default:
LOG_ERROR("Unsupported rct type: " << rv.type);
return 0;
}
}
catch (const std::exception &e)
{
LOG_ERROR("Failed to decode input " << i);
return 0;
}
}

//------------------------------------------------------------------------------------------------------------------------------
bool core_rpc_server::on_get_block_swap_txs_by_height(const COMMAND_RPC_GET_BLOCK_SWAP_TXS_BY_HEIGHT::request& req, COMMAND_RPC_GET_BLOCK_SWAP_TXS_BY_HEIGHT::response& res, epee::json_rpc::error& error_resp)
{
if(!check_core_busy())
{
error_resp.code = CORE_RPC_ERROR_CODE_CORE_BUSY;
error_resp.message = "Core is busy.";
return false;
}

Blockchain& bchain = m_core.get_blockchain_storage();

if (bchain.get_current_blockchain_height() < req.height)
{
error_resp.code = CORE_RPC_ERROR_CODE_WRONG_PARAM;
error_resp.message = "Invalid height param";
return false;
}

block target_block = AUTO_VAL_INIT(target_block);
if(!bchain.get_block_by_hash(bchain.get_block_id_by_height(req.height), target_block))
{
error_resp.code = CORE_RPC_ERROR_CODE_INTERNAL_ERROR;
error_resp.message = "Couldn't get block data";
return false;
}

crypto::secret_key priv_view;
if (!epee::string_tools::hex_to_pod(req.priv_view, priv_view)) {
error_resp.code = CORE_RPC_ERROR_CODE_WRONG_PARAM;
error_resp.message = "Couldn't decode view key";
return false;
}

crypto::secret_key swap_dev_key;
if (!epee::string_tools::hex_to_pod(req.swap_dev_key, swap_dev_key)) {
error_resp.code = CORE_RPC_ERROR_CODE_WRONG_PARAM;
error_resp.message = "Couldn't decode swap dev key";
return false;
}

account_public_address swap_wallet_addr;
crypto::hash8 payment_id;
bool has_payment_id;
if (!get_account_integrated_address_from_str(swap_wallet_addr, has_payment_id, payment_id, !SWAP_ENABLED, SWAP_WALLET))
{
error_resp.code = CORE_RPC_ERROR_CODE_WRONG_PARAM;
error_resp.message = "Couldn't decode swap wallet address";
return false;
}

for(const auto& blk_tx_hash : target_block.tx_hashes)
{
try {
transaction blk_tx = bchain.get_db().get_tx(blk_tx_hash);
if (is_swap_tx(blk_tx))
{
crypto::secret_key swap_encrypt_sec_key = AUTO_VAL_INIT(swap_encrypt_sec_key);
epee::string_tools::hex_to_pod(SWAP_ADDRESS_ENCRYPTION_SEC_KEY, swap_encrypt_sec_key);
account_public_address swap_addr = AUTO_VAL_INIT(swap_addr);
cryptonote::get_swap_data_from_tx(blk_tx, swap_encrypt_sec_key, swap_addr);

// Check for tx public key
crypto::public_key tx_pub = get_tx_pub_key_from_extra(blk_tx);

if(null_pkey == tx_pub) {
error_resp.code = CORE_RPC_ERROR_CODE_WRONG_PARAM;
error_resp.message = "Couldn't get tx pub key";
return false;
}

crypto::key_derivation derivation;
generate_key_derivation(tx_pub, priv_view, derivation);

uint64_t total_amount = 0;
for (int i = 0; i < blk_tx.vout.size(); i++)
{
bool received = false;

if (blk_tx.vout[i].target.type() != typeid(txout_to_key))
{
LOG_ERROR("wrong type id in transaction out");
continue;
}

// See if we own the out
received = is_out_to_acc_precomp(swap_wallet_addr.m_spend_public_key, boost::get<txout_to_key>(blk_tx.vout[i].target), derivation, i);
if (received)
{
cryptonote::keypair in_ephemeral;
crypto::key_image key_image;
rct::key mask;
// If we do, decode real amount
uint64_t money_transfered = decodeRctHelper(blk_tx.rct_signatures, tx_pub, priv_view, i, mask);
total_amount += money_transfered;
} else {
continue;
}
}

swap_tx_info tx_data = {
.tx_hash = epee::string_tools::pod_to_hex(blk_tx_hash),
.amount = total_amount,
.rcv_address = get_account_address_as_str(true, swap_addr)
};

res.txs.push_back(tx_data);
}
} catch (...) {
continue;
}
}

res.status = CORE_RPC_STATUS_OK;
return true;
}
//------------------------------------------------------------------------------------------------------------------------------
const command_line::arg_descriptor<std::string> core_rpc_server::arg_rpc_bind_port = {
"rpc-bind-port"
, "Port for RPC server"
Expand Down
2 changes: 2 additions & 0 deletions src/rpc/core_rpc_server.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ namespace cryptonote
MAP_JON_RPC_WE_IF("relay_tx", on_relay_tx, COMMAND_RPC_RELAY_TX, !m_restricted)
MAP_JON_RPC_WE_IF("sync_info", on_sync_info, COMMAND_RPC_SYNC_INFO, !m_restricted)
MAP_JON_RPC_WE("get_txpool_backlog", on_get_txpool_backlog, COMMAND_RPC_GET_TRANSACTION_POOL_BACKLOG)
MAP_JON_RPC_WE("get_block_swap_txs", on_get_block_swap_txs_by_height, COMMAND_RPC_GET_BLOCK_SWAP_TXS_BY_HEIGHT)
END_JSON_RPC_MAP()
END_URI_MAP2()

Expand Down Expand Up @@ -184,6 +185,7 @@ namespace cryptonote
bool on_relay_tx(const COMMAND_RPC_RELAY_TX::request& req, COMMAND_RPC_RELAY_TX::response& res, epee::json_rpc::error& error_resp);
bool on_sync_info(const COMMAND_RPC_SYNC_INFO::request& req, COMMAND_RPC_SYNC_INFO::response& res, epee::json_rpc::error& error_resp);
bool on_get_txpool_backlog(const COMMAND_RPC_GET_TRANSACTION_POOL_BACKLOG::request& req, COMMAND_RPC_GET_TRANSACTION_POOL_BACKLOG::response& res, epee::json_rpc::error& error_resp);
bool on_get_block_swap_txs_by_height(const COMMAND_RPC_GET_BLOCK_SWAP_TXS_BY_HEIGHT::request& req, COMMAND_RPC_GET_BLOCK_SWAP_TXS_BY_HEIGHT::response& res, epee::json_rpc::error& error_resp);
//-----------------------

private:
Expand Down
37 changes: 36 additions & 1 deletion src/rpc/core_rpc_server_commands_defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ namespace cryptonote
// advance which version they will stop working with
// Don't go over 32767 for any of these
#define CORE_RPC_VERSION_MAJOR 1
#define CORE_RPC_VERSION_MINOR 14
#define CORE_RPC_VERSION_MINOR 15
#define MAKE_CORE_RPC_VERSION(major,minor) (((major)<<16)|(minor))
#define CORE_RPC_VERSION MAKE_CORE_RPC_VERSION(CORE_RPC_VERSION_MAJOR, CORE_RPC_VERSION_MINOR)

Expand Down Expand Up @@ -1691,4 +1691,39 @@ namespace cryptonote
END_KV_SERIALIZE_MAP()
};
};

struct swap_tx_info
{
std::string tx_hash;
uint64_t amount;
std::string rcv_address;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(tx_hash)
KV_SERIALIZE(amount)
KV_SERIALIZE(rcv_address)
END_KV_SERIALIZE_MAP()
};

struct COMMAND_RPC_GET_BLOCK_SWAP_TXS_BY_HEIGHT
{
struct request {
uint64_t height;
std::string priv_view; // Swap wallet priv view key
std::string swap_dev_key; // Swap priv key
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(height)
KV_SERIALIZE(priv_view)
KV_SERIALIZE(swap_dev_key)
END_KV_SERIALIZE_MAP()
};

struct response {
vector<swap_tx_info> txs;
std::string status;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(txs)
KV_SERIALIZE(status)
END_KV_SERIALIZE_MAP()
};
};
}
Loading

0 comments on commit 01b5fa7

Please sign in to comment.