added Carrot support to construct_protocol_tx
This commit is contained in:
@@ -53,6 +53,7 @@ CARROT_DEFINE_SIMPLE_ERROR_TYPE(missing_randomness, carrot_logic_error)
|
||||
CARROT_DEFINE_SIMPLE_ERROR_TYPE(too_few_inputs, carrot_logic_error)
|
||||
CARROT_DEFINE_SIMPLE_ERROR_TYPE(too_few_outputs, carrot_logic_error)
|
||||
CARROT_DEFINE_SIMPLE_ERROR_TYPE(too_many_outputs, carrot_logic_error)
|
||||
CARROT_DEFINE_SIMPLE_ERROR_TYPE(invalid_tx_type, carrot_logic_error)
|
||||
|
||||
class carrot_runtime_error: std::runtime_error { using std::runtime_error::runtime_error; };
|
||||
|
||||
|
||||
@@ -74,6 +74,12 @@ inline void serialize(Archive &a, carrot::encrypted_payment_id_t &x, const boost
|
||||
}
|
||||
//---------------------------------------------------
|
||||
template <class Archive>
|
||||
inline void serialize(Archive &a, carrot::encrypted_return_pubkey_t &x, const boost::serialization::version_type ver)
|
||||
{
|
||||
a & x.bytes;
|
||||
}
|
||||
//---------------------------------------------------
|
||||
template <class Archive>
|
||||
inline void serialize(Archive &a, carrot::CarrotDestinationV1 &x, const boost::serialization::version_type ver)
|
||||
{
|
||||
a & x.address_spend_pubkey;
|
||||
@@ -87,6 +93,7 @@ inline void serialize(Archive &a, carrot::CarrotPaymentProposalV1 &x, const boos
|
||||
{
|
||||
a & x.destination;
|
||||
a & x.amount;
|
||||
a & x.asset_type;
|
||||
a & x.randomness;
|
||||
}
|
||||
//---------------------------------------------------
|
||||
|
||||
@@ -40,3 +40,4 @@
|
||||
|
||||
BLOB_SERIALIZER(carrot::view_tag_t);
|
||||
BLOB_SERIALIZER(carrot::encrypted_janus_anchor_t);
|
||||
BLOB_SERIALIZER(carrot::encrypted_return_pubkey_t);
|
||||
|
||||
@@ -54,6 +54,7 @@ END_SERIALIZE()
|
||||
BEGIN_SERIALIZE_OBJECT_FN(carrot::CarrotPaymentProposalV1)
|
||||
FIELD_F(destination)
|
||||
VARINT_FIELD_F(amount)
|
||||
FIELD_F(asset_type)
|
||||
FIELD_F(randomness)
|
||||
END_SERIALIZE()
|
||||
|
||||
|
||||
@@ -357,16 +357,18 @@ bool try_load_carrot_from_transaction_v1(const cryptonote::transaction &tx,
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
cryptonote::transaction store_carrot_to_coinbase_transaction_v1(
|
||||
const std::vector<CarrotCoinbaseEnoteV1> &enotes,
|
||||
const cryptonote::blobdata &extra_nonce)
|
||||
const cryptonote::blobdata &extra_nonce,
|
||||
const cryptonote::transaction_type &tx_type)
|
||||
{
|
||||
CARROT_CHECK_AND_THROW(tx_type == cryptonote::transaction_type::MINER || tx_type == cryptonote::transaction_type::PROTOCOL, invalid_tx_type, "invalid tx_type : is not MINER or PROTOCOL");
|
||||
const size_t nouts = enotes.size();
|
||||
const std::uint64_t block_index = enotes.at(0).block_index;
|
||||
|
||||
cryptonote::transaction tx;
|
||||
tx.type = cryptonote::transaction_type::MINER;
|
||||
tx.type = tx_type;
|
||||
tx.pruned = false;
|
||||
tx.version = 2;
|
||||
tx.unlock_time = block_index + CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW;
|
||||
tx.unlock_time = CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW;
|
||||
tx.vin.reserve(1);
|
||||
tx.vout.reserve(nouts);
|
||||
tx.extra.reserve(MAX_TX_EXTRA_SIZE);
|
||||
@@ -423,7 +425,7 @@ cryptonote::transaction make_single_enote_carrot_coinbase_transaction_v1(const C
|
||||
std::vector<CarrotCoinbaseEnoteV1> enotes(1);
|
||||
get_coinbase_output_proposal_v1(payment_proposal, block_index, enotes.front());
|
||||
|
||||
return store_carrot_to_coinbase_transaction_v1(enotes, extra_nonce);
|
||||
return store_carrot_to_coinbase_transaction_v1(enotes, extra_nonce, cryptonote::transaction_type::MINER);
|
||||
}
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
bool try_load_carrot_coinbase_enote_from_transaction_v1(const cryptonote::transaction &tx,
|
||||
|
||||
@@ -137,7 +137,8 @@ bool try_load_carrot_from_transaction_v1(const cryptonote::transaction &tx,
|
||||
*/
|
||||
cryptonote::transaction store_carrot_to_coinbase_transaction_v1(
|
||||
const std::vector<CarrotCoinbaseEnoteV1> &enotes,
|
||||
const cryptonote::blobdata &extra_nonce);
|
||||
const cryptonote::blobdata &extra_nonce,
|
||||
const cryptonote::transaction_type &tx_type);
|
||||
/**
|
||||
* brief: make_single_enote_carrot_coinbase_transaction_v1 - store one coinbase Carrot enote to a cryptonote::transaction
|
||||
* param: destination -
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include "string_tools.h"
|
||||
using namespace epee;
|
||||
|
||||
#include "carrot_core/payment_proposal.h"
|
||||
#include "carrot_impl/format_utils.h"
|
||||
#include "common/apply_permutation.h"
|
||||
#include "cryptonote_tx_utils.h"
|
||||
@@ -368,7 +369,7 @@ namespace cryptonote
|
||||
const size_t height,
|
||||
transaction& tx,
|
||||
std::vector<protocol_data_entry>& protocol_data,
|
||||
const uint8_t hf_version
|
||||
const uint8_t hard_fork_version
|
||||
) {
|
||||
|
||||
// Clear the TX contents
|
||||
@@ -378,6 +379,54 @@ namespace cryptonote
|
||||
// Force the TX type to 2
|
||||
tx.version = 2;
|
||||
|
||||
const bool do_carrot = hard_fork_version >= HF_VERSION_CARROT;
|
||||
if (do_carrot)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Create a vector of enotes
|
||||
std::vector<carrot::CarrotCoinbaseEnoteV1> enotes;
|
||||
enotes.reserve(protocol_data.size());
|
||||
|
||||
// Iterate over the protocol_data we received, creating an enote for each entry
|
||||
for (auto const& entry: protocol_data) {
|
||||
|
||||
carrot::CarrotDestinationV1 destination;
|
||||
carrot::make_carrot_main_address_v1(entry.P_change,
|
||||
entry.return_address,
|
||||
destination);
|
||||
|
||||
CHECK_AND_ASSERT_THROW_MES(!destination.is_subaddress,
|
||||
"construct_protocol_tx: subaddress are not allowed in miner transactions");
|
||||
CHECK_AND_ASSERT_THROW_MES(destination.payment_id == carrot::null_payment_id,
|
||||
"construct_protocol_tx: integrated addresses are not allowed in miner transactions");
|
||||
|
||||
LOG_PRINT_L2(((entry.type == cryptonote::transaction_type::STAKE) ? "Yield TX payout submitted " : "Audit TX payout submitted ") << entry.amount_burnt << entry.source_asset);
|
||||
|
||||
const carrot::CarrotPaymentProposalV1 payment_proposal{
|
||||
.destination = destination,
|
||||
.amount = entry.amount_burnt,
|
||||
.asset_type = "SAL1",
|
||||
.randomness = carrot::gen_janus_anchor()
|
||||
};
|
||||
|
||||
// Build the proposal
|
||||
get_coinbase_output_proposal_v1(payment_proposal, height, enotes.back());
|
||||
}
|
||||
|
||||
tx = store_carrot_to_coinbase_transaction_v1(enotes, std::string{}, cryptonote::transaction_type::PROTOCOL);
|
||||
tx.amount_burnt = 0;
|
||||
tx.invalidate_hashes();
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
MERROR("Failed to construct Carrot protocol transaction: " << e.what());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
keypair txkey = keypair::generate(hw::get_device("default"));
|
||||
add_tx_pub_key_to_extra(tx, txkey.pub);
|
||||
if (!sort_tx_extra(tx.extra, tx.extra))
|
||||
|
||||
@@ -197,7 +197,7 @@ struct binary_archive<true> : public binary_archive_base<true>
|
||||
{
|
||||
for (size_t i = 0; i < sizeof(T); i++) {
|
||||
stream_.put((char)(v & 0xff));
|
||||
if (1 < sizeof(T)) v >>= 8;
|
||||
if constexpr (1 < sizeof(T)) { v >>= 8; }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user