Zagg multi node sync (for bitcoin blocks) won’t work since we were not making level dbs sync to each other.
- Setup 2 node zagg network using stellar’s configurations
- Throw transaction with Account Marker operation (for bitcoin transaction HEX) over one of the node.
- The operation has to go through validation from Bitcoin code base using
doValidate()
of the operation. - After getting all the operations validated, the transaction goes into mPendingTransaction (which is nothing but memepool for stellar.)
- After that value is nominated and SCP happens.
- In the extenalize phase of SCP, the
doApply()
gets called and block formation happens and stored into leveldb.
Now in case of multi node setup, this wont work since in each phase of SCP the doValidate() method gets called and we know that we SCP can start at any node not necessarily the node where transaction was thrown.
One solution to this problem we can think of is creating an operation for mining the block. In that case the operation will go through the SCP and every node will create those block.
We can make use of --newdb option for creating the blocks (or mining). Now the up side of this is it is easier to implement than the solution1.
**One of the major concerns in both of these solutions is, when you create x blocks on both these nodes, will those blocks will be exactly the same or they will be different ? **
I dug into it and found that if you run the
generatetoaddress
RPC command with same miner’s address (you can set it in config for both these nodes) then the blocks are exactly the same. -- This one have to retest
The other concern we had was, what exactly happens during catch up in stellar? Do they just copy files (from the archival node) or also apply these transaction ?
I debugged the catch up, and found that they not only download the files from the history archives of the other node but also apply these transaction (i.e it closes the ledger), which means that
doApply()
of operations are also going to get called in catch up.
So I am implementing the 2nd solution and will test it. For this I have added two more keys BITCOIN_MINER_ADDRESS
and BITCOIN_MINER_BLOCKS
apart from eariler added keys (for implementing a new option called --bitcoind with stellar-core command for running the bitcoin along with zagg) BITCOIN_DATADIR
and BITCOIN_REGTEST
in the stellar-core.cfg file.
## Bitcoin related configs
# To run bitcoin in regtest mode. default is true
BITCOIN_REGTEST=true
# Specify the datadirectory for bitcoin. default is /home/$user/.bitcoin
BITCOIN_DATADIR="/home/vishswasb/zagg/node01/"
# Miner public key
BITCOIN_MINER_ADDRESS="2Mtznvnp8P6CnDH6BQyjFCbRTpMq2XHzV3D"
# Number of blocks to be generated: this parameter will be used at the time of --newdb
# Default value is 101
BITCOIN_MINER_BLOCKS=101
Now what will happen is, all nodes will be initialized with same blocks and at the time of SCP validation they will not fail. Also in case if any node fell down, then at the time of catch up the ledger will close and form the blocks with operation’s HEX value.
Here and here is the implementation of block formation at the time of --newdb.
- Setup a 2 zagg node network without bitcoind making both these nodes validators each other. Keep it running for sometime.
- Drop the first node
- Re-join the network and see if it is catching up properly
- Now run the 2 node network with --bitcoind option
Test 1
Check after doing --newdb in both these nodes that each of bitcoin folders has same blocks (match with blockhashes for the confirmation)
Test 2
Form a bitcoin transaction and send over one of these node, wait for ledger to close -> see if the block formation is happening in both of the nodes.
Test 3
Pull down one of these node -> Let the other node running and do bitcoin transaction over one of the operation -> bring up the 1st node and see if it catching up -> check the blocksize and formation in the 1st node.
Mistake: The mistake which I was doing is, I assumed that mine
block action will happen at all the nodes. But I was wrong. Only one block will mine (with coinbase) and broadcast the block to the other and the other block will just validate and accept that block.
2 Operations :
- MineBlockOp opeartion
- SheildPaymentOp opeartion (as of now we will use accountMarker for this)
This operation can be used to mine blocks for passed miner account.
struct MineBlockOp
{
string32<32> minerAccount; // account to be mine. this is noting but sender's bitcoin address.
string64<32> block; //INTERNAL:this is hidden for wallet UI and will be filled once the block gets formed during the op. Its string since its going to be HEX-encoded block.
// int64 nBlock; //INTERNAL: number of blocks - we will fix it for 1 as of now
int64 amount; // corresponding utxo amount that needs to be converted
};
block [ coinbase]
In the stellar wallet, user only has to pass minerAccount
value and amount
which he wants to withdraw (convert stellar account amount to utxos) for MineBlockOp
operation. nBlock
is set to 1 by default (as of now). User need not to pass values for block
and nBlock
. These are the internal fields and used by stellar-core.
- the code validates the
minerAccount
value (if it is proper bitcoin address?) - forms the
block
(callscreateBlock()
in bitcoin code base) - but the block would not be stored into the bitcoin database.
- set
MineBlockOp.block = block
- set
MineBlockOp.nBlock = 1
This method gets called before tx goes into the mempool and during the every phase of SCP.
- validates the
MineBlockOp.block
value
At the time of ledger close:
- doApply() gets called
- store
MineBlockOp.block
into bitcoin database- We can make use of
submitBlock
RPC for this purspose which accepts block HEX as paramter. It validates, stores and broadcast the block to the peers. We can skip the broadcasting part.
- We can make use of
- all nodes will do the same and every nodes's bitcoin db will have same block.
This is basically the Bitcoin transaction operation we will have to use. It accepts bitcoin HEX
.
struct SheildPaymentOp
{
string32<32> hex; // bitcoin transaction hex
string64<32> block; //INTERNAL: this is hidden for wallet UI and will be filled once the block gets formed during the operation. Its string since its going to be HEX-encoded block
};
block [ coinbase (miner = sender, amount = 0),hex ]
Again user have to pass the hex
only not the block
value and will be filled later. Now this new block will be mined for the sender's bitcoin address and amount(or fee) = 0.
- call bitcoin code base to validate
HEX
. - forms the
block
(callscreateBlock()
in bitcoin code base) - but the block would not be stored into the bitcoin database.
- set
SheildPaymentOp.block = block
- validates the
SheildPaymentOp.block
value : this is block HEX - First the block HEX is decoded into block data st. using
DecodeHexBlk
. It returns object of typeCBlock
. - Use
CheckBlock()
for validation of block, which accepts parameter of typeCBlock
.
- store
SheildPaymentOp.block
into bitcoin database - First the block HEX is decoded into block data st. using
DecodeHexBlk
. It returns object of typeCBlock
. - Use
AcceptBlock()
to add block into the db. which accepts paramter of typeCBlock
shared Pointer.
- Send UTXOs to a bogus address
- Or else use OP_RETURN
https://medium.com/@alcio/how-to-destroy-bitcoins-255bb6f2142e
The bigger picture is to do two types of transaction on the Zagg network. Also to perform two funtionalites on the network Withdrwal
and Deposite.
Types Of Account
a) unshielded tx (using account) :Stellar payment
b) shielded tx (using utxo) : First get converted to UTXO -> UTXO goes Zero knowledger -> UTXO gets transfer to the reciepit -> UTxo to Recipent's steallar account
simple payment operation on stellar.
The solution for shielded transaction involves analogy of withdrawing money (utxo) from his stellar account and depositing money (utxo) back to stellar accout after performing the transaction (utxo to utxo). Every person has two types of account (public-private key pairs): a) stellar account b) bitcoin account. Suppose a Person A wants to do the shield transaction of say Aamt=10 to person B.
Person A
: Stellar Account (As): amount_As = 100
: Bitcoin Account (Ab): amount_Ab = 0
Person B
: Stellar Account (Bs): amount_Bs = 0
: Bitcoin Account (Bb): amount_Bb = 0
- Step 1: First person A needs to perform
MineBlockOp
operation in order to withdraw some money (ofAamt
) to his bitcoin account (Ab
) from stellar account (As
).
1. check if Aamt > amount_Ab : he already has sufficient utxos
go to step 2 else go to 5
2. check if Aamt > amount_As
go to throw error else go to 3
3. the miner account = Ab
4. amount = Aamt
5. exit
- Step 2: Now that he has withdrawn some money from his stellar's account, that much of value needs to be deducted from his account. To do that we have to perform a
paymentOp
operation fromAs
toroot account
worth ofAamt
.
Note:
- He can perform both the operations in one transaction.
- He may skip the step 1 since he already has some balance in his bitcoin's address if he wants to.
- You can not persform Step 2 with out having to perform Step 1 in case you do not have sufficient UTXOs. If done the whole tranaction would fail.
- In this operation, basically he is sending money from one of his account(stellar) to another (bitcoin), which is why this called withdrawal
Once person A has sufficient amount of UTXOs , he can send these UTXO to Person B by performing SheildPaymentOp
operation. Here he will have to pass the HEX where sender's address would be bitcoin address of Person A and receiver's address is Bitcoin address of Person B. This transaction is shielded since we will use Zero Knowledge Proof.
- Then he will do
SheildPaymentOp
(bitcoin transaction)- HEX (sender = Ab, receiver = Bb, amount = Aamt)
Once the SheildPaymentOp
operation is performed, person A or person B can deposite his UTXO into their respective stellar's account by burning
utxos.
Bb
will burnAamt
utxo :burnOp
- Ask
root account
to sendAamt
XLM toBs
:paymentOp
- MineBlockOp Operation (Account to UTXO)
- SheildPaymentOp Operation (UTXO to UTXO)
- BurnOp - working on it.
https://docs.google.com/drawings/d/1z0LFOC_UYh8h9aq423wFFl8gD7aASTZGmcMWyCNsWkQ/edit?ts=5cf64ab6
Sri discussion points :
SheildPaymentOp
operation