LearnBitcoin

Bitcoin Dev Archive 2017

Solving the Scalability Problem on Bitcoin

8 messages, 26 to 27 Aug 2017. Started by Adam Tamir Shem-Tov.

Adam Tamir Shem-Tov (2), Thomas Guyot-Sionnest (2), Weiwu Zhang, Btc Ideas, Leandro Coutinho, Matthew Beton

Permalink Original thread on gnusha.org

Adam Tamir Shem-Tov permalink original

<B> Solving the Scalability issue for bitcoin </B> <BR>

I have this idea to solve the scalability problem I wish to make public.

If I am wrong I hope to be corrected, and if I am right we will all gain by it. <BR>

Currently each block is being hashed, and in its contents are the hash of the block preceding it, this goes back to the genesis block.

<BR>

What if we decide, for example, we decide to combine and prune the blockchain in its entirety every 999 blocks to one block (Genesis block not included in count).

<BR>

How would this work?: Once block 1000 has been created, the network would be waiting for a special "pruned block", and until this block was created and verified, block 1001 would not be accepted by any nodes.

This pruned block would prune everything from block 2 to block 1000, leaving only the genesis block. Blocks 2 through 1000, would be calculated, to create a summed up transaction of all transactions which occurred in these 999 blocks.

<BR>

And its hash pointer would be the Genesis block.

This block would now be verified by the full nodes, which if accepted would then be willing to accept a new block (block 1001, not including the pruned block in the count).

<BR>

The new block 1001, would use as its hash pointer the pruned block as its reference. And the count would begin again to the next 1000. The next pruned block would be created, its hash pointer will be referenced to the Genesis Block. And so on..

<BR>

In this way the ledger will always be a maximum of 1000 blocks.

<BR> <B> A bit more detail: </B> <BR> All the outputs needed to verify early transactions will all be in the pruning block. The only information you lose are of the intermediate transactions, not the final ones the community has already accepted.

For example:

<BR>

A = 2.3 BTC, B=0, C=1.4. (Block 1)

<BR>

If A sends 2.3 BTC to B. (Block 2)

<BR>

And then B sends 1.5 to C. (Block 3)

<BR>

The pruning block will report:

<BR>

B = 0.8 and C=2.9. <BR>

The rest of the information you lose, is irrelevant. No one needs to know that A even existed since it is now empty, nor do they need to know how much B and C had previously, only what they have now.

<BR> Note: The Transaction Chain would also need to be rewritten, to delete all intermediate transactions, it will show as though transactions occurred from the Genesis block directly to the pruned block, as though nothing ever existed in between.

<BR>

<BR>

You can keep the old blocks on your drive for 10 more blocks or so, just in case a longer block chain is found, but other than that the information it holds is useless, since it has all been agreed upon. And the pruning block holds all up to date account balances, so cheating is impossible.

<BR>

Granted this pruning block can get extremely large in the future, it will not be the regular size of the other blocks. For example if every account has only 1 satoshi in it, which is the minimum, then the amount of accounts will be at its maximum. Considering a transaction is about 256bytes. That would mean the pruning block would be approximately 500PB, which is 500,000 Terra-bytes. That is a theoretical scenario, which is not likely to occur. (256bytes*23M BTC*100M (satoshis in 1 BTC))

<BR>

A scenario which could be solved by creating a minimum transaction fee of 100 satoshis, which would insure that even in the most unlikely scenario, at worst the pruning block would be 5PB in size.

<BR>

Also, this pruning block does not even need to be downloaded, it could be created by already existing information, each full node by itself, by <BR>

1) combining and pruning all previous blocks <BR>
2) using the genesis block as its hash pointer <BR>

3) using a predefined random number "2", which will be used by all. A random number which is normally added to a block to ensure the block's hashrate difficulty, is not needed in this case, since all information can be verified by each node by itself through pruning. <BR>

4) Any other information which is needed for the SHA256 hash, for example a timestamp could be copied off the last block in the block chain. <BR>

These steps will ensure each full node, will get the exact hash code as the others have gotten for this pruning block.

<BR>

And as I previously stated the next block will use this hash code as its hash reference.

<BR>

By creating a system like this, the pruning block does not have to be created last minute, but gradually over time, every time a new block comes in, and only when the last block arrives (block 1000), will it be finalized, and hashed.

<BR>

And since this block will always be second, it should go by the name "Exodus Block". <BR> Adam Shem-Tov

Thomas Guyot-Sionnest in reply to Adam Tamir Shem-Tov permalink original

Pruning is already implemented in the nodes... Once enabled only unspent inputs and most recent blocks are kept. IIRC there was also a proposal to include UTXO in some blocks for SPV clients to use, but that would be additional to the blockchain data.

