Allow overwriting master key of node
Problem description
Currently it is impossible to overwrite the master key of the node (see example), so if you want to reuse a synced node with another master key (e.g., check a cold wallet and quickly move some WIT), you have to start a node from scratch and synchronize it. That's not a big problem currently, but in the future you don't want to start a new node and synchronize 6 months worth of blocks if you just want to perform one action from a different identity.
./witnet node server --master-key-import master-1.key
...
./witnet node server --master-key-import master-2.key
...
Failed to configure master key: Tried to overwrite node master key with a different one.
Node pkh: wit15j0vp9wwgj3ea9z5s7fjxq3nzyx233cyj24cmh
Imported pkh: wit1k6j82vxznn4nzysmjgr8kk2sqr7x5ye9jsxe69
In order to import a different master key, you first need to export the current master key and delete the storage
Error: Non-zero exit code: 1
Suggested solution
Allow overwriting a master key of a node by introducing an overwrite flag, which will overwrite the current master key from the database with the newly imported:
./witnet node server --master-key-import master-2.key --overwrite
Importing a different master key is not supported because the node will not index old transactions to the new address. For example:
- Send 1 wit to the new address
- Import new master key
-
witnet node balancereturns 0 wits, but the block explorer shows 1 wit - Trying to send a value transfer transaction results in an error
We could fix this by indexing all the blocks after a master key change, but this will not be easy to implement. Maybe it would be enough to iterate over the UTXO set and update the UTXOs from there, but I think that in some places we assume that the node address does never change. Also, we need to make sure that it is very difficult to overwrite a master key that was never exported, to avoid accidentally losing a master key.
If synchronization becomes a problem, we can create exportBlockChain and importBlockChain commands that would allow "copying" blocks from one node to another, or importing a blockchain state that you download from somewhere. This way we could have a similar functionality to the master key override, and you could use this to recover from forks, but this will also be not easy to implement.
We could fix this by indexing all the blocks after a master key change, but this will not be easy to implement. Maybe it would be enough to iterate over the UTXO set and update the UTXOs from there, but I think that in some places we assume that the node address does never change. Also, we need to make sure that it is very difficult to overwrite a master key that was never exported, to avoid accidentally losing a master key.
Yes, I realized this problem too yesterday after hacking out the safeguard for overwriting the master key. 😄
I guess iterating over the UTXO set and checking the UTXO's of the new pkh should be enough. I assume that's how the current balance command works if you are asking for another pkh than your own?
I agree that it should not be easy to overwrite a master key. I would suggest to add a bool field to the database that indicates if the key has been exported. If not, simply refuse to overwrite the key, even when using the --overwrite flag.
If synchronization becomes a problem, we can create exportBlockChain and importBlockChain commands that would allow "copying" blocks from one node to another, or importing a blockchain state that you download from somewhere. This way we could have a similar functionality to the master key override, and you could use this to recover from forks, but this will also be not easy to implement.
That could also be a pretty nice feature allowing for quickly booting up new nodes.