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

Swap mvp #240

Merged
merged 11 commits into from
Oct 2, 2022
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