mirror of
https://github.com/EvernodeXRPL/hpcore.git
synced 2026-04-29 15:37:59 +00:00
Event subscription infrastructure and ledger events. (#319)
- Introduced event subscription infrastructure for users. - Added ability to subscribe to ledger events. - Updated client lib for event subscription support.
This commit is contained in:
@@ -32,6 +32,7 @@ namespace msg::usrmsg::bson
|
||||
{
|
||||
const util::sequence_hash lcl_id = status::get_lcl_id();
|
||||
const std::set<std::string> unl = status::get_unl();
|
||||
const bool in_sync = status::is_in_sync();
|
||||
|
||||
jsoncons::bson::bson_bytes_encoder encoder(msg);
|
||||
encoder.begin_object();
|
||||
@@ -43,6 +44,8 @@ namespace msg::usrmsg::bson
|
||||
encoder.int64_value(lcl_id.seq_no);
|
||||
encoder.key(msg::usrmsg::FLD_LEDGER_HASH);
|
||||
encoder.byte_string_value(lcl_id.hash.to_string_view());
|
||||
encoder.key(msg::usrmsg::FLD_IN_SYNC);
|
||||
encoder.bool_value(in_sync);
|
||||
encoder.key(msg::usrmsg::FLD_ROUND_TIME);
|
||||
encoder.uint64_value(conf::cfg.contract.roundtime);
|
||||
encoder.key(msg::usrmsg::FLD_CONTARCT_EXECUTION_ENABLED);
|
||||
@@ -236,7 +239,7 @@ namespace msg::usrmsg::bson
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs unl list container message.
|
||||
* Constructs unl change notification message.
|
||||
* @param msg Buffer to construct the generated bson message string into.
|
||||
* Message format:
|
||||
* {
|
||||
@@ -245,7 +248,7 @@ namespace msg::usrmsg::bson
|
||||
* }
|
||||
* @param unl_list The unl node pubkey list to be put in the message.
|
||||
*/
|
||||
void create_unl_list_container(std::vector<uint8_t> &msg, const ::std::set<std::string> &unl_list)
|
||||
void create_unl_notification(std::vector<uint8_t> &msg, const ::std::set<std::string> &unl_list)
|
||||
{
|
||||
jsoncons::bson::bson_bytes_encoder encoder(msg);
|
||||
encoder.begin_object();
|
||||
@@ -260,9 +263,61 @@ namespace msg::usrmsg::bson
|
||||
encoder.flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs ledger created notification message.
|
||||
* @param msg Buffer to construct the generated bson message string into.
|
||||
* Message format:
|
||||
* {
|
||||
* "type": "ledger_event",
|
||||
* "event": "ledger_created",
|
||||
* "ledger": { ... }
|
||||
* }
|
||||
* @param ledger The created ledger.
|
||||
*/
|
||||
void create_ledger_created_notification(std::vector<uint8_t> &msg, const ledger::ledger_record &ledger)
|
||||
{
|
||||
jsoncons::bson::bson_bytes_encoder encoder(msg);
|
||||
encoder.begin_object();
|
||||
encoder.key(msg::usrmsg::FLD_TYPE);
|
||||
encoder.string_value(msg::usrmsg::MSGTYPE_LEDGER_EVENT);
|
||||
encoder.key(msg::usrmsg::FLD_EVENT);
|
||||
encoder.string_value(msg::usrmsg::LEDGER_EVENT_LEDGER_CREATED);
|
||||
encoder.key(msg::usrmsg::FLD_LEDGER);
|
||||
encoder.begin_object();
|
||||
populate_ledger_fields(encoder, ledger);
|
||||
encoder.end_object();
|
||||
encoder.end_object();
|
||||
encoder.flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs sync status notification message.
|
||||
* @param msg Buffer to construct the generated bson message string into.
|
||||
* Message format:
|
||||
* {
|
||||
* "type": "ledger_event",
|
||||
* "event": "sync_status",
|
||||
* "in_sync": true | false
|
||||
* }
|
||||
* @param in_sync Whether the node is in sync or not.
|
||||
*/
|
||||
void create_sync_status_notification(std::vector<uint8_t> &msg, const bool in_sync)
|
||||
{
|
||||
jsoncons::bson::bson_bytes_encoder encoder(msg);
|
||||
encoder.begin_object();
|
||||
encoder.key(msg::usrmsg::FLD_TYPE);
|
||||
encoder.string_value(msg::usrmsg::MSGTYPE_LEDGER_EVENT);
|
||||
encoder.key(msg::usrmsg::FLD_EVENT);
|
||||
encoder.string_value(msg::usrmsg::LEDGER_EVENT_SYNC_STATUS);
|
||||
encoder.key(msg::usrmsg::FLD_IN_SYNC);
|
||||
encoder.bool_value(in_sync);
|
||||
encoder.end_object();
|
||||
encoder.flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a ledger query response.
|
||||
* @param msg Buffer to construct the generated json message string into.
|
||||
* @param msg Buffer to construct the generated bson message string into.
|
||||
* Message format:
|
||||
* {
|
||||
* "type": "ledger_query_result",
|
||||
@@ -448,6 +503,46 @@ namespace msg::usrmsg::bson
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract ledger event subscription request.
|
||||
* @param channel Extracted subscription channel.
|
||||
* @param enabled Whether the subscription is enabled or not.
|
||||
* @param d The json document holding the subscription request.
|
||||
* Accepted message format:
|
||||
* {
|
||||
* "type": "subscription",
|
||||
* "channel": "unl_change" | "ledger_event",
|
||||
* "enabled": true | false
|
||||
* }
|
||||
* @return 0 on successful extraction. -1 for failure.
|
||||
*/
|
||||
int extract_subscription_request(usr::NOTIFICATION_CHANNEL &channel, bool &enabled, const jsoncons::ojson &d)
|
||||
{
|
||||
if (!d.contains(msg::usrmsg::FLD_CHANNEL) || !d.contains(msg::usrmsg::FLD_ENABLED) ||
|
||||
!d[msg::usrmsg::FLD_CHANNEL].is<std::string>() || !d[msg::usrmsg::FLD_ENABLED].is<bool>())
|
||||
{
|
||||
LOG_DEBUG << "User subscription request required fields missing or invalid.";
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (d[msg::usrmsg::FLD_CHANNEL] == msg::usrmsg::MSGTYPE_LEDGER_EVENT)
|
||||
{
|
||||
channel = usr::NOTIFICATION_CHANNEL::LEDGER_EVENT;
|
||||
}
|
||||
else if (d[msg::usrmsg::FLD_CHANNEL] == msg::usrmsg::MSGTYPE_UNL_CHANGE)
|
||||
{
|
||||
channel = usr::NOTIFICATION_CHANNEL::UNL_CHANGE;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_DEBUG << "User subscription request invalid channel.";
|
||||
return -1;
|
||||
}
|
||||
|
||||
enabled = d[msg::usrmsg::FLD_ENABLED].as<bool>();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract query information from a ledger query request.
|
||||
* @param extracted_query Extracted query criteria.
|
||||
@@ -547,24 +642,7 @@ namespace msg::usrmsg::bson
|
||||
for (const ledger::ledger_record &ledger : results)
|
||||
{
|
||||
encoder.begin_object();
|
||||
encoder.key(msg::usrmsg::FLD_SEQ_NO);
|
||||
encoder.uint64_value(ledger.seq_no);
|
||||
encoder.key(msg::usrmsg::FLD_TIMESTAMP);
|
||||
encoder.uint64_value(ledger.timestamp);
|
||||
encoder.key(msg::usrmsg::FLD_HASH);
|
||||
encoder.byte_string_value(ledger.ledger_hash);
|
||||
encoder.key(msg::usrmsg::FLD_PREV_HASH);
|
||||
encoder.byte_string_value(ledger.prev_ledger_hash);
|
||||
encoder.key(msg::usrmsg::FLD_STATE_HASH);
|
||||
encoder.byte_string_value(ledger.state_hash);
|
||||
encoder.key(msg::usrmsg::FLD_CONFIG_HASH);
|
||||
encoder.byte_string_value(ledger.config_hash);
|
||||
encoder.key(msg::usrmsg::FLD_USER_HASH);
|
||||
encoder.byte_string_value(ledger.user_hash);
|
||||
encoder.key(msg::usrmsg::FLD_INPUT_HASH);
|
||||
encoder.byte_string_value(ledger.input_hash);
|
||||
encoder.key(msg::usrmsg::FLD_OUTPUT_HASH);
|
||||
encoder.byte_string_value(ledger.output_hash);
|
||||
populate_ledger_fields(encoder, ledger);
|
||||
|
||||
// If raw inputs or outputs is not requested, we don't include that field at all in the response.
|
||||
// Otherwise the field will always contain an array (empty array if no data).
|
||||
@@ -585,6 +663,28 @@ namespace msg::usrmsg::bson
|
||||
}
|
||||
}
|
||||
|
||||
void populate_ledger_fields(jsoncons::bson::bson_bytes_encoder &encoder, const ledger::ledger_record &ledger)
|
||||
{
|
||||
encoder.key(msg::usrmsg::FLD_SEQ_NO);
|
||||
encoder.uint64_value(ledger.seq_no);
|
||||
encoder.key(msg::usrmsg::FLD_TIMESTAMP);
|
||||
encoder.uint64_value(ledger.timestamp);
|
||||
encoder.key(msg::usrmsg::FLD_HASH);
|
||||
encoder.byte_string_value(ledger.ledger_hash);
|
||||
encoder.key(msg::usrmsg::FLD_PREV_HASH);
|
||||
encoder.byte_string_value(ledger.prev_ledger_hash);
|
||||
encoder.key(msg::usrmsg::FLD_STATE_HASH);
|
||||
encoder.byte_string_value(ledger.state_hash);
|
||||
encoder.key(msg::usrmsg::FLD_CONFIG_HASH);
|
||||
encoder.byte_string_value(ledger.config_hash);
|
||||
encoder.key(msg::usrmsg::FLD_USER_HASH);
|
||||
encoder.byte_string_value(ledger.user_hash);
|
||||
encoder.key(msg::usrmsg::FLD_INPUT_HASH);
|
||||
encoder.byte_string_value(ledger.input_hash);
|
||||
encoder.key(msg::usrmsg::FLD_OUTPUT_HASH);
|
||||
encoder.byte_string_value(ledger.output_hash);
|
||||
}
|
||||
|
||||
void populate_ledger_inputs(jsoncons::bson::bson_bytes_encoder &encoder, const std::vector<ledger::ledger_user_input> &inputs)
|
||||
{
|
||||
encoder.begin_array();
|
||||
|
||||
Reference in New Issue
Block a user