diff --git a/iguana/iguana_instantdex.c b/iguana/iguana_instantdex.c index 3db31f059..97f78ec31 100755 --- a/iguana/iguana_instantdex.c +++ b/iguana/iguana_instantdex.c @@ -28,14 +28,14 @@ #define INSTANTDEX_BTCD "RThtXup6Zo7LZAi8kRWgjAyi1s4u6U9Cpf" #define INSTANTDEX_MINPERC 50. -struct instantdex_event { char cmdstr[24],sendcmd[16]; struct instantdex_stateinfo *nextstate; }; +struct instantdex_event { char cmdstr[24],sendcmd[16]; int16_t nextstateind; }; struct instantdex_stateinfo { - char name[24]; uint16_t ind,pad; + char name[24]; int16_t ind,initialstate; cJSON *(*process)(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *A,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp); cJSON *(*timeout)(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *A,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp); - uint16_t timeoutind,errorind; + int16_t timeoutind,errorind; struct instantdex_event *events; int32_t numevents; }; @@ -127,7 +127,7 @@ void instantdex_stateinit(struct instantdex_stateinfo *states,int32_t numstates, state->timeout = instantdex_defaulttimeout; } -struct instantdex_stateinfo *instantdex_statecreate(struct instantdex_stateinfo *states,int32_t *numstatesp,char *name,cJSON *(*process_func)(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *A,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp),cJSON *(*timeout_func)(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *A,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp),char *timeoutstr,char *errorstr) +struct instantdex_stateinfo *instantdex_statecreate(struct instantdex_stateinfo *states,int32_t *numstatesp,char *name,cJSON *(*process_func)(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *A,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp),cJSON *(*timeout_func)(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *A,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp),char *timeoutstr,char *errorstr,int32_t initialstate) { struct instantdex_stateinfo S,*state = 0; if ( (state= instantdex_statefind(states,*numstatesp,name)) == 0 ) @@ -135,6 +135,7 @@ struct instantdex_stateinfo *instantdex_statecreate(struct instantdex_stateinfo states = realloc(states,sizeof(*states) * (*numstatesp + 1)); state = &states[*numstatesp]; instantdex_stateinit(states,*numstatesp,state,name,errorstr,timeoutstr,process_func,timeout_func); + state->initialstate = initialstate; state->ind = (*numstatesp)++; printf("STATES[%d] %s %p %p %d %d\n",*numstatesp,state->name,state->process,state->timeout,state->timeoutind,state->errorind); } @@ -142,6 +143,7 @@ struct instantdex_stateinfo *instantdex_statecreate(struct instantdex_stateinfo { instantdex_stateinit(states,*numstatesp,&S,name,errorstr,timeoutstr,process_func,timeout_func); S.ind = state->ind; + S.initialstate = initialstate; if ( memcmp(&S,state,sizeof(S) - sizeof(void *) - sizeof(int)) != 0 ) { int32_t i; @@ -169,7 +171,7 @@ struct instantdex_event *instantdex_addevent(struct instantdex_stateinfo *states strcpy(state->events[state->numevents].cmdstr,cmdstr); if ( sendcmd != 0 ) strcpy(state->events[state->numevents].sendcmd,sendcmd); - state->events[state->numevents].nextstate = nextstate; + state->events[state->numevents].nextstateind = nextstate->ind; state->numevents++; } return(state->events); @@ -182,6 +184,31 @@ struct instantdex_event *instantdex_addevent(struct instantdex_stateinfo *states } } +int32_t instantdex_FSMtest(struct instantdex_stateinfo *states,int32_t numstates) +{ + int32_t i,n,m=0,initials[100],maxiters = 1; struct instantdex_stateinfo *state; struct instantdex_event *event; + for (i=n=0; i 0 && n < sizeof(initials)/sizeof(*initials) ) + { + for (i=0; iinitialstate >= 0 ) + { + event = &state->events[rand() % state->numevents]; + if ( event->nextstateind < 0 ) + break; + state = &states[event->nextstateind]; + } + printf("reached terminal state.%s after m.%d events\n",state->name,m); + } + } + return(m); +} + cJSON *InstantDEX_argjson(char *reference,char *message,char *othercoinaddr,char *otherNXTaddr,int32_t iter,int32_t val,int32_t val2) { cJSON *argjson = cJSON_CreateObject(); diff --git a/iguana/pnacl/Release/iguana.pexe b/iguana/pnacl/Release/iguana.pexe index d0190b2f6..6dc1891ca 100644 Binary files a/iguana/pnacl/Release/iguana.pexe and b/iguana/pnacl/Release/iguana.pexe differ diff --git a/iguana/swaps/iguana_BTCswap.c b/iguana/swaps/iguana_BTCswap.c index 64e991a86..ed35f80be 100755 --- a/iguana/swaps/iguana_BTCswap.c +++ b/iguana/swaps/iguana_BTCswap.c @@ -696,35 +696,35 @@ struct instantdex_stateinfo *BTC_initFSM(int32_t *n) // states instantdex_statecreate(s,n,,handlerfunc,errorhandler,, // a given state has a couple of handlers and custom events, with timeouts and errors invoking a bypass - s = instantdex_statecreate(s,n,"BTC_cleanup",BTC_cleanupfunc,0,0,0); // from states without any commits + s = instantdex_statecreate(s,n,"BTC_cleanup",BTC_cleanupfunc,0,0,0,0); // from states without any commits - s = instantdex_statecreate(s,n,"BOB_reclaim",BOB_reclaimfunc,0,0,0); // Bob's gets his deposit back + s = instantdex_statecreate(s,n,"BOB_reclaim",BOB_reclaimfunc,0,0,0,0); // Bob's gets his deposit back instantdex_addevent(s,*n,"BOB_reclaim","brcfound","poll","BTC_cleanup"); instantdex_addevent(s,*n,"BOB_reclaim","poll","poll","BOB_reclaim"); - s = instantdex_statecreate(s,n,"ALICE_reclaim",ALICE_reclaimfunc,0,0,0); // Alice retrieves alt payment + s = instantdex_statecreate(s,n,"ALICE_reclaim",ALICE_reclaimfunc,0,0,0,0); // Alice retrieves alt payment instantdex_addevent(s,*n,"ALICE_reclaim","arcfound","poll","BTC_cleanup"); instantdex_addevent(s,*n,"ALICE_reclaim","poll","poll","ALICE_reclaim"); - s = instantdex_statecreate(s,n,"ALICE_claimedbtc",ALICE_claimbtcfunc,0,0,0); // mainstream cases + s = instantdex_statecreate(s,n,"ALICE_claimedbtc",ALICE_claimbtcfunc,0,0,0,0); // mainstream cases instantdex_addevent(s,*n,"ALICE_claimedbtc","aclfound","poll","BTC_cleanup"); instantdex_addevent(s,*n,"ALICE_claimedbtc","poll","poll","ALICE_claimedbtc"); - s = instantdex_statecreate(s,n,"BOB_claimedalt",BOB_claimaltfunc,0,0,0); + s = instantdex_statecreate(s,n,"BOB_claimedalt",BOB_claimaltfunc,0,0,0,0); instantdex_addevent(s,*n,"BOB_claimedalt","bclfound","poll","BTC_cleanup"); instantdex_addevent(s,*n,"BOB_claimedalt","poll","poll","BOB_claimedalt"); // need to create states before they can be referred to, that way a one pass FSM compile is possible - s = instantdex_statecreate(s,n,"BOB_sentprivs",BTC_waitprivsfunc,0,"BTC_cleanup",0); - s = instantdex_statecreate(s,n,"BOB_waitfee",BOB_waitfeefunc,0,"BTC_cleanup",0); - s = instantdex_statecreate(s,n,"BOB_sentdeposit",BOB_waitBTCalttxfunc,0,"BOB_reclaim",0); - s = instantdex_statecreate(s,n,"BOB_altconfirm",BOB_waitaltconfirmfunc,0,"BOB_reclaim",0); - s = instantdex_statecreate(s,n,"BOB_sentpayment",BOB_waitprivMfunc,0,"BOB_reclaim",0); - s = instantdex_statecreate(s,n,"ALICE_sentprivs",BTC_waitprivsfunc,0,"BTC_cleanup",0); - s = instantdex_statecreate(s,n,"Alice_waitfee",ALICE_waitfeefunc,0,"BTC_cleanup",0); - s = instantdex_statecreate(s,n,"ALICE_waitdeposit",ALICE_waitdepositfunc,0,"BTC_cleanup",0); - s = instantdex_statecreate(s,n,"ALICE_sentalt",ALICE_waitBTCpaytxfunc,0,"ALICE_reclaim",0); - s = instantdex_statecreate(s,n,"ALICE_waitconfirms",ALICE_waitpayconf_or_bobreclaimfunc,0,"ALICE_reclaim",0); + s = instantdex_statecreate(s,n,"BOB_sentprivs",BTC_waitprivsfunc,0,"BTC_cleanup",0,0); + s = instantdex_statecreate(s,n,"BOB_waitfee",BOB_waitfeefunc,0,"BTC_cleanup",0,0); + s = instantdex_statecreate(s,n,"BOB_sentdeposit",BOB_waitBTCalttxfunc,0,"BOB_reclaim",0,0); + s = instantdex_statecreate(s,n,"BOB_altconfirm",BOB_waitaltconfirmfunc,0,"BOB_reclaim",0,0); + s = instantdex_statecreate(s,n,"BOB_sentpayment",BOB_waitprivMfunc,0,"BOB_reclaim",0,0); + s = instantdex_statecreate(s,n,"ALICE_sentprivs",BTC_waitprivsfunc,0,"BTC_cleanup",0,0); + s = instantdex_statecreate(s,n,"Alice_waitfee",ALICE_waitfeefunc,0,"BTC_cleanup",0,0); + s = instantdex_statecreate(s,n,"ALICE_waitdeposit",ALICE_waitdepositfunc,0,"BTC_cleanup",0,0); + s = instantdex_statecreate(s,n,"ALICE_sentalt",ALICE_waitBTCpaytxfunc,0,"ALICE_reclaim",0,0); + s = instantdex_statecreate(s,n,"ALICE_waitconfirms",ALICE_waitpayconf_or_bobreclaimfunc,0,"ALICE_reclaim",0,0); // events instantdex_addevent(s,*n,,,,) if ( 0 ) // following are implicit states and events handled externally to setup datastructures @@ -737,60 +737,61 @@ struct instantdex_stateinfo *BTC_initFSM(int32_t *n) instantdex_addevent(s,*n,"ALICE_idle","BTCoffer","BTCdeckC","ALICE_gotoffer"); } // after offer is sent, wait for other side to choose and sent their deck, then send privs - s = instantdex_statecreate(s,n,"BOB_sentoffer",BTC_waitdeckCfunc,0,"BTC_cleanup",0); - s = instantdex_statecreate(s,n,"ALICE_sentoffer",BTC_waitdeckCfunc,0,"BTC_cleanup",0); + s = instantdex_statecreate(s,n,"BOB_sentoffer",BTC_waitdeckCfunc,0,"BTC_cleanup",0,1); + s = instantdex_statecreate(s,n,"ALICE_sentoffer",BTC_waitdeckCfunc,0,"BTC_cleanup",0,1); instantdex_addevent(s,*n,"BOB_sentoffer","BTCdeckC","BTCprivC","BOB_sentprivs"); // send privs + Chose instantdex_addevent(s,*n,"ALICE_sentoffer","BTCdeckC","BTCprivC","ALICE_sentprivs"); // gotoffer states have received deck and sent BTCdeckC already (along with deck) - s = instantdex_statecreate(s,n,"BOB_gotoffer",BTC_waitprivCfunc,0,"BTC_cleanup",0); - s = instantdex_statecreate(s,n,"ALICE_gotoffer",BTC_waitprivCfunc,0,"BTC_cleanup",0); + s = instantdex_statecreate(s,n,"BOB_gotoffer",BTC_waitprivCfunc,0,"BTC_cleanup",0,1); + s = instantdex_statecreate(s,n,"ALICE_gotoffer",BTC_waitprivCfunc,0,"BTC_cleanup",0,1); instantdex_addevent(s,*n,"BOB_gotoffer","BTCprivC","BTCprivs","BOB_sentprivs"); // send privs instantdex_addevent(s,*n,"ALICE_gotoffer","BTCprivC","BTCprivs","ALICE_sentprivs"); // to reach sentprivs, all paths must have sent/recv deck and Chose and verified cut and choose - s = instantdex_statecreate(s,n,"BOB_sentprivs",BTC_waitprivsfunc,0,"BTC_cleanup",0); + s = instantdex_statecreate(s,n,"BOB_sentprivs",BTC_waitprivsfunc,0,"BTC_cleanup",0,0); instantdex_addevent(s,*n,"BOB_sentprivs","BTCprivs","poll","BOB_waitfee"); - s = instantdex_statecreate(s,n,"ALICE_sentprivs",BTC_waitprivsfunc,0,"BTC_cleanup",0); + s = instantdex_statecreate(s,n,"ALICE_sentprivs",BTC_waitprivsfunc,0,"BTC_cleanup",0,0); instantdex_addevent(s,*n,"ALICE_sentprivs","BTCprivs","poll","Alice_waitfee"); // Bob waits for fee and sends deposit when it appears - s = instantdex_statecreate(s,n,"BOB_waitfee",BOB_waitfeefunc,0,"BTC_cleanup",0); + s = instantdex_statecreate(s,n,"BOB_waitfee",BOB_waitfeefunc,0,"BTC_cleanup",0,0); instantdex_addevent(s,*n,"BOB_waitfee","feefound","BTCdeptx","BOB_sentdeposit"); instantdex_addevent(s,*n,"BOB_waitfee","poll","poll","BOB_waitfee"); // Alice waits for fee and then waits for deposit to confirm and sends altpayment - s = instantdex_statecreate(s,n,"Alice_waitfee",ALICE_waitfeefunc,0,"BTC_cleanup",0); + s = instantdex_statecreate(s,n,"Alice_waitfee",ALICE_waitfeefunc,0,"BTC_cleanup",0,0); instantdex_addevent(s,*n,"Alice_waitfee","feefound","poll","ALICE_waitdeposit"); instantdex_addevent(s,*n,"Alice_waitfee","poll","poll","Alice_waitfee"); - s = instantdex_statecreate(s,n,"ALICE_waitdeposit",ALICE_waitdepositfunc,0,"BTC_cleanup",0); + s = instantdex_statecreate(s,n,"ALICE_waitdeposit",ALICE_waitdepositfunc,0,"BTC_cleanup",0,0); instantdex_addevent(s,*n,"ALICE_waitdeposit","depfound","BTCalttx","ALICE_sentalt"); instantdex_addevent(s,*n,"ALICE_waitdeposit","poll","poll","ALICE_waitdeposit"); // now Bob's turn to make sure altpayment is confirmed and send real payment - s = instantdex_statecreate(s,n,"BOB_sentdeposit",BOB_waitBTCalttxfunc,0,"BOB_reclaim",0); + s = instantdex_statecreate(s,n,"BOB_sentdeposit",BOB_waitBTCalttxfunc,0,"BOB_reclaim",0,0); instantdex_addevent(s,*n,"BOB_sentdeposit","BTCalttx","poll","BOB_altconfirm"); - s = instantdex_statecreate(s,n,"BOB_altconfirm",BOB_waitaltconfirmfunc,0,"BOB_reclaim",0); + s = instantdex_statecreate(s,n,"BOB_altconfirm",BOB_waitaltconfirmfunc,0,"BOB_reclaim",0,0); instantdex_addevent(s,*n,"BOB_altconfirm","altfound","BTCpaytx","BOB_sentpayment"); instantdex_addevent(s,*n,"BOB_altconfirm","poll","poll","BOB_altconfirm"); // now Alice's turn to make sure payment is confrmed and send in claim or see bob's reclaim and reclaim - s = instantdex_statecreate(s,n,"ALICE_sentalt",ALICE_waitBTCpaytxfunc,0,"ALICE_reclaim",0); + s = instantdex_statecreate(s,n,"ALICE_sentalt",ALICE_waitBTCpaytxfunc,0,"ALICE_reclaim",0,0); instantdex_addevent(s,*n,"ALICE_sentalt","BTCpaytx","poll","ALICE_waitconfirms"); - s = instantdex_statecreate(s,n,"ALICE_waitconfirms",ALICE_waitpayconf_or_bobreclaimfunc,0,"ALICE_reclaim",0); + s = instantdex_statecreate(s,n,"ALICE_waitconfirms",ALICE_waitpayconf_or_bobreclaimfunc,0,"ALICE_reclaim",0,0); instantdex_addevent(s,*n,"ALICE_waitconfirms","bobfound","poll","ALICE_reclaim"); instantdex_addevent(s,*n,"ALICE_waitconfirms","payfound","BTCprivM","ALICE_claimedbtc"); instantdex_addevent(s,*n,"ALICE_waitconfirms","poll","poll","ALICE_waitconfirms"); // Bob waits for privM either from Alice or alt blockchain - s = instantdex_statecreate(s,n,"BOB_sentpayment",BOB_waitprivMfunc,0,"BOB_reclaim",0); + s = instantdex_statecreate(s,n,"BOB_sentpayment",BOB_waitprivMfunc,0,"BOB_reclaim",0,0); instantdex_addevent(s,*n,"BOB_sentpayment","btcfound","BTCdone","BOB_claimedalt"); instantdex_addevent(s,*n,"BOB_sentpayment","BTCprivM","BTCdone","BOB_claimedalt"); instantdex_addevent(s,*n,"BOB_sentpayment","poll","poll","BOB_sentpayment"); + instantdex_FSMtest(s,*n); return(s); } @@ -828,11 +829,11 @@ char *instantdex_statemachine(struct instantdex_stateinfo *states,int32_t numsta } else { - if ( state->events[i].sendcmd != 0 ) + if ( state->events[i].sendcmd[0] != 0 ) { - if ( state->events[i].nextstate->ind > 1 ) + if ( state->events[i].nextstateind > 1 ) { - swap->state = &states[state->events[i].nextstate->ind]; + swap->state = &states[state->events[i].nextstateind]; return(instantdex_sendcmd(myinfo,&A->offer,newjson,state->events[i].sendcmd,swap->othertrader,INSTANTDEX_HOPS,serdata,serdatalen)); } else return(clonestr("{\"error\":\"instantdex_statemachine: illegal state\"}")); } else return(clonestr("{\"result\":\"instantdex_statemachine: processed\"}"));