Bitcoin Forum
April 17, 2021, 03:32:26 AM *
News: Latest Bitcoin Core release: 0.21.0 [Torrent]
 
   Home   Help Search Login Register More  
Pages: [1] 2 »  All
  Print  
Author Topic: What is stopping pruning from being added to the qt client?  (Read 2703 times)
mustyoshi
Sr. Member
****
Offline Offline

Activity: 287
Merit: 250



View Profile
July 15, 2013, 09:25:33 PM
 #1

Can't the client just download and parse the entire blockchain removing the unspent outputs as they get spent?

I don't understand why it hasn't already been implemented, I imagine it would be immensely useful for miners who don't want to foot the entire 10GB blockchain, and just want the probably .5GB block header + unspent output that would be the result of the parsing.
1618630346
Hero Member
*
Offline Offline

Posts: 1618630346

View Profile Personal Message (Offline)

Ignore
1618630346
Reply with quote  #2

1618630346
Report to moderator
1618630346
Hero Member
*
Offline Offline

Posts: 1618630346

View Profile Personal Message (Offline)

Ignore
1618630346
Reply with quote  #2

1618630346
Report to moderator
Advertised sites are not endorsed by the Bitcoin Forum. They may be unsafe, untrustworthy, or illegal in your jurisdiction. Advertise here.
1618630346
Hero Member
*
Offline Offline

Posts: 1618630346

View Profile Personal Message (Offline)

Ignore
1618630346
Reply with quote  #2

1618630346
Report to moderator
1618630346
Hero Member
*
Offline Offline

Posts: 1618630346

View Profile Personal Message (Offline)

Ignore
1618630346
Reply with quote  #2

1618630346
Report to moderator
1618630346
Hero Member
*
Offline Offline

Posts: 1618630346

View Profile Personal Message (Offline)

Ignore
1618630346
Reply with quote  #2

1618630346
Report to moderator
piotr_n
Legendary
*
Offline Offline

Activity: 2043
Merit: 1064


aka tonikt


View Profile WWW
July 15, 2013, 09:27:57 PM
 #2

it does remove unspent outputs as they get spent
it doesn't remove the block data - because then it would not be able to serve blocks to clients that are fresh and need to download the chain.

Check out gocoin - my original project of full bitcoin node & cold wallet written in Go.
PGP fingerprint: AB9E A551 E262 A87A 13BB  9059 1BE7 B545 CDF3 FD0E
mustyoshi
Sr. Member
****
Offline Offline

Activity: 287
Merit: 250



View Profile
July 15, 2013, 09:31:13 PM
 #3

it does remove unspent outputs as they get spent
it doesn't remove the block data - because then it would not be able to serve blocks to clients that are fresh and need to download the chain.
But if transactions have already been embedded in the blockchain, new nodes don't need the data anyways.
piotr_n
Legendary
*
Offline Offline

Activity: 2043
Merit: 1064


aka tonikt


View Profile WWW
July 15, 2013, 09:36:30 PM
 #4

it does remove unspent outputs as they get spent
it doesn't remove the block data - because then it would not be able to serve blocks to clients that are fresh and need to download the chain.
But if transactions have already been embedded in the blockchain, new nodes don't need the data anyways.
Indeed. https://bitcointalk.org/index.php?topic=247110.msg2683001#msg2683001
But you know, they are very busy now with "tackling the low lying fruit" - whatever useless feature it is Smiley

Check out gocoin - my original project of full bitcoin node & cold wallet written in Go.
PGP fingerprint: AB9E A551 E262 A87A 13BB  9059 1BE7 B545 CDF3 FD0E
gmaxwell
Moderator
Legendary
*
qt
Offline Offline

Activity: 3388
Merit: 5084



View Profile
July 16, 2013, 02:09:29 AM
Last edit: July 16, 2013, 02:30:41 AM by gmaxwell
 #5

But if transactions have already been embedded in the blockchain, new nodes don't need the data anyways.
They do, in fact. Otherwise miners could just "embed" in the blockchain a bunch of transactions stealing people's coin or creating additional coin out of thin air and your node would happily accept it.  Part of the check and balance of Bitcoin is the ability of miners to cheat is reduced to very narrow cases, making it unprofitable for them to do so.