Implementing your solution is impossible because there is no way to determine authenticity of the blockchain mid way. The proof that a block hash leads to the genesis block is also a proof of all the work that's been spent on it (the years of hashing). At the very least we'd have to keep all blocks until a hard-coded checkpoint in the code, which also means that as nodes upgrades and prune more blocks older nodes will have difficulty syncing the blockchain.

Finally it's not just the addresses and balance you need to save, but also each unspent output block number, tx position and script that are required for validation on input. That's a lot of data that you're suggesting to save every 1000 blocks (and why 1000?), and as said earlier it doesn't even guarantee you can drop older blocks. I'm not even going into the details of making it work (hard fork, large block sync/verification issues, possible attack vectors opened by this...)

What is wrong with the current implementation of node pruning that you are trying to solve?

Adam Tamir Shem-Tov in reply to Thomas Guyot-Sionnest permalink original

Thank you Thomas for your response.

1) Implement solution is impossible... I have given a solution in part II. By adding a Genesis Account which will be the new sender.

2)Keeping older blocks: Yes as I said 10 older blocks should be kept, that should suffice. I am not locked on that number, if you think there is a reason to keep more than that, it is open to debate.

3) Why 1000? To be honest, that number came off the top of my head. These are minor details, the concept must first be accepted, then we can work on the minor details.

4)Finally it's not just the addresses and balance you need to save... I think the Idea of the Genesis Account, solves this issue.

5) The problem with node pruning is that it is not standardized, and for a new node to enter the network and to verify the data, it needs to download all data and prune it by itself. This will drastically lower the information needed by the full nodes by getting rid of the junk. Currently we are around 140GB, that number is getting bigger exponentially, by the number of users and transactions created. It could reach a Terrabyte sooner than expected, we need to act now.

On your second email: When I say account: I mean private-public key. The way bitcoin works, as I understand it, is that the funds are verified by showing that they have an origin, this "origin" needs to provide a signature, otherwise the transaction won't be accepted. If I am proposing to remove all intermediate origins, then the funds become untraceable and hence unverifiable. To fix that, a new transaction needs to replace old ones. A simplified version: If there was a transaction chain A->B->C->D, and I wish to show only A->D, only a transaction like that never actually occurred, it would be impossible to say that it did without having A's private key, in order to sign this transaction. In order to create this transaction, I need A's private key. And if I wish this to be publicly implemented I need this key to be public, so that any node creating this Exodus Block can sign with it. Hence the Genesis Account. And yes, it is not really an account.

On 27 August 2017 at 00:31, Thomas Guyot-Sionnest <dermoth@aei•ca> wrote:

Quoted text (77 lines)
> Pruning is already implemented in the nodes... Once enabled only unspent
> inputs and most recent blocks are kept. IIRC there was also a proposal to
> include UTXO in some blocks for SPV clients to use, but that would be
> additional to the blockchain data.
>
> Implementing your solution is impossible because there is no way to
> determine authenticity of the blockchain mid way. The proof that a block
> hash leads to the genesis block is also a proof of all the work that's been
> spent on it (the years of hashing). At the very least we'd have to keep all
> blocks until a hard-coded checkpoint in the code, which also means that as
> nodes upgrades and prune more blocks older nodes will have difficulty
> syncing the blockchain.
>
> Finally it's not just the addresses and balance you need to save, but also
> each unspent output block number, tx position and script that are required
> for validation on input. That's a lot of data that you're suggesting to
> save every 1000 blocks (and why 1000?), and as said earlier it doesn't even
> guarantee you can drop older blocks. I'm not even going into the details of
> making it work (hard fork, large block sync/verification issues, possible
> attack vectors opened by this...)
>
> What is wrong with the current implementation of node pruning that you are
> trying to solve?
>
> --
> Thomas
>
> On 26/08/17 03:21 PM, Adam Tamir Shem-Tov via bitcoin-dev wrote:
>
> <B> Solving the Scalability issue for bitcoin </B> <BR>
>
> I have this idea to solve the scalability problem I wish to make public.
>
> If I am wrong I hope to be corrected, and if I am right we will all gain
> by it. <BR>
>
> Currently each block is being hashed, and in its contents are the hash of
> the block preceding it, this goes back to the genesis block.
>
> <BR>
>
> What if we decide, for example, we decide to combine and prune the
> blockchain in its entirety every 999 blocks to one block (Genesis block not
> included in count).
>
> <BR>
>
> How would this work?: Once block 1000 has been created, the network would
> be waiting for a special "pruned block", and until this block was created
> and verified, block 1001 would not be accepted by any nodes.
>
> This pruned block would prune everything from block 2 to block 1000,
> leaving only the genesis block. Blocks 2 through 1000, would be calculated,
> to create a summed up transaction of all transactions which occurred in
> these 999 blocks.
>
> <BR>
>
> And its hash pointer would be the Genesis block.
>
> This block would now be verified by the full nodes, which if accepted
> would then be willing to accept a new block (block 1001, not including the
> pruned block in the count).
>
> <BR>
>
> The new block 1001, would use as its hash pointer the pruned block as its
> reference. And the count would begin again to the next 1000. The next
> pruned block would be created, its hash pointer will be referenced to the
> Genesis Block. And so on..
>
> <BR>
>
> In this way the ledger will always be a maximum of 1000 blocks.
>
>
>
Weiwu Zhang in reply to Adam Tamir Shem-Tov permalink original

