-
anonyphi[m]
Last week I posted regarding an idea to write a small C++ module which enables using the Monero network for small scale encrypted communications. The idea was to encode message characters into double precision floating point numbers, which will then be sent as tx amounts into the recipient's sub-address, who after receiving them - decodes them back into a character string . Right now my module does not interact with any Monero processes
-
anonyphi[m]
- and only uses modules from the standard C++ library. Anyone interested to read more about it, can find it here:
github.com/dvd280/sparrow-messenger
-
Inge
so best case 1.42Kb per letter and median 0.5 letters per minute
-
crypto_grampy[m]
<anonyphi[m]> "Last week I posted regarding..." <- This is very cool. For experiment sake, maybe consider adding some kind of start/end character sequence so a wallet would know to interpret the values a message, a meta block that could contain things like return address, name, etc, and then have your message in a content block.
-
anonyphi[m]
crypto_grampy: can you elaborate? I am not sure what you mean
-
crypto_grampy[m]
anonyphi[m]: If your 'messaging protocol' was wrapped in say .000000777's, you could make a wallet that worked as normal, but interpreted values wrapped in a start and end value as text messages. If that makes sense.
-
anonyphi[m]
To integrate this with wallet functionality there needs to be consensus on it... The module as it stands just automates the encoding/decoding part. The user still needs to send the transactions himself when he's sending, or export the transfers csv him self when he is recieving.
-
anonyphi[m]
s/him/himself/, s/self//
-
anonyphi[m]
s/him/himself/, s/self//, s/recieving/receiving/
-
anonyphi[m]
crypto_grampy: I do agree that this opens up a large opportunity to add unique functionality to monero
-
crypto_grampy[m]
anonyphi[m]: Yep. I'm just saying if you developed it further as a messaging protocol in mind. It would be fun to hack one of the wallets and add something like that in
-
anonyphi[m]
crypto_grampy: Yeah, I thought of doing it using the monero-cpp library that woodser wrote, but it is currently ready only for linux, so working out the dependencies to make it compatible with other platforms is quite a pain.
-
anonyphi[m]
The module is intended mostly as a demonstration of how would one go about doing communication on the monero network with minimal fees/costs. It still is quite expensive to send long messages.
-
rbrunner
anonyphi[m]: Does this demonstration, to keep it simple, still encode 1 letter per transaction, as you described in your first Reddit post about this?
-
anonyphi[m]
rbrunner: Yes, if the message is n characters long, the number of transactions that the program creates is n+2 (the extra two are separator characters, so that the reciever is able to distinguish between messages
-
anonyphi[m]
s/rbrunner: Yes, if the message is n characters long, the number of transactions that the program creates is n+2 (the extra two are separator characters, so that the reciever is able to distinguish between messages/rbrunner: Yes, if the message is n characters long, the number of transactions that the program encodes and puts in the EncodedTxs.txt is n+2 (the extra two are separator characters, so that the reciever is able to distinguish
-
anonyphi[m]
between messages). this means that the EncodedTxs.txt file will have n+2 rows, one per transaction./
-
sech1
1 character per transaction is the opposite of "communication on the monero network with minimal fees/costs"
-
sech1
more like maximal fees/costs :D
-
anonyphi[m]
sech1: It is not false, if you have method to communicate through a channel that's secured by 3 GH/s that is cheaper, I would be happy to use it instead.
-
anonyphi[m]
* channel that's completely private and secured by
-
sech1
just use tx_extra and encrypt stuff there, up to 100 Kb per transaction
-
sech1
actually don't, Monero blockchain is not a messaging app
-
anonyphi[m]
sech1: Im sorry but it seems like you do not get to decide how people use their funds.
-
sech1
there are talks already to remove tx_extra field in the next hardfork
-
sech1
precisely for this reason
-
sech1
*remove or limit in size drastically
-
anonyphi[m]
sech1: This does not affect my method... My implementation makes the transaction amounts themselves serve as data bytes.
-
rbrunner
anonyphi[m]: I would love to hear your opinion about BitMessage and one of its implementations, PyBitMessage? How would you compare that with your Monero-based method?
-
rbrunner
I readily agree that the BitMessage is *not* secured by gigahashes of mining power like the Monero network, but then I fail to see any possible attacks on it that would such hashpower to defend against
-
rbrunner
The network seems to be safe without that
-
anonyphi[m]
rbrunner: main difference between using monero and every other platform, is that with monero you get security that you just can not get in any other protocol. the reason is that if you wanted to max your security - you could send each transaction through a different node on the network. You also do not need a chain of active connections between you and the reciever. This method is asynchronous. meaning that the recieving party does not
-
anonyphi[m]
need to be online when the message is sent, and the reciving party does not need the sender to be online to read his message.
-
anonyphi[m]
s/./,/
-
anonyphi[m]
s/rbrunner: main difference between using monero and every other platform, is that with monero you get security that you just can not get in any other protocol. the reason is that if you wanted to max your security - you could send each transaction through a different node on the network. You also do not need a chain of active connections between you and the reciever. This method is asynchronous. meaning that the recieving party does not
-
anonyphi[m]
need to be online when the message is sent, and the reciving party does not need the sender to be online to read his message./rbrunner: main difference between using monero and every other platform, is that with monero you get security that you just can not get in any other protocol. the reason is that if you wanted to max your security - you could send each transaction through a different node on the network. You also do not need a
-
anonyphi[m]
chain of active connections between you and the reciever. This method is asynchronous, meaning that the recieving party does not need to be online when the message is sent, and the reciving party does not need the sender to be online at the time of reading his message./
-
anonyphi[m]
s/rbrunner: main difference between using monero and every other platform, is that with monero you get security that you just can not get in any other protocol. the reason is that if you wanted to max your security - you could send each transaction through a different node on the network. You also do not need a chain of active connections between you and the reciever. This method is asynchronous. meaning that the recieving party does not
-
anonyphi[m]
need to be online when the message is sent, and the reciving party does not need the sender to be online to read his message./rbrunner: main difference between using monero and every other platform, is that with monero you get security that you just can not get in any other protocol. the reason is that if you wanted to max your security - you could send each transaction through a different node on the network. You also do not need a
-
anonyphi[m]
chain of active connections between you and the reciever. This method is asynchronous, meaning that the recieving party does not need to be online when the message is sent, and also it does not need the sender to be online at the time of reading his message./
-
rbrunner
Would you mind to continue on #monero, as this is now not about Monero development specifically?
-
anonyphi[m]
np sure
-
moneromooo
... 1 char per tx ? Wha the atual fuck ? :D
-
anonyphi[m]
moneromooo: it is slow, and it is expensive, I admit.
-
anonyphi[m]
but it is also pretty safe, especially if users make sure to send each byte to a different node on the network
-
rbrunner
I knew moneromooo would like it
-
woodser[m]
<anonyphi[m]> "crypto_grampy: Yeah, I thought..." <- I don't think the monero-cpp library has any dependencies that monero-project doesn't have
-
woodser[m]
getting the build to work on windows might take some tweaking as I haven't tried myself
-
anonyphi[m]
woodser: yeah Im certain that it is possible, it's just too much work. either way I think I kind of prefer the non intrusive method of not interfacing with sensitive Monero processes directly.
-
anonyphi[m]
* much work for me. either
-
woodser[m]
perhaps wallet rpc and a library in your preferred language is a better approach
-
anonyphi[m]
Possibly, my aim was just to show it was possible. people who can do C++ will have no problem understanding my 150~ lines of standard C++ and converting them to more custom solutions if they wish
-
anarkiocrypto[m]
> However in the case of a core wallet churning continuously through a primary address, both the “recipient” and the “change” output are sent to the same wallet, and may be combined later! Unless the anomaly exhibited extremely precise change control practices, it is likely that in many cases two outputs created by the same transaction would be consumed by the same or subsequent transactions.
-
anarkiocrypto[m]
What is the change output of a churn if you churn the whole balance? (Regular churn, not this spam attack.) Does it differ if you churn to the same wallet or send all to a fresh new wallet? Any opsec tips for churns? I churn since 2016 but didn't know the above info... 1/11 isn't enough plausible deniability for me (e.g. collusion of sender/recipient), and AFAIK each churn creates a new branch for 11^x possibilities, but please let
-
anarkiocrypto[m]
me know if I'm wrong.
-
sech1
change output is 0 XMR if you churn everything
-
sech1
it goes back to the original wallet and can still be combined with other outputs in that wallet
-
anarkiocrypto[m]
Empty input?
-
sech1
yes, 0 XMR. But your wallet can still use it when selecting inputs
-
anarkiocrypto[m]
When and how would it be selected for a TX if it has no value? Is it random?
-
sech1
afaik wallet selects two random inputs and if they have enough XMR combined then they will be used. One of the inputs can still be 0 XMR
-
anarkiocrypto[m]
OK thanks. I assume both churn and change has the same timestamp. If you churn quickly (e.g. a few churns with 1 hour between churns), could it be visible in e.g. xmrchain that you are spending the churn and its change? How about one input, 2 output TXs? I will try to find out what inputs I have and how many 0 XMRs are there.
-
sech1
use sweep_single to churn a single input, that way you make sure it's not combined with anything. Also use random time intervals between churns and move the final churn to a separate wallet to avoid combining inputs later
-
anarkiocrypto[m]
Thanks. I generate a new fresh wallet to receive Monero and move to a separate wallet per use case for spending (e.g. Bitcoin ATM vs. VPS payments vs. Bitrefill). I churn a few times between steps, anything from 1 hour to a few days, no specific or automated times. I use Monero GUI but will download Monero CLI to see inputs and access sweep_single.
-
moneromooo
The 0 change output goes to a random address, not the sending address. It'd be too confusing.
-
anarkiocrypto[m]
Is it burned or goes to a random address that is used? E.g. people can receive other people's 0 XMR churn changes and use them in their TXs?
-
anarkiocrypto[m]
Another question: Would it be recommended to use a fresh subaddress per churn in the same wallet? I only use main addresses right now.
-
sech1
if it goes to a random address then chances of receiving 0 XMR output are astronomically low
-
anarkiocrypto[m]
Also I guess 0 XMR changes can also be used as decoy inputs in regular TXs?
-
sech1
this phrase is not correct then: "However in the case of a core wallet churning continuously through a primary address, both the “recipient” and the “change” output are sent to the same wallet"
-
anarkiocrypto[m]
-
moneromooo
They can be used as fake outs.
-
anarkiocrypto[m]
Thanks for the help. Looks like churn is how I expected (churn 1 input, get 1 input back).
-
rbrunner
If I need to record the time something happens in the Monero codebase with more than 1 sec resolution, is ticks and misc_utils::get_tick_count() the way to go?
-
moneromooo
See perf_timer.h, it uses those IIRC, and converts to SI.
-
moneromooo
Or gettimeofday.
-
rbrunner
Thanks. So if I want to record the exact-enough time a tx entered the pool, so somebody can ask "give me the txs that entered the pool at or later than point in time x"
-
rbrunner
Those ticks look like the right way to do it, with a datatype of uint64_t then.
-
moneromooo
Oh, you can set log level to msg.p2p:INFO and you'll get the timestamp for these.
-
moneromooo
Oh, sorry, programmatically ? Then yes.
-
moneromooo
If your intent is to know which txes are new, I suggest you use the txpool cookie instead.
-
rbrunner
Exactly. There are probably a dozen ways to do it, but I try to stay within style and do it "like it should be done".
-
moneromooo
er, in fact, scratch that.
-
rbrunner
Yeah, I think I need something really time-based. From wallet2 to connected daemon.
-
rbrunner
With the time of that daemon, of course.
-
moneromooo
You might want to have the daemon send the time with that response, or you may miss things.
-
rbrunner
Yes, that's part of the pattern.
-
moneromooo
Though sending the time might open the door to fingerprinting, since a clearnet and tor daemons would have the same time offset...
-
rbrunner
"Here, have pool txs until point x. Ask again with x+1 if you want new ones next time"
-
moneromooo
So maybe you want to quantize that time a bit.
-
moneromooo
Quantizing would require asking with x again, thus getting dupes. Not sure which is best.
-
rbrunner
I see. I suspect that the system should be robust and able to deal with duplicates anyway, so that looks doable.
-
rbrunner
Since you are here already: If I want to store say one hour worth of tx ids, ordered by such a tick-resolution timestamp, and regularly delete the oldest ones to keep it one hour give or take
-
rbrunner
What would be a good C++ / STL data structure to do so?
-
rbrunner
Can find out myself of course, but you probably know just like that :)
-
moneromooo
map or multimap.
-
moneromooo
The iterator will be sorted by key.
-
rbrunner
Alright, thanks, will read up about those two!
-
moneromooo
multimap if you can have dupes.
-
anonyphi[m]
why not use two parallel vectors
-
moneromooo
I guess deque would also work since it's always ends yo're interested in.
-
moneromooo
Less memory allocation.
-
rbrunner
What's that "two parallel vectors" idea?
-
moneromooo
multimap will be less annoying if you need to remove some txes at random places though, which ahppens as blocks get mined.
-
anonyphi[m]
two vectors, one for ids, one for timestamps, every new tx/stamp pair is pushed into their respective verctors
-
anonyphi[m]
vectors allow deleting objects within them, although it would require memory reallocation.
-
anonyphi[m]
also, if you plan on having a constant number of ticks in your container then why not use an array?
-
anonyphi[m]
i mean two arrays inside some class
-
rbrunner
Maybe I just submit something and vtnerd will give the absolutely best optimized version in their code review :)
-
rbrunner
anonyphi[m]: No, the number of things will not be constant, so simple array is probably not a good way to go.
-
atomfried[m]
while talking about containers, monero seems to use std::unordered_map, was it ever considered to use a faster hashmap?
-
sech1
std::unordered_map is as fast as the compiler/c++ library that implement it
-
sech1
a "faster" hashmap might not be faster than std::unordered_map on some systems
-
atomfried[m]
yes i know, but there exist different benchmarks that the version in the standard libs are not that fast compared to other implementations
-
sech1
is it even a bottleneck in any place? My guess is crypto math and PoW are the 99% of bottlenecks. Not hash maps
-
atomfried[m]
for example google sparshhash or googles dense_hash_map outperform the std::unordered_map in a lot of benchmarks
-
atomfried[m]
sech1: i am just poking arround if this was ever considered
-
sech1
I'm not a fan of unneeded optimizations. More dependencies on more 3rd-party code that can break
-
UkoeHB
atomfried[m]: aren't there limitations/risks to other hash map strategies?
-
atomfried[m]
UkoeHB: that should be evaluated ofc but as far as i know std::unordered_map uses chaining and dense_hash_map uses quadradic probing, a lot of the performance difference comes from the different strategies used i guess
-
atomfried[m]
some of them also use sse instructions to speedup some things
-
atomfried[m]
-
rbrunner
The daemon keeps the tx pool on disk and accesses through LMDB, right? Why is that, because the size is open-ended, and/or because you don't want to loose it if the daemon restarts?
-
hyc
size
-
hyc
and sure, it's more efficient network-wise not to lose it on restarts
-
rbrunner
Ok. But say for a new purpose I would need the pool transactions ordered in a new way, it should be possible to keep their hashes in RAM in the right order and then pick the transactions themselves from the DB?
-
rbrunner
Or would it be altogether better to create a new index for that order in the DB?
-
hyc
IMO you should always assume your data will grow larger than RAM so yes, a new index in the DB would be best
-
hyc
but what do you have in mind?
-
rbrunner
I try my luck with this here:
monero-project/monero #7571
-
rbrunner
For that I would need chronological ordering of pool txs, according to the time they entered the pool
-
rbrunner
Not yet sure how they are ordered now in the DB however
-
hyc
i dunno either, mooo wrote that
-
rbrunner
Doesn't a new index open up all kinds of upgrade problems?
-
hyc
how so?
-
hyc
if you're merely adding a table, older versions will just ignore it
-
rbrunner
So a daemon that includes that logic needs a check "Index exists already?" and if not creates it first?
-
rbrunner
Auto-upgrade, so to say
-
hyc
that would work yes
-
hyc
just like the other auto-upgrades it already does
-
hyc
i see txpool is keyed by txn hash
-
hyc
so yes you would need a new table keyed on timestamp, containing hash
-
rbrunner
Ok, thanks. Looks like a lot to learn for me if I really go down that route ...
-
hyc
I can write that specific code if you want. not a big deal.
-
hyc
it'd be up to you to wire it in to wherever you need to use it
-
rbrunner
Sounds an interesting offer. Let's see how this develops, I am only in the investigation phase now.
-
hyc
ok, keep me posted
-
rbrunner
Sure thing!
-
moneromooo
No upgrade problem, the lmdb open call creates the table if it does not exist.
-
hyc
moneromooo: looks like txn receive_time is a uint64_t, but resolution is only 1 second
-
moneromooo
The txpool object already keep an in-RAM index of txes sorted by fee/byte.
-
hyc
that might be annoying for lots of txes arriving in the same second
-
moneromooo
If you need better resolution, I have no problem with bumping resolution.
-
moneromooo
That one might need a db upgrade though, to convert txpool_meta.
-
hyc
I guess it will depend on what the wallet needs. there's no problem using DUPSORT in LMDB to allow multiple records per timestamp key
-
hyc
with an eye toward eventually handling thousands of txs/sec, we would prob want to bump rez up finer than millisecond at least
-
moneromooo
Maybe a first step might be to make the fee/byte index a lmdb table too. Easiest job first :)
-
hyc
I would use gettimeofday() to retrieve microseconds, and shuffle so 44 bits of seconds OR'd with 20 bits of microseconds
-
hyc
that gives headroom for 4096 * 70 years
-
rbrunner
Hmmm ... if you take that with the thousands of txs/sec serious I think the way wallet2 works now would probably break down anyway, for every sync time it fetches the whole tx pool.
-
hyc
that can be fixed some other day
-
rbrunner
:)
-
rbrunner
"The txpool object already keep an in-RAM index of txes sorted by fee/byte." Looks tempting for me like an easy way out, I make a second RAM-only index, with the same "right" ...
-
hyc
anyway, after your work, wallet2 wouldn't need to do that any more would it
-
hyc
it would only need to fetch txns newer than the last time it looked
-
rbrunner
Yeah, probably
-
hyc
all of this still implies that users should just always have a long-lived wallet-rpc running all the time
-
hyc
and UIs should just talk to that. would save so much of the UX badness everyone complains about.
-
hyc
have it on home network, listening on i2p, and it'd be accessible from anywhere, no port forwarding issues
-
rbrunner
In an ideal world ...