Bitcoin is based on the concept of autonomous validation— The Bitcoin algorithm is zero trust as much as is possible. It would be great if the whole thing could be completely autonomous, but there appears to be no way to autonomously achieve consensus ordering, so Bitcoin uses a  vote of scarce resource for just to determine ordering. But this requires actually checking the historical data, not just trusting it blindly.  There could be a lot of flexibility in how nodes go about doing this— no need to delay the initial usage for it, for example, but it's not a pointless activity.

piotr_n, Its really frightening to see someone claiming to write Bitcoin software for other people to use who doesn't understand this, and proposing changes which would reduce the security model with some implication that they weren't a trade-off and weren't being done simply because someone was lazy or stupid.  I'll take comfort in the view that you're probably making these claims not because you believe them but because they serve to further your inexplicable insulting conduct.

An additional point of correction, which is obvious to anyone who is familiar with the development of the reference software but which might not be known to readers of the thread:  Bitcoin 0.8 featured a complete rewrite of the entire storage engine used it Bitcoin which was the necessary first step to implementing pruning.  In addition to the massive short term performance improvements this risky and laborious rewrite also achieved the complete decoupling of the historical data and the data needed for validation... prior to 0.7 Bitcoin needed random access to the blocks even during normal operation, which would have made pruning pretty difficult to implement.  Right now all thats required is solving the P2P issues related to announcing and discovering historical blocks in a network where not every full node has them.  Mistakes made in database structure changes or mistakes made in the p2p changes could all cause network wide failures, loss of funds, etc. So these actions must be undertaken carefully.

piotr_n
Legendary
*
Offline Offline

Activity: 2043
Merit: 1064


aka tonikt


View Profile WWW
July 16, 2013, 08:38:19 AM
Last edit: July 16, 2013, 09:00:21 AM by piotr_n
 #6

piotr_n, Its really frightening to see someone claiming to write Bitcoin software for other people to use who doesn't understand this, and proposing changes which would reduce the security model with some implication that they weren't a trade-off and weren't being done simply because someone was lazy or stupid.  I'll take comfort in the view that you're probably making these claims not because you believe them but because they serve to further your inexplicable insulting conduct.
Excuse me?
What I don't understand about writing bitcoin software, that you do?
You have this patronizing attitude all the time, but I don't think you are smarter than me, so I am not going to bend before you, just because you are here longer.
If I have an idea, I am always open for a criticism - as long as it is technical and specific (not like in your quote above).

Are you saying that I don't understand how the concept of checkpoints reduces bitcoin's security model?
Oh, trust me that I do. But I am not the one who invented them and put them into the code, in the first place - I am not the one who broke the security model already.
I am only a one who proposed getting a further advantage of checkpoints, in order to implement an ultimate purging solutions.

Maybe you just don't understand something here?
Maybe you don't understand that if the only way for a bitcoin software to work is by validating a chain up to a checkpoint that is fixed inside the very same code that validates the chain - then validating the chain up to that point is just a big waste of time, bandwidth, CPU and storage.

Check out gocoin - my original project of full bitcoin node & cold wallet written in Go.
PGP fingerprint: AB9E A551 E262 A87A 13BB  9059 1BE7 B545 CDF3 FD0E
Mike Hearn
Legendary
*
expert
Offline Offline

Activity: 1526
Merit: 1013


View Profile
July 16, 2013, 09:10:06 AM
 #7

Checkpoints are optional. If you don't want to trust them or suspect they might be wrong in some way, delete them and the code will still work in a zero trust manner.

However if old data gets thrown away completely and all you have is a checkpoint, then they aren't optional any more. That's the key difference.
piotr_n
Legendary
*
Offline Offline

Activity: 2043
Merit: 1064


aka tonikt


View Profile WWW
July 16, 2013, 09:16:06 AM
 #8

Coming from this angle, when you want to start disabling things in the source code, then everything becomes optional. Smiley

But seriously, I'm not criticizing checkpoints here.
Checkpoints are needed - for the very reasons that they were put in, in the first place.
I mean, they should probably be replaced with some other mechanism, something that would not be a value fixed in a source code, something which does not require upgrading the client in order to move a checkpoint, but eventually we still need the protection that they add - no argument here.

Check out gocoin - my original project of full bitcoin node & cold wallet written in Go.
PGP fingerprint: AB9E A551 E262 A87A 13BB  9059 1BE7 B545 CDF3 FD0E
Mike Hearn
Legendary
*
expert
Offline Offline