On Sat, 26 Aug 2017, Adam Tamir Shem-Tov via bitcoin-dev wrote:

Quoted text (11 lines)
> For example:
>
> A = 2.3 BTC, B=0, C=1.4. (Block 1)
>
> If A sends 2.3 BTC to B. (Block 2)
>
> And then B sends 1.5 to C. (Block 3)
>
> The pruning block will report:
>
> B = 0.8 and C=2.9.

You effecitvely want these two transactions:

A -(2.30)-> B; B -(1.5)-> C;

To be shorten to one transaction:

A -(0.8)-> B -(1.5)-> C;

For that to work a lot of changes has to be done to Bitcoin. For simplicity of the discussion I'll assume all transactions are standard transactions.

First, a block has to refer to the hash of the "balance sheet" (with nonce), not the hash of the previous block. This way, a previous block can be replaced with a smaller one without affecting the hash reference. To add problem to this significant change, Bitcoin uses UTXO table instead of "balance sheet". The difference is that UTXO is indexed by transaction ID while a balance sheet is indexed by owner's public keys. The shortening you suggested wouldn't affect the balance sheet but would totally replace UTXOs for B and C, and probably even A, if A has some changes left.

Second, Alice has to place a new signature on the shortened transaction. The design challenge is how do we motivate A to do so, since A needs to do it after "B->C", at which time Alice's business is done and her wallet offline. Luckily, all bitcoins come from miners. Imagine A gets her money from A', and all the way back, the originating A" must be a miner. We just need to design a different reward mechanism, where miners are not only rewarded by finding blocks, but also by shortening transactions after his expenses. Whatever new reward mechanism it may be, it will interfer with block hash reference discussed in the previous paragraph.

Third, hash references are stablized by work. This is necessary, otherwise a smaller block intended to replace a long one will not be forced to maintain the same balance sheet. However, because work is done on blocks, shortening can only happen within one block. Normally, Bob who receives a transaction in a block, will not spend it to Carol in the same block, because he wants 6 confirmations before being sure, therefore, there will be little opportunity of shortening in one block. You mentioned the idea of shortening between 1000 blocks - that surely give a lot of opportunities to shorten a large directed transaction graph, but you would abandon the proof of work in those 999 blocks in between.

There are three major design issue that needs to be worked out, but almost all unique aspects of Bitcoin will be affected. Just to name a few:

- wallets need to be aware that the UTXO in it may change to some
   other UTXO with the same sum value.
- nLockTime transactions are affected. Such transactions timed for
   near future probably can stay by ruling that shortening can only
   happen after a year; however, those timed for years to come will
   find itself losing UTXO referenes (e.g. a will).
- I assumed all transactions standard, but if they are not, those who can
   redeem them will lose the UTXO references to them after shortening.

I am, like you, risking proposing what is already proposed or explaining what is already explained. The thinking around Bitcoin is a big tome!

Regards Weiwu Z.

Btc Ideas in reply to Thomas Guyot-Sionnest permalink original

I also like only keeping the last "n" blocks. Every "n" minus all the previous balances are kept, but the transactions are deleted. There's good enough record keeping, and there's excessive. Part of scaling is being able to get the blockchain and sync quickly.

Jason

-------- Original Message -------- On Aug 27, 2017, 05:31, Thomas Guyot-Sionnest via bitcoin-dev wrote:

Quoted text (44 lines)
> Pruning is already implemented in the nodes... Once enabled only unspent inputs and most recent blocks are kept. IIRC there was also a proposal to include UTXO in some blocks for SPV clients to use, but that would be additional to the blockchain data.
>
> Implementing your solution is impossible because there is no way to determine authenticity of the blockchain mid way. The proof that a block hash leads to the genesis block is also a proof of all the work that's been spent on it (the years of hashing). At the very least we'd have to keep all blocks until a hard-coded checkpoint in the code, which also means that as nodes upgrades and prune more blocks older nodes will have difficulty syncing the blockchain.
>
> Finally it's not just the addresses and balance you need to save, but also each unspent output block number, tx position and script that are required for validation on input. That's a lot of data that you're suggesting to save every 1000 blocks (and why 1000?), and as said earlier it doesn't even guarantee you can drop older blocks. I'm not even going into the details of making it work (hard fork, large block sync/verification issues, possible attack vectors opened by this...)
>
> What is wrong with the current implementation of node pruning that you are trying to solve?
>
> --
> Thomas
>
> On 26/08/17 03:21 PM, Adam Tamir Shem-Tov via bitcoin-dev wrote:
>
>> <B> Solving the Scalability issue for bitcoin </B> <BR>
>>
>> I have this idea to solve the scalability problem I wish to make public.
>>
>> If I am wrong I hope to be corrected, and if I am right we will all gain by it. <BR>
>>
>> Currently each block is being hashed, and in its contents are the hash of the block preceding it, this goes back to the genesis block.
>>
>> <BR>
>>
>> What if we decide, for example, we decide to combine and prune the blockchain in its entirety every 999 blocks to one block (Genesis block not included in count).
>>
>> <BR>
>>
>> How would this work?: Once block 1000 has been created, the network would be waiting for a special "pruned block", and until this block was created and verified, block 1001 would not be accepted by any nodes.
>>
>> This pruned block would prune everything from block 2 to block 1000, leaving only the genesis block. Blocks 2 through 1000, would be calculated, to create a summed up transaction of all transactions which occurred in these 999 blocks.
>>
>> <BR>
>>
>> And its hash pointer would be the Genesis block.
>>
>> This block would now be verified by the full nodes, which if accepted would then be willing to accept a new block (block 1001, not including the pruned block in the count).
>>
>> <BR>
>>
>> The new block 1001, would use as its hash pointer the pruned block as its reference. And the count would begin again to the next 1000. The next pruned block would be created, its hash pointer will be referenced to the Genesis Block. And so on..
>>
>> <BR>
>>
>> In this way the ledger will always be a maximum of 1000 blocks.
Thomas Guyot-Sionnest in reply to Adam Tamir Shem-Tov permalink original

How do you trust your <1000 block blockchain if you don't download/validate the whole thing? (I know it should be easy to spot that by looking at the blocks/tx or comparing to other nodes, but from a programmatic point of view this is much harder). You can of course include a checkpoint in the code to tell which recent block is valid (which is already done afaik), but you still need all blocks from that checkpoint to validate the chain (not 10!). If you rely on such checkpoint, why not just include the UTXO's as well so you can start mid-way based on code trust?

Indeed pruning doesn't allow you to start mid-way yet but there are much easier solutions to that than what you propose.

Leandro Coutinho in reply to Adam Tamir Shem-Tov permalink original
Quoted text (1 line)
>>> 5) The problem with node pruning is that it is not standardized, and

for a new node to enter the network and to verify the data, it needs to download all data and prune it by itself. This will drastically lower the information needed by the full nodes by getting rid of the junk. Currently we are around 140GB, that number is getting bigger exponentially, by the number of users and transactions created. It could reach a Terrabyte sooner than expected, we need to act now.

To have to download all blockchain for then prune is a big drawback.
So I thought about the concept of "trusted" nodes, where you could choose
some nodes to connect and from which block you want to download. Of course
they would do this by their own risk, but there are ways to minimize the
risk, like:
  - check the latest blocks (hashes) if they match what you find in some
sites, like blockchain.info
  - download and compare the utxo from all (some) the nodes you are
connected

Currently utxo size is around 2GB and we cant know how fast it will grow (?)

Em 26/08/2017 19:39, "Adam Tamir Shem-Tov via bitcoin-dev" < bitcoin-dev@lists•linuxfoundation•org> escreveu:

Thank you Thomas for your response.

1) Implement solution is impossible... I have given a solution in part II. By adding a Genesis Account which will be the new sender.

2)Keeping older blocks: Yes as I said 10 older blocks should be kept, that should suffice. I am not locked on that number, if you think there is a reason to keep more than that, it is open to debate.

3) Why 1000? To be honest, that number came off the top of my head. These are minor details, the concept must first be accepted, then we can work on the minor details.

4)Finally it's not just the addresses and balance you need to save... I think the Idea of the Genesis Account, solves this issue.

