Post
Topic
Board Announcements (Altcoins)
Re: [ANN] BitcoinDark (BTCD)--Sha-256/PoW-PoS hybrid/Bounty Opportunities
by
jl777
on 07/09/2014, 23:25:01 UTC
here is the sendmsg function, which is really the critical one:

Code:

char *sendmessage(int32_t L,char *verifiedNXTaddr,char *NXTACCTSECRET,char *msg,int32_t msglen,char *destNXTaddr,char *origargstr)
{
    uint64_t txid;
    char buf[4096];
    unsigned char encodedD[4096],encodedL[4096],encodedP[4096],finalbuf[4096],*outbuf;
    int32_t len,createdflag;
    struct NXT_acct *np = 0,*destnp;
    //printf("sendmessage.(%s) -> NXT.(%s) (%s) (%s)\n",NXTaddr,destNXTaddr,msg,origargstr);
    if ( Server_NXTaddr == 0 )
    {
        if ( Global_pNXT->privacyServer_NXTaddr[0] == 0 )
        {
            sprintf(buf,"{\"error\":\"%s cant sendmessage.(%s) to null privacyServer\"}",verifiedNXTaddr,msg);
            return(clonestr(buf));
        }
        np = get_NXTacct(&createdflag,Global_mp,Global_pNXT->privacyServer_NXTaddr);
        printf("set np <- NXT.%s\n",Global_pNXT->privacyServer_NXTaddr);
    }
    else
    {
        np = get_NXTacct(&createdflag,Global_mp,verifiedNXTaddr);
        if ( strcmp(Server_NXTaddr,destNXTaddr) == 0 )
        {
            queue_message(np,msg,origargstr);
            sprintf(buf,"{\"result\":\"msg.(%s) from NXT.%s queued\"}",msg,verifiedNXTaddr);
            return(clonestr(buf));
        }
    }
    destnp = get_NXTacct(&createdflag,Global_mp,destNXTaddr);
    memset(finalbuf,0,sizeof(finalbuf));
    memset(encodedD,0,sizeof(encodedD)); // encoded to dest
    memset(encodedL,0,sizeof(encodedL)); // encoded to max L onion layers
    memset(encodedP,0,sizeof(encodedP)); // encoded to privacyserver
    if ( origargstr != 0 )
        len = onionize(verifiedNXTaddr,NXTACCTSECRET,encodedD,destNXTaddr,(unsigned char *)origargstr,(int32_t)strlen(origargstr)+1);
    else
    {
        len = onionize(verifiedNXTaddr,NXTACCTSECRET,encodedD,destNXTaddr,(unsigned char *)msg,msglen);
        msg = origargstr = "";
    }
    printf("sendmessage (%s) len.%d to %s\n",origargstr,msglen,destNXTaddr);
    if ( len > sizeof(finalbuf)-256 )
    {
        printf("sendmessage, payload too big %d\n",len);
        sprintf(buf,"{\"error\":\"%s cant sendmessage.(%s) to %s too long.%d\"}",verifiedNXTaddr,msg,destNXTaddr,len);
    }
    else if ( len > 0 )
    {
        outbuf = encodedD;
        printf("np.%p NXT.%s np->udp %p | destnp.%p destnp_udp.%p\n",np,np!=0?np->H.NXTaddr:"no np",np!=0?np->udp:0,destnp,destnp!=0?destnp->udp:0);
        if ( np != 0 && np->udp != 0 )
        {
            if ( L > 0 )
            {
                len = add_random_onionlayers(L,verifiedNXTaddr,NXTACCTSECRET,encodedL,outbuf,len);
                outbuf = encodedL;
            }
            len = onionize(verifiedNXTaddr,NXTACCTSECRET,encodedP,Global_pNXT->privacyServer_NXTaddr,outbuf,len);
            outbuf = encodedP;
            sprintf(buf,"{\"status\":\"%s sends via %s encrypted sendmessage to %s pending\"}",verifiedNXTaddr,Global_pNXT->privacyServer_NXTaddr,destNXTaddr);
        }
        else if ( Server_NXTaddr != 0 && destnp->udp != 0 )
        {
            printf("can do direct!\n");
            np = destnp;
            sprintf(buf,"{\"status\":\"%s sends direct encrypted sendmessage to %s pending\"}",verifiedNXTaddr,destNXTaddr);
        } else np = 0;  // have to use p2p network
        if ( len > 0 && len < sizeof(finalbuf) )
        {
            len = crcize(finalbuf,outbuf,len);
            if ( len > sizeof(finalbuf) )
            {
                printf("sendmessage: len.%d > sizeof(finalbuf) %ld\n",len,sizeof(finalbuf));
                exit(-1);
            }
            if ( np != 0 && len < 1400 )
            {
                int32_t portable_udpwrite(const struct sockaddr *addr,uv_udp_t *handle,void *buf,long len,int32_t allocflag);
                printf("udpsend finalbuf.%d\n",len);
                portable_udpwrite(&np->Uaddr,(uv_udp_t *)np->udp,finalbuf,len,ALLOCWR_ALLOCFREE);
            }
            else if ( Server_NXTaddr != 0 ) // test to verify this is hub
            {
                printf("len.%d Server_NXTaddr.(%s) broadcast %d via p2p\n",len,Server_NXTaddr,len);
                txid = call_libjl777_broadcast((char *)finalbuf,600);
                if ( txid == 0 )
                {
                    sprintf(buf,"{\"error\":\"%s cant send via p2p sendmessage.(%s) [%s] to %s pending\"}",verifiedNXTaddr,origargstr,msg,destNXTaddr);
                }
                else
                {
                    sprintf(buf,"{\"status\":\"%s sends via p2p encrypted sendmessage to %s pending\"}",verifiedNXTaddr,destNXTaddr);
                }
            }
            else sprintf(buf,"{\"error\":\"%s cant sendmessage.(%s) to %s unexpected case\"}",verifiedNXTaddr,msg,destNXTaddr);
        } else sprintf(buf,"{\"error\":\"%s cant sendmessage.(%s) to %s error encoding layer, len.%d\"}",verifiedNXTaddr,msg,destNXTaddr,len);
    } else sprintf(buf,"{\"error\":\"%s cant sendmessage.(%s) to %s probably no pubkey\"}",verifiedNXTaddr,msg,destNXTaddr);
    return(clonestr(buf));
}