Activity: 1526
Merit: 1013


View Profile
July 16, 2013, 10:04:56 AM
 #9

Well, I'm not sure they're needed exactly. They're an additional safety measure on the grounds that defence in depth is a good idea. But Bitcoin would still work fine without them.
TierNolan
Legendary
*
Offline Offline

Activity: 1232
Merit: 1006


View Profile
July 16, 2013, 10:05:19 AM
 #10

Mistakes made in database structure changes or mistakes made in the p2p changes could all cause network wide failures, loss of funds, etc. So these actions must be undertaken carefully.

Actually that is a potential side/sub-project.

What about creating a new node type "block-server".  These nodes maintain historical data only.

You can ask them for blocks (and the block header chain), but not for transactions.

These nodes would download all new blocks and verify the headers and POW.  They wouldn't even have to check any of the internal data.  Any block that is part of the chain up to the most recent checkpoint is stored and any block (including orphans) that can be traced back to the checkpoint would be stored as long as they meet the POW requirements.  By keeping the checkpoint reasonably recent, overloading these servers is harder.

Writing a node like that from the ground up wouldn't be that difficult.

Once there was a reasonable number of those nodes on the network, then block pruning would be much less potentially disastrous.  Even if there is a bug and it causes a "prune" of historical data for the entire network, there would still be some nodes with everything.

1LxbG5cKXzTwZg9mjL3gaRE835uNQEteWF
piotr_n
Legendary
*
Offline Offline

Activity: 2043
Merit: 1064


aka tonikt


View Profile WWW
July 16, 2013, 10:17:00 AM
Last edit: July 16, 2013, 10:46:15 AM by piotr_n
 #11

Well, I'm not sure they're needed exactly. They're an additional safety measure on the grounds that defence in depth is a good idea. But Bitcoin would still work fine without them.
Bitcoin would work, but the node's storage could easily get stuffed with bogus blocks that hook very early in the chain, thus are extremely cheap to be created.
And it's almost guaranteed that as soon as you'd switch them off, such attacks would appear.

Moreover, since we're talking about block purging.
Block purging implies that there must be some kind of judgement whether an orphaned block buried deep inside a chain is already old enough to purge it - you cannot have any purging without some sort of checkpoints that would tell you how old an orphan needs to be, to be considered too old.

Check out gocoin - my original project of full bitcoin node & cold wallet written in Go.
PGP fingerprint: AB9E A551 E262 A87A 13BB  9059 1BE7 B545 CDF3 FD0E
TierNolan
Legendary
*
Offline Offline

Activity: 1232
Merit: 1006


View Profile
July 16, 2013, 10:53:32 AM
 #12

Bitcoin would work, but the node's storage could easily get stuffed with bogus blocks that hook very early in the chain, thus are extremely cheap to be created.
And it's almost guaranteed you that as soon as you'd switch them off, such attacks would appear.

Without checkpoints, it could still be reasonably safe.

The process is
- download headers first to get estimate of the longest chain
- only store forks that fork within 5k of the longest chain
- total storage limit of 1MB * (current time - genesis time) / 2.5 mins

Block deletion could happen but have a timeout of say 60 days.  If a block was stored more than 60 days ago and has not been part of the main chain at any point in that time, it can be deleted.

However, it is unlikely to be actually needed.

1LxbG5cKXzTwZg9mjL3gaRE835uNQEteWF
piotr_n
Legendary
*
Offline Offline

Activity: 2043
Merit: 1064


aka tonikt


View Profile WWW
July 16, 2013, 11:01:27 AM
 #13

The process is
- download headers first to get estimate of the longest chain
- only store forks that fork within 5k of the longest chain
- total storage limit of 1MB * (current time - genesis time) / 2.5 mins
But this is just a different way of doing checkpoints - moving one (current height minus 5K blocks), instead of values fixed in the code.
You basically define a rule that your node does not accept any fork older than 5k blocks.
Which is of course a much better solution than the current checkpoints scheme.

Check out gocoin - my original project of full bitcoin node & cold wallet written in Go.
PGP fingerprint: AB9E A551 E262 A87A 13BB  9059 1BE7 B545 CDF3 FD0E
TierNolan
Legendary
*
Offline Offline

Activity: 1232
Merit: 1006


View Profile
July 16, 2013, 11:43:43 AM
 #14

