Packs one announce-rate-table entry as a 5-key map. Insertion order matches Reticulum.py:get_rate_table (lines 1517-1524): hash, last, rate_violations, blocked_until, timestamps. rnpath.py:339-369 accesses every field unguarded.
| 4053 | // Reticulum.py:get_rate_table (lines 1517-1524): hash, last, rate_violations, |
| 4054 | // blocked_until, timestamps. rnpath.py:339-369 accesses every field unguarded. |
| 4055 | static void remote_path_pack_rate_entry(MsgPack::Packer& p, |
| 4056 | const Bytes& dest_hash, |
| 4057 | const Transport::RateEntry& entry) { |
| 4058 | p.packMapSize(5); |
| 4059 | |
| 4060 | p.pack("hash"); |
| 4061 | p.packBinary(dest_hash.data(), dest_hash.size()); |
| 4062 | |
| 4063 | p.pack("last"); |
| 4064 | p.packFloat64(entry._last); |
| 4065 | |
| 4066 | // Python stores this as int (counter incremented by 1); C++ field is |
| 4067 | // double for legacy reasons. Emit as uint to match Python's wire bytes -- |
| 4068 | // rnpath.py:351 only checks `> 0` and stringifies, both work either way. |
| 4069 | p.pack("rate_violations"); |
| 4070 | p.serialize(static_cast<uint32_t>(entry._rate_violations)); |
| 4071 | |
| 4072 | p.pack("blocked_until"); |
| 4073 | p.packFloat64(entry._blocked_until); |
| 4074 | |
| 4075 | // timestamps must always be a (possibly empty) list -- rnpath.py:344 |
| 4076 | // does entry["timestamps"][0] unguarded. RateEntry::RateEntry(double now) |
| 4077 | // at Transport.h:259 seeds the vector with `now`, so >=1 element in practice. |
| 4078 | p.pack("timestamps"); |
| 4079 | p.packArraySize(entry._timestamps.size()); |
| 4080 | for (double ts : entry._timestamps) { |
| 4081 | p.packFloat64(ts); |
| 4082 | } |
| 4083 | } |
| 4084 | |
| 4085 | /*static*/ Bytes Transport::remote_path_handler(const Bytes& path, const Bytes& data, const Bytes& request_id, const Bytes& link_id, const Identity& remote_identity, double requested_at) { |
| 4086 |
no test coverage detected