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

Support greedy addressees #106

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 15 additions & 5 deletions src/ga_tx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -572,14 +572,20 @@ namespace sdk {

// Add all outputs and compute the total amount of satoshi to be sent
amount required_total{ 0 };
uint32_t greedy_index = NO_CHANGE_INDEX;

if (num_addressees) {
int addressee_index = 0;
for (auto& addressee : *addressees_p) {
const auto addressee_asset_id = asset_id_from_json(net_params, addressee);
if (addressee_asset_id == asset_id) {
required_total += add_tx_addressee(session, net_params, result, tx, addressee);
reordered_addressees.push_back(addressee);
if (addressee.value("is_greedy", false)) {
greedy_index = addressee_index;
}
}
++addressee_index;
}
}

Expand Down Expand Up @@ -716,11 +722,7 @@ namespace sdk {
// so compute what we can send (everything minus the
// fee) and exit the loop
required_total = available_total - fee;
if (is_liquid) {
set_tx_output_commitment(tx, 0, asset_id, required_total.value());
} else {
tx->outputs[0].satoshi = required_total.value();
}
set_tx_output_value(net_params, tx, 0, asset_id, required_total.value());
if (num_addressees == 1u) {
addressees_p->at(0)["satoshi"] = required_total.value();
}
Expand Down Expand Up @@ -749,6 +751,14 @@ namespace sdk {

change = total - required_with_fee;

if (change != 0 && greedy_index != NO_CHANGE_INDEX) {
// If a 'greedy' addressee exists send change there
set_tx_output_value(net_params, tx, greedy_index, asset_id, change.value());
addressees_p->at(greedy_index)["satoshi"] = change.value();
required_total += change;
continue;
}

if ((!have_change_output && change < dust_threshold)
|| (have_change_output && change >= dust_threshold)) {
// We don't have a change output, and have only dust left over, or
Expand Down
15 changes: 14 additions & 1 deletion src/transaction_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -424,7 +424,10 @@ namespace sdk {

// Transactions with outputs below the dust threshold (except OP_RETURN)
// are not relayed by network nodes
if (!result.value("send_all", false) && satoshi.value() < session.get_dust_threshold()) {
jgriffiths marked this conversation as resolved.
Show resolved Hide resolved
// This check only applies when the amount has been set explicitly, so send all
// and greedy outputs are ignored as the amount is calculated later
if (!result.value("send_all", false) && !addressee.value("is_greedy", false)
&& satoshi.value() < session.get_dust_threshold()) {
set_tx_error(result, res::id_invalid_amount);
}

Expand All @@ -435,6 +438,16 @@ namespace sdk {
asset_id_from_json(net_params, addressee));
}

void set_tx_output_value(const network_parameters& net_params, wally_tx_ptr& tx, uint32_t index,
jkauffman1 marked this conversation as resolved.
Show resolved Hide resolved
const std::string& asset_id, amount::value_type satoshi)
{
if (net_params.is_liquid()) {
set_tx_output_commitment(tx, index, asset_id, satoshi);
} else {
tx->outputs[index].satoshi = satoshi;
}
}

void update_tx_size_info(const network_parameters& net_params, const wally_tx_ptr& tx, nlohmann::json& result)
{
const bool valid = tx->num_inputs != 0u && tx->num_outputs != 0u;
Expand Down
3 changes: 3 additions & 0 deletions src/transaction_utils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,9 @@ namespace sdk {
amount add_tx_addressee(ga_session& session, const network_parameters& net_params, nlohmann::json& result,
wally_tx_ptr& tx, nlohmann::json& addressee);

void set_tx_output_value(const network_parameters& net_params, wally_tx_ptr& tx, uint32_t index,
const std::string& asset_id, amount::value_type satoshi);

vbf_t generate_final_vbf(byte_span_t input_abfs, byte_span_t input_vbfs, uint64_span_t input_values,
const std::vector<abf_t>& output_abfs, const std::vector<vbf_t>& output_vbfs, uint32_t num_inputs);

Expand Down