But this is just a different way of doing checkpoints - moving one (current height minus 5K blocks), instead of values fixed in the code.

No, it isn't a checkpoint.  It is a filter to decide if you should store a block.  The idea is to prevent storing forks that are unlikely to be part of a valid chain.

If I have stored blocks 0 to 50k of a chain and then I find another chain that is 100k blocks long.  If I have checkpointed at 45k on the first chain, then I can't recover.

However, with a filter, I would immediately be able to store all the blocks on the new chain.

The disk space rule might actually kick in though.

However, the quota increases by 1MB every 2.5 mins.  This means that once I find the main chain (and stay locked to it), it will generate 1MB every 10 mins and but the quota will increase by 4 MB in that time, so the "window" will open.

It does raise the question of how to find the longest chain in a hostile environment.

1LxbG5cKXzTwZg9mjL3gaRE835uNQEteWF
gmaxwell
Moderator
Legendary
*
qt
Offline Offline

Activity: 3388
Merit: 5084



View Profile
July 17, 2013, 07:01:28 AM
Last edit: July 17, 2013, 07:22:43 AM by gmaxwell
 #15

What I don't understand about writing bitcoin software, that you do?
You have this patronizing attitude all the time,
I suggest you review this thread before you continue to complain about patronizing.

When someone says "new nodes don't need the data anyways." and you respond "Indeed.", it's a little hard to not get the impression that you actually might have no clue what the Bitcoin security model is,  even when you do follow it up by, "But you know, they are very busy now with "tackling the low lying fruit" - whatever useless feature it is"— suggesting that you're just agreeing with a confused complaint and trivializing the actual nuance and complexity of the issue for the sake accusing people actually doing work on the reference client of working on useless things.

One of these explanations has lower entropy than the other, I suppose. But the trolls in the mining subforum seem to have dulled my Occam's razor.  Feel free to provide your own alternative psychoanalysis. In the meantime, I'm stuck providing the detailed technical discussion that you declined to provide, whatever your reasons.

Quote
Are you saying that I don't understand how the concept of checkpoints reduces bitcoin's security model?
You were suggesting that historic data would be made unavailable and non-validated. That isn't what checkpoints do.

Quote
Maybe you don't understand that if the only way for a bitcoin software to work is by validating a chain up to a checkpoint that is fixed inside the very same code that validates the chain - then validating the chain up to that point is just a big waste of time, bandwidth, CPU and storage.
That simply isn't correct.  If the history is validated then it cannot be forged and replaced with a false history which invents additional coins out of thin air.  Without validation any of this cheating is undetectable.  People often make crazy claims like "Satoshi embedded a billion of his own bitcoin into the system!", it's excellent that we can point out that every copy of the software verifies that this isn't so, and that any user with the source can audit it to confirm that it does. The fidelity of Bitcoin's lifetime conformance to the understood rules is check-able trivially by anyone (or by their designees). Checkpoints don't harm this, but checkpoints without the possibility of validation would destroy it.

