without wanting to spread FUD and I know this comment will generate heat but I was just curious to see on github some of the iguana code: if ( myinfo->IAMNOTARY != 0 && (lastheight % myinfo->NOTARY.NUMRELAYS) == myinfo->NOTARY.RELAYID ) { // if designated relay, submit checkpoint -> add ip/relayid to opreturn // if ( strcmp(coin->symbol,"BTCD") == 0 ) { if ( btc != 0 ) { } } else { } } return(timestamp); that is code in datachain.c, which is mostly for smartchains next year and it is not completed yet, though that function really wont have much more to do. Another possible use is for enabling dPoW for third party chains, but again, that is not completed yet. oh, and it might be more useful to see the entire (not completed yet) datachain.c file: /****************************************************************************** * Copyright © 2014-2016 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * * holder information and the developer policies on copyright and licensing. * * * * Unless otherwise agreed in a custom licensing agreement, no part of the * * SuperNET software, including this file may be copied, modified, propagated * * or distributed except according to the terms contained in the LICENSE file * * * * Removal or modification of this copyright notice is prohibited. * * * ******************************************************************************/
#include "../iguana/iguana777.h" #include "datachain_events.c"
uint32_t datachain_checkpoint(struct supernet_info *myinfo,struct iguana_info *coin,uint32_t lastcheckpoint,uint32_t timestamp,bits256 merkle,int32_t lastheight,bits256 lasthash2) { char str[65],str2[65]; struct iguana_info *btc = iguana_coinfind("BTC"); printf("datachain_checkpoint.%s for %s.%u to %u lastheight.%d %s\n",bits256_str(str,merkle),coin->symbol,lastcheckpoint,timestamp,lastheight,bits256_str(str2,lasthash2)); if ( myinfo->IAMNOTARY != 0 && (lastheight % myinfo->NOTARY.NUMRELAYS) == myinfo->NOTARY.RELAYID ) { // if designated relay, submit checkpoint -> add ip/relayid to opreturn // if ( strcmp(coin->symbol,"BTCD") == 0 ) { if ( btc != 0 ) { } } else { } } return(timestamp); }
int32_t datachain_events_rewind(struct supernet_info *myinfo,int32_t ordered,struct datachain_info *dPoW,int32_t height,uint32_t hdrsi,uint32_t unspentind) { uint64_t hdrsi_unspentind; int32_t i; printf("datachain_events_rewind\n"); if ( dPoW->numevents > 0 ) { datachain_events_sort(dPoW); hdrsi_unspentind = ((uint64_t)hdrsi << 32) | unspentind; for (i=dPoW->numevents-1; i>=0; i--) if ( hdrsi_unspentind > dPoW->events[i]->hdrsi_unspentind ) break; printf("dPoW rewind %d to %d\n",dPoW->numevents,i+1); dPoW->numevents = i+1; } return(dPoW->numevents); }
int32_t datachain_checkpoint_update(struct supernet_info *myinfo,struct iguana_info *coin,uint32_t timestamp) { int32_t i,num,n,lastheight; bits256 *tree,hash2,lasthash2,merkle; struct iguana_block *block; //printf("datachain_checkpoint_update\n"); if ( coin->lastcheckpoint <= coin->blocks.hwmchain.height ) { num = (coin->blocks.hwmchain.height - coin->lastcheckpoint) + 1; tree = (bits256 *)coin->blockspace; if ( num <= IGUANA_MAXPACKETSIZE/(sizeof(bits256) * 2) ) { lastheight = -1; memset(lasthash2.bytes,0,sizeof(lasthash2)); for (i=n=0; i<num; i++) { hash2 = iguana_blockhash(coin,coin->lastcheckpoint + i); if ( bits256_nonz(hash2) != 0 ) { if ( (block= iguana_blockfind("datachain",coin,hash2)) != 0 && block->height == coin->lastcheckpoint + i && block->mainchain != 0 && block->RO.timestamp < timestamp ) { tree[n++] = hash2; lastheight = block->height; lasthash2 = hash2; } else break; } else { printf("got zero blockhash for %s.[%d]\n",coin->symbol,coin->lastcheckpoint + i); break; } } if ( n > 0 && lastheight >= 0 && bits256_nonz(lasthash2) != 0 ) { merkle = iguana_merkle(tree,num); coin->lastcheckpoint = datachain_checkpoint(myinfo,coin,coin->lastcheckpoint,timestamp,merkle,lastheight,lasthash2); } } } return(coin->lastcheckpoint); }
void datachain_BTC_clock(struct supernet_info *myinfo,int32_t ordered,struct iguana_info *btc,int32_t height,uint32_t hdrsi,uint32_t unspentind,uint32_t timestamp) { int32_t retval; struct iguana_info *btcd = iguana_coinfind("BTCD"); //printf("datachain_BTC_clock\n"); if ( (retval= datachain_eventadd(myinfo,ordered,&myinfo->dPoW.BTC,DATACHAIN_ISBTC,0)) < 0 ) { myinfo->dPoW.BTC.numevents = datachain_events_rewind(myinfo,ordered,&myinfo->dPoW.BTC,height,hdrsi,unspentind); } else if ( retval > 0 ) { if ( ordered != 0 && btcd != 0 && btcd->started != 0 && btcd->active != 0 ) { // new BTC block actions, ie gather BTCD hashes for checkpoint btcd->lastcheckpoint = datachain_checkpoint_update(myinfo,btcd,timestamp); printf("NEWBLOCK.%s ht.%d\n",btc->symbol,height); } } }
void datachain_KOMODO_newblock(struct supernet_info *myinfo,int32_t ordered,struct iguana_info *btcd,int32_t height,uint32_t hdrsi,uint32_t unspentind,uint32_t timestamp) { int32_t retval; struct iguana_info *virt,*tmp; //printf("datachain_KOMODO_newblock\n"); if ( (retval= datachain_eventadd(myinfo,ordered,&myinfo->dPoW.BTCD,DATACHAIN_ISKOMODO,0)) < 0 ) { myinfo->dPoW.BTCD.numevents = datachain_events_rewind(myinfo,ordered,&myinfo->dPoW.BTCD,height,hdrsi,unspentind); } else if ( retval > 0 ) { // new BTCD block actions, ie gather all virtual hashes for checkpoint if ( ordered != 0 ) { HASH_ITER(hh,myinfo->allcoins,virt,tmp) { if ( virt->started != 0 && virt->active != 0 && virt->virtualchain != 0 ) virt->lastcheckpoint = datachain_checkpoint_update(myinfo,virt,timestamp); } //printf("NEWBLOCK.%s ht.%d\n",btcd->symbol,height); } } }
void datachain_virt_newblock(struct supernet_info *myinfo,int32_t ordered,struct iguana_info *virt,int32_t height,uint32_t hdrsi,uint32_t unspentind,uint32_t timestamp) { int32_t retval; printf("datachain_virt_newblock\n"); if ( (retval= datachain_eventadd(myinfo,ordered,&virt->dPoW,0,0)) < 0 ) { virt->dPoW.numevents = datachain_events_rewind(myinfo,ordered,&virt->dPoW,height,hdrsi,unspentind); } else if ( retval > 0 ) { // new virt block actions, maybe nothing to do? if ( ordered != 0 ) printf("NEWBLOCK.%s ht.%d\n",virt->symbol,height); } }
int32_t datachain_datascript(struct iguana_info *coin,uint8_t *script,uint8_t *data,int32_t datalen) { int32_t i,pkey0,plen,len = 0; uint8_t p2sh_rmd160[20]; struct vin_info V; memset(&V,0,sizeof(V)); if ( len < 32*3 ) pkey0 = 2, plen = 32; else pkey0 = 4, plen = 64; V.M = V.N = (datalen / plen) + ((datalen % plen) != 0); for (i=0; i<V.N; i++) { V.signers[i].pubkey[0] = pkey0; memcpy(V.signers[i].pubkey+1,&data[len],plen), len += plen; } return(bitcoin_MofNspendscript(p2sh_rmd160,script,0,&V)); }
int32_t datachain_datascript_decode(uint8_t *opreturn,uint8_t *script,int32_t scriptlen,struct vin_info *vp,int32_t type) { int32_t plen,i,oplen=0; //for (i=0; i<scriptlen; i++) // printf("%02x",script[i]); //printf(" <- MofNscript\n"); for (i=0; i<vp->N; i++) { if ( (plen= bitcoin_pubkeylen(vp->signers[i].pubkey)) > 32 ) memcpy(&opreturn[oplen],vp->signers[i].pubkey+1,plen-1), oplen += (plen - 1); } return(oplen); }
int32_t datachain_opreturnscript(struct iguana_info *coin,uint8_t *script,char *datastr,int32_t datalen) { int32_t offset = 0; script[offset++] = 0x6a; if ( datalen >= 0x4c ) { if ( datalen > 0xff ) { script[offset++] = 0x4d; script[offset++] = datalen & 0xff; script[offset++] = (datalen >> 8) & 0xff; } else { script[offset++] = 0x4c; script[offset++] = datalen; } } else script[offset++] = datalen; decode_hex(&script[offset],datalen,datastr); return(datalen + offset); }
int32_t datachain_opreturn_decode(uint8_t *opreturn,uint8_t *script,int32_t scriptlen) { int32_t datalen,len = 1; if ( (datalen= script[len++]) >= 76 ) { if ( datalen == 0x4c ) datalen = script[len++]; else if ( datalen == 0x4d ) { datalen = script[len++]; datalen = (datalen << 8) | script[len++]; } } memcpy(opreturn,&script[len],datalen); if ( len+datalen == scriptlen ) return(datalen); else return(-1); }
void datachain_opreturn(struct supernet_info *myinfo,int32_t ordered,struct iguana_info *coin,uint32_t timestamp,int32_t btc_or_btcd,int64_t crypto777_payment,int64_t burned,int32_t height,uint64_t hdrsi_unspentind,uint8_t *opreturn,int32_t oplen) { uint32_t hdrsi,unspentind; struct datachain_event *event; hdrsi = (uint32_t)(hdrsi_unspentind >> 32); unspentind = (uint32_t)hdrsi_unspentind; //printf("datachain_opreturn\n"); if ( btc_or_btcd == DATACHAIN_ISBTC ) // BTC { if ( opreturn == 0 ) datachain_BTC_clock(myinfo,ordered,coin,height,hdrsi,unspentind,timestamp); else { if ( (event= datachain_event_create(coin,crypto777_payment,burned,height,hdrsi,unspentind,opreturn,oplen)) != 0 ) datachain_eventadd(myinfo,ordered,&myinfo->dPoW.BTC,btc_or_btcd,event); } } else if ( btc_or_btcd == DATACHAIN_ISKOMODO ) // BTCD { if ( opreturn == 0 ) datachain_KOMODO_newblock(myinfo,ordered,coin,height,hdrsi,unspentind,timestamp); else { if ( (event= datachain_event_create(coin,crypto777_payment,burned,height,hdrsi,unspentind,opreturn,oplen)) != 0 ) datachain_eventadd(myinfo,ordered,&myinfo->dPoW.BTCD,btc_or_btcd,event); } } else { if ( opreturn == 0 ) datachain_virt_newblock(myinfo,ordered,coin,height,hdrsi,unspentind,timestamp); else { if ( (event= datachain_event_create(coin,crypto777_payment,burned,height,hdrsi,unspentind,opreturn,oplen)) != 0 ) datachain_eventadd(myinfo,ordered,&coin->dPoW,btc_or_btcd,event); } } if ( opreturn != 0 ) { int32_t i; for (i=0; i<oplen; i++) printf("%02x",opreturn[i]); printf(" <- opreturn.%s len.%d ht.%d [%d] u.%u 777 %.8f burn %.8f\n",coin->symbol,oplen,height,hdrsi,unspentind,dstr(crypto777_payment),dstr(burned)); } }
int32_t iguana_opreturn(struct supernet_info *myinfo,int32_t ordered,struct iguana_info *coin,uint32_t timestamp,struct iguana_bundle *bp,int64_t crypto777_payment,int32_t height,uint64_t hdrsi_unspentind,int64_t burned,uint32_t fileid,uint64_t scriptpos,uint32_t scriptlen) { uint8_t type,scriptspace[IGUANA_MAXSCRIPTSIZE],opreturn[8192]; char fname[1024]; uint32_t oplen=0; int32_t btc_or_btcd=0,len = -1; struct vin_info V; //printf("iguana_opreturn\n"); if ( strcmp("BTC",coin->symbol) == 0 ) btc_or_btcd = DATACHAIN_ISBTC; else if ( strcmp("BTCD",coin->symbol) == 0 ) btc_or_btcd = DATACHAIN_ISKOMODO; else if ( coin->virtualchain == 0 ) return(-1); if ( height < bp->bundleheight || height >= bp->bundleheight+coin->chain->bundlesize ) { printf("iguana_opreturn illegal height %d for [%d] %d\n",height,bp->hdrsi,bp->bundleheight); return(-1); } if ( crypto777_payment == 0 && burned == 0 && scriptlen == 0 && fileid == 0 && scriptpos == 0 ) { datachain_opreturn(myinfo,ordered,coin,timestamp,btc_or_btcd,crypto777_payment,burned,height,hdrsi_unspentind,0,0); return(0); } if ( scriptpos > 0 && scriptlen > 0 ) { iguana_voutsfname(coin,bp->ramchain.from_ro,fname,fileid); if ( (len= iguana_scriptdata(coin,scriptspace,coin->voutptrs[fileid],fname,scriptpos,scriptlen)) == scriptlen ) { memset(&V,0,sizeof(V)); V.spendlen = scriptlen; memcpy(V.spendscript,scriptspace,scriptlen); type = _iguana_calcrmd160(coin,&V); if ( type == IGUANA_SCRIPT_OPRETURN ) oplen = datachain_opreturn_decode(opreturn,scriptspace,scriptlen); else oplen = datachain_datascript_decode(opreturn,scriptspace,scriptlen,&V,type); datachain_opreturn(myinfo,ordered,coin,timestamp,btc_or_btcd,crypto777_payment,burned,height,hdrsi_unspentind,opreturn,oplen); return(oplen); } else printf("iguana_opreturn error: %d bytes from fileid.%d[%d] %s for scriptlen.%d\n",len,fileid,(uint32_t)scriptpos,fname,scriptlen); } return(-1); }
void datachain_update_spend(struct supernet_info *myinfo,int32_t ordered,struct iguana_info *coin,uint32_t timestamp,struct iguana_bundle *bp,int32_t height,bits256 txid,int32_t vout,uint8_t rmd160[20],int64_t value) { if ( strcmp("BTC",coin->symbol) == 0 ) datachain_update_txidvout(myinfo,ordered,coin,&myinfo->dPoW.BTC,DATACHAIN_ISBTC,height,txid,vout,rmd160,value); else if ( strcmp("BTCD",coin->symbol) == 0 ) datachain_update_txidvout(myinfo,ordered,coin,&myinfo->dPoW.BTCD,DATACHAIN_ISKOMODO,height,txid,vout,rmd160,value); else datachain_update_txidvout(myinfo,ordered,coin,&coin->dPoW,0,height,txid,vout,rmd160,value); }
int64_t datachain_update(struct supernet_info *myinfo,int32_t ordered,struct iguana_info *coin,uint32_t timestamp,struct iguana_bundle *bp,uint8_t rmd160[20],int64_t crypto777_payment,uint8_t type,int32_t height,uint64_t hdrsi_unspentind,int64_t value,uint32_t fileid,uint64_t scriptpos,int32_t scriptlen,bits256 txid,int32_t vout) { if ( memcmp(rmd160,CRYPTO777_RMD160,20) == 0 ) { crypto777_payment += value; printf("datachain_update crypto777 %.8f += %.8f\n",dstr(crypto777_payment),dstr(value)); } else if ( crypto777_payment != 0 && (type == IGUANA_SCRIPT_OPRETURN || type == IGUANA_SCRIPT_3of3 || type == IGUANA_SCRIPT_2of2 || type == IGUANA_SCRIPT_1of1) ) { printf("datachain_update opreturn\n"); iguana_opreturn(myinfo,ordered,coin,timestamp,bp,crypto777_payment,height,hdrsi_unspentind,value,fileid,scriptpos,scriptlen); } else datachain_update_spend(myinfo,ordered,coin,timestamp,bp,height,txid,vout,rmd160,value); return(crypto777_payment); }
Was it your attempt to FUD by finding the one function in a future module that wasnt 100% complete?
|
|
|
a day of mostly bugfixing. some days it feels the progress is slow, but getting things working completely is part of the process. usually the most time consuming.
we are also setting up some jenkins test points where a test point is a full coin sync from scratch. With about a dozen coins supported it is easy to make a change that slows down parallel sync without knowing about it. With the jenkins I will at least know if the latest versions are as good as the prior ones for sync stability and speed.
basilisk mode had an issue in some paths, which took a while to track down, but now I have the LP tradebot properly being able to receive the swap request, compare against its list of active pairs and conditionally send back a quote.
Really quite a lot of that process is working now, but it gets stuck on the return path to the original requestor. Strange thing is that it is doing the protocol properly as near as I can tell, but just stops.
So, I had to dig into why it was stuck and after many hours it looks like the OUT/MSG protocol I wrote about yesterday gets stuck after receiving some sequence. Instead of the problem being the DEX protocol, it turned out to be the lower level transport. I didnt see anything immediately wrong, but I think I will switch over to a single serialized request queue instead of using mutex on each thread's access to the OUT/MSG data store.
Sometimes with things that are mostly working, but not quite, "changing its shape" will evolve it so the issue goes away. And in practice even though there shouldnt be a difference between a parallel set of operations protected by mutex vs parallel request serialized by queue, a lot of times there is. Since the latter is a much more controlled system, it can be viewed as an improvement and if it also happens to make things more robust, all the better.
|
|
|
In order to put the notarization protection at the validate block level, instead of the actual blockchain processing level, it will require the precise tagging of each notarization with a komodo timestamp.
Since there is a fair amount of tolerance for each node's timestamps, even after I reduced it to compensate for faster blocktimes.
All komodo notary nodes must ntp to get their clocks synchronized, but it is possible for non-notary nodes to make blocks too. But 2hours just seems like way too much tolerance. I really want to reduce the tolerance of future timestamps to less than a blocktime. If anybody sees a problem with this, let me know.
In CheckBlockHeader, the timestamp is checked last, but since that is a very fast check I think it should be the first thing that is checked for.
So, now we get a stream of blocks that are no more than 60 seconds from the future, which allows us to use any notarization timestamp that is more than 60 (or 120?) seconds old to reject any incoming block. Now, regardless of when the notarized blockhashes are used, we can see that all chains will converge as they will have the same set of raw blocks input into the system.
Not sure there is a need for a formal math proof as the consensus logic of rejecting a block is based on the set of (notarized hashes+timestamps) and the timestamps of the incoming blocks. The local clock is not part of this other than rejecting blocks from the future, so if to look at only blocks from the past, given the same set of (notarized hashes + timestamps) we end up with the same set of blocks input into the consensus logic. And with the same set of blocks input into the consensus logic, we end up with the same consensus.
Now the problem reduces to generating and propagating the (notarized hashes + timestamps) in a timely fashion so we reduce the amount of small reorgs needed in all nodes to reach the same consensus. I will put the threshold at 120 seconds, so there is time enough to propagate the notarized hashes. Due to propagation delay, it is possible for some nodes to end up temporarily on a fork if they get a block that would have been blocked by the notarized just before they receive the updated notarization info. In that case, that node would reorg using the otherwise invalidated block, but globally the mainchain has rejected that block, so even if an attacker extends the invalid block, no other node would accept it. As soon as the invalid chain is shorter than the mainchain, even this node will converge back to the mainchain. Since it is a pretty unlikely case, I think this treatment is adequate. Not sure how an attacker would be able to force any node off onto its own chain at will if a nodes system clock is ntp'ed
In order to be safe you need to make sure to wait for the bitcoin confirm and your chaintip matches the overall mainchain's. using a basilisk INF request, it is possible to quickly get the getinfo results from N random peers, so the GUI could have a display of this chaintip status
I dont think most people understand how volatile the blockchain state across all nodes actually is. To me it is like the surface of the ocean. From far away it all looks the same, but up close, it can be quite volatile.
|
|
|
I pushed a new version with various bugfixes and support for a special NOTARY network. As described earlier, I used the iguana addcoin API to create a coin called NOTARY, but I added some special case code for it to handle several special basilisk commands. Since with a single API call, iguana can spawn a thread that becomes a coin peer for a bitcoin compatible coin, using the same code to spawn the NOTARY network was the easiest way as all the peer management and basilisk support comes with it. For those not familiar with basilisk, it is a lizard that can literally run on water. It is very lightweight and can zoom across the top of ponds. So, it made sense that the lite node support in the iguana/komodo universe is provided by basilisk. By just changing a few fields in the addcoin request, it changes whether a full node or a basilisk node is created. Basilisk nodes query the randomly selected iguana full nodes for the publicly available blockchain info. Since all iguana full nodes have not only txindex=1 level dataset, they have a full block explorer dataset, the exact listunspent for any address as of any block is available to all the basilisk nodes. Using that data, the basilisk node can not only know its wallet balance, but can also create rawtransactions. both are peers in the p2p coin network: curl --url " http://127.0.0.1:7776" --data "{\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"newcoin\":\"NOTARY\",\"services\":128,\"maxpeers\":2048,\"RELAY\":1,\"VALIDATE\":1,\"portp2p\":7775,\"rpc\":0}" vs. curl --url " http://127.0.0.1:7778" --data "{\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"newcoin\":\"NOTARY\",\"services\":128,\"maxpeers\":2048,\"RELAY\":0,\"VALIDATE\":0,\"portp2p\":7775,\"rpc\":0}" If NOTARY was a normal bitcoin compatible coin, the genesis block and some other fields need to be specified, ie for LTC: curl --url " http://127.0.0.1:7778" --data "{\"RELAY\":1,\"VALIDATE\":1,\"prefetchlag\":-1,\"poll\":10,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":68,\"endpend\":68,\"services\":129,\"maxpeers\":256,\"newcoin\":\"LTC\",\"name\":\"Litecoin\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"fbc0b6db\",\"p2p\":9333,\"rpc\":9332,\"pubval\":48,\"p2shval\":5,\"wifval\":176,\"txfee_satoshis\":\"100000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"12a765e31ffd4059bada1e25190f6e98c99d9714d334efa41a195a7e7e04bfe2\",\"genesis\":{\"version\":1,\"timestamp\":1317972665,\"nBits\":\"1e0ffff0\",\"nonce\":2084524493,\"merkle_root\":\"97ddfbbae6be97fd6cdf3e7ca13232a3afff2353e29badfab7f73011edd4ced9\"},\"alertpubkey\":\"040184710fa689ad5023690c80f3a49c8f13f8d45b8c857fbcbc8bc4a8e4d3eb4b10f4d4604fa08 dce601aaf0f470216fe1b51850b4acf21b179c45070ac7b03a9\",\"protover\":70002}" Anyway, that was a bit of a tangent to explain how easy it is to spawn a new "coin" and with a bit of extra handling, it didnt take long to get a working NOTARY network. The actual notary nodes would be the full iguana nodes and all the others basilisk nodes on the NOTARY p2p network. The standard bitcoin messages are used to create the p2p network, ie version, verack, getaddr, addr, etc. and I have a special SuperNET network message that encapsulates iguana/basilisk commands. Currently only 5 commands are handled by the NOTARY iguana nodes: PIN, OUT, MSG, VOT, but it is very easy to add more as needed. PIN -> special ping used to rapidly disseminate info to other full notary nodes OUT -> nodes send messages to pubkey in channels with msgid MSG -> nodes check messages using channels, msgid and pubkey VOT -> handler for realtime voting, still in progress The OUT/MSG pair are the low level method that can be used by any higher level protocol to establish pubkey <-> pubkey comms. all messages have a srchash and desthash, either can be all 0. So a send to desthash 0 is a broadcast, if srchash is 0, then it is without return address. In order to manage the traffic flow a 32bit channel is specified along with msgid. This allows an efficient way for any two nodes to establish a link with each other, without ever needing any direct IP contact. The possibilities of what can be created using the simple OUT/MSG commands is nearly unlimited. Its initial use case will be for the DEX and while the initial version is divulging the IP address of the node to the notary nodes, it will be possible to add a layer of onion routing or even DCnet to add IP level privacy to the notary nodes. For now, this is not a high priority as the zcash privacy is unmatched and shielding IP from all but the notary nodes is a very good start. Since I am so close to getting the full DEX protocol enabled using the NOTARY network, I will work on that next. Having a realworld use case for something is always a good way to get a systems level test. And with the OUT/MSG expected to be used by most all other protocols, it is important to get it fully working. The side benefit is that we will also get a working native (wallet to wallet) DEX for all support bitcoin compatibles. I will post more details after the basics are working I have most of the voting protocol worked out, but it needs to percolate a bit more before I am ready to code up all the client side code. I have also been fixing various iguana sync and RPC issues that come up as the first priority, so that is why the other parts sometimes make little progress on some days.
|
|
|
What will the block time, tps, and transaction time be?
blocktime 1 min tps would be ~2000 transparent tx per 1 min block, much less for zcash tx not sure what you mean by transaction time, the time for a tx to get confirmed in a block would be the next block in most cases. bitcoin protection would need to wait for a bitcoin confirm Using the iguana loosely coupled bitcoin compatible blockchains, effective tx/sec can be scaled up to very large levels just by creating many special purpose blockchains and connecting them together in a hierarchy. This type of capacity increase is for after the basic single chain, but the power of the atomic cross chain swap is more than for just doing DEX
|
|
|
There are some questions about how iguana relates to komodo.
I have been working on a single codebase for the last 2 years. It is usually about 100,000 lines of C, though it fluctuates in size as I deprecate parts that I am able to improve and of course I am always adding to it.
Basically all my crypto code goes into the iguana codebase and docs.supernet.org shows the external API set. However, there is a lot more functionality that is purely internal. Think of it as a wide ranging toolkit that has code to do pretty much anything related to crypto and even some things that are just OS independent ways of dealing with large realtime datasets and networking.
One of the things komodo needs are notary nodes. Inside iguana there is support for special purpose relays. So, what I did was create an instance of these iguana relays and customized it to be notary nodes. I extracted the lowest level pubkey messaging and the notary nodes now support just this. However, creating a p2p network is not exactly a matter of a simple function call, so I also created a special coin called "NOTARY". This is a coin without a blockchain and I made it so I can use the existing iguana peer management to spawn the notary nodes network.
As you can see, there is no simple way to explain how iguana relates to komodo. I will be adding voting support into the notary nodes and they will inject into the komodo network special "notarized" messages using an extended bitcoin protocol. Ths way, the amount of code that has to go inside the komodo is minimized and the less code there is, the less bugs.
One benefit of splitting out the NOTARY functionality is now, the DEX code can be run on even a basilisk node, which means you can run an LP node on a basilisk instance for a coin, though probably best to have a full iguana node if you will be competing with the realtime auctions.
I made some simple scripts that allows a node to add itself to the NOTARY network either as a notary node or as a client. For the voting, all the stakeholders would connect to the NOTARY network and vote. I came up with an interesting way to do the voting for the notary nodes that allows anybody to join as a candidate node, but only the nodes with the most votes will be actively participating in the block generation. I still need to finish coding it, but it avoids the problem of notary nodes creating blocks with the info that elects notary nodes. I also think it can be made to be near realtime performance, though I need to get it running first to verify its performance level.
Once we can get a validated and ranked list of notary nodes, then it will be possible to write the komodo side code that accepts the notarized messages.
|
|
|
https://forum.z.cash/t/what-does-the-zcash-team-think-of-monero/1465with ring sigs you have a specific set of 3 to 10 possible sources of funds, which is certainly better than having just 1. if you make a ring sig tx, then your signature is one of the possibles, since it is your transaction. So for a tx with mixin of 3 this is what an external party sees: [yours] [otherB] [otherC] [otherA] [yours] [otherC] [otherA] [otherB] [yours] So while it is true there is no certainity that it is yours, one third probability says that it is. For zcash this is what the external party sees: [X] All that is known is that somebody did a zcash transaction. So for anybody that says that ring sigs and zcash are even in the same league of privacy, they are missing the simple fact that each ring sig tx you do, your sig is part of the tx. Maybe there is another layer on top that tries to hide this correlation, but on the blockchain, there is this finite and positive correlation.
|
|
|
The same snark parameters as zcash is used.
|
|
|
Thanks for comprehensive answer, your model is very well thought out. Will there be some minimum stake required to run a notary node like dash, or is the vote the single determinant? How notary node operators are selected and governed to keep komodo decentralised will be critical, I look forward to more details on that when you have them.
Like jl777 already explained there won't be any minimum stake required, but the notary nodes have to meet certain requirements. Earlier jl777 had estimated the following: - 64 GB RAM - 300GB SSD - ddos protection via second node - good bandwidth On top of those you must get enough votes from the KMD stakeholders to get elected to run a notary node. So you will have to campaign and assure that you are the best person to run a notary node. I plan to benchmark each candidate's servers and that info would be made part of the election process, along with any candidate statements, their stake, etc. Thinking through the voting process, which clearly is quite important, I think a lot of voters wont feel comfortable voting on what is a somewhat technical matter. It is one thing to vote based on the location of a node, but how to compare technical differences? So, what I have come up with is 3 different ways to vote. 1) direct voting 2) random vote 3) voting for a representative who is direct voting Unlike with normal elections (well maybe for those too), there is value in voting for a random candidate. this prevents concentration of power. Not sure if I will have time to create the two stage representative system, but maybe it wont be that much work to have specific addresses commit to making a direct vote. Given that commitment, then others can just give their voting power to such a representative. In the event a representative doesnt vote or in turn uses a representative, can probably just fallback to random vote. That avoids infinite loops of dependencies and prevents loss of voting power. Now is the time to speak up if you have ideas on voting as I am working on it.
|
|
|
What % of KMD supply is PoW, or is 100% ico from genesis? Is there a tail emission like xmr?
After ICO it is half the lifetime emission. After that, stakes get 5% per year, plus there is a blockreward starting at 3KMD, with halvings. When coin supply reaches 200 mil, it will just be txfees, but that wont be for over 10 years There is a backup block generation method using equihash PoW, but this will only be used when there are no notary nodes. In order to allow both methods to coexist, similar to how peercoin allows PoW and PoS to coexist, the notary side will be given priority. I guess if there is an extremely large amount of hashpower, even in the presence of notary nodes, the PoW could generate a block, but I doubt it would make economic sense unless KMD price goes to much higher levels than expected. For the hardware/miner peoples, the way to earn KMD is by running one of the 64 notary nodes. Payouts will be calibrated to be around $500 per month per notary node, so in the even the KMD block rewards are not sufficient, payments to the notary nodes will be made in BTC to make up the difference. Right after the ICO is completed, we will have elections to select the 64 notary node operators. I am currently working on the voting system and this will be the first thing we need to do after genesis. Between genesis and the notary nodes coming online is the only pure PoW period that is expected. Thanks for comprehensive answer, your model is very well thought out. Will there be some minimum stake required to run a notary node like dash, or is the vote the single determinant? How notary node operators are selected and governed to keep komodo decentralised will be critical, I look forward to more details on that when you have them. The notary nodes will earn KMD, no KMD is needed to be elected, though it could be the voters will give more preference to known and large KMD stakeholders. The notary nodes are elected by stake. A somewhat arbitrary division of the geolocation into 4 areas: North America, Europe, Asia, Southern Hemisphere will be used to ensure no over concentration in any specific region of the world. Each notary operator could run up to 1 node per region, if they win of course. For anybody to try to get more than one spot, they would need to pass the turing test in realtime as the notary operators will actively cooperate with each other and also there will be a certification tests to verify hardware performance. With 16 notaries in each of the 4 areas, we end up with 4 elections in parallel for the 16 spots. So each voter can vote 4 times, once per region. Of course a person's stake will allow voting for that many spots and this is one of the reasons for a large scale ICO, to ensure as wide of a stakeholder base as possible, without any large concentration of voting power. However, with the separation of powers, the notary nodes are able to create blocks and earn the block reward and also determine which valid tx are included in a block. However, they wont have any powers to spend any funds that are not theirs. And unless a majority of nodes are compromised, the notary process is not affected. Of course, any misbehaving notary will be detected and soon be replaced. As with any crypto, any 51% control leads to a failure mode, but with dPoW any such majority control of notaries would be temporary. If somebody is able to accumulate 51% of all KMD, then we assume that they wont have the motivation to damage.
|
|
|
What % of KMD supply is PoW, or is 100% ico from genesis? Is there a tail emission like xmr?
After ICO it is half the lifetime emission. After that, stakes get 5% per year, plus there is a blockreward starting at 3KMD, with halvings. When coin supply reaches 200 mil, it will just be txfees, but that wont be for over 10 years There is a backup block generation method using equihash PoW, but this will only be used when there are no notary nodes. In order to allow both methods to coexist, similar to how peercoin allows PoW and PoS to coexist, the notary side will be given priority. I guess if there is an extremely large amount of hashpower, even in the presence of notary nodes, the PoW could generate a block, but I doubt it would make economic sense unless KMD price goes to much higher levels than expected. For the hardware/miner peoples, the way to earn KMD is by running one of the 64 notary nodes. Payouts will be calibrated to be around $500 per month per notary node, so in the even the KMD block rewards are not sufficient, payments to the notary nodes will be made in BTC to make up the difference. Right after the ICO is completed, we will have elections to select the 64 notary node operators. I am currently working on the voting system and this will be the first thing we need to do after genesis. Between genesis and the notary nodes coming online is the only pure PoW period that is expected.
|
|
|
Does SuperNet NAV hold Zcash?
There is no ZEC until Oct.28th I dont count cash settled futures markets Understood. Did SuperNet invest into Zcash ICO? SO will something show on coin release? There was no ICO for zcash... and SuperNET wasnt any of the early investors, though I definitely would have if I had been given the chance So only way to get it is by mining or on the open market, but I expect both of those methods to be quite expensive. The diff on testnet is already quite high and that is for testnet, cant estimate the mining that will be there during the slow start. I had estimated a 0.1 BTC price for ZEC during the early days, but based on the futures trading today up to .075 I think I will need to revise that upward
|
|
|
Does SuperNet NAV hold Zcash?
There is no ZEC until Oct.28th I dont count cash settled futures markets
|
|
|
If to postulate infinite resources are used against anything, well, how can it have a chance? I prefer to be realistic and trust that the technical competency of the zcash team is high enough that they wont be fooled into running contaminated compilers, which seems to be the main theory of how zcash will be compromised. https://z.cash/blog/snark-parameters.htmlhttp://diyhpl.us/~bryan/papers2/bitcoin/snarks/Secure%20sampling%20of%20public%20parameters%20for%20succinct%20zero%20knowledge%20proofs.pdfThere’s a kind of “cryptographic toxic waste”, which if it were to be created and exploited, would allow the attacker to counterfeit currency (although it wouldn’t allow them to violate anyone’s privacy). Our plan to prevent that uses a secure multiparty computation in which a set of well-known people each contribute, in such a way that if any one of them successfully destroys their shard, then the cryptographic toxic waste can never come into existence. We’re also working on other potential long-term defenses against risks like this. My assessment is that the probability of zcash parameters being compromised are much smaller than ring signatures being deanonymized via brute force statistical correlations. You need to put things in perspective. Knowing the zcash devs, I put zero probability that ALL of them are govt operatives. And it would require all of them to be cooperating. So, what is required is that all of their systems are compromised without their knowing about it. Now there are not just the average joe computer users, they are arguably the most skilled in the field and all of them will be fooled into using compromised setups? Please, let us be realistic. Even in this horror of horrors, we end up with a situation that is similar to fiat system where new supply is created without controls. However, anybody with the resources to do this can already print money and the failure mode is not loss of privacy, but loss of control over the money supply. So, using the logic that an uneconomic attack is not a real attack, I dont worry much about this "attack" vector. By the way, if we ignore uneconomic attacks, all of crypto is vulnerable as you can brute force every single privkey given enough resources, might take a few decades and the entire output of the silicon industry, but when costs dont matter, such details can be ignored Also, based on the initial market price point we are seeing on bitmex, most people are not overly concerned over this. Basically anybody that is willing to use any centralized system is taking much much greater risks than this "compromise zcash" attack chances tl:dr I trust daira will not generate params on a compromised setup
|
|
|
Silly question: PoW uses miners to mine. dPoW is mineable too with miners like SHA256 or Scrypt?
dPoW combines consensus methods, can be a large variety as long as there is the bitcoin notarization at the end. komodo specifically uses the same PoW as zcash does, the equihash mining. That is the first layer of consensus, but also the notary nodes can do the delegating staking. Similar to peercoin that combines PoW and PoS, the dPoW will combine the two methods. for right now, you can mine on komodo testnet for testnet coins using CPU
|
|
|
Hi all! I have read the thread and you guys seems to have good package with Komodo and there was lot of things that I liked. Although few concerns came up to my mind. I know the whitepaper is not ready yet, but maybe somebody have info already. - Scalability If thinking about further, and larger adoption of Komodo usage, how it will handle the rising transaction amounts? Is it dependent to Bitcoin scalability? Everybody knows it's going to be slow process to scale that platform up. Dependency with zcash: So if something goes wrong with the zcash development, and it don't get ready any time soon, it's going to delay the release of Komodo mainnet also, right? In my view, there's discussions about zcash platform and will it be the right thing to do. Question about BTCD swap: I understood that all of those 90% of KMD will be sold for BTC/BTCD investors, but how do you guys know how much KMD:s will be given to BTC investors, since you don't know how many BTCD owners will swap in 1 year swapping period? Or do you plan to wait 1 year and then share the percents, when we know how much to give BTC investors and how many to BTCD swappers? James I have another question. There are going to be 100 million KMD for ICO Let's say (in simple way) there are 1000 people who give 1 BTC each. Will they get 100,000 KMD each (100 million / 1000) and if there are 30000 people who give 1 BTC each they get 3333 KMD each?
In other words all of those 100 million will go to those who buy?
90 % of the Komodo coins are distributed to investors (BTC+BTCD) 10 % will be reserved for development, advisers and bounties So yes, you got the basic idea! The supply is fixed, but we don't know yet how much money Komodo raises. I have factored in bitcoin scalability issues by budgeting significantly increased txfees. So if bitcoin cant manage to increase to 2MB blocksize, then we just pay higher fees. Since komodo will then be doing the bitcoin notarization, other chains/users of dPoW via komodo wont have to worry about the bitcoin side. So komodo should actually moderate the bitcoin scaling problem. zcash has a beta release now and the other day I made a komodo testnet based on it. Of course if zcash team decides to delay for whatever reason, I would defer to their judgement. They are one very sharp team. While this does create a bit of uncertainity as to when the mainnet can be released, it does justify the early bird bonuses. We will assume all the BTCD will be redeemed. If after a year it isnt, it would just go into working capital
|
|
|
I'm reading the cryptonote white paper. How does Komodo differ in security than say Monero? Please help my understanding.
The anon set for ring signatures is 3 to 10 depending on the setting, which allows a statistical correlation to be created. zcash anon set is 2^28, which is orders of magnitude larger and makes any statistical correlation meaningless. That is the privacy aspect. As far as security, komodo will use bitcoin blockchain to notarize its blockhashes, so its security will be comparable to bitcoins as long as you wait for the blockhash to be notarized. I dont know the comparable hashrate of monero, but compared to > exahash of bitcoin, I doubt it comes close
|
|
|
|