Day changed to 2025-09-02
[00:14] bob: I chose Bob for Built On Bitcoin! Is that sexy?
[13:43] dorion: hello bob, welcome. a name is what you make of it, innit ?
[15:32] bob: Correct
[15:40] dorion: bob, the first step is to make a key and register it with wotbot.
[15:40] dorion: !w help
[15:40] wotbot: Available commands: hi, help, register, up, down, key, rate, unrate, rated
Day changed to 2025-09-03
[15:39] nekoluce: hey
[15:39] nekoluce: good morning
Day changed to 2025-09-12
[23:09] jfw: ftr, both our public bitcoin nodes fell over now from overflow of disk space; looks like the debug logging finally insists on some attention along with grep.
Day changed to 2025-09-13
[01:01] jfw: for added conspiratorial fodder, the younger node failed around 22 UTC of Sept. 11. The older one, 17 UTC of Sept. 9. For some time prior, I was seeing more than usual long stuck spells with no new blocks relayed.
[08:32] lru: there is a big controversy over op_return size and the risk of arbitrary data in the blockchain... I assume your versions filter strictly
[13:19] jfw: yeah, that's the surface narrative, which doesn't make a lot of sense. http://jfxpt.com/2025/jwrd-logs-for-Aug-2025/#14781
[13:19] sourcerer: 2025-08-19 23:56:42 (#jwrd) jfw: apparently there are >1 people for whom soft-forking to force a stealth block size increase to the detriment of security, reliability, sanity, consensus, etc. is fine and dandy, but then *using* this capability for anything other than what they had in mind to use it for is evil spamming that's going to kill bitcoin
[13:28] jfw: I guess most likely one of those trendy layer-N things is generating a lot of nonstandard transactions that happen to tickle some overly verbose log messages
[13:30] jfw: though that doesn't explain who's trying to promote luke-jr from laughingstock to jesus
[17:08] dorion: knots is the proverbial tv raft.
[22:10] lru: I wondered if "Luke Dashjr" was the same as "luke-jr" I'd read about on trilema
[23:59] jfw: the same
Day changed to 2025-09-19
[23:43] whaack: !e view-height
[23:43] btcexplorer: block_height: 914921
[23:43] btcexplorer: mins_since_last_block: 5216
[23:43] whaack: recently restarted bdexplorer, should be caught up in 1-2 days
[23:50] whaack: bitcoind seems stuck tho, so we'll see later
Day changed to 2025-09-22
[00:17] jfw: !e view-height
[00:17] btcexplorer: block_height: 915121
[00:17] btcexplorer: mins_since_last_block: 6265
[17:52] dorion: !e view-height
[17:52] btcexplorer: block_height: 915144
[17:52] btcexplorer: mins_since_last_block: 7042
[17:52] dorion: still some 800+ blocks behind other sources.
[18:00] jfw: my home node got synced up yest but then filled up debug.log too. will look into patching that sooner rather than later.
[20:59] dorion: alright, sounds good.
[22:23] whaack_: restarted my node again, with flags:
[22:23] whaack_: bitcoind -daemon -permissive -logtimestamps -myip=205.134.172.28 -addnode=205.134.172.27 -addnode=54.39.156.17 -addnode=143.202.160.10 -addnode=208.94.240.42 -addnode=85.167.101.64 -addnode=94.176.238.102 -addnode=205.134.172.6 -addnode=45.11.57.212 -verifyall &
[22:24] whaack_: !e view-height
[22:24] btcexplorer: block_height: 915210
[22:24] btcexplorer: mins_since_last_block: 6651
[22:24] whaack_: looks like we're moving forward again
Day changed to 2025-09-24
[15:25] whaack: !e view-height
[15:25] btcexplorer: block_height: 915529
[15:25] btcexplorer: mins_since_last_block: 6423
[15:25] whaack: dorion: http://ztkfg.com/2025/09/philadelphia-bridge-nationals-recap/
[15:27] whaack: this guy has a nice bridge site http://www.rpbridge.net/, with https disabled! http://www.rpbridge.net/8q47.htm jfw i have a feeling you make like the puzzle contest here if you are into combinatorics problems.
[16:03] dorion: whaack did you want to make that first pic in portrait mode or give readers a neck stretch ?
[16:03] dorion: lolz
[16:27] dorion: I see there are several such cases. In my process, I found I have to sort the landscape and portrait pics and have separate scripts for scaling them properly.
[17:17] jfw: or there's convert -auto-orient ...
[18:46] dorion: based on which proggy ? I used a gimp based script hanbot had published.
Day changed to 2025-09-25
[13:30] jfw: dorion: "convert". it's from imagemagick, per the earlier recipe from MP and http://jfxpt.com/2019/blogging-photos-and-chat-logs-some-handy-scripts/
[13:32] jfw: iirc, I worked out how to handle the aspect ratios consistently on the gimp scripting method but not an equivalent for reading the orientation meta tag(s).
[20:34] whaack: I'm confused, are the images not rotated correctly for you guys?
[20:34] whaack: I see them properly oriented on my end.
[20:36] whaack: Maybe my browser is looking at the metadata in the photo and orienting it for me?
[20:40] whaack: !e view-height
[20:40] btcexplorer: block_height: 915529
[20:40] btcexplorer: mins_since_last_block: 8178
[22:42] jfw: interesting, seems it auto-orients on the post-apocalyptic firefox but not the traditional.
[22:47] jfw: MDN will naturally say "works on all browsers".
Day changed to 2025-09-27
[18:00] caai: jwrd: as a follow up from last night, i think setting up irc servers/clients is a great idea. many people would be interested in gaining control of the data from their daily conversations.
Day changed to 2025-09-30
[03:10] jfw: dorion: while looking into some of the more prolific debug.log lines today, such as askfor tx, I believe I found an exploitable memory leak, where one of the global data structures can be made to grow indefinitely until out of memory.
[03:15] jfw: not like it's much surprise by now, it's like you can't walk two steps in that code without tripping on yet another "previously unknown"
[03:26] lru: jfw: are you referring to mapAskFor as that global data structure?
[03:26] jfw: lru: that one's not exactly global.
[03:27] lru: yeah
[03:27] lru: and SendMessage() eats it / erases it
[03:28] jfw: the logic seems similar to the old "block orphanage" - cutting down on redundant requests, but with the requirement of keeping possibly large data sets.
[03:31] lru: oh, mapAlreadyAskedFor is the global
[03:32] lru: I can't tell if AskFor() is really meaning to add to that or whether it is just supposed to be a lookup
[03:32] jfw: indeed that's the suspect. yes, AskFor means to add because it's the only one that does
[03:33] lru: there is a "mapAlreadyAskedFor[inv] = nNow;" in main.cpp
[03:37] jfw: hm, true, but when that runs, it was already in the peer-specific mapAskFor, which means it was already added to mapAlreadyAskedFor (by AskFor). but if the latter was inadvertent then indeed that would no longer hold
[03:39] lru: in 2019, this code was ripped out of bitcoin core, and the AskFor() code at that point had a .find(), not operator[]...so somebody must have thought it was a lookup and not an add
[03:39] jfw: it certainly is perplexing why you'd say "already asked for" when all you've done is queued it up for asking...
[03:40] lru: yeah
[03:40] lru: only to later do an .insert()
[03:40] jfw: not sure it makes a difference as far as the leak though
[03:42] jfw: just spam made-up txid inv messages, it'll eventually send the getdata and add to mapAlreadyAskedFor, never to be .erase'd because the data's never received and/or isn't accepted.
[03:57] lru: so...that line in AskFor() goes all the way back to the first commit :-)
[03:58] lru: on 2011/Jul/21, Matt Corallo declares in a git commit message what the original intent was for mapAlreadyAskedFor:
[03:59] lru: "Actually use mapAlreadyAskedFor. Previously, mapAlreadyAskedFor was read from, but never added to. The original intent was to use mapAlreadyAskedFor to keep track of the time an item was requested and "Each retry is 2 minutes after the last". This implements that intent."
[03:59] lru: it's a one-liner commit adding:
[03:59] lru: + mapAlreadyAskedFor[inv] = nNow;
[03:59] lru: to main.cpp
[04:00] lru: so I suspect the use of operator[] on a std::map was a bug from the original code, with C++'s trickly behaviour of adding a new record to a map even when just reading from it (like done in AskFor())
[04:02] lru: I don't know if that helps, but I tried :-)
[14:40] dorion: thanks for the efforts lru.
[14:56] jfw: either original bug or misinterpretation by bluematt; satoshi was already gone by 2011
[14:58] jfw: I'd have trouble blaming C++ here; the part where nRequestTime is set up as a reference (i.e. in+out) and the lack of any checking for key not found should be pretty big clues.
[15:04] dorion: jfw, is the path forward clear yet ?
[15:14] jfw: not really. possibly replacing mapAlreadyAskedFor with a size-limited time-based thing
[15:16] jfw: then if one peer spams it, it falls back to not being useful and probably fetches every new transaction from every peer that announces it
[15:21] jfw: or make one for each peer, so a bad apple won't spoil the bunch; just that it'll have to check each peer's list instead of one central place
[15:22] jfw: (and I'd rather push it toward being able to handle lots of peers)
[15:31] jfw: worth noting that low-value transaction spamming is already a weak point due to the unbounded mempool, but we intend to fix that.
[15:47] jfw: it's actually a pretty core piece of the gossip network mechanism, isn't it. suppose you're a well-connected node. a new transaction appears and spreads through the network. a bunch of peers send it to you right around the same time. bandwidth scales as the product of peer count and transaction rate.
[15:50] jfw: it'd be nice to get that much closer to just transaction rate, because penalizing peer count will hurt the overall network connectivity. so it's set up to first send just the hash (inv message), saving maybe 10-20x on byte count (though possibly not much on packet count). node then has to decide whom to ask for the full data and when to retry.
[15:53] jfw: but in the view that latency and packet counts matter more than byte counts, it'd actually be better to skip the "inv" dance and just push out the whole transaction every time; then there's no need to track any "asked for" state.
[15:54] jfw: blocks might be another story.
[16:32] dorion: http://jfxpt.com/2025/jwrd-logs-for-Sep-2025/#14964 -- i agree with this approach.
[16:32] sourcerer: 2025-09-30 15:22:59 (#jwrd) jfw: (and I'd rather push it toward being able to handle lots of peers)
[16:33] jfw: the situation gets uglier with blocks, since they don't fit in a small number of packets. currently, the first peer to send the inv is the first asked for the data, with others then asked at minimum 2-minute spacing if the block doesn't arrive. thus, you could gum up block propagation by being fast to send the inv and then slow to send the block. but if there's no delay before asking the next
[16:33] jfw: peer, propagation is also slowed by downloading the same megabyte from lots of peers at once.
[16:35] jfw: this is where the Luby codes approach might be neat: just have each peer send random chunks of the block until it's fully assembled. there's some redundacy but it's minimized.
[16:36] jfw: or more simply bittorrent style, asking peers for specific chunks of the block. either of these would require changing the protocol tho.
[16:38] jfw: the most practical solution might be to make the delay tunable; you'd set it based on your expected bandwidth and the 1MB block size.
[16:51] jfw: but that still doesn't resolve the need to track an unlimited number of block hashes. I'm thinking the "getheaders" might hold the solution
[16:59] jfw: whenever you get a block inv not already in chain, always ask the sending peer for header. that's ~80 bytes. when you get a header not already in chain *and passing proof-of-work*, ask for the full block, and then you can more safely keep the list of live requests and limit by time or number of concurrent attempts or what-have-you.
[17:01] jfw: then for transactions, forget the "already asked" and just always ask. trouble though: transactions may be usually small but not necessarily; after all, they can be up to the block size.
[17:17] jfw: so really a working limiter is needed for all cases. maybe limit the number of outstanding requests per peer and then make sure they're properly removed from the global map when disconnecting the peer if it was the only one advertising them.
[20:36] jfw: 2
[00:14] bob: I chose Bob for Built On Bitcoin! Is that sexy?
[13:43] dorion: hello bob, welcome. a name is what you make of it, innit ?
[15:32] bob: Correct
[15:40] dorion: bob, the first step is to make a key and register it with wotbot.
[15:40] dorion: !w help
[15:40] wotbot: Available commands: hi, help, register, up, down, key, rate, unrate, rated
Day changed to 2025-09-03
[15:39] nekoluce: hey
[15:39] nekoluce: good morning
Day changed to 2025-09-12
[23:09] jfw: ftr, both our public bitcoin nodes fell over now from overflow of disk space; looks like the debug logging finally insists on some attention along with grep.
Day changed to 2025-09-13
[01:01] jfw: for added conspiratorial fodder, the younger node failed around 22 UTC of Sept. 11. The older one, 17 UTC of Sept. 9. For some time prior, I was seeing more than usual long stuck spells with no new blocks relayed.
[08:32] lru: there is a big controversy over op_return size and the risk of arbitrary data in the blockchain... I assume your versions filter strictly
[13:19] jfw: yeah, that's the surface narrative, which doesn't make a lot of sense. http://jfxpt.com/2025/jwrd-logs-for-Aug-2025/#14781
[13:19] sourcerer: 2025-08-19 23:56:42 (#jwrd) jfw: apparently there are >1 people for whom soft-forking to force a stealth block size increase to the detriment of security, reliability, sanity, consensus, etc. is fine and dandy, but then *using* this capability for anything other than what they had in mind to use it for is evil spamming that's going to kill bitcoin
[13:28] jfw: I guess most likely one of those trendy layer-N things is generating a lot of nonstandard transactions that happen to tickle some overly verbose log messages
[13:30] jfw: though that doesn't explain who's trying to promote luke-jr from laughingstock to jesus
[17:08] dorion: knots is the proverbial tv raft.
[22:10] lru: I wondered if "Luke Dashjr" was the same as "luke-jr" I'd read about on trilema
[23:59] jfw: the same
Day changed to 2025-09-19
[23:43] whaack: !e view-height
[23:43] btcexplorer: block_height: 914921
[23:43] btcexplorer: mins_since_last_block: 5216
[23:43] whaack: recently restarted bdexplorer, should be caught up in 1-2 days
[23:50] whaack: bitcoind seems stuck tho, so we'll see later
Day changed to 2025-09-22
[00:17] jfw: !e view-height
[00:17] btcexplorer: block_height: 915121
[00:17] btcexplorer: mins_since_last_block: 6265
[17:52] dorion: !e view-height
[17:52] btcexplorer: block_height: 915144
[17:52] btcexplorer: mins_since_last_block: 7042
[17:52] dorion: still some 800+ blocks behind other sources.
[18:00] jfw: my home node got synced up yest but then filled up debug.log too. will look into patching that sooner rather than later.
[20:59] dorion: alright, sounds good.
[22:23] whaack_: restarted my node again, with flags:
[22:23] whaack_: bitcoind -daemon -permissive -logtimestamps -myip=205.134.172.28 -addnode=205.134.172.27 -addnode=54.39.156.17 -addnode=143.202.160.10 -addnode=208.94.240.42 -addnode=85.167.101.64 -addnode=94.176.238.102 -addnode=205.134.172.6 -addnode=45.11.57.212 -verifyall &
[22:24] whaack_: !e view-height
[22:24] btcexplorer: block_height: 915210
[22:24] btcexplorer: mins_since_last_block: 6651
[22:24] whaack_: looks like we're moving forward again
Day changed to 2025-09-24
[15:25] whaack: !e view-height
[15:25] btcexplorer: block_height: 915529
[15:25] btcexplorer: mins_since_last_block: 6423
[15:25] whaack: dorion: http://ztkfg.com/2025/09/philadelphia-bridge-nationals-recap/
[15:27] whaack: this guy has a nice bridge site http://www.rpbridge.net/, with https disabled! http://www.rpbridge.net/8q47.htm jfw i have a feeling you make like the puzzle contest here if you are into combinatorics problems.
[16:03] dorion: whaack did you want to make that first pic in portrait mode or give readers a neck stretch ?
[16:03] dorion: lolz
[16:27] dorion: I see there are several such cases. In my process, I found I have to sort the landscape and portrait pics and have separate scripts for scaling them properly.
[17:17] jfw: or there's convert -auto-orient ...
[18:46] dorion: based on which proggy ? I used a gimp based script hanbot had published.
Day changed to 2025-09-25
[13:30] jfw: dorion: "convert". it's from imagemagick, per the earlier recipe from MP and http://jfxpt.com/2019/blogging-photos-and-chat-logs-some-handy-scripts/
[13:32] jfw: iirc, I worked out how to handle the aspect ratios consistently on the gimp scripting method but not an equivalent for reading the orientation meta tag(s).
[20:34] whaack: I'm confused, are the images not rotated correctly for you guys?
[20:34] whaack: I see them properly oriented on my end.
[20:36] whaack: Maybe my browser is looking at the metadata in the photo and orienting it for me?
[20:40] whaack: !e view-height
[20:40] btcexplorer: block_height: 915529
[20:40] btcexplorer: mins_since_last_block: 8178
[22:42] jfw: interesting, seems it auto-orients on the post-apocalyptic firefox but not the traditional.
[22:47] jfw: MDN will naturally say "works on all browsers".
Day changed to 2025-09-27
[18:00] caai: jwrd: as a follow up from last night, i think setting up irc servers/clients is a great idea. many people would be interested in gaining control of the data from their daily conversations.
Day changed to 2025-09-30
[03:10] jfw: dorion: while looking into some of the more prolific debug.log lines today, such as askfor tx, I believe I found an exploitable memory leak, where one of the global data structures can be made to grow indefinitely until out of memory.
[03:15] jfw: not like it's much surprise by now, it's like you can't walk two steps in that code without tripping on yet another "previously unknown"
[03:26] lru: jfw: are you referring to mapAskFor as that global data structure?
[03:26] jfw: lru: that one's not exactly global.
[03:27] lru: yeah
[03:27] lru: and SendMessage() eats it / erases it
[03:28] jfw: the logic seems similar to the old "block orphanage" - cutting down on redundant requests, but with the requirement of keeping possibly large data sets.
[03:31] lru: oh, mapAlreadyAskedFor is the global
[03:32] lru: I can't tell if AskFor() is really meaning to add to that or whether it is just supposed to be a lookup
[03:32] jfw: indeed that's the suspect. yes, AskFor means to add because it's the only one that does
[03:33] lru: there is a "mapAlreadyAskedFor[inv] = nNow;" in main.cpp
[03:37] jfw: hm, true, but when that runs, it was already in the peer-specific mapAskFor, which means it was already added to mapAlreadyAskedFor (by AskFor). but if the latter was inadvertent then indeed that would no longer hold
[03:39] lru: in 2019, this code was ripped out of bitcoin core, and the AskFor() code at that point had a .find(), not operator[]...so somebody must have thought it was a lookup and not an add
[03:39] jfw: it certainly is perplexing why you'd say "already asked for" when all you've done is queued it up for asking...
[03:40] lru: yeah
[03:40] lru: only to later do an .insert()
[03:40] jfw: not sure it makes a difference as far as the leak though
[03:42] jfw: just spam made-up txid inv messages, it'll eventually send the getdata and add to mapAlreadyAskedFor, never to be .erase'd because the data's never received and/or isn't accepted.
[03:57] lru: so...that line in AskFor() goes all the way back to the first commit :-)
[03:58] lru: on 2011/Jul/21, Matt Corallo declares in a git commit message what the original intent was for mapAlreadyAskedFor:
[03:59] lru: "Actually use mapAlreadyAskedFor. Previously, mapAlreadyAskedFor was read from, but never added to. The original intent was to use mapAlreadyAskedFor to keep track of the time an item was requested and "Each retry is 2 minutes after the last". This implements that intent."
[03:59] lru: it's a one-liner commit adding:
[03:59] lru: + mapAlreadyAskedFor[inv] = nNow;
[03:59] lru: to main.cpp
[04:00] lru: so I suspect the use of operator[] on a std::map was a bug from the original code, with C++'s trickly behaviour of adding a new record to a map even when just reading from it (like done in AskFor())
[04:02] lru: I don't know if that helps, but I tried :-)
[14:40] dorion: thanks for the efforts lru.
[14:56] jfw: either original bug or misinterpretation by bluematt; satoshi was already gone by 2011
[14:58] jfw: I'd have trouble blaming C++ here; the part where nRequestTime is set up as a reference (i.e. in+out) and the lack of any checking for key not found should be pretty big clues.
[15:04] dorion: jfw, is the path forward clear yet ?
[15:14] jfw: not really. possibly replacing mapAlreadyAskedFor with a size-limited time-based thing
[15:16] jfw: then if one peer spams it, it falls back to not being useful and probably fetches every new transaction from every peer that announces it
[15:21] jfw: or make one for each peer, so a bad apple won't spoil the bunch; just that it'll have to check each peer's list instead of one central place
[15:22] jfw: (and I'd rather push it toward being able to handle lots of peers)
[15:31] jfw: worth noting that low-value transaction spamming is already a weak point due to the unbounded mempool, but we intend to fix that.
[15:47] jfw: it's actually a pretty core piece of the gossip network mechanism, isn't it. suppose you're a well-connected node. a new transaction appears and spreads through the network. a bunch of peers send it to you right around the same time. bandwidth scales as the product of peer count and transaction rate.
[15:50] jfw: it'd be nice to get that much closer to just transaction rate, because penalizing peer count will hurt the overall network connectivity. so it's set up to first send just the hash (inv message), saving maybe 10-20x on byte count (though possibly not much on packet count). node then has to decide whom to ask for the full data and when to retry.
[15:53] jfw: but in the view that latency and packet counts matter more than byte counts, it'd actually be better to skip the "inv" dance and just push out the whole transaction every time; then there's no need to track any "asked for" state.
[15:54] jfw: blocks might be another story.
[16:32] dorion: http://jfxpt.com/2025/jwrd-logs-for-Sep-2025/#14964 -- i agree with this approach.
[16:32] sourcerer: 2025-09-30 15:22:59 (#jwrd) jfw: (and I'd rather push it toward being able to handle lots of peers)
[16:33] jfw: the situation gets uglier with blocks, since they don't fit in a small number of packets. currently, the first peer to send the inv is the first asked for the data, with others then asked at minimum 2-minute spacing if the block doesn't arrive. thus, you could gum up block propagation by being fast to send the inv and then slow to send the block. but if there's no delay before asking the next
[16:33] jfw: peer, propagation is also slowed by downloading the same megabyte from lots of peers at once.
[16:35] jfw: this is where the Luby codes approach might be neat: just have each peer send random chunks of the block until it's fully assembled. there's some redundacy but it's minimized.
[16:36] jfw: or more simply bittorrent style, asking peers for specific chunks of the block. either of these would require changing the protocol tho.
[16:38] jfw: the most practical solution might be to make the delay tunable; you'd set it based on your expected bandwidth and the 1MB block size.
[16:51] jfw: but that still doesn't resolve the need to track an unlimited number of block hashes. I'm thinking the "getheaders" might hold the solution
[16:59] jfw: whenever you get a block inv not already in chain, always ask the sending peer for header. that's ~80 bytes. when you get a header not already in chain *and passing proof-of-work*, ask for the full block, and then you can more safely keep the list of live requests and limit by time or number of concurrent attempts or what-have-you.
[17:01] jfw: then for transactions, forget the "already asked" and just always ask. trouble though: transactions may be usually small but not necessarily; after all, they can be up to the block size.
[17:17] jfw: so really a working limiter is needed for all cases. maybe limit the number of outstanding requests per peer and then make sure they're properly removed from the global map when disconnecting the peer if it was the only one advertising them.
[20:36] jfw: 2