[And here I'm writing for the sake of people who randomly find this thread in searches, I don't expect you to learn anything here you don't know:]

Checkpoints serve three main purposes:

(1)  Prevents DOS attacks against node synchronization.  Under the original synchronization behavior an attacker can send a node hundreds of gigabytes of difficulty 1 blocks (which thanks to FPGAs and asics can be very cheaply produced).  This difficulty 1 chain might— once synced far enough in _theory_ eventually have more sum diff than the real chain, so a checkpointless node can be forced to evaluate it.  Checkpoints kill this attack dead, though they aren't the only way to kill it, they're a simple and reliable one.

(2) Prevents isolation attacks against newly started nodes.  People most often talk about the Bitcoin security assumption being that most-hashpower-is-honest, but equally important is that "information is hard to stifle" assumption: Bitcoin is not secure if a network attacker can isolate you from the honest network.  A newly started node might instead be intercepted by a local network attacker which feeds it a low difficulty fantasy hashchain and tricks it into accepting payments on this alternative network, even though the attacker only has a single small GPU miner with about 0.0000001% of the network hashrate.  Checkpoints mean that a user which was reliably able to obtain the software (E.g. via another network or PKI/WOT authenticated signatures) will not be tricked by an attacker which has not put in an enormous amount of energy creating a simulated network.

(3) Simplifies discussions about the risk of mass-chain-rewrites.  Many new users in the past fixated on the risk of 'doomsday rewrites' of the chain. There is no particular reason to be concerned about these: Under any situation where these are possible the system is otherwise doomed but people do anyways, and understanding why this not a likely attack requires sitting down and multiplying out the costs. With checkpoints this concern is thoroughly moot. In particular, a new argument against doomsday rewrites arises: any would-be rewriter takes a risk that a checkpoint is adopted while he is in the process of preparing his rewrite in secret and losing all his work.  The compromise, of course, is that it creates a risk of consensus failure if ever a checkpoint is ambiguously set. But the introduction of checkpoints is transparent and they are never set close to current time or controversially, so no practical parties are worried about this.

Quote
when you want to start disabling things in the source code

If you do not like checkpoints, the reference software has a supported and advertised option to disable them -checkpoints=0, you don't need to modify the source or delete them or anything.  I, and a number of other folks run supervised nodes in this state, and it works fine— though do check to make sure you're not isolated. Smiley

Quote
Checkpoints are needed - for the very reasons that they were put in, in the first place.
They really aren't. We have a number of other alternatives.

I'd personally like to remove the checkpoints: Difficulty checkpointing and headers-first synchronization are superior replacements, though they are slightly more complicated to implement.  They are superior because they provide protection even far away from the checkpoints and when they are not been recently updated. Eliminating the rigid checkpoints also would allow for some better performance optimizations.

The loss of (3) would be unfortunate but in recent times the community of users is seems to be less worried about rewrites and the benefit would be the elimination of researchers who see 'checkpoints' and come to a totally erroneous conclusion about the security model.

It does raise the question of how to find the longest chain in a hostile environment.
Sync headers first, this is only 80 bytes of data per header. Set a minimum difficulty of 100k past the first point where that was achieved (which can easily be maintained by a dozen ASICs now, so there should be no prospect of a viable Bitcoin falling below that ever again) to eliminate cheap header flooding. Add a minimum sum difficulty hint to prevent isolation from being anything but a DOS unless it is also a high hashpower attack.  Even better robusness to header spamming could come from reverse header syncing but it really wouldn't be important.



piotr_n
Legendary
*
Offline Offline

Activity: 2043
Merit: 1064


aka tonikt


View Profile WWW
July 17, 2013, 08:24:49 AM
Last edit: July 17, 2013, 10:17:49 AM by piotr_n
 #16

Quote
Are you saying that I don't understand how the concept of checkpoints reduces bitcoin's security model?
You were suggesting that historic data would be made unavailable and non-validated. That isn't what checkpoints do.

Not quite.
First of all, "what checkpoints do", among all the bullshit that you've lectured us about, is making sure that a node will have an exact content of UTXO db, at a specific block height.
Second, all I suggested was extending a protocol with a possibility to automatically mine into block a hash that points to moving snapshots of UTXO db. I call such a hash a "checkpoint", but feel free to call it however you like.
There is no better chain compression (and bootstrapping time improvement) than this.

In my concept, it would be totally up to a user whether he wants to get a valid UTXOs by doing it the old fashion way (starting from the genesis block and verifying through all the 250k blocks), or if he prefers to enter a hash of a block that he knows is trusted and, using the reference mined into that block, to fetch the entire content of UTXO within a few minutes.

Your great achievement, so much advanced SPV clients that nobody wants to use, isn't anyhow more secured than the solution I proposed would have been.
The only difference is that the later would at least be useful - very useful, since we see all the time people complaining about bootstrapping times and blockchain size (aka pruning).


Quote
Maybe you don't understand that if the only way for a bitcoin software to work is by validating a chain up to a checkpoint that is fixed inside the very same code that validates the chain - then validating the chain up to that point is just a big waste of time, bandwidth, CPU and storage.
That simply isn't correct.  If the history is validated then it cannot be forged and replaced with a false history which invents additional coins out of thin air.
False history that ends up at the exactly same hash? Hmmm.. Do you even have an idea what a 256 bit number is?

Stop dreaming and get real. It would be easier to brute force the private keys, since there is much more of them, rather than to find a matching tx history leading to the same hash and tricking the entire network into distributing this copy, instead of the original one.

If you think 256-bit hash is not secured enough, I have no problems with you making it 512 bits, but bear in mind that if anyone manages to reverse SHA256^2 then you can as start looking for another job, because the entire bitcoin is totally broken then  - no matter compressed, or not.

Check out gocoin - my original project of full bitcoin node & cold wallet written in Go.
PGP fingerprint: AB9E A551 E262 A87A 13BB  9059 1BE7 B545 CDF3 FD0E
d'aniel
Sr. Member
****
Offline Offline

Activity: 461
Merit: 250


View Profile
July 17, 2013, 08:48:15 AM
 #17

We've got a rabid one here.
TierNolan
Legendary
*
Offline Offline

Activity: 1232
Merit: 1006


View Profile
July 17, 2013, 08:52:09 AM
 #18

You were suggesting that historic data would be made unavailable and non-validated. That isn't what checkpoints do.

Isn't that what happens with the main client at the moment?  Script is not verified until the client passes the last checkpoint?

Quote
(1)  Prevents DOS attacks against node synchronization.  Under the original synchronization behavior an attacker can send a node hundreds of gigabytes of difficulty 1 blocks (which thanks to FPGAs and asics can be very cheaply produced).  This difficulty 1 chain might— once synced far enough in _theory_ eventually have more sum diff than the real chain, so a checkpointless node can be forced to evaluate it.  Checkpoints kill this attack dead, though they aren't the only way to kill it, they're a simple and reliable one.

That is a 51% attack.  POW builds directly with hashing power.  Building a 1 difficulty chain with more POW than the main chain is just as hard as building a shorter chain that has more POW.

Quote
(2) Prevents isolation attacks against newly started nodes.

This could also be achieved by setting a lower bound on the total POW rather than adding a checkpoint.

I wrote in another thread about a change to the getheaders message.  It would add a step field, so that a node could ask for every 20000th block header.  This allows much faster detecting of dishonest nodes.

Quote
(3) Simplifies discussions about the risk of mass-chain-rewrites.  

It certainly does that.  There is a risk that a disagreement could cause a fork.

If/when there are more clients, then they should either make sure that they only ever add checkpoints after they have been agreed (either by adding to the reference client or some other consensus system).

Maybe there could be an "advisory" BIP on the topic.


Quote
I'd personally like to remove the checkpoints: Difficulty checkpointing and headers-first synchronization are superior replacements, though they are slightly more complicated to implement.  They are superior because they provide protection even far away from the checkpoints and when they are not been recently updated. Eliminating the rigid checkpoints also would allow for some better performance optimizations.

It seems that rigid checkpointing gives a performance boost as you can skip script checking.

Quote
Sync headers first, this is only 80 bytes of data per header.

As I said in the other thread, this can be improved by allowing a header step.

Ask for every 20160th block header.

Pick one at random and ask for 10 headers in steps of 2016 starting from there.  In face, maybe a count field could also be added.

Repeat with steps of 201 and 20, and 1.

That is very little data.  However, it allows the node to estimate the difficulty of the chain and also detect hostile nodes that lie about their chain.

Quote
Even better robusness to header spamming could come from reverse header syncing but it really wouldn't be important.

That works too.  However, I think my suggestion eliminates the spam problem.  Effectively, the other node sends a claim and then your node replies with a challenge.

Also, by having fixed steps from the start, all nodes will agree.  You aren't asking one node for 245000 and another for 245001.  This allows partitioning of the nodes into sets which agree with each.

1LxbG5cKXzTwZg9mjL3gaRE835uNQEteWF
jgarzik
Legendary
*
qt
Offline Offline

Activity: 1596
Merit: 1012


View Profile
July 17, 2013, 08:58:06 AM
 #19

What about creating a new node type "block-server".  These nodes maintain historical data only.

That is an existing proposal known as "archive node."


Jeff Garzik, Bloq CEO, former bitcoin core dev team; opinions are my own.
Visit bloq.com / metronome.io
Donations / tip jar: 1BrufViLKnSWtuWGkryPsKsxonV2NQ7Tcj
Peter Todd
Legendary
*
expert
Offline Offline

Activity: 1106
Merit: 1052


View Profile
July 17, 2013, 11:54:43 AM
 #20

We've got a rabid one here.

Sorry about that - piotr_n is a bot I wrote to get all the good material out of gmaxwell's brain to plagiarize for my upcoming book on crypto-coin theory, "Proof of Work Consensus" (yes I see the irony of the title)

I'll see if I can tweak the settings a bit.

Pages: [1] 2 »  All
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!