Example #1
0
struct iguana_peer *iguana_choosepeer(struct iguana_info *coin)
{
    int32_t i,j,r,iter; struct iguana_peer *addr;
    r = rand();
    portable_mutex_lock(&coin->peers_mutex);
    if ( coin->MAXPEERS == 0 )
        coin->MAXPEERS = IGUANA_MAXPEERS;
    if ( coin->peers.numranked > 0 )
    {
        for (j=0; j<coin->peers.numranked; j++)
        {
            i = (j + r) % coin->MAXPEERS;
            if ( (addr= coin->peers.ranked[i]) != 0 && addr->pendblocks < IGUANA_MAXPENDING && addr->dead == 0 && addr->usock >= 0 )
            {
                portable_mutex_unlock(&coin->peers_mutex);
                return(addr);
            }
        }
    }
    portable_mutex_unlock(&coin->peers_mutex);
    for (iter=0; iter<2; iter++)
    {
        for (i=0; i<coin->MAXPEERS; i++)
        {
            addr = &coin->peers.active[(i + r) % coin->MAXPEERS];
            if ( addr->dead == 0 && addr->usock >= 0 && (iter == 1 || addr->pendblocks < IGUANA_MAXPENDING) )
                return(addr);
        }
    }
    return(0);
}
Example #2
0
void lock_queue(queue_t *queue)
{
    if ( queue->initflag == 0 )
    {
        portable_mutex_init(&queue->mutex);
        queue->initflag = 1;
    }
	portable_mutex_lock(&queue->mutex);
}
Example #3
0
struct basilisk_swap *basilisk_request_started(struct supernet_info *myinfo,uint32_t requestid)
{
    int32_t i; struct basilisk_swap *active = 0;
    portable_mutex_lock(&myinfo->DEX_swapmutex);
    for (i=0; i<myinfo->numswaps; i++)
        if ( myinfo->swaps[i]->req.requestid == requestid )
        {
            //printf("REQUEST STARTED.[%d] <- req.%u\n",i,requestid);
            active = myinfo->swaps[i];
            break;
        }
    portable_mutex_unlock(&myinfo->DEX_swapmutex);
    return(active);
}
Example #4
0
int32_t iguana_scriptdata(struct iguana_info *coin, uint8_t *scriptspace, long fileptr[2], char *fname, uint64_t scriptpos, int32_t scriptlen)
#endif
{
    FILE *fp; long err; int32_t retval = scriptlen;
#ifndef __PNACL__
    if ( scriptpos < 0xffffffff )
    {
        if ( fileptr[0] == 0 )
#if defined(_M_X64)
            fileptr[0] = (uint64_t)OS_mapfile(fname,&fileptr[1],0);
#else
			fileptr[0] = (long)OS_mapfile(fname, &fileptr[1], 0);
#endif
        if ( fileptr[0] != 0 )
        {
            if ( (scriptpos + scriptlen) <= fileptr[1] )
            {
                memcpy(scriptspace,(void *)(fileptr[0] + (uint32_t)scriptpos),scriptlen);
                return(retval);
            }
            else if ( 0 )
            {
                printf("munmap (%s)\n",fname);
                munmap((void *)fileptr[0],fileptr[1]);
                fileptr[0] = fileptr[1] = 0;
            }
        }
    }
#else
    static portable_mutex_t mutex;
    portable_mutex_lock(&mutex);
#endif
    if ( (fp= fopen(fname,"rb")) != 0 )
    {
        fseek(fp,scriptpos,SEEK_SET);
        if ( (err= fread(scriptspace,1,scriptlen,fp)) != scriptlen )
        {
            retval = -1;
            printf("%s script[%d] offset.%llu err.%ld\n",fname,scriptlen,(long long)scriptpos,err);
        } //else printf("%s script[%d] offset.%llu read.%ld\n",fname,scriptlen,(long long)scriptpos,err);
        fclose(fp);
    } else retval = -1;
#ifdef __PNACL__
    portable_mutex_unlock(&mutex);
#endif
    return(retval);
}
Example #5
0
char *basilisk_respond_getmessage(struct supernet_info *myinfo,uint8_t *key,int32_t keylen)
{
    cJSON *retjson,*msgjson; struct basilisk_message *msg; char *ptr = 0,strbuf[32768];
    retjson = cJSON_CreateObject();
    portable_mutex_lock(&myinfo->messagemutex);
    HASH_FIND(hh,myinfo->messagetable,key,keylen,msg);
    if ( msg != 0 )
    {
        msgjson = cJSON_CreateObject();
        if ( basilisk_addhexstr(&ptr,msgjson,strbuf,sizeof(strbuf),msg->data,msg->datalen) != 0 )
        {
            jadd(retjson,"message",msgjson);
            jaddstr(retjson,"result","success");
            printf("havemessage len.%d\n",msg->datalen);
        } else jaddstr(retjson,"error","couldnt add message");
    } else jaddstr(retjson,"error","no message");
    portable_mutex_unlock(&myinfo->messagemutex);
    return(jprint(retjson,1));
}
Example #6
0
char *basilisk_respond_addmessage(struct supernet_info *myinfo,uint8_t *key,int32_t keylen,uint8_t *data,int32_t datalen,int32_t sendping)
{
    struct basilisk_message *msg;
    if ( keylen == sizeof(bits256)+sizeof(uint32_t)*2 )
    {
        msg = calloc(1,sizeof(*msg) + datalen);
        msg->expiration = (uint32_t)time(NULL) + INSTANTDEX_LOCKTIME*2;
        msg->keylen = keylen;
        memcpy(msg->key,key,keylen);
        msg->datalen = datalen;
        memcpy(msg->data,data,datalen);
        portable_mutex_lock(&myinfo->messagemutex);
        HASH_ADD_KEYPTR(hh,myinfo->messagetable,msg->key,msg->keylen,msg);
        portable_mutex_unlock(&myinfo->messagemutex);
        if ( sendping != 0 )
        {
            queue_enqueue("basilisk_message",&myinfo->msgQ,&msg->DL,0);
            return(clonestr("{\"result\":\"message added to hashtable\"}"));
        } else return(0);
    } else return(0);
}
Example #7
0
void *OS_portable_tmpalloc(char *dirname,char *name,struct OS_memspace *mem,long origsize)
{
#ifdef __PNACL
    return(OS_nonportable_tmpalloc(dirname,name,mem,origsize));
#else
    char fname[1024]; void *ptr; long size;
    if ( mem->threadsafe != 0 )
        portable_mutex_lock(&mem->mutex);
    if ( origsize != 0 && (mem->M.fileptr == 0 || (mem->used + origsize) > mem->totalsize) )
    {
        //coin->TMPallocated += origsize;
        memset(&mem->M,0,sizeof(mem->M));
        sprintf(fname,"tmp/%s/%s.%d",dirname,name,mem->counter), OS_compatible_path(fname);
        mem->counter++;
        if ( mem->totalsize == 0 )
        {
            mem->totalsize = (1024 * 1024 * 16);
        }
        //if ( coin->R.RSPACE.size == 0 )
        //    coin->R.RSPACE.size = mem->size;
        if ( mem->totalsize > origsize )
            size = mem->totalsize;
        else size = origsize;
        fprintf(stderr,"filealloc.(%s) -> ",fname);
        if ( OS_filealloc(&mem->M,fname,mem,size) == 0 )
        {
            printf("couldnt map tmpfile %s\n",fname);
            return(0);
        }
        fprintf(stderr,"created\n");
    }
    ptr = iguana_memalloc(mem,origsize,1);
    if ( mem->threadsafe != 0 )
        portable_mutex_unlock(&mem->mutex);
    return(ptr);
#endif
}
Example #8
0
void *iguana_kvconnectiterator(struct iguana_info *coin,struct iguanakv *kv,struct iguana_kvitem *item,uint64_t args,void *key,void *value,int32_t valuesize)
{
    struct iguana_iAddr *iA = value; char ipaddr[64]; int32_t i; struct iguana_peer *addr = 0;
    if ( iA->ipbits != 0 && iguana_numthreads(1 << IGUANA_CONNTHREAD) < IGUANA_MAXCONNTHREADS && iA->status != IGUANA_PEER_READY && iA->status != IGUANA_PEER_CONNECTING )
    {
        //printf("%x\n",iA->ipbits);
        expand_ipbits(ipaddr,iA->ipbits);
        portable_mutex_lock(&coin->peers_mutex);
        for (i=0; i<coin->MAXPEERS; i++)
        {
            addr = &coin->peers.active[i];
            if ( addr->pending != 0 || addr->ipbits == iA->ipbits || strcmp(ipaddr,addr->ipaddr) == 0 )
            {
                portable_mutex_unlock(&coin->peers_mutex);
                return(0);
            }
            if ( addr->ipbits == 0 )
            {
                iguana_initpeer(coin,addr,iA->ipbits);
                break;
            }
        }
        portable_mutex_unlock(&coin->peers_mutex);
        if ( addr != 0 )
        {
            //printf("status.%d addr.%p possible peer.(%s) (%s).%x %u threads %d %d %d %d\n",iA->status,addr,ipaddr,addr->ipaddr,addr->ipbits,addr->pending,iguana_numthreads(0),iguana_numthreads(1),iguana_numthreads(2),iguana_numthreads(3));
            iA->status = IGUANA_PEER_CONNECTING;
            if ( iguana_rwiAddrind(coin,1,iA,item->hh.itemind) > 0 )
            {
                //printf("iguana_startconnection.(%s) status.%d\n",ipaddr,IGUANA_PEER_CONNECTING);
                iguana_launch("connection",iguana_startconnection,addr,IGUANA_CONNTHREAD);
            }
        } else printf("no open peer slots left\n");
    }
    return(0);
}
int32_t PLUGNAME(_process_json)(char *forwarder,char *sender,int32_t valid,struct plugin_info *plugin,uint64_t tag,char *retbuf,int32_t maxlen,char *jsonstr,cJSON *json,int32_t initflag,char *tokenstr)
{
    char *resultstr,*methodstr,*retstr = 0;
    retbuf[0] = 0;
    if ( Debuglevel > 2 )
        fprintf(stderr,"<<<<<<<<<<<< INSIDE PLUGIN! process %s (%s)\n",plugin->name,jsonstr);
    if ( initflag > 0 )
    {
        // configure settings
        plugin->allowremote = 1;
        portable_mutex_init(&plugin->mutex);
        init_InstantDEX(calc_nxt64bits(SUPERNET.NXTADDR),0);
        update_NXT_assettrades();
        INSTANTDEX.readyflag = 1;
        strcpy(retbuf,"{\"result\":\"InstantDEX init\"}");
    }
    else
    {
        if ( plugin_result(retbuf,json,tag) > 0 )
            return((int32_t)strlen(retbuf));
        resultstr = cJSON_str(cJSON_GetObjectItem(json,"result"));
        if ( (methodstr= cJSON_str(cJSON_GetObjectItem(json,"method"))) == 0 )
            methodstr = cJSON_str(cJSON_GetObjectItem(json,"requestType"));
        retbuf[0] = 0;
        if ( methodstr == 0 || methodstr[0] == 0 )
        {
            printf("(%s) has not method\n",jsonstr);
            return(0);
        }
        portable_mutex_lock(&plugin->mutex);
        if ( resultstr != 0 && strcmp(resultstr,"registered") == 0 )
        {
            plugin->registered = 1;
            strcpy(retbuf,"{\"result\":\"activated\"}");
        }
        else if ( strcmp(methodstr,"msigaddr") == 0 )
        {
            char *devMGW_command(char *jsonstr,cJSON *json);
            if ( SUPERNET.gatewayid >= 0 )
            {
                if ( (retstr= devMGW_command(jsonstr,json)) != 0 )
                {
                    //should_forward(sender,retstr);
                }
            } //else retstr = nn_loadbalanced((uint8_t *)jsonstr,(int32_t)strlen(jsonstr)+1);
        }
        else if ( strcmp(methodstr,"LSUM") == 0 )
        {
            sprintf(retbuf,"{\"result\":\"%s\",\"amount\":%d}",(rand() & 1) ? "BUY" : "SELL",(rand() % 100) * 100000);
            retstr = clonestr(retbuf);
        }
        else if ( SUPERNET.iamrelay == 0 )
        {
            retstr = InstantDEX_parser(forwarder,sender,valid,jsonstr,json);
//printf("InstantDEX_parser return.(%s)\n",retstr);
        } else retstr = clonestr("{\"result\":\"relays only relay\"}");
        if ( retstr != 0 )
        {
            if ( strlen(retstr) >= maxlen-1 )
                retstr[maxlen-1] = 0;
            strcpy(retbuf,retstr);
            free(retstr);
        }
        //else sprintf(retbuf,"{\"error\":\"method %s not found\"}",methodstr);
        portable_mutex_unlock(&plugin->mutex);
    }
    return((int32_t)strlen(retbuf) + retbuf[0]!=0);
}
char *InstantDEX(char *jsonstr,char *remoteaddr,int32_t localaccess)
{
    char *prices777_allorderbooks();
    char *InstantDEX_openorders();
    char *InstantDEX_tradehistory(int32_t firsti,int32_t endi);
    char *InstantDEX_cancelorder(char *activenxt,char *secret,uint64_t sequenceid,uint64_t quoteid);
    struct destbuf exchangestr,method,gui,name,base,rel; double balance;
    char *retstr = 0,key[512],retbuf[1024],*activenxt,*secret,*coinstr; struct InstantDEX_quote iQ; struct exchange_info *exchange;
    cJSON *json; uint64_t assetbits,sequenceid; uint32_t maxdepth; int32_t invert=0,keysize,allfields; struct prices777 *prices;
    //printf("INSTANTDEX.(%s)\n",jsonstr);
    if ( INSTANTDEX.readyflag == 0 )
        return(0);
    if ( jsonstr != 0 && (json= cJSON_Parse(jsonstr)) != 0 )
    {
        // test: asset/asset, asset/external, external/external, autofill and automatch
        // peggy integration
        bidask_parse(&exchangestr,&name,&base,&rel,&gui,&iQ,json);
        if ( iQ.s.offerNXT == 0 )
            iQ.s.offerNXT = SUPERNET.my64bits;
        //printf("isask.%d base.(%s) rel.(%s)\n",iQ.s.isask,base.buf,rel.buf);
        copy_cJSON(&method,jobj(json,"method"));
        if ( (sequenceid= j64bits(json,"orderid")) == 0 )
            sequenceid = j64bits(json,"sequenceid");
        allfields = juint(json,"allfields");
        if ( (maxdepth= juint(json,"maxdepth")) <= 0 )
            maxdepth = MAX_DEPTH;
        if ( exchangestr.buf[0] == 0 )
        {
            if ( iQ.s.baseid != 0 && iQ.s.relid != 0 )
                strcpy(exchangestr.buf,"nxtae");
            else strcpy(exchangestr.buf,"basket");
        }
        assetbits = InstantDEX_name(key,&keysize,exchangestr.buf,name.buf,base.buf,&iQ.s.baseid,rel.buf,&iQ.s.relid);
        //printf("2nd isask.%d base.(%s) rel.(%s)\n",iQ.s.isask,base.buf,rel.buf);
        exchange = exchange_find(exchangestr.buf);
        secret = jstr(json,"secret"), activenxt = jstr(json,"activenxt");
        if ( secret == 0 )
        {
            secret = SUPERNET.NXTACCTSECRET;
            activenxt = SUPERNET.NXTADDR;
        }
        if ( strcmp(method.buf,"allorderbooks") == 0 )
            retstr = prices777_allorderbooks();
        /*else if ( strcmp(method.buf,"coinshuffle") == 0 )
        {
            if ( strcmp(exchangestr.buf,"shuffle") == 0 )
                retstr = InstantDEX_coinshuffle(base.buf,&iQ,json);
            else retstr = clonestr("{\"error\":\"coinshuffle must use shuffle exchange\"}");
        }*/
        else if ( strcmp(method.buf,"openorders") == 0 )
            retstr = InstantDEX_openorders(SUPERNET.NXTADDR,juint(json,"allorders"));
        else if ( strcmp(method.buf,"allexchanges") == 0 )
            retstr = jprint(exchanges_json(),1);
        else if ( strcmp(method.buf,"cancelorder") == 0 )
            retstr = InstantDEX_cancelorder(jstr(json,"activenxt"),jstr(json,"secret"),sequenceid,iQ.s.quoteid);
        else if ( strcmp(method.buf,"orderstatus") == 0 )
            retstr = InstantDEX_orderstatus(sequenceid,iQ.s.quoteid);
        else if ( strcmp(method.buf,"tradehistory") == 0 )
            retstr = InstantDEX_tradehistory(juint(json,"firsti"),juint(json,"endi"));
        else if ( strcmp(method.buf,"lottostats") == 0 )
            retstr = jprint(InstantDEX_lottostats(),1);
        else if ( strcmp(method.buf,"balance") == 0 )
        {
            if ( exchange != 0 && exchange->trade != 0 )
            {
                if ( (coinstr= jstr(json,"base")) != 0 )
                {
                    if ( exchange->coinbalance != 0 )
                    {
                        if ( exchange->balancejson == 0 )
                        {
                            (*exchange->trade)(&retstr,exchange,0,0,0,0,0);
                            if ( retstr != 0 )
                            {
                                exchange->balancejson = cJSON_Parse(retstr);
                                free(retstr);
                            }
                        }
                        return((*exchange->coinbalance)(exchange,&balance,coinstr));
                    }
                    else retstr = clonestr("{\"error\":\"coinbalance missing\"}");
                }
                else (*exchange->trade)(&retstr,exchange,0,0,0,0,0);
            } else retstr = clonestr("{\"error\":\"cant find exchange\"}");
            printf("%s ptr%.p trade.%p\n",exchangestr.buf,exchange,exchange!=0?exchange->trade:0);
        }
        else if ( strcmp(method.buf,"tradesequence") == 0 )
        {
            //printf("call tradesequence.(%s)\n",jsonstr);
            retstr = InstantDEX_tradesequence(activenxt,secret,json);
        }
        else if ( strcmp(method.buf,"makebasket") == 0 )
        {
            if ( (prices= prices777_makebasket(0,json,1,"basket",0,0)) != 0 )
                retstr = clonestr("{\"result\":\"basket made\"}");
            else retstr = clonestr("{\"error\":\"couldnt make basket\"}");
        }
        else if ( strcmp(method.buf,"peggyrates") == 0 )
        {
            if ( SUPERNET.peggy != 0 )
                retstr = peggyrates(juint(json,"timestamp"));
            else retstr = clonestr("{\"error\":\"peggy disabled\"}");
        }
        else if ( strcmp(method.buf,"LSUM") == 0 )
        {
            sprintf(retbuf,"{\"result\":\"%s\",\"amount\":%d}",(rand() & 1) ? "BUY" : "SELL",(rand() % 100) * 100000);
            retstr = clonestr(retbuf);
        }
        else if ( strcmp(method.buf,"placebid") == 0 || strcmp(method.buf,"placeask") == 0 )
            return(InstantDEX_placebidask(0,sequenceid,exchangestr.buf,name.buf,base.buf,rel.buf,&iQ,jstr(json,"extra"),secret,activenxt,json));
        else if ( strcmp(exchangestr.buf,"active") == 0 && strcmp(method.buf,"orderbook") == 0 )
            retstr = prices777_activebooks(name.buf,base.buf,rel.buf,iQ.s.baseid,iQ.s.relid,maxdepth,allfields,strcmp(exchangestr.buf,"active") == 0 || juint(json,"tradeable"));
        else if ( (prices= prices777_find(&invert,iQ.s.baseid,iQ.s.relid,exchangestr.buf)) == 0 )
        {
            if ( (prices= prices777_poll(exchangestr.buf,name.buf,base.buf,iQ.s.baseid,rel.buf,iQ.s.relid)) != 0 )
            {
                if ( prices777_equiv(prices->baseid) == prices777_equiv(iQ.s.baseid) && prices777_equiv(prices->relid) == prices777_equiv(iQ.s.relid) )
                    invert = 0;
                else if ( prices777_equiv(prices->baseid) == prices777_equiv(iQ.s.relid) && prices777_equiv(prices->relid) == prices777_equiv(iQ.s.baseid) )
                    invert = 1;
                else invert = 0, printf("baserel not matching (%s %s) %llu %llu vs (%s %s) %llu %llu\n",prices->base,prices->rel,(long long)prices->baseid,(long long)prices->relid,base.buf,rel.buf,(long long)iQ.s.baseid,(long long)iQ.s.relid);
            }
        }
        if ( retstr == 0 && prices != 0 )
        {
            if ( strcmp(method.buf,"disable") == 0 )
            {
                if ( prices != 0 )
                {
                    if ( strcmp(prices->exchange,"unconf") == 0 )
                        return(clonestr("{\"error\":\"cannot disable unconf\"}"));
                    prices->disabled = 1;
                    return(clonestr("{\"result\":\"success\"}"));
                }
                else return(clonestr("{\"error\":\"no prices to disable\"}"));
            }
            else if ( strcmp(method.buf,"enable") == 0 )
            {
                if ( prices != 0 )
                {
                    prices->disabled = 0;
                    return(clonestr("{\"result\":\"success\"}"));
                }
                else return(clonestr("{\"error\":\"no prices to enable\"}"));
            }
            else if ( strcmp(method.buf,"orderbook") == 0 )
            {
                if ( maxdepth < MAX_DEPTH )
                    return(prices777_orderbook_jsonstr(invert,SUPERNET.my64bits,prices,&prices->O,maxdepth,allfields));
                else if ( (retstr= prices->orderbook_jsonstrs[invert][allfields]) == 0 )
                {
                    retstr = prices777_orderbook_jsonstr(invert,SUPERNET.my64bits,prices,&prices->O,MAX_DEPTH,allfields);
                    portable_mutex_lock(&prices->mutex);
                    if ( prices->orderbook_jsonstrs[invert][allfields] != 0 )
                        free(prices->orderbook_jsonstrs[invert][allfields]);
                    prices->orderbook_jsonstrs[invert][allfields] = retstr;
                    portable_mutex_unlock(&prices->mutex);
                    if ( retstr == 0 )
                        retstr = clonestr("{}");
                }
                if ( retstr != 0 )
                    retstr = clonestr(retstr);
            }
        }
        //if ( Debuglevel > 2 )
            printf("(%s) %p exchange.(%s) base.(%s) %llu rel.(%s) %llu | name.(%s) %llu\n",retstr!=0?retstr:"",prices,exchangestr.buf,base.buf,(long long)iQ.s.baseid,rel.buf,(long long)iQ.s.relid,name.buf,(long long)assetbits);
    }
    return(retstr);
}