the onion commands:
Code:

int32_t onionize(char *verifiedNXTaddr,char *NXTACCTSECRET,unsigned char *encoded,char *destNXTaddr,unsigned char *payload,int32_t len)
{
    static unsigned char zerokey[crypto_box_PUBLICKEYBYTES];
    unsigned char onetime_pubkey[crypto_box_PUBLICKEYBYTES],onetime_privkey[crypto_box_SECRETKEYBYTES];
    uint64_t nxt64bits;
    int32_t createdflag;
    uint16_t *payload_lenp,slen;
    struct NXT_acct *np;
    nxt64bits = calc_nxt64bits(destNXTaddr);
    np = get_NXTacct(&createdflag,Global_mp,destNXTaddr);
    if ( memcmp(np->pubkey,zerokey,sizeof(zerokey)) == 0 )
    {
        if ( Global_pNXT->privacyServer_NXTaddr[0] != 0 )
        {
            char cmdstr[4096];
            sprintf(cmdstr,"{\"requestType\":\"getpubkey\",\"NXT\":\"%s\",\"addr\":\"%s\",\"time\":%ld}",verifiedNXTaddr,destNXTaddr,time(NULL));
            send_tokenized_cmd(Global_mp->Lfactor,verifiedNXTaddr,NXTACCTSECRET,cmdstr,Global_pNXT->privacyServer_NXTaddr);
            //int n = construct_tokenized_req(_tokbuf,cmdstr,NXTACCTSECRET);
            //sendmessage(verifiedNXTaddr,NXTACCTSECRET,_tokbuf,(int32_t)n+1,Global_pNXT->privacyServer_NXTaddr,_tokbuf);
        }
        return(0);
    }
    crypto_box_keypair(onetime_pubkey,onetime_privkey);
    memcpy(encoded,&nxt64bits,sizeof(nxt64bits));
    encoded += sizeof(nxt64bits);
    memcpy(encoded,onetime_pubkey,sizeof(onetime_pubkey));
    encoded += sizeof(onetime_pubkey);
    payload_lenp = (uint16_t *)encoded;
    encoded += sizeof(*payload_lenp);
    //printf("ONIONIZE: np.%p NXT.%s %s pubkey.%llx encode len.%d -> ",np,np->H.NXTaddr,destNXTaddr,*(long long *)np->pubkey,len);
    len = _encode_str(encoded,(char *)payload,len,np->pubkey,onetime_privkey);
    slen = len;
    memcpy(payload_lenp,&slen,sizeof(*payload_lenp));
    printf("new len.%d + %ld = %ld\n",len,sizeof(*payload_lenp) + sizeof(onetime_pubkey) + sizeof(nxt64bits),sizeof(*payload_lenp) + sizeof(onetime_pubkey) + sizeof(nxt64bits)+len);
    return(len + sizeof(*payload_lenp) + sizeof(onetime_pubkey) + sizeof(nxt64bits));
}

