Class: BSV::Overlay::TopicBroadcaster
- Inherits:
-
Object
- Object
- BSV::Overlay::TopicBroadcaster
- Defined in:
- lib/bsv/overlay/topic_broadcaster.rb
Overview
Broadcasts transactions to overlay topics via SHIP (Service Host Interconnect Protocol).
Discovers interested overlay hosts by querying the ls_ship SLAP service, then dispatches a TaggedBEEF to each host in parallel and verifies acknowledgements according to the configured requirements.
Topic validation
All topics must be non-empty strings beginning with tm_. An empty topics array or a topic without the tm_ prefix raises ArgumentError.
Acknowledgement modes
Three independent ack modes may be combined:
-
require_ack_from_any_host(default: ‘all’) — at least one successful host must satisfy the requirement. -
require_ack_from_all_hosts(default:[]) — every successful host must satisfy the requirement. An empty array disables this check. -
require_ack_from_specific_hosts(default: {}) — named hosts must each satisfy their individual requirement.
Requirement values:
-
‘all’ — the host must have acknowledged every one of the broadcaster’s topics.
-
‘any’ — the host must have acknowledged at least one topic.
-
Array<String> — the host must have acknowledged all topics in the array.
Host caching
SHIP host discovery results are cached for SHIP_CACHE_TTL seconds (5 minutes) to avoid redundant SLAP queries on repeated broadcasts.
Constant Summary collapse
- SHIP_CACHE_TTL =
Seconds before the SHIP host cache expires.
300
Instance Method Summary collapse
-
#broadcast(tx) ⇒ OverlayBroadcastResult
Broadcast a transaction to all interested overlay hosts.
-
#find_interested_hosts ⇒ Hash{String => Set<String>}
Discover overlay hosts interested in the broadcaster’s topics via SHIP.
-
#initialize(topics, network_preset: :mainnet, facilitator: nil, resolver: nil, require_ack_from_all_hosts: [], require_ack_from_any_host: 'all', require_ack_from_specific_hosts: {}) ⇒ TopicBroadcaster
constructor
A new instance of TopicBroadcaster.
Constructor Details
#initialize(topics, network_preset: :mainnet, facilitator: nil, resolver: nil, require_ack_from_all_hosts: [], require_ack_from_any_host: 'all', require_ack_from_specific_hosts: {}) ⇒ TopicBroadcaster
Returns a new instance of TopicBroadcaster.
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/bsv/overlay/topic_broadcaster.rb', line 51 def initialize( topics, network_preset: :mainnet, facilitator: nil, resolver: nil, require_ack_from_all_hosts: [], require_ack_from_any_host: 'all', require_ack_from_specific_hosts: {} ) validate_topics!(topics) @topics = topics.dup.freeze @network_preset = network_preset @facilitator = facilitator || default_facilitator @resolver = resolver || default_resolver @require_ack_from_all_hosts = require_ack_from_all_hosts @require_ack_from_any_host = require_ack_from_any_host @require_ack_from_specific_hosts = require_ack_from_specific_hosts @ship_cache = nil @ship_cache_at = nil @ship_cache_mutex = Mutex.new end |
Instance Method Details
#broadcast(tx) ⇒ OverlayBroadcastResult
Broadcast a transaction to all interested overlay hosts.
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
# File 'lib/bsv/overlay/topic_broadcaster.rb', line 80 def broadcast(tx) beef = serialise_beef(tx) return beef if beef.is_a?(OverlayBroadcastResult) if local? host_topics = { 'http://localhost:8080' => Set.new(@topics) } else host_topics = find_interested_hosts if host_topics.empty? return error_result( 'ERR_NO_HOSTS_INTERESTED', "No #{@network_preset} hosts are interested in receiving this transaction." ) end end results = dispatch(beef, host_topics) successful = results.compact if successful.empty? return error_result( 'ERR_ALL_HOSTS_REJECTED', "All #{@network_preset} topical hosts have rejected the transaction." ) end host_acks = build_host_acks(successful) ack_check = check_ack_requirements(host_acks) return ack_check if ack_check.is_a?(OverlayBroadcastResult) OverlayBroadcastResult.new( status: 'success', txid: tx.txid_hex, message: "Sent to #{successful.size} Overlay Service host(s)." ) end |
#find_interested_hosts ⇒ Hash{String => Set<String>}
Discover overlay hosts interested in the broadcaster’s topics via SHIP.
Results are cached for SHIP_CACHE_TTL seconds.
123 124 125 126 127 128 129 130 131 132 |
# File 'lib/bsv/overlay/topic_broadcaster.rb', line 123 def find_interested_hosts @ship_cache_mutex.synchronize do return @ship_cache.transform_values(&:dup) if @ship_cache && (Time.now.to_f - @ship_cache_at) < SHIP_CACHE_TTL hosts = fetch_ship_hosts @ship_cache = hosts @ship_cache_at = Time.now.to_f hosts.transform_values(&:dup) end end |