5) The problem with node pruning is that it is not standardized, and for a new node to enter the network and to verify the data, it needs to download all data and prune it by itself. This will drastically lower the information needed by the full nodes by getting rid of the junk. Currently we are around 140GB, that number is getting bigger exponentially, by the number of users and transactions created. It could reach a Terrabyte sooner than expected, we need to act now.

On your second email: When I say account: I mean private-public key. The way bitcoin works, as I understand it, is that the funds are verified by showing that they have an origin, this "origin" needs to provide a signature, otherwise the transaction won't be accepted. If I am proposing to remove all intermediate origins, then the funds become untraceable and hence unverifiable. To fix that, a new transaction needs to replace old ones. A simplified version: If there was a transaction chain A->B->C->D, and I wish to show only A->D, only a transaction like that never actually occurred, it would be impossible to say that it did without having A's private key, in order to sign this transaction. In order to create this transaction, I need A's private key. And if I wish this to be publicly implemented I need this key to be public, so that any node creating this Exodus Block can sign with it. Hence the Genesis Account. And yes, it is not really an account.

On 27 August 2017 at 00:31, Thomas Guyot-Sionnest <dermoth@aei•ca> wrote:

Quoted text (77 lines)
> Pruning is already implemented in the nodes... Once enabled only unspent
> inputs and most recent blocks are kept. IIRC there was also a proposal to
> include UTXO in some blocks for SPV clients to use, but that would be
> additional to the blockchain data.
>
> Implementing your solution is impossible because there is no way to
> determine authenticity of the blockchain mid way. The proof that a block
> hash leads to the genesis block is also a proof of all the work that's been
> spent on it (the years of hashing). At the very least we'd have to keep all
> blocks until a hard-coded checkpoint in the code, which also means that as
> nodes upgrades and prune more blocks older nodes will have difficulty
> syncing the blockchain.
>
> Finally it's not just the addresses and balance you need to save, but also
> each unspent output block number, tx position and script that are required
> for validation on input. That's a lot of data that you're suggesting to
> save every 1000 blocks (and why 1000?), and as said earlier it doesn't even
> guarantee you can drop older blocks. I'm not even going into the details of
> making it work (hard fork, large block sync/verification issues, possible
> attack vectors opened by this...)
>
> What is wrong with the current implementation of node pruning that you are
> trying to solve?
>
> --
> Thomas
>
> On 26/08/17 03:21 PM, Adam Tamir Shem-Tov via bitcoin-dev wrote:
>
> <B> Solving the Scalability issue for bitcoin </B> <BR>
>
> I have this idea to solve the scalability problem I wish to make public.
>
> If I am wrong I hope to be corrected, and if I am right we will all gain
> by it. <BR>
>
> Currently each block is being hashed, and in its contents are the hash of
> the block preceding it, this goes back to the genesis block.
>
> <BR>
>
> What if we decide, for example, we decide to combine and prune the
> blockchain in its entirety every 999 blocks to one block (Genesis block not
> included in count).
>
> <BR>
>
> How would this work?: Once block 1000 has been created, the network would
> be waiting for a special "pruned block", and until this block was created
> and verified, block 1001 would not be accepted by any nodes.
>
> This pruned block would prune everything from block 2 to block 1000,
> leaving only the genesis block. Blocks 2 through 1000, would be calculated,
> to create a summed up transaction of all transactions which occurred in
> these 999 blocks.
>
> <BR>
>
> And its hash pointer would be the Genesis block.
>
> This block would now be verified by the full nodes, which if accepted
> would then be willing to accept a new block (block 1001, not including the
> pruned block in the count).
>
> <BR>
>
> The new block 1001, would use as its hash pointer the pruned block as its
> reference. And the count would begin again to the next 1000. The next
> pruned block would be created, its hash pointer will be referenced to the
> Genesis Block. And so on..
>
> <BR>
>
> In this way the ledger will always be a maximum of 1000 blocks.
>
>
>
Matthew Beton in reply to Adam Tamir Shem-Tov permalink original

I think a slight problem with this is that wallets (often ones made by third party wallet software) do not fully empty. I don't know how often this happens, but some wallets, even if you tell them to send all funds, leave a small fraction of bitcoin remaining. If this is the case, it could be detrimental to the 'pruning idea', as wallets with any coins left cannot be pruned. For example:

A has 1 BTC A -> B -> C If these wallets are not removing all the BTC, and a fraction is left over, B will not be able to be pruned out of the chain. On the other hand, of the wallets are completely emptied, the new 'pruned block' will be able to show A sending 1btc to C.

This could be a problem, and so we need a way to persuade people to get their wallets to send everything instead of leaving a small fraction left over. I don't know how problematic this could be, or how frequently this happens, but I'm just putting it out there.