int32_t add_random_onionlayers(int32_t numlayers,char *verifiedNXTaddr,char *NXTACCTSECRET,uint8_t *final,uint8_t *src,int32_t len)
{
    char destNXTaddr[64];
    uint8_t bufs[2][4096],*dest;
    struct peerinfo *peer;
    struct NXT_acct *np;
    if ( numlayers > 1 )
        numlayers = ((rand() >> 8) % numlayers);
    if ( numlayers > 0 )
    {
        memset(bufs,0,sizeof(bufs));
        dest = bufs[numlayers & 1];
        memcpy(dest,src,len);
        while ( numlayers > 0 )
        {
            src = bufs[numlayers & 1];
            dest = bufs[(numlayers & 1) ^ 1];
            peer = get_random_pserver();
            if ( peer == 0 )
            {
                printf("FATAL: cant get random peer!\n");
                return(-1);
            }
            np = search_addresses(peer->pubBTCD);
            if ( np == 0 && peer->pubnxtbits != 0 )
            {
                expand_nxt64bits(destNXTaddr,peer->pubnxtbits);
                np = search_addresses(destNXTaddr);
            }
            if ( np == 0 )
                np = search_addresses(peer->pubBTC);
            if ( np == 0 )
            {
                printf("FATAL: %s %s %s is unknown account\n",peer->pubBTCD,destNXTaddr,peer->pubBTC);
                return(-1);
            }
            if ( memcmp(np->pubkey,peer->pubkey,sizeof(np->pubkey)) != 0 )
            {
                printf("Warning: (%s %s %s) pubkey updated %llx -> %llx\n",peer->pubBTCD,destNXTaddr,peer->pubBTC,*(long long *)np->pubkey,*(long long *)peer->pubkey);
                memcpy(np->pubkey,peer->pubkey,sizeof(np->pubkey));
            }
            printf("add layer %d: NXT.%s\n",numlayers,np->H.NXTaddr);
            len = onionize(verifiedNXTaddr,NXTACCTSECRET,dest,np->H.NXTaddr,src,len);
            if ( len > 4096 )
            {
                printf("FATAL: onion layers too big.%d\n",len);
                return(-1);
            }
            numlayers--;
        }
        src = dest;
    }
    memcpy(final,src,len);
    return(len);
}

int32_t deonionize(unsigned char *pubkey,unsigned char *decoded,unsigned char *encoded,int32_t len,uint64_t mynxtbits)
{
    //void *origencoded = encoded;
    int32_t err;
    uint16_t payload_len;
    if ( mynxtbits == 0 || memcmp(&mynxtbits,encoded,sizeof(mynxtbits)) == 0 )
    {
        encoded += sizeof(mynxtbits);
        memcpy(pubkey,encoded,crypto_box_PUBLICKEYBYTES);
        encoded += crypto_box_PUBLICKEYBYTES;
        memcpy(&payload_len,encoded,sizeof(payload_len));
        //printf("deonionize >>>>> pubkey.%llx vs mypubkey.%llx (%ld) -> %d %2x\n",*(long long *)pubkey,*(long long *)Global_mp->session_pubkey,(long)encoded - (long)origencoded,payload_len,payload_len);
        encoded += sizeof(payload_len);
        if ( (payload_len + sizeof(payload_len) + sizeof(Global_mp->session_pubkey) + sizeof(mynxtbits)) == len )
        {
            len = payload_len;
            err = _decode_cipher((char *)decoded,encoded,&len,pubkey,Global_mp->session_privkey);
            if ( err == 0 )
            {
               // printf("payload_len.%d err.%d new len.%d\n",payload_len,err,len);
                return(len);
            }
        } else printf("mismatched len expected %ld got %d\n",(payload_len + sizeof(payload_len) + sizeof(Global_mp->session_pubkey) + sizeof(mynxtbits)),len);
    }
    else
    {
        uint64_t destbits;
        memcpy(&destbits,encoded,sizeof(destbits));
        printf("deonionize onion for NXT.%llu not this address.(%llu)\n",(long long)destbits,(long long)mynxtbits);
    }
    return(0);
}
So there is the guts of the entire SuperNET!
As you can see it is not so much actual code. There are many special cases and nonstandard handling I skipped, but for those who are wondering how "real" teleport is, this has been pretty much working for over a month.
The SuperNET support is creating a need for some brain surgery and if I am not ready to code it, I cannot force it.
it is hard to explain.
maybe if you are an artist you can understand
force an artist to paint when he is no ready, then it wont be any good.
the reason is that I need to have all the things done in my head before I start writing
Now, maybe you are in a hurry to have teleport because?
cant wait for .02?

please let me make the Teleport + SuperNET to my standards. All the discussions with the SuperNET, questions, sometimes even trolls is sharpening in my mind the exact things that are needed.

James

P.S. for those who understand some coding, you know how hard it is to have small amounts of code do a lot of things, let along doing amazing things and you will not the long distance calling is not there yet. So, this I must do for SuperNET, then we get SuperTeleport! Not just teleporting BTCD to any other BTCD node, but BTCD to ANY node in the SuperNET. Isnt that worth a week or even two delay?