Secure SPV / light node wallet support proposal

This is a question we want the community to vote on, to help us decide which direction to go with a new feature we have planned. I will first outline the feature, hopefully without going into too much technical detail, and then outline the two choices we are considering for technical implementation, with some of the consequences for each. If you have further questions about any technical details, please feel free to reach out to Moonshot or Julian on Discord.

SPV stands for “simple payment verification”, which is a form of light node cryptocurrency wallet that does not load the entire blockchain. This is common for mobile applications, and in the long term is likely to be what most people use for Phore, because the Phore blockchain grows indefinitely, and requires significant data storage, processing, and bandwidth to stay synchronized with a complete, accurate copy of the complete history of the Phore blockchain. Bitcoin is already at this point–I believe the majority of people with bitcoin wallets are not running full bitcoin nodes–SPV wallets are much more common.

SPV wallets bring with them a certain requirement for trust–they rely on full nodes to provide blockchain information. At a high level, what they do is describe the cryptocurrency addresses they control (in somewhat vague terms to preserve privacy), and the full nodes tell the SPV wallet which transactions have occurred for those addresses, so that the SPV wallet can calculate their balance properly. The SPV wallet is trusting that the full node is giving them accurate information.

We are working on a feature that will reduce the level of trust needed for Phore to securely support SPV light node wallets. Each Phore block would store a list (in a merkle tree, for the more technically inclined) of the Phore addresses that are staking / eligible to stake, so that when a full node provides a block to an SPV wallet, the SPV wallet can compare what they receive to their own representation and better verify its accuracy. This will make it harder for a malicious actor to provide false information to a SPV light node wallet.

This brings us to to choices that have tradeoffs. Here is a brief description of each option, with some of the tradeoffs that come with each:

StakingOpcode

Opcodes are the “programming” part of a cryptocurrency transaction that define what is needed to lock and unlock the coins in that transaction, and in a typical simple transaction it contains the address it was sent to, which the recipient has to show ownership of in order to spend. Phore supports many different opcodes and will likely be adding support for more over time on the Phore main blockchain.

One option we have for this SPV wallet solution is to add a new staking opcode (think of it as a staking tag) to the transaction for each amount of Phore that is eligible for staking. This will allow the list we store in each block to be based on which transactions contain the special opcode. Some transactions, notably masternode collateral transactions, would not have this opcode and would not be eligible for staking.

On the plus side, this allows users to continue to stake any amount of Phore, as long as the staking opcode is added to the transaction. The staking process might change somewhat, in that you may need to designate which Phore you do and don’t want to stake with, and send transaction(s) to yourself with that Phore to add the opcode as part of the transition.

We would likely make the wallets add this opcode by default for any transactions so it would be mostly invisible to users, but this also means we probably need to add some complexity to the interface to choose staking and non-staking transactions. For example, masternode collateral transactions should not have the opcode, since they are not eligible for staking, so we would need a checkbox or some other way to designate transactions that should not have it. It could also potentially create some additional complexity for exchanges and other third parties that use our wallets in more complex ways than a normal user does, as they may need to deal with staking transactions differently.

One other downside is that this would make the average transaction size slightly larger to add the staking opcode to a significant percentage of Phore transactions.

100_PHR_Min

Another option we are considering is to not require the opcode, but instead to set a 100 Phore minimum for staking. This will help accomplish the same objective, by limiting the list of staking eligible inputs enough that we can store the list in each block header without taking up too much space.

This option is somewhat less complicated for users, since the wallet can calculate all the inputs that are 100 PHR or more and use that to create the list. No checkbox would be needed for designating which inputs should be able to stake.

One of the main side effects or downside (depending on your point of view) is that any inputs that are less than 100 PHR would not be able to stake. This would include masternode rewards and staking rewards as well, since they are less than 100 PHR. A few considerations for this:

  1. Balances less than 100 PHR are not likely to get staking rewards very often anyway. If I assume that 30% of Phore is staking on average, then a masternode reward of 4.2 PHR would get a staking reward about once every 2 years, and a staking reward even less than that. A balance of 99.9 PHR, just under the proposed cutoff, would otherwise get a staking reward about once a month.
  2. We could add a feature to the wallet to allow you to automatically combine smaller balances into 100 PHR or larger inputs, or to automatically combine smaller change balances with other larger inputs to keep most/all of your PHR staking. We would make this optional in some way though, because there are privacy implications to doing this–when you combine inputs from different addresses, you are revealing that those addresses are probably controlled by the same wallet, so without additional steps taken to prevent this, combining them would be somewhat less private than leaving them separated.

We could also add a feature to combine inputs into 100+ PHR chunks, but not to combine inputs from different addresses, which would mean for example when a masternode owner received enough masternode rewards to have 100+ PHR on that address, the wallet could combine just those together while maintaining the separation between different addresses.

======

The team feels that the 2nd option of setting a 100 PHR minimum for staking is preferable, mainly because it is the simpler solution with the least complexity and confusion for users, so that is the one we recommend. However, we highly value the community’s input, and we are happy to choose the other option if the community prefers it, or to not implement this change if the community doesn’t like either one.

For the 100 PHR minimum change, we feel it will be simple to explain that

  • We have a 100 PHR minimum for staking
  • Any balances less than that would not be receiving staking rewards very often anyway
  • Our staking guide could be modified to instruct people to send themselves a transaction to combine any smaller inputs into a larger transaction of at least 100 PHR to make it stake
  • Either initially or as we mature the feature, we can look to automate much of this so that inputs are combined into 100+ PHR inputs without the user needing to take much or any action.

TL;DR

The team has added to proposals to the system as options for supporting secure proof of stake SPV wallets, which we consider to be an important feature for the future, and one that has not been implemented before. We recommend the 100 PHR minimum staking option as the simplest and best option for implementing this, but want the community to ultimately decide which option to implement, or if we should do neither and keep staking the way it is now.

Please vote as follows based on your preference:

100_PHR_Min: Vote yes for this proposal if you prefer the 100 Phore Staking Minimum option described above.
StakingOpcode: Vote yes for this proposal if you prefer the staking opcode option described above.

If you prefer to keep staking the way it is and not implement the secure proof of stake SPV wallet feature, vote no to both of the above proposals.

We will implement whichever proposal passes, which requires at least 10% of the masternode owners to vote yes, after subtracting any no votes, and after that it ranks the proposals by yes/no voting ratio. We have allocated all of the remaining budget to these proposals after assuming the other two budget proposals pass, so it is likely that only the higher ranking of these two proposals will pass. If neither vote passes, we will not implement either option.

I’d also like to point out that the 100 PHR minimum is much more straightforward and easy to implement. This means quicker turnaround once we decide and a smaller likelihood of bugs.

The maximum size of the “proof-of-stake” in the block header is 32 * log2(SUPPLY / 100) or 544 bytes (O(log N)). The complexity of calculating a tree (which should happen every-ish block) is O(n) or a max of 380000 hashes per block. This works out to an ABSOLUTE max of 0.2 seconds on an Intel m3 CPU. Realistically, the current UTXO count is approximately 10000, so this would require 20k hashes per block, which is next to nothing (~1-10 ms per block on a shitty CPU).

Note: most of block verifying time is spent validating ECDSA signatures, not calculating hashes.