From 7e35f61a63bb7a7b92e66419e339d3be313f9f0c Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 29 Jan 2019 01:25:02 -1100 Subject: [PATCH 01/80] Gen tx --- src/cc/sudoku.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/cc/sudoku.cpp b/src/cc/sudoku.cpp index 20d11567a..adba75920 100644 --- a/src/cc/sudoku.cpp +++ b/src/cc/sudoku.cpp @@ -476,6 +476,7 @@ void sudoku_gen(uint8_t key32[32],uint8_t unsolved[9][9],uint32_t srandi) } //////////////////////// start of CClib interface +// ./komodod -ac_name=SUDOKU -ac_supply=1000000 -pubkey= -addnode=5.9.102.210 -gen -genproclimit=1 -ac_cclib=sudoku -ac_perc=10000000 -ac_reward=100000000 -ac_cc=60000 -ac_script=2ea22c80203d1579313abe7d8ea85f48c65ea66fc512c878c0d0e6f6d54036669de940febf8103120c008203000401cc & UniValue sudoku_txidinfo(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) { @@ -517,13 +518,15 @@ UniValue sudoku_generate(uint64_t txfee,struct CCcontract_info *cp,cJSON *params priv2addr(coinaddr,pub33,privkey); pk = buf2pk(pub33); sudokupk = GetUnspendable(cp,0); - inputsum = amount + 2*txfee; - mtx.vout.push_back(MakeCC1vout(cp->evalcode,txfee,sudokupk)); - mtx.vout.push_back(MakeCC1vout(cp->evalcode,inputsum - 2*txfee,pk)); - rawtx = FinalizeCCTx(0,cp,mtx,sudokupk,txfee,sudoku_genopret(unsolved)); result.push_back(Pair("srand",(int)srandi)); result.push_back(Pair("amount",ValueFromAmount(amount))); - result.push_back(Pair("hex",rawtx)); + if ( (inputsum= AddCClibInputs(cp,mtx,sudokupk,amount+2*txfee,16)) >= amount+2*txfee ) + { + mtx.vout.push_back(MakeCC1vout(cp->evalcode,txfee,sudokupk)); + mtx.vout.push_back(MakeCC1vout(cp->evalcode,inputsum - 2*txfee,pk)); + rawtx = FinalizeCCTx(0,cp,mtx,sudokupk,txfee,sudoku_genopret(unsolved)); + result.push_back(Pair("hex",rawtx)); + } else result.push_back(Pair("error","not enough SUDOKU funds")); return(result); } From 89a9ce3b121332c92c0826dce8d51cea859bb675 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 29 Jan 2019 01:29:19 -1100 Subject: [PATCH 02/80] +print --- src/cc/cclib.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc/cclib.cpp b/src/cc/cclib.cpp index 8a7d054f7..7d5a26e42 100644 --- a/src/cc/cclib.cpp +++ b/src/cc/cclib.cpp @@ -257,9 +257,9 @@ int64_t AddCClibInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubK { txid = it->first.txhash; vout = (int32_t)it->first.index; + char str[65]; fprintf(stderr,"check %s/v%d %.8f`\n",uint256_str(str,txid),vout,(double)it->second.satoshis/COIN); if ( it->second.satoshis < threshold ) continue; - //char str[65]; fprintf(stderr,"check %s/v%d %.8f`\n",uint256_str(str,txid),vout,(double)it->second.satoshis/COIN); // no need to prevent dup if ( GetTransaction(txid,vintx,hashBlock,false) != 0 ) { From 21ee88562ce2b4fe2c8d7fff9197f83a070d1bdf Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 29 Jan 2019 01:39:10 -1100 Subject: [PATCH 03/80] CCbalance --- src/cc/cclib.cpp | 2 +- src/wallet/rpcwallet.cpp | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/cc/cclib.cpp b/src/cc/cclib.cpp index 7d5a26e42..83afb86ef 100644 --- a/src/cc/cclib.cpp +++ b/src/cc/cclib.cpp @@ -257,7 +257,7 @@ int64_t AddCClibInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubK { txid = it->first.txhash; vout = (int32_t)it->first.index; - char str[65]; fprintf(stderr,"check %s/v%d %.8f`\n",uint256_str(str,txid),vout,(double)it->second.satoshis/COIN); + char str[65]; fprintf(stderr,"%s check %s/v%d %.8f\n",coinaddr,uint256_str(str,txid),vout,(double)it->second.satoshis/COIN); if ( it->second.satoshis < threshold ) continue; // no need to prevent dup diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 970dfa3cf..fc1839de2 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -5220,6 +5220,7 @@ UniValue CCaddress(struct CCcontract_info *cp,char *name,std::vectorunspendableCCaddr)); + result.push_back(Pair("CCbalance",ValueFromAmount(CCaddress_balance(cp->unspendableCCaddr)))); sprintf(str,"%smarker",name); result.push_back(Pair(str,cp->normaladdr)); result.push_back(Pair("GatewaysPubkey","03ea9c062b9652d8eff34879b504eda0717895d27597aaeb60347d65eed96ccb40")); @@ -5234,7 +5235,10 @@ UniValue CCaddress(struct CCcontract_info *cp,char *name,std::vector Date: Tue, 29 Jan 2019 01:45:41 -1100 Subject: [PATCH 04/80] Sudokupk signing --- src/cc/sudoku.cpp | 9 +++++++-- src/wallet/rpcwallet.cpp | 3 +++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/cc/sudoku.cpp b/src/cc/sudoku.cpp index adba75920..336edffcd 100644 --- a/src/cc/sudoku.cpp +++ b/src/cc/sudoku.cpp @@ -502,7 +502,7 @@ CScript sudoku_genopret(uint8_t unsolved[9][9]) UniValue sudoku_generate(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) { CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); - UniValue result(UniValue::VOBJ); CPubKey sudokupk,pk; uint8_t privkey[32],unsolved[9][9],pub33[33]; uint32_t srandi; uint256 hash; char coinaddr[64]; uint64_t inputsum,amount; std::string rawtx; + UniValue result(UniValue::VOBJ); CPubKey sudokupk,pk; uint8_t privkey[32],unsolved[9][9],pub33[33]; uint32_t srandi; uint256 hash; char coinaddr[64]; uint64_t inputsum,amount,change=0; std::string rawtx; if ( params != 0 ) { printf("params.(%s)\n",jprint(params,0)); @@ -523,7 +523,12 @@ UniValue sudoku_generate(uint64_t txfee,struct CCcontract_info *cp,cJSON *params if ( (inputsum= AddCClibInputs(cp,mtx,sudokupk,amount+2*txfee,16)) >= amount+2*txfee ) { mtx.vout.push_back(MakeCC1vout(cp->evalcode,txfee,sudokupk)); - mtx.vout.push_back(MakeCC1vout(cp->evalcode,inputsum - 2*txfee,pk)); + mtx.vout.push_back(MakeCC1vout(cp->evalcode,amount,pk)); + if ( inputsum > amount + 2*txfee ) + change = (inputsum - amount - 2*txfee); + if ( change > txfee ) + mtx.vout.push_back(MakeCC1vout(cp->evalcode,change,sudokupk)); + CCaddr2set(cp,cp->evalcode,sudokupk,cp->CCpriv,cp->CCaddr); rawtx = FinalizeCCTx(0,cp,mtx,sudokupk,txfee,sudoku_genopret(unsolved)); result.push_back(Pair("hex",rawtx)); } else result.push_back(Pair("error","not enough SUDOKU funds")); diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index fc1839de2..3409710ad 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -5240,7 +5240,10 @@ UniValue CCaddress(struct CCcontract_info *cp,char *name,std::vector Date: Tue, 29 Jan 2019 01:47:34 -1100 Subject: [PATCH 05/80] Test --- src/cc/sudoku.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cc/sudoku.cpp b/src/cc/sudoku.cpp index 336edffcd..d460b5fdd 100644 --- a/src/cc/sudoku.cpp +++ b/src/cc/sudoku.cpp @@ -522,6 +522,7 @@ UniValue sudoku_generate(uint64_t txfee,struct CCcontract_info *cp,cJSON *params result.push_back(Pair("amount",ValueFromAmount(amount))); if ( (inputsum= AddCClibInputs(cp,mtx,sudokupk,amount+2*txfee,16)) >= amount+2*txfee ) { + printf("inputsum %.8f\n",(double)inputsum/COIN); mtx.vout.push_back(MakeCC1vout(cp->evalcode,txfee,sudokupk)); mtx.vout.push_back(MakeCC1vout(cp->evalcode,amount,pk)); if ( inputsum > amount + 2*txfee ) From d1389403787889dca59e51500adfcba76183e57c Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 29 Jan 2019 01:50:31 -1100 Subject: [PATCH 06/80] Test --- src/cc/cclib.cpp | 2 +- src/cc/sudoku.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cc/cclib.cpp b/src/cc/cclib.cpp index 83afb86ef..77b9edcf6 100644 --- a/src/cc/cclib.cpp +++ b/src/cc/cclib.cpp @@ -257,7 +257,7 @@ int64_t AddCClibInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubK { txid = it->first.txhash; vout = (int32_t)it->first.index; - char str[65]; fprintf(stderr,"%s check %s/v%d %.8f\n",coinaddr,uint256_str(str,txid),vout,(double)it->second.satoshis/COIN); + //char str[65]; fprintf(stderr,"%s check %s/v%d %.8f\n",coinaddr,uint256_str(str,txid),vout,(double)it->second.satoshis/COIN); if ( it->second.satoshis < threshold ) continue; // no need to prevent dup diff --git a/src/cc/sudoku.cpp b/src/cc/sudoku.cpp index d460b5fdd..38b4e242f 100644 --- a/src/cc/sudoku.cpp +++ b/src/cc/sudoku.cpp @@ -529,7 +529,7 @@ UniValue sudoku_generate(uint64_t txfee,struct CCcontract_info *cp,cJSON *params change = (inputsum - amount - 2*txfee); if ( change > txfee ) mtx.vout.push_back(MakeCC1vout(cp->evalcode,change,sudokupk)); - CCaddr2set(cp,cp->evalcode,sudokupk,cp->CCpriv,cp->CCaddr); + CCaddr2set(cp,cp->evalcode,sudokupk,cp->CCpriv,cp->unspendableCCaddr); rawtx = FinalizeCCTx(0,cp,mtx,sudokupk,txfee,sudoku_genopret(unsolved)); result.push_back(Pair("hex",rawtx)); } else result.push_back(Pair("error","not enough SUDOKU funds")); From 1a7fbca0da6472493cc508085c63b550eeac477f Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 29 Jan 2019 01:55:20 -1100 Subject: [PATCH 07/80] Test --- src/cc/CCtx.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc/CCtx.cpp b/src/cc/CCtx.cpp index a8d832661..25e13df7f 100644 --- a/src/cc/CCtx.cpp +++ b/src/cc/CCtx.cpp @@ -177,7 +177,7 @@ std::string FinalizeCCTx(uint64_t CCmask,struct CCcontract_info *cp,CMutableTran { privkey = unspendablepriv; cond = othercond; - //fprintf(stderr,"FinalizeCCTx() matched unspendable CC addr.(%s)\n",unspendable); + fprintf(stderr,"FinalizeCCTx(%d) matched unspendable CC addr.(%s)\n",cp->evalcode,unspendable); } else if (strcmp(destaddr, tokensunspendable) == 0) { From 9de5df85e89e48324e4edc983e36cf28ae8fc20a Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 29 Jan 2019 01:59:32 -1100 Subject: [PATCH 08/80] Use mypk --- src/cc/CCtx.cpp | 2 +- src/cc/sudoku.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cc/CCtx.cpp b/src/cc/CCtx.cpp index 25e13df7f..4fe4d9673 100644 --- a/src/cc/CCtx.cpp +++ b/src/cc/CCtx.cpp @@ -73,7 +73,7 @@ std::string FinalizeCCTx(uint64_t CCmask,struct CCcontract_info *cp,CMutableTran unspendablepk = GetUnspendable(cp, unspendablepriv); GetCCaddress(cp, unspendable, unspendablepk); othercond = MakeCCcond1(cp->evalcode, unspendablepk); - +printf("evalcode.%d (%s)\n",cp->evalcode,unspendable); // tokens support: // to spend from dual-eval mypk vout diff --git a/src/cc/sudoku.cpp b/src/cc/sudoku.cpp index 38b4e242f..d97b81b0d 100644 --- a/src/cc/sudoku.cpp +++ b/src/cc/sudoku.cpp @@ -530,7 +530,7 @@ UniValue sudoku_generate(uint64_t txfee,struct CCcontract_info *cp,cJSON *params if ( change > txfee ) mtx.vout.push_back(MakeCC1vout(cp->evalcode,change,sudokupk)); CCaddr2set(cp,cp->evalcode,sudokupk,cp->CCpriv,cp->unspendableCCaddr); - rawtx = FinalizeCCTx(0,cp,mtx,sudokupk,txfee,sudoku_genopret(unsolved)); + rawtx = FinalizeCCTx(0,cp,mtx,pubkey2pk(Mypubkey()),txfee,sudoku_genopret(unsolved)); result.push_back(Pair("hex",rawtx)); } else result.push_back(Pair("error","not enough SUDOKU funds")); return(result); From 1aefc8dbff7167374dfeceb3280bde387ea31e4b Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 29 Jan 2019 02:05:22 -1100 Subject: [PATCH 09/80] Default validation for sudoku --- src/cc/CCtx.cpp | 4 ++-- src/cc/cclib.cpp | 4 ++++ src/cc/sudoku.cpp | 7 ++++++- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/cc/CCtx.cpp b/src/cc/CCtx.cpp index 4fe4d9673..5228703ea 100644 --- a/src/cc/CCtx.cpp +++ b/src/cc/CCtx.cpp @@ -73,7 +73,7 @@ std::string FinalizeCCTx(uint64_t CCmask,struct CCcontract_info *cp,CMutableTran unspendablepk = GetUnspendable(cp, unspendablepriv); GetCCaddress(cp, unspendable, unspendablepk); othercond = MakeCCcond1(cp->evalcode, unspendablepk); -printf("evalcode.%d (%s)\n",cp->evalcode,unspendable); + //printf("evalcode.%d (%s)\n",cp->evalcode,unspendable); // tokens support: // to spend from dual-eval mypk vout @@ -177,7 +177,7 @@ printf("evalcode.%d (%s)\n",cp->evalcode,unspendable); { privkey = unspendablepriv; cond = othercond; - fprintf(stderr,"FinalizeCCTx(%d) matched unspendable CC addr.(%s)\n",cp->evalcode,unspendable); + //fprintf(stderr,"FinalizeCCTx(%d) matched unspendable CC addr.(%s)\n",cp->evalcode,unspendable); } else if (strcmp(destaddr, tokensunspendable) == 0) { diff --git a/src/cc/cclib.cpp b/src/cc/cclib.cpp index 77b9edcf6..112fba5de 100644 --- a/src/cc/cclib.cpp +++ b/src/cc/cclib.cpp @@ -51,6 +51,8 @@ CClib_methods[] = }; std::string CClib_rawtxgen(struct CCcontract_info *cp,uint8_t funcid,cJSON *params); + +bool sudoku_validate(struct CCcontract_info *cp,int32_t height,Eval *eval,const CTransaction tx); UniValue sudoku_txidinfo(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); UniValue sudoku_generate(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); UniValue sudoku_solution(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); @@ -190,6 +192,8 @@ bool CClib_validate(struct CCcontract_info *cp,int32_t height,Eval *eval,const C { int32_t numvins,numvouts,preventCCvins,preventCCvouts,i,numblocks; bool retval; uint256 txid; uint8_t hash[32]; char str[65],destaddr[64]; std::vector > txids; + if ( cp->evalcode != EVAL_FAUCET2 ) + return(sudoku_validate(cp,height,eval,tx)); numvins = tx.vin.size(); numvouts = tx.vout.size(); preventCCvins = preventCCvouts = -1; diff --git a/src/cc/sudoku.cpp b/src/cc/sudoku.cpp index d97b81b0d..ccd5a913f 100644 --- a/src/cc/sudoku.cpp +++ b/src/cc/sudoku.cpp @@ -522,7 +522,7 @@ UniValue sudoku_generate(uint64_t txfee,struct CCcontract_info *cp,cJSON *params result.push_back(Pair("amount",ValueFromAmount(amount))); if ( (inputsum= AddCClibInputs(cp,mtx,sudokupk,amount+2*txfee,16)) >= amount+2*txfee ) { - printf("inputsum %.8f\n",(double)inputsum/COIN); + //printf("inputsum %.8f\n",(double)inputsum/COIN); mtx.vout.push_back(MakeCC1vout(cp->evalcode,txfee,sudokupk)); mtx.vout.push_back(MakeCC1vout(cp->evalcode,amount,pk)); if ( inputsum > amount + 2*txfee ) @@ -558,3 +558,8 @@ UniValue sudoku_pending(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) return(result); } + +bool sudoku_validate(struct CCcontract_info *cp,int32_t height,Eval *eval,const CTransaction tx) +{ + return(true); +} From 66dc70b22804cb518ae049e6f2073e01cbc91585 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 29 Jan 2019 02:10:38 -1100 Subject: [PATCH 10/80] Print --- src/cc/sudoku.cpp | 2 ++ src/wallet/rpcwallet.cpp | 3 +++ 2 files changed, 5 insertions(+) diff --git a/src/cc/sudoku.cpp b/src/cc/sudoku.cpp index ccd5a913f..097a01d86 100644 --- a/src/cc/sudoku.cpp +++ b/src/cc/sudoku.cpp @@ -477,6 +477,8 @@ void sudoku_gen(uint8_t key32[32],uint8_t unsolved[9][9],uint32_t srandi) //////////////////////// start of CClib interface // ./komodod -ac_name=SUDOKU -ac_supply=1000000 -pubkey= -addnode=5.9.102.210 -gen -genproclimit=1 -ac_cclib=sudoku -ac_perc=10000000 -ac_reward=100000000 -ac_cc=60000 -ac_script=2ea22c80203d1579313abe7d8ea85f48c65ea66fc512c878c0d0e6f6d54036669de940febf8103120c008203000401cc & +// cclib "gen" 17 "1" +// 5d13c1ad80daf37215c74809a36720c2ada90bacadb2e10bf0866092ce558432 UniValue sudoku_txidinfo(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) { diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 3409710ad..e09ddc89f 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -5389,7 +5389,10 @@ UniValue cclib(const UniValue& params, bool fHelp) throw runtime_error("evalcode not between EVAL_FIRSTUSER and EVAL_LASTUSER\n"); } if ( params.size() == 2 ) + { jsonparams = cJSON_Parse(params[2].get_str().c_str()); + printf("Parse.(%s) -> %p\n",params[2].get_str().c_str(),jsonparams); + } } cp = CCinit(&C,evalcode); return(CClib(cp,method,jsonparams)); From 220bf38e5de0ca7ee59f3dfcedef70f0124d8c50 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 29 Jan 2019 02:14:30 -1100 Subject: [PATCH 11/80] Print --- src/wallet/rpcwallet.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index e09ddc89f..34ee7ce95 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -5380,6 +5380,7 @@ UniValue cclib(const UniValue& params, bool fHelp) if ( ensure_CCrequirements() < 0 ) throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n"); method = (char *)params[0].get_str().c_str(); + printf("params.size() %d (%s)\n",(int32_t)params.size(),params[2].get_str().c_str()); if ( params.size() >= 1 ) { evalcode = atoi(params[1].get_str().c_str()); From 542e08db60d4e046df46897bffb722993f404449 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 29 Jan 2019 02:16:59 -1100 Subject: [PATCH 12/80] Test --- src/wallet/rpcwallet.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 34ee7ce95..3104a5006 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -5380,8 +5380,7 @@ UniValue cclib(const UniValue& params, bool fHelp) if ( ensure_CCrequirements() < 0 ) throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n"); method = (char *)params[0].get_str().c_str(); - printf("params.size() %d (%s)\n",(int32_t)params.size(),params[2].get_str().c_str()); - if ( params.size() >= 1 ) + if ( params.size() >= 2 ) { evalcode = atoi(params[1].get_str().c_str()); if ( evalcode < EVAL_FIRSTUSER || evalcode > EVAL_LASTUSER ) @@ -5389,7 +5388,7 @@ UniValue cclib(const UniValue& params, bool fHelp) printf("evalcode.%d vs (%d, %d)\n",evalcode,EVAL_FIRSTUSER,EVAL_LASTUSER); throw runtime_error("evalcode not between EVAL_FIRSTUSER and EVAL_LASTUSER\n"); } - if ( params.size() == 2 ) + if ( params.size() == 3 ) { jsonparams = cJSON_Parse(params[2].get_str().c_str()); printf("Parse.(%s) -> %p\n",params[2].get_str().c_str(),jsonparams); From 3f5b87742be1a0496f53fd590d0ea791d0afae67 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 29 Jan 2019 02:21:11 -1100 Subject: [PATCH 13/80] Print --- src/cc/sudoku.cpp | 9 +++++++++ src/wallet/rpcwallet.cpp | 4 ++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/cc/sudoku.cpp b/src/cc/sudoku.cpp index 097a01d86..590cc9c9b 100644 --- a/src/cc/sudoku.cpp +++ b/src/cc/sudoku.cpp @@ -484,7 +484,16 @@ UniValue sudoku_txidinfo(uint64_t txfee,struct CCcontract_info *cp,cJSON *params { UniValue result(UniValue::VOBJ); if ( params != 0 ) + { printf("params.(%s)\n",jprint(params,0)); + int32_t i,n = cJSON_GetArraySize(); + for (i=0; i EVAL_LASTUSER ) { - printf("evalcode.%d vs (%d, %d)\n",evalcode,EVAL_FIRSTUSER,EVAL_LASTUSER); + //printf("evalcode.%d vs (%d, %d)\n",evalcode,EVAL_FIRSTUSER,EVAL_LASTUSER); throw runtime_error("evalcode not between EVAL_FIRSTUSER and EVAL_LASTUSER\n"); } if ( params.size() == 3 ) { jsonparams = cJSON_Parse(params[2].get_str().c_str()); - printf("Parse.(%s) -> %p\n",params[2].get_str().c_str(),jsonparams); + //printf("Parse.(%s) -> %p\n",params[2].get_str().c_str(),jsonparams); } } cp = CCinit(&C,evalcode); From 7b2612734453d4e526ecbc032d81f4bc076c7247 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 29 Jan 2019 02:22:11 -1100 Subject: [PATCH 14/80] +print --- src/cc/sudoku.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/cc/sudoku.cpp b/src/cc/sudoku.cpp index 590cc9c9b..26548ea0e 100644 --- a/src/cc/sudoku.cpp +++ b/src/cc/sudoku.cpp @@ -479,6 +479,7 @@ void sudoku_gen(uint8_t key32[32],uint8_t unsolved[9][9],uint32_t srandi) // ./komodod -ac_name=SUDOKU -ac_supply=1000000 -pubkey= -addnode=5.9.102.210 -gen -genproclimit=1 -ac_cclib=sudoku -ac_perc=10000000 -ac_reward=100000000 -ac_cc=60000 -ac_script=2ea22c80203d1579313abe7d8ea85f48c65ea66fc512c878c0d0e6f6d54036669de940febf8103120c008203000401cc & // cclib "gen" 17 "1" // 5d13c1ad80daf37215c74809a36720c2ada90bacadb2e10bf0866092ce558432 +// cclib "txidinfo" 17 \"[5d13c1ad80daf37215c74809a36720c2ada90bacadb2e10bf0866092ce558432]\" UniValue sudoku_txidinfo(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) { @@ -486,7 +487,7 @@ UniValue sudoku_txidinfo(uint64_t txfee,struct CCcontract_info *cp,cJSON *params if ( params != 0 ) { printf("params.(%s)\n",jprint(params,0)); - int32_t i,n = cJSON_GetArraySize(); + cJSON *item; int32_t i,n = cJSON_GetArraySize(params); for (i=0; i Date: Tue, 29 Jan 2019 02:26:19 -1100 Subject: [PATCH 15/80] Prints --- src/cc/sudoku.cpp | 2 +- src/wallet/rpcwallet.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cc/sudoku.cpp b/src/cc/sudoku.cpp index 26548ea0e..95cb05684 100644 --- a/src/cc/sudoku.cpp +++ b/src/cc/sudoku.cpp @@ -486,7 +486,7 @@ UniValue sudoku_txidinfo(uint64_t txfee,struct CCcontract_info *cp,cJSON *params UniValue result(UniValue::VOBJ); if ( params != 0 ) { - printf("params.(%s)\n",jprint(params,0)); + printf("%p params.(%s) is array.%d\n",params,jprint(params,0),is_cJSON_Array(params)); cJSON *item; int32_t i,n = cJSON_GetArraySize(params); for (i=0; i %p\n",params[2].get_str().c_str(),jsonparams); + printf("Parse.(%s) -> %p\n",params[2].get_str().c_str(),jsonparams); } } cp = CCinit(&C,evalcode); From caca5ec036fa5d370203ce6f9296995c3007e593 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 29 Jan 2019 02:27:45 -1100 Subject: [PATCH 16/80] Test --- src/cc/sudoku.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cc/sudoku.cpp b/src/cc/sudoku.cpp index 95cb05684..20d18018c 100644 --- a/src/cc/sudoku.cpp +++ b/src/cc/sudoku.cpp @@ -395,6 +395,7 @@ int sudoku(uint8_t solved9[LINE][LINE],uint8_t unsolved9[LINE][LINE],uint32_t sr * * ******************************************************************************/ +#include "cJSON.h" #define SUDOKU_NINETH 387420489 void sudoku_rowdisp(uint32_t x) From 44cce95c52f89ee88c0af7fac6c178c23959aaa4 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 29 Jan 2019 02:30:05 -1100 Subject: [PATCH 17/80] Test --- src/cc/sudoku.cpp | 39 +++++++++++++++++++-------------------- src/wallet/rpcwallet.cpp | 3 ++- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/cc/sudoku.cpp b/src/cc/sudoku.cpp index 20d18018c..b60373e23 100644 --- a/src/cc/sudoku.cpp +++ b/src/cc/sudoku.cpp @@ -482,26 +482,6 @@ void sudoku_gen(uint8_t key32[32],uint8_t unsolved[9][9],uint32_t srandi) // 5d13c1ad80daf37215c74809a36720c2ada90bacadb2e10bf0866092ce558432 // cclib "txidinfo" 17 \"[5d13c1ad80daf37215c74809a36720c2ada90bacadb2e10bf0866092ce558432]\" -UniValue sudoku_txidinfo(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) -{ - UniValue result(UniValue::VOBJ); - if ( params != 0 ) - { - printf("%p params.(%s) is array.%d\n",params,jprint(params,0),is_cJSON_Array(params)); - cJSON *item; int32_t i,n = cJSON_GetArraySize(params); - for (i=0; i data; int32_t i,j; @@ -549,6 +529,25 @@ UniValue sudoku_generate(uint64_t txfee,struct CCcontract_info *cp,cJSON *params return(result); } +UniValue sudoku_txidinfo(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) +{ + UniValue result(UniValue::VOBJ); + if ( params != 0 ) + { + cJSON *item; int32_t i,n = cJSON_GetArraySize(params); + for (i=0; i %p\n",params[2].get_str().c_str(),jsonparams); + printf("%p params.(%s) is array.%d\n",params,jprint(params,0),is_cJSON_Array(params)); + //printf("Parse.(%s) -> %p\n",params[2].get_str().c_str(),jsonparams); } } cp = CCinit(&C,evalcode); From ccbbb3291c54b88fc8540c20d082b815d4d21b53 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 29 Jan 2019 02:31:28 -1100 Subject: [PATCH 18/80] Test --- src/wallet/rpcwallet.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 39a88c9eb..5cea2f7ac 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -5391,7 +5391,8 @@ UniValue cclib(const UniValue& params, bool fHelp) if ( params.size() == 3 ) { jsonparams = cJSON_Parse(params[2].get_str().c_str()); - printf("%p params.(%s) is array.%d\n",params,jprint(params,0),is_cJSON_Array(params)); + if ( jsonparams != 0 ) + printf("%p params.(%s) is array.%d\n",jsonparams,jprint(jsonparams,0),is_cJSON_Array(params)); //printf("Parse.(%s) -> %p\n",params[2].get_str().c_str(),jsonparams); } } From e2a1c43d8a6fc81e9e9e4daff4460a613a770ad1 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 29 Jan 2019 02:33:01 -1100 Subject: [PATCH 19/80] Test --- src/cc/includes/cJSON.h | 4 ++-- src/cryptoconditions/src/include/cJSON.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/cc/includes/cJSON.h b/src/cc/includes/cJSON.h index ed8c26b7f..d919a47a9 100755 --- a/src/cc/includes/cJSON.h +++ b/src/cc/includes/cJSON.h @@ -35,8 +35,8 @@ * * ******************************************************************************/ -#ifndef cJSON__h -#define cJSON__h +#ifndef cJSON__ccih +#define cJSON__ccih #include #include diff --git a/src/cryptoconditions/src/include/cJSON.h b/src/cryptoconditions/src/include/cJSON.h index 2a6139680..547dddad5 100644 --- a/src/cryptoconditions/src/include/cJSON.h +++ b/src/cryptoconditions/src/include/cJSON.h @@ -35,8 +35,8 @@ * * ******************************************************************************/ -#ifndef cJSON__h -#define cJSON__h +#ifndef cJSON__cch +#define cJSON__cch #ifdef __cplusplus extern "C" From 4123105b95e49de239884f9f071799091793d01b Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 29 Jan 2019 02:34:19 -1100 Subject: [PATCH 20/80] Test --- src/wallet/rpcwallet.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 5cea2f7ac..6a6f64237 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -5392,7 +5392,7 @@ UniValue cclib(const UniValue& params, bool fHelp) { jsonparams = cJSON_Parse(params[2].get_str().c_str()); if ( jsonparams != 0 ) - printf("%p params.(%s) is array.%d\n",jsonparams,jprint(jsonparams,0),is_cJSON_Array(params)); + printf("%p params.(%s)\n",jsonparams,jprint(jsonparams,0)); //printf("Parse.(%s) -> %p\n",params[2].get_str().c_str(),jsonparams); } } From af6030a98b5d88e360ad581b3fbec23902e2ecd3 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 29 Jan 2019 02:38:12 -1100 Subject: [PATCH 21/80] Test --- src/cc/cclib.cpp | 2 ++ src/cc/sudoku.cpp | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/cc/cclib.cpp b/src/cc/cclib.cpp index 112fba5de..614fb8567 100644 --- a/src/cc/cclib.cpp +++ b/src/cc/cclib.cpp @@ -63,6 +63,7 @@ UniValue CClib_method(struct CCcontract_info *cp,char *method,cJSON *params) UniValue result(UniValue::VOBJ); uint64_t txfee = 10000; if ( cp->evalcode == EVAL_SUDOKU ) { + printf("CClib_method params.%p\n",params); if ( strcmp(method,"txidinfo") == 0 ) return(sudoku_txidinfo(txfee,cp,params)); else if ( strcmp(method,"gen") == 0 ) @@ -119,6 +120,7 @@ UniValue CClib_info(struct CCcontract_info *cp) UniValue CClib(struct CCcontract_info *cp,char *method,cJSON *params) { UniValue result(UniValue::VOBJ); int32_t i; std::string rawtx; + printf("CClib params.%p\n",params); for (i=0; ievalcode == CClib_methods[i].evalcode && strcmp(method,CClib_methods[i].method) == 0 ) diff --git a/src/cc/sudoku.cpp b/src/cc/sudoku.cpp index b60373e23..fdc70211a 100644 --- a/src/cc/sudoku.cpp +++ b/src/cc/sudoku.cpp @@ -498,7 +498,7 @@ UniValue sudoku_generate(uint64_t txfee,struct CCcontract_info *cp,cJSON *params UniValue result(UniValue::VOBJ); CPubKey sudokupk,pk; uint8_t privkey[32],unsolved[9][9],pub33[33]; uint32_t srandi; uint256 hash; char coinaddr[64]; uint64_t inputsum,amount,change=0; std::string rawtx; if ( params != 0 ) { - printf("params.(%s)\n",jprint(params,0)); + printf("%p params.(%s)\n",params,jprint(params,0)); amount = jdouble(jitem(params,0),0) * COIN + 0.0000000049; } else amount = COIN; result.push_back(Pair("result","success")); From a4beca11a346d22b90fb12295218eceaba351b81 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 29 Jan 2019 02:39:57 -1100 Subject: [PATCH 22/80] Test --- src/cc/sudoku.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cc/sudoku.cpp b/src/cc/sudoku.cpp index fdc70211a..a820f2231 100644 --- a/src/cc/sudoku.cpp +++ b/src/cc/sudoku.cpp @@ -534,6 +534,7 @@ UniValue sudoku_txidinfo(uint64_t txfee,struct CCcontract_info *cp,cJSON *params UniValue result(UniValue::VOBJ); if ( params != 0 ) { + printf("%p params.(%s)\n",params,jprint(params,0)); cJSON *item; int32_t i,n = cJSON_GetArraySize(params); for (i=0; i Date: Tue, 29 Jan 2019 02:44:02 -1100 Subject: [PATCH 23/80] Test --- src/cc/sudoku.cpp | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/cc/sudoku.cpp b/src/cc/sudoku.cpp index a820f2231..a44b2d329 100644 --- a/src/cc/sudoku.cpp +++ b/src/cc/sudoku.cpp @@ -534,14 +534,20 @@ UniValue sudoku_txidinfo(uint64_t txfee,struct CCcontract_info *cp,cJSON *params UniValue result(UniValue::VOBJ); if ( params != 0 ) { - printf("%p params.(%s)\n",params,jprint(params,0)); - cJSON *item; int32_t i,n = cJSON_GetArraySize(params); - for (i=0; i Date: Tue, 29 Jan 2019 02:50:02 -1100 Subject: [PATCH 24/80] txid: --- src/cc/cclib.cpp | 4 ++-- src/cc/sudoku.cpp | 17 +++-------------- src/wallet/rpcwallet.cpp | 3 --- 3 files changed, 5 insertions(+), 19 deletions(-) diff --git a/src/cc/cclib.cpp b/src/cc/cclib.cpp index 614fb8567..c1c3d9f24 100644 --- a/src/cc/cclib.cpp +++ b/src/cc/cclib.cpp @@ -63,7 +63,7 @@ UniValue CClib_method(struct CCcontract_info *cp,char *method,cJSON *params) UniValue result(UniValue::VOBJ); uint64_t txfee = 10000; if ( cp->evalcode == EVAL_SUDOKU ) { - printf("CClib_method params.%p\n",params); + //printf("CClib_method params.%p\n",params); if ( strcmp(method,"txidinfo") == 0 ) return(sudoku_txidinfo(txfee,cp,params)); else if ( strcmp(method,"gen") == 0 ) @@ -120,7 +120,7 @@ UniValue CClib_info(struct CCcontract_info *cp) UniValue CClib(struct CCcontract_info *cp,char *method,cJSON *params) { UniValue result(UniValue::VOBJ); int32_t i; std::string rawtx; - printf("CClib params.%p\n",params); + //printf("CClib params.%p\n",params); for (i=0; ievalcode == CClib_methods[i].evalcode && strcmp(method,CClib_methods[i].method) == 0 ) diff --git a/src/cc/sudoku.cpp b/src/cc/sudoku.cpp index a44b2d329..b2ca38321 100644 --- a/src/cc/sudoku.cpp +++ b/src/cc/sudoku.cpp @@ -534,20 +534,9 @@ UniValue sudoku_txidinfo(uint64_t txfee,struct CCcontract_info *cp,cJSON *params UniValue result(UniValue::VOBJ); if ( params != 0 ) { - char *jsonstr; cJSON *item; int32_t i,n; - jsonstr = jprint(params,0); - params = cJSON_Parse(jsonstr); - if ( params != 0 ) - { - n = cJSON_GetArraySize(params); - printf("%p params.(%s) <- (%s)\n",params,jprint(params,0),jsonstr); - for (i=0; i %p\n",params[2].get_str().c_str(),jsonparams); } } cp = CCinit(&C,evalcode); From 4fafbdeeadecc175395dacf4ab428fd1d8ba4768 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 29 Jan 2019 02:52:05 -1100 Subject: [PATCH 25/80] Uint256 --- src/cc/sudoku.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/cc/sudoku.cpp b/src/cc/sudoku.cpp index b2ca38321..e77455352 100644 --- a/src/cc/sudoku.cpp +++ b/src/cc/sudoku.cpp @@ -480,7 +480,7 @@ void sudoku_gen(uint8_t key32[32],uint8_t unsolved[9][9],uint32_t srandi) // ./komodod -ac_name=SUDOKU -ac_supply=1000000 -pubkey= -addnode=5.9.102.210 -gen -genproclimit=1 -ac_cclib=sudoku -ac_perc=10000000 -ac_reward=100000000 -ac_cc=60000 -ac_script=2ea22c80203d1579313abe7d8ea85f48c65ea66fc512c878c0d0e6f6d54036669de940febf8103120c008203000401cc & // cclib "gen" 17 "1" // 5d13c1ad80daf37215c74809a36720c2ada90bacadb2e10bf0866092ce558432 -// cclib "txidinfo" 17 \"[5d13c1ad80daf37215c74809a36720c2ada90bacadb2e10bf0866092ce558432]\" +// cclib "txidinfo" 17 \"{"txid":"5d13c1ad80daf37215c74809a36720c2ada90bacadb2e10bf0866092ce558432"}\" CScript sudoku_genopret(uint8_t unsolved[9][9]) { @@ -534,9 +534,10 @@ UniValue sudoku_txidinfo(uint64_t txfee,struct CCcontract_info *cp,cJSON *params UniValue result(UniValue::VOBJ); if ( params != 0 ) { - char str[65]; bits256 txid; - txid = jbits256(params,"txid"); - printf("txid.(%s)\n",bits256_str(str,txid)); + char str[65]; bits256 _txid; uint256 txid; + _txid = jbits256(params,(char *)"txid"); + memcpy(&txid,*_txid,sizeof(txid)); + printf("txid.(%s)\n",txid.GetHex().c_str()); } result.push_back(Pair("result","success")); result.push_back(Pair("name","sudoku")); From d1e3f85f54832e66d565ec8df17f94ad9c6cab1e Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 29 Jan 2019 02:52:39 -1100 Subject: [PATCH 26/80] Test --- src/cc/sudoku.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc/sudoku.cpp b/src/cc/sudoku.cpp index e77455352..61b1eb389 100644 --- a/src/cc/sudoku.cpp +++ b/src/cc/sudoku.cpp @@ -536,7 +536,7 @@ UniValue sudoku_txidinfo(uint64_t txfee,struct CCcontract_info *cp,cJSON *params { char str[65]; bits256 _txid; uint256 txid; _txid = jbits256(params,(char *)"txid"); - memcpy(&txid,*_txid,sizeof(txid)); + memcpy(&txid,&_txid,sizeof(txid)); printf("txid.(%s)\n",txid.GetHex().c_str()); } result.push_back(Pair("result","success")); From 26ca2c628bf6ba309b86a5f10287575f1e0ff550 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 29 Jan 2019 02:55:04 -1100 Subject: [PATCH 27/80] Test --- src/cc/sudoku.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/cc/sudoku.cpp b/src/cc/sudoku.cpp index 61b1eb389..deee89023 100644 --- a/src/cc/sudoku.cpp +++ b/src/cc/sudoku.cpp @@ -534,10 +534,13 @@ UniValue sudoku_txidinfo(uint64_t txfee,struct CCcontract_info *cp,cJSON *params UniValue result(UniValue::VOBJ); if ( params != 0 ) { - char str[65]; bits256 _txid; uint256 txid; - _txid = jbits256(params,(char *)"txid"); - memcpy(&txid,&_txid,sizeof(txid)); - printf("txid.(%s)\n",txid.GetHex().c_str()); + char str[65],*txidstr; uint256 txid; + printf("params -> (%s)\n",jprint(params,0)); + if ( (txidstr= jstr(params,(char *)"txid")) != 0 ) + { + decode_hex((uint8_t *)&txid,32,txidstr); + printf("txid.(%s) <- %s\n",txid.GetHex().c_str(),txidstr); + } } result.push_back(Pair("result","success")); result.push_back(Pair("name","sudoku")); From 124ad45bc86e46394db88e020992d1fa684cf9b8 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 29 Jan 2019 02:59:27 -1100 Subject: [PATCH 28/80] Test --- src/cc/sudoku.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cc/sudoku.cpp b/src/cc/sudoku.cpp index deee89023..8c30ad462 100644 --- a/src/cc/sudoku.cpp +++ b/src/cc/sudoku.cpp @@ -480,7 +480,7 @@ void sudoku_gen(uint8_t key32[32],uint8_t unsolved[9][9],uint32_t srandi) // ./komodod -ac_name=SUDOKU -ac_supply=1000000 -pubkey= -addnode=5.9.102.210 -gen -genproclimit=1 -ac_cclib=sudoku -ac_perc=10000000 -ac_reward=100000000 -ac_cc=60000 -ac_script=2ea22c80203d1579313abe7d8ea85f48c65ea66fc512c878c0d0e6f6d54036669de940febf8103120c008203000401cc & // cclib "gen" 17 "1" // 5d13c1ad80daf37215c74809a36720c2ada90bacadb2e10bf0866092ce558432 -// cclib "txidinfo" 17 \"{"txid":"5d13c1ad80daf37215c74809a36720c2ada90bacadb2e10bf0866092ce558432"}\" +// cclib "txidinfo" 17 \"5d13c1ad80daf37215c74809a36720c2ada90bacadb2e10bf0866092ce558432\" CScript sudoku_genopret(uint8_t unsolved[9][9]) { @@ -535,9 +535,9 @@ UniValue sudoku_txidinfo(uint64_t txfee,struct CCcontract_info *cp,cJSON *params if ( params != 0 ) { char str[65],*txidstr; uint256 txid; - printf("params -> (%s)\n",jprint(params,0)); - if ( (txidstr= jstr(params,(char *)"txid")) != 0 ) + if ( (txidstr= jprint(params,0)) != 0 ) { + printf("params -> (%s)\n",txidstr); decode_hex((uint8_t *)&txid,32,txidstr); printf("txid.(%s) <- %s\n",txid.GetHex().c_str(),txidstr); } From 08ee5412fae588bdd768204bf6dbced9aa957277 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 29 Jan 2019 03:01:40 -1100 Subject: [PATCH 29/80] Test --- src/cc/sudoku.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/cc/sudoku.cpp b/src/cc/sudoku.cpp index 8c30ad462..af41ac9b0 100644 --- a/src/cc/sudoku.cpp +++ b/src/cc/sudoku.cpp @@ -537,7 +537,9 @@ UniValue sudoku_txidinfo(uint64_t txfee,struct CCcontract_info *cp,cJSON *params char str[65],*txidstr; uint256 txid; if ( (txidstr= jprint(params,0)) != 0 ) { - printf("params -> (%s)\n",txidstr); + if ( txidstr[0] == '"' ) + txidstr++; + //printf("params -> (%s)\n",txidstr); decode_hex((uint8_t *)&txid,32,txidstr); printf("txid.(%s) <- %s\n",txid.GetHex().c_str(),txidstr); } From 70fb39618932912de5b4b17460ead72fdde71736 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 29 Jan 2019 03:04:20 -1100 Subject: [PATCH 30/80] Test --- src/cc/sudoku.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/cc/sudoku.cpp b/src/cc/sudoku.cpp index af41ac9b0..34d3201c4 100644 --- a/src/cc/sudoku.cpp +++ b/src/cc/sudoku.cpp @@ -537,8 +537,11 @@ UniValue sudoku_txidinfo(uint64_t txfee,struct CCcontract_info *cp,cJSON *params char str[65],*txidstr; uint256 txid; if ( (txidstr= jprint(params,0)) != 0 ) { - if ( txidstr[0] == '"' ) + if ( txidstr[0] == '"' && txidstr[strlen(txidstr)-1] == '"' ) + { + txidstr[strlen(txidstr)-1] = 0; txidstr++; + } //printf("params -> (%s)\n",txidstr); decode_hex((uint8_t *)&txid,32,txidstr); printf("txid.(%s) <- %s\n",txid.GetHex().c_str(),txidstr); From b4dda82a701732e39815f42e74fe9849ed3dcdf7 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 29 Jan 2019 03:06:07 -1100 Subject: [PATCH 31/80] Revtxid --- src/cc/sudoku.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cc/sudoku.cpp b/src/cc/sudoku.cpp index 34d3201c4..a3f6ce525 100644 --- a/src/cc/sudoku.cpp +++ b/src/cc/sudoku.cpp @@ -544,6 +544,7 @@ UniValue sudoku_txidinfo(uint64_t txfee,struct CCcontract_info *cp,cJSON *params } //printf("params -> (%s)\n",txidstr); decode_hex((uint8_t *)&txid,32,txidstr); + txid = revuint256(txid); printf("txid.(%s) <- %s\n",txid.GetHex().c_str(),txidstr); } } From a9dcf78e331f2486d175f62d6deb07fec96ee641 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 29 Jan 2019 03:17:56 -1100 Subject: [PATCH 32/80] sudoku_txidinfo --- src/cc/CCcustom.cpp | 2 +- src/cc/sudoku.cpp | 48 +++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 45 insertions(+), 5 deletions(-) diff --git a/src/cc/CCcustom.cpp b/src/cc/CCcustom.cpp index 0b150e6e0..8e878d37d 100644 --- a/src/cc/CCcustom.cpp +++ b/src/cc/CCcustom.cpp @@ -281,7 +281,7 @@ int32_t CClib_initcp(struct CCcontract_info *cp,uint8_t evalcode) sprintf(&cp->CChexstr[i*2],"%02x",pub33[i]); cp->CChexstr[i*2] = 0; GetCCaddress(cp,cp->unspendableCCaddr,pk); - printf("evalcode.%d initialized\n",evalcode); + //printf("evalcode.%d initialized\n",evalcode); return(0); } } diff --git a/src/cc/sudoku.cpp b/src/cc/sudoku.cpp index a3f6ce525..cf382a518 100644 --- a/src/cc/sudoku.cpp +++ b/src/cc/sudoku.cpp @@ -492,6 +492,23 @@ CScript sudoku_genopret(uint8_t unsolved[9][9]) return(opret); } +uint8_t sudoku_genopreturndecode(char *unsolved,CScript scriptPubKey) +{ + std::vector vopret; uint8_t *script,e,f; std::vector data; int32_t i; + GetOpReturnData(scriptPubKey,vopret); + script = (uint8_t *)vopret.data(); + if ( vopret.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> data) != 0 && e == EVAL_SUDOKU && f == 'G' ) + { + if ( data.size() == 81 ) + { + for (i=0; i<81; i++) + unsolved[i] = data[i] == 0 ? '-' : '0' + data[i]; + unsolved[i] = 0; + return(f); + } + } + return(0);} + UniValue sudoku_generate(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) { CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); @@ -531,10 +548,10 @@ UniValue sudoku_generate(uint64_t txfee,struct CCcontract_info *cp,cJSON *params UniValue sudoku_txidinfo(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) { - UniValue result(UniValue::VOBJ); + UniValue result(UniValue::VOBJ); int32_t numvouts; char str[65],*txidstr; uint256 txid,hashBlock; CTransaction tx; char unsolved[82]; if ( params != 0 ) { - char str[65],*txidstr; uint256 txid; + result.push_back(Pair("result","success")); if ( (txidstr= jprint(params,0)) != 0 ) { if ( txidstr[0] == '"' && txidstr[strlen(txidstr)-1] == '"' ) @@ -545,10 +562,33 @@ UniValue sudoku_txidinfo(uint64_t txfee,struct CCcontract_info *cp,cJSON *params //printf("params -> (%s)\n",txidstr); decode_hex((uint8_t *)&txid,32,txidstr); txid = revuint256(txid); - printf("txid.(%s) <- %s\n",txid.GetHex().c_str(),txidstr); + result.push_back(Pair("txid",txid.GetHex())); + if ( GetTransaction(txid,tx,hashBlock,false) != 0 && (numvouts= tx.vout.size()) > 1 ) + { + if ( sudoku_genopreturndecode(unsolved,tx.vout[numvouts-1].scriptPubKey) == 'G' ) + { + result.push_back(Pair("result","success")); + result.push_back(Pair("amount",ValueFromAmount(tx.vout[1].nValue))); + result.push_back(Pair("unsolved",unsolved)); + } + else + { + result.push_back(Pair("result","error")); + result.push_back(Pair("error","couldnt extract sudoku_generate opreturn")); + } + } + else + { + result.push_back(Pair("result","error")); + result.push_back(Pair("error","couldnt find txid")); + } } } - result.push_back(Pair("result","success")); + else + { + result.push_back(Pair("result","error")); + result.push_back(Pair("error","missing txid in params")); + } result.push_back(Pair("name","sudoku")); result.push_back(Pair("method","txidinfo")); return(result); From 7217c87e60a8e7ae0e479f766b79e099585157bd Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 29 Jan 2019 03:25:46 -1100 Subject: [PATCH 33/80] sudoku_pending --- src/cc/sudoku.cpp | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/src/cc/sudoku.cpp b/src/cc/sudoku.cpp index cf382a518..fdeac91fa 100644 --- a/src/cc/sudoku.cpp +++ b/src/cc/sudoku.cpp @@ -481,6 +481,15 @@ void sudoku_gen(uint8_t key32[32],uint8_t unsolved[9][9],uint32_t srandi) // cclib "gen" 17 "1" // 5d13c1ad80daf37215c74809a36720c2ada90bacadb2e10bf0866092ce558432 // cclib "txidinfo" 17 \"5d13c1ad80daf37215c74809a36720c2ada90bacadb2e10bf0866092ce558432\" +/*{ + "result": "success", + "txid": "5d13c1ad80daf37215c74809a36720c2ada90bacadb2e10bf0866092ce558432", + "result": "success", + "amount": 1.00000000, + "unsolved": "46-8---15-75-61-3----4----8-1--75-----3--24----2-----6-4----------73----------36-", + "name": "sudoku", + "method": "txidinfo" +}*/ CScript sudoku_genopret(uint8_t unsolved[9][9]) { @@ -607,12 +616,31 @@ UniValue sudoku_solution(uint64_t txfee,struct CCcontract_info *cp,cJSON *params UniValue sudoku_pending(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) { - UniValue result(UniValue::VOBJ); - if ( params != 0 ) - printf("params.(%s)\n",jprint(params,0)); + UniValue result(UniValue::VOBJ),a(UniValue::VARRAY); + char coinaddr[64],unsolved[82]; int64_t nValue; uint256 txid,hashBlock; CTransaction tx; int32_t vout,numvouts; + std::vector > unspentOutputs; + GetCCaddress(cp,coinaddr,pk); + SetCCunspents(unspentOutputs,coinaddr); + for (std::vector >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++) + { + txid = it->first.txhash; + vout = (int32_t)it->first.index; + //char str[65]; fprintf(stderr,"%s check %s/v%d %.8f\n",coinaddr,uint256_str(str,txid),vout,(double)it->second.satoshis/COIN); + if ( it->second.satoshis != txfee || vout != 0 ) + continue; + if ( GetTransaction(txid,tx,hashBlock,false) != 0 && (numvouts= tx.vout.size()) > 1 ) + { + if ( (nValue= IsCClibvout(cp,tx,vout)) == txfee && myIsutxo_spentinmempool(txid,vout) == 0 ) + { + if ( sudoku_genopreturndecode(unsolved,tx.vout[numvouts-1].scriptPubKey) == 'G' ) + a.push_back(txid); + } + } + } result.push_back(Pair("result","success")); result.push_back(Pair("name","sudoku")); result.push_back(Pair("method","pending")); + result.push_back(Pair("pending",a)); return(result); } From b5aa0536c2f8d314101158444b7fa4375ffadcba Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 29 Jan 2019 03:27:22 -1100 Subject: [PATCH 34/80] syntax --- src/cc/sudoku.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/cc/sudoku.cpp b/src/cc/sudoku.cpp index fdeac91fa..268281eb7 100644 --- a/src/cc/sudoku.cpp +++ b/src/cc/sudoku.cpp @@ -616,10 +616,11 @@ UniValue sudoku_solution(uint64_t txfee,struct CCcontract_info *cp,cJSON *params UniValue sudoku_pending(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) { - UniValue result(UniValue::VOBJ),a(UniValue::VARRAY); - char coinaddr[64],unsolved[82]; int64_t nValue; uint256 txid,hashBlock; CTransaction tx; int32_t vout,numvouts; + UniValue result(UniValue::VOBJ),a(UniValue::VARR); + char coinaddr[64],unsolved[82]; int64_t nValue; uint256 txid,hashBlock; CTransaction tx; int32_t vout,numvouts; CPubKey sudokupk; std::vector > unspentOutputs; - GetCCaddress(cp,coinaddr,pk); + sudokupk = GetUnspendable(cp,0); + GetCCaddress(cp,coinaddr,sudokupk); SetCCunspents(unspentOutputs,coinaddr); for (std::vector >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++) { From b60a712efbefda09e4657a230c18b8bda8aa81d8 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 29 Jan 2019 03:28:05 -1100 Subject: [PATCH 35/80] GetHex() --- src/cc/sudoku.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc/sudoku.cpp b/src/cc/sudoku.cpp index 268281eb7..9fa714665 100644 --- a/src/cc/sudoku.cpp +++ b/src/cc/sudoku.cpp @@ -634,7 +634,7 @@ UniValue sudoku_pending(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) if ( (nValue= IsCClibvout(cp,tx,vout)) == txfee && myIsutxo_spentinmempool(txid,vout) == 0 ) { if ( sudoku_genopreturndecode(unsolved,tx.vout[numvouts-1].scriptPubKey) == 'G' ) - a.push_back(txid); + a.push_back(txid.GetHex()); } } } From 43b78b093b946ddb9b30a97788ab5c5c6435e138 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 29 Jan 2019 04:41:00 -1100 Subject: [PATCH 36/80] Jsonstr --- src/cc/sudoku.cpp | 59 +++++++++++++++++++++++++++++++------------- src/komodo_globals.h | 2 +- src/komodo_utils.h | 2 +- 3 files changed, 44 insertions(+), 19 deletions(-) diff --git a/src/cc/sudoku.cpp b/src/cc/sudoku.cpp index 9fa714665..d0e5ad543 100644 --- a/src/cc/sudoku.cpp +++ b/src/cc/sudoku.cpp @@ -478,10 +478,12 @@ void sudoku_gen(uint8_t key32[32],uint8_t unsolved[9][9],uint32_t srandi) //////////////////////// start of CClib interface // ./komodod -ac_name=SUDOKU -ac_supply=1000000 -pubkey= -addnode=5.9.102.210 -gen -genproclimit=1 -ac_cclib=sudoku -ac_perc=10000000 -ac_reward=100000000 -ac_cc=60000 -ac_script=2ea22c80203d1579313abe7d8ea85f48c65ea66fc512c878c0d0e6f6d54036669de940febf8103120c008203000401cc & -// cclib "gen" 17 "1" -// 5d13c1ad80daf37215c74809a36720c2ada90bacadb2e10bf0866092ce558432 -// cclib "txidinfo" 17 \"5d13c1ad80daf37215c74809a36720c2ada90bacadb2e10bf0866092ce558432\" -/*{ +/* cclib "gen" 17 "1" + 5d13c1ad80daf37215c74809a36720c2ada90bacadb2e10bf0866092ce558432 +*/ + +/* cclib "txidinfo" 17 \"5d13c1ad80daf37215c74809a36720c2ada90bacadb2e10bf0866092ce558432\" +{ "result": "success", "txid": "5d13c1ad80daf37215c74809a36720c2ada90bacadb2e10bf0866092ce558432", "result": "success", @@ -491,6 +493,16 @@ void sudoku_gen(uint8_t key32[32],uint8_t unsolved[9][9],uint32_t srandi) "method": "txidinfo" }*/ +/* cclib "pending" 17 +{ + "result": "success", + "name": "sudoku", + "method": "pending", + "pending": [ + "5d13c1ad80daf37215c74809a36720c2ada90bacadb2e10bf0866092ce558432" + ] +}*/ + CScript sudoku_genopret(uint8_t unsolved[9][9]) { CScript opret; uint8_t evalcode = EVAL_SUDOKU; std::vector data; int32_t i,j; @@ -516,7 +528,8 @@ uint8_t sudoku_genopreturndecode(char *unsolved,CScript scriptPubKey) return(f); } } - return(0);} + return(0); +} UniValue sudoku_generate(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) { @@ -548,7 +561,6 @@ UniValue sudoku_generate(uint64_t txfee,struct CCcontract_info *cp,cJSON *params change = (inputsum - amount - 2*txfee); if ( change > txfee ) mtx.vout.push_back(MakeCC1vout(cp->evalcode,change,sudokupk)); - CCaddr2set(cp,cp->evalcode,sudokupk,cp->CCpriv,cp->unspendableCCaddr); rawtx = FinalizeCCTx(0,cp,mtx,pubkey2pk(Mypubkey()),txfee,sudoku_genopret(unsolved)); result.push_back(Pair("hex",rawtx)); } else result.push_back(Pair("error","not enough SUDOKU funds")); @@ -603,17 +615,6 @@ UniValue sudoku_txidinfo(uint64_t txfee,struct CCcontract_info *cp,cJSON *params return(result); } -UniValue sudoku_solution(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) -{ - UniValue result(UniValue::VOBJ); - if ( params != 0 ) - printf("params.(%s)\n",jprint(params,0)); - result.push_back(Pair("result","success")); - result.push_back(Pair("name","sudoku")); - result.push_back(Pair("method","solution")); - return(result); -} - UniValue sudoku_pending(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) { UniValue result(UniValue::VOBJ),a(UniValue::VARR); @@ -645,6 +646,30 @@ UniValue sudoku_pending(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) return(result); } +UniValue sudoku_solution(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) +{ + UniValue result(UniValue::VOBJ); char *jsonstr; + if ( params != 0 ) + { + if ( (jsonstr= jprint(params,0)) != 0 ) + { + if ( jsonstr[0] == '"' && jsonstr[strlen(jsonstr)-1] == '"' ) + { + jsonstr[strlen(jsonstr)-1] = 0; + jsonstr++; + } + params = cJSON_Parse(jsonstr); + free(jsonstr); + } + if ( params != 0 ) + printf("params.(%s)\n",jprint(params,0)); + } + CCaddr2set(cp,cp->evalcode,pk,priv32,coinaddr); + result.push_back(Pair("result","success")); + result.push_back(Pair("name","sudoku")); + result.push_back(Pair("method","solution")); + return(result); +} bool sudoku_validate(struct CCcontract_info *cp,int32_t height,Eval *eval,const CTransaction tx) { diff --git a/src/komodo_globals.h b/src/komodo_globals.h index 79b56cbbb..c85c68451 100644 --- a/src/komodo_globals.h +++ b/src/komodo_globals.h @@ -173,7 +173,7 @@ int64_t komodo_current_supply(uint32_t nHeight) else if ( decay == SATOSHIDEN ) { int64_t lowestSubsidy, subsidyDifference, stepDifference, stepTriangle; - int64_t denominator, modulo; + int64_t denominator, modulo=1; int32_t sign = 1; if ( j == ASSETCHAINS_LASTERA ) diff --git a/src/komodo_utils.h b/src/komodo_utils.h index bcd95e698..862f0c6b0 100644 --- a/src/komodo_utils.h +++ b/src/komodo_utils.h @@ -1047,7 +1047,7 @@ uint64_t komodo_block_prg(uint32_t nHeight) { int i; uint8_t hashSrc[8]; - uint64_t result, hashSrc64 = (uint64_t)ASSETCHAINS_MAGIC << 32 + nHeight; + uint64_t result=0, hashSrc64 = (uint64_t)ASSETCHAINS_MAGIC << 32 + nHeight; bits256 hashResult; for ( i = 0; i < sizeof(hashSrc); i++ ) From 2781b296ef3b7af07b657efc649c95075df78bce Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 29 Jan 2019 04:42:14 -1100 Subject: [PATCH 37/80] Syntax --- src/cc/sudoku.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc/sudoku.cpp b/src/cc/sudoku.cpp index d0e5ad543..e51703456 100644 --- a/src/cc/sudoku.cpp +++ b/src/cc/sudoku.cpp @@ -648,7 +648,7 @@ UniValue sudoku_pending(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) UniValue sudoku_solution(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) { - UniValue result(UniValue::VOBJ); char *jsonstr; + UniValue result(UniValue::VOBJ); char *jsonstr,coinaddr[64]; CPubKey pk; uint8_t priv32[32]; if ( params != 0 ) { if ( (jsonstr= jprint(params,0)) != 0 ) From 10b462a7db4b5ef2f447fc9f13c4bcd3a715b946 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 29 Jan 2019 04:43:29 -1100 Subject: [PATCH 38/80] Test --- src/cc/sudoku.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/cc/sudoku.cpp b/src/cc/sudoku.cpp index e51703456..698242aea 100644 --- a/src/cc/sudoku.cpp +++ b/src/cc/sudoku.cpp @@ -659,7 +659,6 @@ UniValue sudoku_solution(uint64_t txfee,struct CCcontract_info *cp,cJSON *params jsonstr++; } params = cJSON_Parse(jsonstr); - free(jsonstr); } if ( params != 0 ) printf("params.(%s)\n",jprint(params,0)); From 145a386aab6358727969e4d632b683be23752585 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 29 Jan 2019 04:45:08 -1100 Subject: [PATCH 39/80] Test --- src/cc/sudoku.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cc/sudoku.cpp b/src/cc/sudoku.cpp index 698242aea..76b148836 100644 --- a/src/cc/sudoku.cpp +++ b/src/cc/sudoku.cpp @@ -662,6 +662,7 @@ UniValue sudoku_solution(uint64_t txfee,struct CCcontract_info *cp,cJSON *params } if ( params != 0 ) printf("params.(%s)\n",jprint(params,0)); + else printf("couldnt parse.(%s)\n",jsonstr); } CCaddr2set(cp,cp->evalcode,pk,priv32,coinaddr); result.push_back(Pair("result","success")); From 3c43c027a8de82d51ad5981d82141cc3941d5db9 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 29 Jan 2019 04:54:58 -1100 Subject: [PATCH 40/80] %22 conversion --- src/cc/sudoku.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/cc/sudoku.cpp b/src/cc/sudoku.cpp index 76b148836..ba5ed156c 100644 --- a/src/cc/sudoku.cpp +++ b/src/cc/sudoku.cpp @@ -648,7 +648,7 @@ UniValue sudoku_pending(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) UniValue sudoku_solution(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) { - UniValue result(UniValue::VOBJ); char *jsonstr,coinaddr[64]; CPubKey pk; uint8_t priv32[32]; + UniValue result(UniValue::VOBJ); int32_t i,j; char *jsonstr,*newstr,coinaddr[64]; CPubKey pk; uint8_t priv32[32]; if ( params != 0 ) { if ( (jsonstr= jprint(params,0)) != 0 ) @@ -658,7 +658,17 @@ UniValue sudoku_solution(uint64_t txfee,struct CCcontract_info *cp,cJSON *params jsonstr[strlen(jsonstr)-1] = 0; jsonstr++; } - params = cJSON_Parse(jsonstr); + newstr = malloc(strlen(jsonstr)+1); + for (i=j=0; jsonstr[i]!=0; i++) + { + if ( jsonstr[i] == '%' && jsonstr[i+1] == '2' && jsonstr[i+2] == '2' ) + { + newstr[j++] = '"'; + i += 2; + } else newstr[j++] = jsonstr[i]; + } + newstr[j] = 0; + params = cJSON_Parse(newstr); } if ( params != 0 ) printf("params.(%s)\n",jprint(params,0)); From e2028c9616d04f365b874e12775f1edd3ad9454d Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 29 Jan 2019 04:56:44 -1100 Subject: [PATCH 41/80] (Char *) --- src/cc/sudoku.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc/sudoku.cpp b/src/cc/sudoku.cpp index ba5ed156c..95a2269f5 100644 --- a/src/cc/sudoku.cpp +++ b/src/cc/sudoku.cpp @@ -658,7 +658,7 @@ UniValue sudoku_solution(uint64_t txfee,struct CCcontract_info *cp,cJSON *params jsonstr[strlen(jsonstr)-1] = 0; jsonstr++; } - newstr = malloc(strlen(jsonstr)+1); + newstr = (char *)malloc(strlen(jsonstr)+1); for (i=j=0; jsonstr[i]!=0; i++) { if ( jsonstr[i] == '%' && jsonstr[i+1] == '2' && jsonstr[i+2] == '2' ) From 127261626619af84296f02b0e898d5da74fe06b2 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 29 Jan 2019 05:22:17 -1100 Subject: [PATCH 42/80] sudoku_solution --- src/cc/sudoku.cpp | 72 +++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 64 insertions(+), 8 deletions(-) diff --git a/src/cc/sudoku.cpp b/src/cc/sudoku.cpp index 95a2269f5..35e947996 100644 --- a/src/cc/sudoku.cpp +++ b/src/cc/sudoku.cpp @@ -503,6 +503,10 @@ void sudoku_gen(uint8_t key32[32],uint8_t unsolved[9][9],uint32_t srandi) ] }*/ +/* + cclib "solution" 17 \"[%22469823715875961234231457698914675823653182479782394156346219587528736941197548362%22,1548777525,1548777526,...]\" + */ + CScript sudoku_genopret(uint8_t unsolved[9][9]) { CScript opret; uint8_t evalcode = EVAL_SUDOKU; std::vector data; int32_t i,j; @@ -513,6 +517,13 @@ CScript sudoku_genopret(uint8_t unsolved[9][9]) return(opret); } +CScript sudoku_solutionopret(char *solution,uint32_t timestamps[81]) +{ + CScript opret; uint8_t evalcode = EVAL_SUDOKU; + opret << OP_RETURN << E_MARSHAL(ss << evalcode << 'S' << solution << timestamps); + return(opret); +} + uint8_t sudoku_genopreturndecode(char *unsolved,CScript scriptPubKey) { std::vector vopret; uint8_t *script,e,f; std::vector data; int32_t i; @@ -562,7 +573,9 @@ UniValue sudoku_generate(uint64_t txfee,struct CCcontract_info *cp,cJSON *params if ( change > txfee ) mtx.vout.push_back(MakeCC1vout(cp->evalcode,change,sudokupk)); rawtx = FinalizeCCTx(0,cp,mtx,pubkey2pk(Mypubkey()),txfee,sudoku_genopret(unsolved)); - result.push_back(Pair("hex",rawtx)); + if ( rawtx.size() > 0 ) + result.push_back(Pair("hex",rawtx)); + else result.push_back(Pair("error","couldnt finalize CCtx")); } else result.push_back(Pair("error","not enough SUDOKU funds")); return(result); } @@ -648,7 +661,12 @@ UniValue sudoku_pending(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) UniValue sudoku_solution(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) { - UniValue result(UniValue::VOBJ); int32_t i,j; char *jsonstr,*newstr,coinaddr[64]; CPubKey pk; uint8_t priv32[32]; + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); + UniValue result(UniValue::VOBJ); int32_t i,j,ind,n; char *jsonstr,*newstr,coinaddr[64],CCaddr[64],*solution=0; CPubKey pk,mypk; uint8_t vals9[9][9],priv32[32],pubk33[33]; uint32_t timestamps[81]; uint64_t balance,inputsum; std::string rawhex; + mypk = pubkey2pk(Mypubkey()); + memset(timestamps,0,sizeof(timestamps)); + result.push_back(Pair("name","sudoku")); + result.push_back(Pair("method","solution")); if ( params != 0 ) { if ( (jsonstr= jprint(params,0)) != 0 ) @@ -669,15 +687,53 @@ UniValue sudoku_solution(uint64_t txfee,struct CCcontract_info *cp,cJSON *params } newstr[j] = 0; params = cJSON_Parse(newstr); - } + } else params = 0; if ( params != 0 ) + { + if ( (n= cJSON_GetArraySize(params)) > 2 && n < (sizeof(timestamps)/sizeof(*timestamps))+1 ) + { + for (i=1; i= balance ) + { + mtx.vout.push_back(CTxOut(balance-txfee,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG)); + CCaddr2set(cp,cp->evalcode,pk,priv32,CCaddr); + rawtx = FinalizeCCTx(0,cp,mtx,pubkey2pk(Mypubkey()),txfee,sudoku_solutionopret(solution,timestamps)); + } + } + } + result.push_back(Pair("result","success")); + if ( rawtx.size() > 0 ) + result.push_back(Pair("hex",rawtx)); + else result.push_back(Pair("error","couldnt finalize CCtx")); printf("params.(%s)\n",jprint(params,0)); - else printf("couldnt parse.(%s)\n",jsonstr); + return(result); + } + else + { + result.push_back(Pair("result","error")); + result.push_back(Pair("error","couldnt parse parameters")); + result.push_back(Pair("parameters",newstr)); + return(result); + } } - CCaddr2set(cp,cp->evalcode,pk,priv32,coinaddr); - result.push_back(Pair("result","success")); - result.push_back(Pair("name","sudoku")); - result.push_back(Pair("method","solution")); + result.push_back(Pair("result","error")); + result.push_back(Pair("error","missing parameters")); return(result); } From 28973e71c4e8d02a021bcf93870e4e81c9083493 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 29 Jan 2019 05:23:09 -1100 Subject: [PATCH 43/80] Test --- src/cc/sudoku.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cc/sudoku.cpp b/src/cc/sudoku.cpp index 35e947996..4d9443200 100644 --- a/src/cc/sudoku.cpp +++ b/src/cc/sudoku.cpp @@ -662,7 +662,7 @@ UniValue sudoku_pending(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) UniValue sudoku_solution(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) { CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); - UniValue result(UniValue::VOBJ); int32_t i,j,ind,n; char *jsonstr,*newstr,coinaddr[64],CCaddr[64],*solution=0; CPubKey pk,mypk; uint8_t vals9[9][9],priv32[32],pubk33[33]; uint32_t timestamps[81]; uint64_t balance,inputsum; std::string rawhex; + UniValue result(UniValue::VOBJ); int32_t i,j,ind,n; char *jsonstr,*newstr,coinaddr[64],CCaddr[64],*solution=0; CPubKey pk,mypk; uint8_t vals9[9][9],priv32[32],pub33[33]; uint32_t timestamps[81]; uint64_t balance,inputsum; std::string rawtx; mypk = pubkey2pk(Mypubkey()); memset(timestamps,0,sizeof(timestamps)); result.push_back(Pair("name","sudoku")); @@ -711,7 +711,7 @@ UniValue sudoku_solution(uint64_t txfee,struct CCcontract_info *cp,cJSON *params result.push_back(Pair("amount",ValueFromAmount(balance))); if ( (inputsum= AddCClibInputs(cp,mtx,pk,balance,16)) >= balance ) { - mtx.vout.push_back(CTxOut(balance-txfee,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG)); + mtx.vout.push_back(CTxOut(balance-txfee,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG)); CCaddr2set(cp,cp->evalcode,pk,priv32,CCaddr); rawtx = FinalizeCCTx(0,cp,mtx,pubkey2pk(Mypubkey()),txfee,sudoku_solutionopret(solution,timestamps)); } From 3b5218ccdf23e740019ccfb3b8f8c91837d4d9eb Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 29 Jan 2019 05:25:27 -1100 Subject: [PATCH 44/80] Serialize timestamps --- src/cc/sudoku.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/cc/sudoku.cpp b/src/cc/sudoku.cpp index 4d9443200..5e5247acd 100644 --- a/src/cc/sudoku.cpp +++ b/src/cc/sudoku.cpp @@ -519,8 +519,15 @@ CScript sudoku_genopret(uint8_t unsolved[9][9]) CScript sudoku_solutionopret(char *solution,uint32_t timestamps[81]) { - CScript opret; uint8_t evalcode = EVAL_SUDOKU; - opret << OP_RETURN << E_MARSHAL(ss << evalcode << 'S' << solution << timestamps); + CScript opret; uint8_t evalcode = EVAL_SUDOKU; std::vector data; int32_t i; + for (i=0; i<81; i++) + { + data.push_back((timestamps[i] >> 24) & 0xff); + data.push_back((timestamps[i] >> 16) & 0xff); + data.push_back((timestamps[i] >> 8) & 0xff); + data.push_back(timestamps[i] & 0xff); + } + opret << OP_RETURN << E_MARSHAL(ss << evalcode << 'S' << solution << data); return(opret); } From 17ccb0fc88f621bc0bdcad1e22a74b671c1fe44f Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 29 Jan 2019 05:26:17 -1100 Subject: [PATCH 45/80] Test --- src/cc/sudoku.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cc/sudoku.cpp b/src/cc/sudoku.cpp index 5e5247acd..f1f0a1e89 100644 --- a/src/cc/sudoku.cpp +++ b/src/cc/sudoku.cpp @@ -519,7 +519,7 @@ CScript sudoku_genopret(uint8_t unsolved[9][9]) CScript sudoku_solutionopret(char *solution,uint32_t timestamps[81]) { - CScript opret; uint8_t evalcode = EVAL_SUDOKU; std::vector data; int32_t i; + CScript opret; uint8_t evalcode = EVAL_SUDOKU; std::string str(solution); std::vector data; int32_t i; for (i=0; i<81; i++) { data.push_back((timestamps[i] >> 24) & 0xff); @@ -527,7 +527,7 @@ CScript sudoku_solutionopret(char *solution,uint32_t timestamps[81]) data.push_back((timestamps[i] >> 8) & 0xff); data.push_back(timestamps[i] & 0xff); } - opret << OP_RETURN << E_MARSHAL(ss << evalcode << 'S' << solution << data); + opret << OP_RETURN << E_MARSHAL(ss << evalcode << 'S' << str << data); return(opret); } From 357d1979a9a0f0153b67cecf563b9ec154b6ed67 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 29 Jan 2019 05:31:49 -1100 Subject: [PATCH 46/80] Check privacy --- src/cc/sudoku.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/cc/sudoku.cpp b/src/cc/sudoku.cpp index f1f0a1e89..e71c9df5a 100644 --- a/src/cc/sudoku.cpp +++ b/src/cc/sudoku.cpp @@ -708,8 +708,12 @@ UniValue sudoku_solution(uint64_t txfee,struct CCcontract_info *cp,cJSON *params { for (i=ind=0; i<9; i++) for (j=0; j<9; j++) - vals9[i][j] = solution[ind++]; + vals9[i][j] = solution[ind++] - '0'; sudoku_privkey(priv32,vals9); + // 0a760244c109bb5c9ef989126205f6585b9d4167afa0a2733fbab7fe74967049 privkey + for (i=0; i<32; i++) + printf("%02x",priv32[i]); + printf(" priv32\n"); priv2addr(coinaddr,pub33,priv32); pk = buf2pk(pub33); GetCCaddress(cp,CCaddr,pk); From f262751d437ff0d88865d12e6a7bf08f1cfad27e Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 29 Jan 2019 05:35:29 -1100 Subject: [PATCH 47/80] Prints --- src/cc/cclib.cpp | 4 ++-- src/cc/sudoku.cpp | 4 ---- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/cc/cclib.cpp b/src/cc/cclib.cpp index c1c3d9f24..adc17f54c 100644 --- a/src/cc/cclib.cpp +++ b/src/cc/cclib.cpp @@ -263,7 +263,7 @@ int64_t AddCClibInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubK { txid = it->first.txhash; vout = (int32_t)it->first.index; - //char str[65]; fprintf(stderr,"%s check %s/v%d %.8f\n",coinaddr,uint256_str(str,txid),vout,(double)it->second.satoshis/COIN); + char str[65]; fprintf(stderr,"%s check %s/v%d %.8f vs %.8f\n",coinaddr,uint256_str(str,txid),vout,(double)it->second.satoshis/COIN,(double)threshold/COIN); if ( it->second.satoshis < threshold ) continue; // no need to prevent dup @@ -278,7 +278,7 @@ int64_t AddCClibInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubK n++; if ( (total > 0 && totalinputs >= total) || (maxinputs > 0 && n >= maxinputs) ) break; - } else fprintf(stderr,"nValue too small or already spent in mempool\n"); + } else fprintf(stderr,"nValue %.8f too small or already spent in mempool\n",(double)nValue/COIN); } else fprintf(stderr,"couldnt get tx\n"); } return(totalinputs); diff --git a/src/cc/sudoku.cpp b/src/cc/sudoku.cpp index e71c9df5a..7ff297004 100644 --- a/src/cc/sudoku.cpp +++ b/src/cc/sudoku.cpp @@ -710,10 +710,6 @@ UniValue sudoku_solution(uint64_t txfee,struct CCcontract_info *cp,cJSON *params for (j=0; j<9; j++) vals9[i][j] = solution[ind++] - '0'; sudoku_privkey(priv32,vals9); - // 0a760244c109bb5c9ef989126205f6585b9d4167afa0a2733fbab7fe74967049 privkey - for (i=0; i<32; i++) - printf("%02x",priv32[i]); - printf(" priv32\n"); priv2addr(coinaddr,pub33,priv32); pk = buf2pk(pub33); GetCCaddress(cp,CCaddr,pk); From 9195d9034aa4be0846fa77620bddb60358e1953a Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 29 Jan 2019 05:39:17 -1100 Subject: [PATCH 48/80] Cmpaddr as arg to IsCClibvout --- src/cc/cclib.cpp | 12 ++++++------ src/cc/sudoku.cpp | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/cc/cclib.cpp b/src/cc/cclib.cpp index adc17f54c..d1817b2ce 100644 --- a/src/cc/cclib.cpp +++ b/src/cc/cclib.cpp @@ -141,12 +141,12 @@ UniValue CClib(struct CCcontract_info *cp,char *method,cJSON *params) return(result); } -int64_t IsCClibvout(struct CCcontract_info *cp,const CTransaction& tx,int32_t v) +int64_t IsCClibvout(struct CCcontract_info *cp,const CTransaction& tx,int32_t v,char *cmpaddr) { char destaddr[64]; if ( tx.vout[v].scriptPubKey.IsPayToCryptoCondition() != 0 ) { - if ( Getscriptaddress(destaddr,tx.vout[v].scriptPubKey) > 0 && strcmp(destaddr,cp->unspendableCCaddr) == 0 ) + if ( Getscriptaddress(destaddr,tx.vout[v].scriptPubKey) > 0 && strcmp(destaddr,cmpaddr) == 0 ) return(tx.vout[v].nValue); } return(0); @@ -171,7 +171,7 @@ bool CClibExactAmounts(struct CCcontract_info *cp,Eval* eval,const CTransaction //fprintf(stderr,"vini.%d check hash and vout\n",i); if ( hashBlock == zerohash ) return eval->Invalid("cant faucet2 from mempool"); - if ( (assetoshis= IsCClibvout(cp,vinTx,tx.vin[i].prevout.n)) != 0 ) + if ( (assetoshis= IsCClibvout(cp,vinTx,tx.vin[i].prevout.n,cp->unspendableCCaddr)) != 0 ) inputs += assetoshis; } } @@ -179,7 +179,7 @@ bool CClibExactAmounts(struct CCcontract_info *cp,Eval* eval,const CTransaction for (i=0; iunspendableCCaddr)) != 0 ) outputs += assetoshis; } if ( inputs != outputs+FAUCET2SIZE+txfee ) @@ -220,7 +220,7 @@ bool CClib_validate(struct CCcontract_info *cp,int32_t height,Eval *eval,const C else { preventCCvouts = 1; - if ( IsCClibvout(cp,tx,0) != 0 ) + if ( IsCClibvout(cp,tx,0,cp->unspendableCCaddr) != 0 ) { preventCCvouts++; i = 1; @@ -269,7 +269,7 @@ int64_t AddCClibInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubK // no need to prevent dup if ( GetTransaction(txid,vintx,hashBlock,false) != 0 ) { - if ( (nValue= IsCClibvout(cp,vintx,vout)) > 1000000 && myIsutxo_spentinmempool(txid,vout) == 0 ) + if ( (nValue= IsCClibvout(cp,vintx,vout,cp->unspendableCCaddr)) > 1000000 && myIsutxo_spentinmempool(txid,vout) == 0 ) { if ( total != 0 && maxinputs != 0 ) mtx.vin.push_back(CTxIn(txid,vout,CScript())); diff --git a/src/cc/sudoku.cpp b/src/cc/sudoku.cpp index 7ff297004..87f66d751 100644 --- a/src/cc/sudoku.cpp +++ b/src/cc/sudoku.cpp @@ -652,7 +652,7 @@ UniValue sudoku_pending(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) continue; if ( GetTransaction(txid,tx,hashBlock,false) != 0 && (numvouts= tx.vout.size()) > 1 ) { - if ( (nValue= IsCClibvout(cp,tx,vout)) == txfee && myIsutxo_spentinmempool(txid,vout) == 0 ) + if ( (nValue= IsCClibvout(cp,tx,vout,coinaddr)) == txfee && myIsutxo_spentinmempool(txid,vout) == 0 ) { if ( sudoku_genopreturndecode(unsolved,tx.vout[numvouts-1].scriptPubKey) == 'G' ) a.push_back(txid.GetHex()); From b2435c8c1637d3aba2d1c666996123793b527527 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 29 Jan 2019 05:41:26 -1100 Subject: [PATCH 49/80] Set cmpaddr --- src/cc/cclib.cpp | 6 +++--- src/cc/sudoku.cpp | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/cc/cclib.cpp b/src/cc/cclib.cpp index d1817b2ce..036a7d119 100644 --- a/src/cc/cclib.cpp +++ b/src/cc/cclib.cpp @@ -252,7 +252,7 @@ bool CClib_validate(struct CCcontract_info *cp,int32_t height,Eval *eval,const C } } -int64_t AddCClibInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,int64_t total,int32_t maxinputs) +int64_t AddCClibInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,int64_t total,int32_t maxinputs,char *cmpaddr) { char coinaddr[64]; int64_t threshold,nValue,price,totalinputs = 0; uint256 txid,hashBlock; std::vector origpubkey; CTransaction vintx; int32_t vout,n = 0; std::vector > unspentOutputs; @@ -269,7 +269,7 @@ int64_t AddCClibInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubK // no need to prevent dup if ( GetTransaction(txid,vintx,hashBlock,false) != 0 ) { - if ( (nValue= IsCClibvout(cp,vintx,vout,cp->unspendableCCaddr)) > 1000000 && myIsutxo_spentinmempool(txid,vout) == 0 ) + if ( (nValue= IsCClibvout(cp,vintx,vout,cmpaddr)) > 1000000 && myIsutxo_spentinmempool(txid,vout) == 0 ) { if ( total != 0 && maxinputs != 0 ) mtx.vin.push_back(CTxIn(txid,vout,CScript())); @@ -333,7 +333,7 @@ std::string CClib_rawtxgen(struct CCcontract_info *cp,uint8_t funcid,cJSON *para return(""); cclibpk = GetUnspendable(cp,0); mypk = pubkey2pk(Mypubkey()); - if ( (inputs= AddCClibInputs(cp,mtx,cclibpk,nValue+txfee,60)) > 0 ) + if ( (inputs= AddCClibInputs(cp,mtx,cclibpk,nValue+txfee,60,cp->unspendableCCaddr)) > 0 ) { if ( inputs > nValue ) CCchange = (inputs - nValue - txfee); diff --git a/src/cc/sudoku.cpp b/src/cc/sudoku.cpp index 87f66d751..b407c5c3a 100644 --- a/src/cc/sudoku.cpp +++ b/src/cc/sudoku.cpp @@ -570,7 +570,7 @@ UniValue sudoku_generate(uint64_t txfee,struct CCcontract_info *cp,cJSON *params sudokupk = GetUnspendable(cp,0); result.push_back(Pair("srand",(int)srandi)); result.push_back(Pair("amount",ValueFromAmount(amount))); - if ( (inputsum= AddCClibInputs(cp,mtx,sudokupk,amount+2*txfee,16)) >= amount+2*txfee ) + if ( (inputsum= AddCClibInputs(cp,mtx,sudokupk,amount+2*txfee,16,cp->unspendableCCaddr)) >= amount+2*txfee ) { //printf("inputsum %.8f\n",(double)inputsum/COIN); mtx.vout.push_back(MakeCC1vout(cp->evalcode,txfee,sudokupk)); @@ -716,7 +716,7 @@ UniValue sudoku_solution(uint64_t txfee,struct CCcontract_info *cp,cJSON *params result.push_back(Pair("sudokuaddr",CCaddr)); balance = CCaddress_balance(CCaddr); result.push_back(Pair("amount",ValueFromAmount(balance))); - if ( (inputsum= AddCClibInputs(cp,mtx,pk,balance,16)) >= balance ) + if ( (inputsum= AddCClibInputs(cp,mtx,pk,balance,16,CCaddr)) >= balance ) { mtx.vout.push_back(CTxOut(balance-txfee,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG)); CCaddr2set(cp,cp->evalcode,pk,priv32,CCaddr); From eee12923bcbef17db21380d266a80001e3267666 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 29 Jan 2019 05:49:54 -1100 Subject: [PATCH 50/80] jsonstr --- src/cc/cclib.cpp | 2 +- src/cc/sudoku.cpp | 36 ++++++++++++++++++++++++++++++------ 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/src/cc/cclib.cpp b/src/cc/cclib.cpp index 036a7d119..eb93a5042 100644 --- a/src/cc/cclib.cpp +++ b/src/cc/cclib.cpp @@ -263,7 +263,7 @@ int64_t AddCClibInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubK { txid = it->first.txhash; vout = (int32_t)it->first.index; - char str[65]; fprintf(stderr,"%s check %s/v%d %.8f vs %.8f\n",coinaddr,uint256_str(str,txid),vout,(double)it->second.satoshis/COIN,(double)threshold/COIN); + //char str[65]; fprintf(stderr,"%s check %s/v%d %.8f vs %.8f\n",coinaddr,uint256_str(str,txid),vout,(double)it->second.satoshis/COIN,(double)threshold/COIN); if ( it->second.satoshis < threshold ) continue; // no need to prevent dup diff --git a/src/cc/sudoku.cpp b/src/cc/sudoku.cpp index b407c5c3a..c3fa87c74 100644 --- a/src/cc/sudoku.cpp +++ b/src/cc/sudoku.cpp @@ -478,7 +478,7 @@ void sudoku_gen(uint8_t key32[32],uint8_t unsolved[9][9],uint32_t srandi) //////////////////////// start of CClib interface // ./komodod -ac_name=SUDOKU -ac_supply=1000000 -pubkey= -addnode=5.9.102.210 -gen -genproclimit=1 -ac_cclib=sudoku -ac_perc=10000000 -ac_reward=100000000 -ac_cc=60000 -ac_script=2ea22c80203d1579313abe7d8ea85f48c65ea66fc512c878c0d0e6f6d54036669de940febf8103120c008203000401cc & -/* cclib "gen" 17 "1" +/* cclib "gen" 17 \"1\" 5d13c1ad80daf37215c74809a36720c2ada90bacadb2e10bf0866092ce558432 */ @@ -505,6 +505,14 @@ void sudoku_gen(uint8_t key32[32],uint8_t unsolved[9][9],uint32_t srandi) /* cclib "solution" 17 \"[%22469823715875961234231457698914675823653182479782394156346219587528736941197548362%22,1548777525,1548777526,...]\" + { + "name": "sudoku", + "method": "solution", + "sudokuaddr": "RSeoPJvMUSLfUHM1BomB97geW9zPznwHXk", + "amount": 1.00000000, + "result": "success", + "hex": "0400008085202f8901328455ce926086f00be1b2adac0ba9adc22067a30948c71572f3da80adc1135d010000007b4c79a276a072a26ba067a565802102c57d40c1ddc92a5246a937bd7338823f1e8c916b137f2092d38cf250d74cb5ab8140f92d54f611aa3cb3d187eaadd56b06f3a8c0f5fba23956b26fdefc6038d9b6282de38525f72ebd8945a7994cef63ebca711ecf8fe6baeefcc218cf58efb59dc2a100af03800111a10001ffffffff02f0b9f505000000002321039433dc3749aece1bd568f374a45da3b0bc6856990d7da3cd175399577940a775ac0000000000000000fd9f016a4d9b01115351343639383233373135383735393631323334323331343537363938393134363735383233363533313832343739373832333934313536333436323139353837353238373336393431313937353438333632fd4401000000005c5078355c50783600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000" + } */ CScript sudoku_genopret(uint8_t unsolved[9][9]) @@ -552,12 +560,20 @@ uint8_t sudoku_genopreturndecode(char *unsolved,CScript scriptPubKey) UniValue sudoku_generate(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) { CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); - UniValue result(UniValue::VOBJ); CPubKey sudokupk,pk; uint8_t privkey[32],unsolved[9][9],pub33[33]; uint32_t srandi; uint256 hash; char coinaddr[64]; uint64_t inputsum,amount,change=0; std::string rawtx; + UniValue result(UniValue::VOBJ); CPubKey sudokupk,pk; uint8_t privkey[32],unsolved[9][9],pub33[33]; uint32_t srandi; uint256 hash; char coinaddr[64],*jsonstr; uint64_t inputsum,amount,change=0; std::string rawtx; + amount = COIN; if ( params != 0 ) { - printf("%p params.(%s)\n",params,jprint(params,0)); - amount = jdouble(jitem(params,0),0) * COIN + 0.0000000049; - } else amount = COIN; + if ( (jsonstr= jprint(params,0)) != 0 ) + { + if ( jsonstr[0] == '"' && jsonstr[strlen(jsonstr)-1] == '"' ) + { + jsonstr[strlen(jsonstr)-1] = 0; + jsonstr++; + } + amount = atof(jsonstr) * COIN + 0.0000000049; + } + } result.push_back(Pair("result","success")); result.push_back(Pair("name","sudoku")); result.push_back(Pair("method","gen")); @@ -581,8 +597,16 @@ UniValue sudoku_generate(uint64_t txfee,struct CCcontract_info *cp,cJSON *params mtx.vout.push_back(MakeCC1vout(cp->evalcode,change,sudokupk)); rawtx = FinalizeCCTx(0,cp,mtx,pubkey2pk(Mypubkey()),txfee,sudoku_genopret(unsolved)); if ( rawtx.size() > 0 ) + { + CTransaction tx; result.push_back(Pair("hex",rawtx)); - else result.push_back(Pair("error","couldnt finalize CCtx")); + if ( DecodeHexTx(tx,rawtx) != 0 ) + { + LOCK(cs_main); + if ( myAddtomempool(tx) != 0 ) + RelayTransaction(tx); + } + } else result.push_back(Pair("error","couldnt finalize CCtx")); } else result.push_back(Pair("error","not enough SUDOKU funds")); return(result); } From 24136eae68cf48fa6178afa1bafe0d713eed620f Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 29 Jan 2019 05:52:18 -1100 Subject: [PATCH 51/80] Add taxied --- src/cc/sudoku.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/cc/sudoku.cpp b/src/cc/sudoku.cpp index c3fa87c74..d767acab6 100644 --- a/src/cc/sudoku.cpp +++ b/src/cc/sudoku.cpp @@ -478,7 +478,7 @@ void sudoku_gen(uint8_t key32[32],uint8_t unsolved[9][9],uint32_t srandi) //////////////////////// start of CClib interface // ./komodod -ac_name=SUDOKU -ac_supply=1000000 -pubkey= -addnode=5.9.102.210 -gen -genproclimit=1 -ac_cclib=sudoku -ac_perc=10000000 -ac_reward=100000000 -ac_cc=60000 -ac_script=2ea22c80203d1579313abe7d8ea85f48c65ea66fc512c878c0d0e6f6d54036669de940febf8103120c008203000401cc & -/* cclib "gen" 17 \"1\" +/* cclib "gen" 17 \"10\" 5d13c1ad80daf37215c74809a36720c2ada90bacadb2e10bf0866092ce558432 */ @@ -604,7 +604,10 @@ UniValue sudoku_generate(uint64_t txfee,struct CCcontract_info *cp,cJSON *params { LOCK(cs_main); if ( myAddtomempool(tx) != 0 ) + { RelayTransaction(tx); + result.push_back(Pair("txid",tx.GetHash().ToString())); + } } } else result.push_back(Pair("error","couldnt finalize CCtx")); } else result.push_back(Pair("error","not enough SUDOKU funds")); From 69aedc198169602fc42ac00971f24c6de3498c4e Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 29 Jan 2019 06:14:29 -1100 Subject: [PATCH 52/80] Nun-ending --- src/cc/sudoku.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cc/sudoku.cpp b/src/cc/sudoku.cpp index d767acab6..db2ea24bd 100644 --- a/src/cc/sudoku.cpp +++ b/src/cc/sudoku.cpp @@ -690,6 +690,7 @@ UniValue sudoku_pending(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) result.push_back(Pair("name","sudoku")); result.push_back(Pair("method","pending")); result.push_back(Pair("pending",a)); + result.push_back(Pair("numpending",a.size())); return(result); } From a783c9d7f52c8e0cb0a59d6d2ccabeea63a76fb1 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 29 Jan 2019 07:10:01 -1100 Subject: [PATCH 53/80] sudoku_captcha --- src/cc/sudoku.cpp | 61 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 55 insertions(+), 6 deletions(-) diff --git a/src/cc/sudoku.cpp b/src/cc/sudoku.cpp index db2ea24bd..bdc47ea61 100644 --- a/src/cc/sudoku.cpp +++ b/src/cc/sudoku.cpp @@ -515,6 +515,46 @@ void sudoku_gen(uint8_t key32[32],uint8_t unsolved[9][9],uint32_t srandi) } */ +int32_t sudoku_captcha(uint32_t timestamps[81]) +{ + int32_t i,solvetime,avetime,n = 0; uint64_t variance = 0; std::vector list; + for (i=0; i<81; i++) + { + if ( timestamps[i] != 0 ) + { + list.push_back(timestamps[i]); + n++; + } + } + if ( n > 81/2 ) + { + std::sort(list.begin(),list.end()); + solvetime = (list[0] - list[n-1]); + if ( list[0] < list[n-1] ) + return(-1); + else if ( list[0] > chainActive.LastTip()->nTime+200 ) + return(-1); + else if ( solvetime >= 777 ) + return(0); + else + { + avetime = (solvetime / (n-1)); + if ( avetime == 0 ) + return(-1); + for (i=0; i data; int32_t i,j; @@ -730,7 +770,7 @@ UniValue sudoku_solution(uint64_t txfee,struct CCcontract_info *cp,cJSON *params for (i=1; i= balance ) + if ( sudoku_captcha(timestamps) < 0 ) { - mtx.vout.push_back(CTxOut(balance-txfee,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG)); - CCaddr2set(cp,cp->evalcode,pk,priv32,CCaddr); - rawtx = FinalizeCCTx(0,cp,mtx,pubkey2pk(Mypubkey()),txfee,sudoku_solutionopret(solution,timestamps)); + result.push_back(Pair("result","error")); + result.push_back(Pair("error","captcha failure")); + return(result); + } + else + { + if ( (inputsum= AddCClibInputs(cp,mtx,pk,balance,16,CCaddr)) >= balance ) + { + mtx.vout.push_back(CTxOut(balance-txfee,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG)); + CCaddr2set(cp,cp->evalcode,pk,priv32,CCaddr); + rawtx = FinalizeCCTx(0,cp,mtx,pubkey2pk(Mypubkey()),txfee,sudoku_solutionopret(solution,timestamps)); + } } } } @@ -756,7 +805,7 @@ UniValue sudoku_solution(uint64_t txfee,struct CCcontract_info *cp,cJSON *params if ( rawtx.size() > 0 ) result.push_back(Pair("hex",rawtx)); else result.push_back(Pair("error","couldnt finalize CCtx")); - printf("params.(%s)\n",jprint(params,0)); + //printf("params.(%s)\n",jprint(params,0)); return(result); } else From 1c6dd009cf6807710dc048de06067bc1024ba1a9 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 29 Jan 2019 07:11:46 -1100 Subject: [PATCH 54/80] Print --- src/cc/sudoku.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/cc/sudoku.cpp b/src/cc/sudoku.cpp index bdc47ea61..d0db3db90 100644 --- a/src/cc/sudoku.cpp +++ b/src/cc/sudoku.cpp @@ -531,7 +531,10 @@ int32_t sudoku_captcha(uint32_t timestamps[81]) std::sort(list.begin(),list.end()); solvetime = (list[0] - list[n-1]); if ( list[0] < list[n-1] ) + { + printf("list[0] %u vs list[%d-1] %u\n",list[0],list[n-1]); return(-1); + } else if ( list[0] > chainActive.LastTip()->nTime+200 ) return(-1); else if ( solvetime >= 777 ) @@ -543,7 +546,9 @@ int32_t sudoku_captcha(uint32_t timestamps[81]) return(-1); for (i=0; i Date: Tue, 29 Jan 2019 07:12:46 -1100 Subject: [PATCH 55/80] N --- src/cc/sudoku.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc/sudoku.cpp b/src/cc/sudoku.cpp index d0db3db90..0be42cba5 100644 --- a/src/cc/sudoku.cpp +++ b/src/cc/sudoku.cpp @@ -532,7 +532,7 @@ int32_t sudoku_captcha(uint32_t timestamps[81]) solvetime = (list[0] - list[n-1]); if ( list[0] < list[n-1] ) { - printf("list[0] %u vs list[%d-1] %u\n",list[0],list[n-1]); + printf("list[0] %u vs list[%d-1] %u\n",list[0],n,list[n-1]); return(-1); } else if ( list[0] > chainActive.LastTip()->nTime+200 ) From 82cf345e94de801e4dcec919932ff4d6ec33ad83 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 29 Jan 2019 07:13:16 -1100 Subject: [PATCH 56/80] Diff --- src/cc/sudoku.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc/sudoku.cpp b/src/cc/sudoku.cpp index 0be42cba5..0b45c8483 100644 --- a/src/cc/sudoku.cpp +++ b/src/cc/sudoku.cpp @@ -517,7 +517,7 @@ void sudoku_gen(uint8_t key32[32],uint8_t unsolved[9][9],uint32_t srandi) int32_t sudoku_captcha(uint32_t timestamps[81]) { - int32_t i,solvetime,avetime,n = 0; uint64_t variance = 0; std::vector list; + int32_t i,solvetime,diff,avetime,n = 0; uint64_t variance = 0; std::vector list; for (i=0; i<81; i++) { if ( timestamps[i] != 0 ) From 2bc78f3998919bc7ec292480effa9629ef43ee6f Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 29 Jan 2019 07:16:17 -1100 Subject: [PATCH 57/80] N --- src/cc/sudoku.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cc/sudoku.cpp b/src/cc/sudoku.cpp index 0b45c8483..0696ec979 100644 --- a/src/cc/sudoku.cpp +++ b/src/cc/sudoku.cpp @@ -526,7 +526,7 @@ int32_t sudoku_captcha(uint32_t timestamps[81]) n++; } } - if ( n > 81/2 ) + //if ( n > 81/2 ) { std::sort(list.begin(),list.end()); solvetime = (list[0] - list[n-1]); @@ -557,7 +557,7 @@ int32_t sudoku_captcha(uint32_t timestamps[81]) return(-1 * 0); else return(0); } - } else return(-1); + } //else return(-1); } CScript sudoku_genopret(uint8_t unsolved[9][9]) From 03274df1f9fc444b7faa600620986ec4739078a6 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 29 Jan 2019 07:18:13 -1100 Subject: [PATCH 58/80] Reverse polarity --- src/cc/sudoku.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cc/sudoku.cpp b/src/cc/sudoku.cpp index 0696ec979..0fa750d6d 100644 --- a/src/cc/sudoku.cpp +++ b/src/cc/sudoku.cpp @@ -529,13 +529,13 @@ int32_t sudoku_captcha(uint32_t timestamps[81]) //if ( n > 81/2 ) { std::sort(list.begin(),list.end()); - solvetime = (list[0] - list[n-1]); - if ( list[0] < list[n-1] ) + solvetime = (list[n-1] - list[0]); + if ( list[0] >= list[n-1] ) { printf("list[0] %u vs list[%d-1] %u\n",list[0],n,list[n-1]); return(-1); } - else if ( list[0] > chainActive.LastTip()->nTime+200 ) + else if ( list[n-1] > chainActive.LastTip()->nTime+200 ) return(-1); else if ( solvetime >= 777 ) return(0); From 425d5ddbafe762f9629ce6b6fba915a550cf8deb Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 29 Jan 2019 07:20:02 -1100 Subject: [PATCH 59/80] Enable captcha --- src/cc/sudoku.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cc/sudoku.cpp b/src/cc/sudoku.cpp index 0fa750d6d..05450659a 100644 --- a/src/cc/sudoku.cpp +++ b/src/cc/sudoku.cpp @@ -526,7 +526,7 @@ int32_t sudoku_captcha(uint32_t timestamps[81]) n++; } } - //if ( n > 81/2 ) + if ( n > 81/2 ) { std::sort(list.begin(),list.end()); solvetime = (list[n-1] - list[0]); @@ -557,7 +557,7 @@ int32_t sudoku_captcha(uint32_t timestamps[81]) return(-1 * 0); else return(0); } - } //else return(-1); + } else return(-1); } CScript sudoku_genopret(uint8_t unsolved[9][9]) From a7f14184a71fdd9437524a68ebfa9566272679db Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 29 Jan 2019 07:21:58 -1100 Subject: [PATCH 60/80] Split gen --- src/cc/sudoku.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/cc/sudoku.cpp b/src/cc/sudoku.cpp index 05450659a..5e3801efb 100644 --- a/src/cc/sudoku.cpp +++ b/src/cc/sudoku.cpp @@ -639,7 +639,13 @@ UniValue sudoku_generate(uint64_t txfee,struct CCcontract_info *cp,cJSON *params if ( inputsum > amount + 2*txfee ) change = (inputsum - amount - 2*txfee); if ( change > txfee ) - mtx.vout.push_back(MakeCC1vout(cp->evalcode,change,sudokupk)); + { + if ( change > 10000*COIN ) + { + mtx.vout.push_back(MakeCC1vout(cp->evalcode,change/2,sudokupk)); + mtx.vout.push_back(MakeCC1vout(cp->evalcode,change/2,sudokupk)); + } else mtx.vout.push_back(MakeCC1vout(cp->evalcode,change,sudokupk)); + } rawtx = FinalizeCCTx(0,cp,mtx,pubkey2pk(Mypubkey()),txfee,sudoku_genopret(unsolved)); if ( rawtx.size() > 0 ) { From 16512daaaa1939c6977b9a653a062c6834a6ce4d Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 29 Jan 2019 07:34:07 -1100 Subject: [PATCH 61/80] -print --- src/cc/cclib.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc/cclib.cpp b/src/cc/cclib.cpp index eb93a5042..69d8d4aaa 100644 --- a/src/cc/cclib.cpp +++ b/src/cc/cclib.cpp @@ -278,7 +278,7 @@ int64_t AddCClibInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubK n++; if ( (total > 0 && totalinputs >= total) || (maxinputs > 0 && n >= maxinputs) ) break; - } else fprintf(stderr,"nValue %.8f too small or already spent in mempool\n",(double)nValue/COIN); + } //else fprintf(stderr,"nValue %.8f too small or already spent in mempool\n",(double)nValue/COIN); } else fprintf(stderr,"couldnt get tx\n"); } return(totalinputs); From 6283d6dd284d62e2eb1b5c279154911dc3e6d043 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 29 Jan 2019 07:36:23 -1100 Subject: [PATCH 62/80] Pending total --- src/cc/sudoku.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/cc/sudoku.cpp b/src/cc/sudoku.cpp index 5e3801efb..3e19ba964 100644 --- a/src/cc/sudoku.cpp +++ b/src/cc/sudoku.cpp @@ -716,7 +716,7 @@ UniValue sudoku_txidinfo(uint64_t txfee,struct CCcontract_info *cp,cJSON *params UniValue sudoku_pending(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) { UniValue result(UniValue::VOBJ),a(UniValue::VARR); - char coinaddr[64],unsolved[82]; int64_t nValue; uint256 txid,hashBlock; CTransaction tx; int32_t vout,numvouts; CPubKey sudokupk; + char coinaddr[64],unsolved[82]; int64_t nValue,total=0; uint256 txid,hashBlock; CTransaction tx; int32_t vout,numvouts; CPubKey sudokupk; std::vector > unspentOutputs; sudokupk = GetUnspendable(cp,0); GetCCaddress(cp,coinaddr,sudokupk); @@ -733,7 +733,10 @@ UniValue sudoku_pending(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) if ( (nValue= IsCClibvout(cp,tx,vout,coinaddr)) == txfee && myIsutxo_spentinmempool(txid,vout) == 0 ) { if ( sudoku_genopreturndecode(unsolved,tx.vout[numvouts-1].scriptPubKey) == 'G' ) + { a.push_back(txid.GetHex()); + total += tx.vout[1].nValue; + } } } } @@ -742,6 +745,7 @@ UniValue sudoku_pending(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) result.push_back(Pair("method","pending")); result.push_back(Pair("pending",a)); result.push_back(Pair("numpending",a.size())); + result.push_back(Pair("total",ValueFromAmount(total))); return(result); } From e66ebf2a862d754cf0bee59eca7e4e8c582f871e Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 29 Jan 2019 08:04:19 -1100 Subject: [PATCH 63/80] Add txid for solution --- src/cc/sudoku.cpp | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/src/cc/sudoku.cpp b/src/cc/sudoku.cpp index 3e19ba964..e7861fa97 100644 --- a/src/cc/sudoku.cpp +++ b/src/cc/sudoku.cpp @@ -504,7 +504,7 @@ void sudoku_gen(uint8_t key32[32],uint8_t unsolved[9][9],uint32_t srandi) }*/ /* - cclib "solution" 17 \"[%22469823715875961234231457698914675823653182479782394156346219587528736941197548362%22,1548777525,1548777526,...]\" + cclib "solution" 17 \"[%22fdc9409741f2ede29307da1a06438da0ea6f8d885d2d5c3199c4ef541ec1b5fd%22,%22469823715875961234231457698914675823653182479782394156346219587528736941197548362%22,1548777525,1548777526,...]\" { "name": "sudoku", "method": "solution", @@ -752,7 +752,7 @@ UniValue sudoku_pending(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) UniValue sudoku_solution(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) { CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); - UniValue result(UniValue::VOBJ); int32_t i,j,ind,n; char *jsonstr,*newstr,coinaddr[64],CCaddr[64],*solution=0; CPubKey pk,mypk; uint8_t vals9[9][9],priv32[32],pub33[33]; uint32_t timestamps[81]; uint64_t balance,inputsum; std::string rawtx; + UniValue result(UniValue::VOBJ); int32_t i,j,ind,n; uint256 txid; char *jsonstr,*newstr,*txidstr,coinaddr[64],CCaddr[64],*solution=0; CPubKey pk,mypk; uint8_t vals9[9][9],priv32[32],pub33[33]; uint32_t timestamps[81]; uint64_t balance,inputsum; std::string rawtx; CTransaction tx; mypk = pubkey2pk(Mypubkey()); memset(timestamps,0,sizeof(timestamps)); result.push_back(Pair("name","sudoku")); @@ -780,14 +780,21 @@ UniValue sudoku_solution(uint64_t txfee,struct CCcontract_info *cp,cJSON *params } else params = 0; if ( params != 0 ) { - if ( (n= cJSON_GetArraySize(params)) > 2 && n < (sizeof(timestamps)/sizeof(*timestamps))+1 ) + if ( (n= cJSON_GetArraySize(params)) > 2 && n < (sizeof(timestamps)/sizeof(*timestamps))+2 ) { - for (i=1; i= balance ) { - mtx.vout.push_back(CTxOut(balance-txfee,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG)); + mtx.vout.push_back(CTxOut(balance,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG)); CCaddr2set(cp,cp->evalcode,pk,priv32,CCaddr); rawtx = FinalizeCCTx(0,cp,mtx,pubkey2pk(Mypubkey()),txfee,sudoku_solutionopret(solution,timestamps)); } } } - } - result.push_back(Pair("result","success")); + result.push_back(Pair("result","success")); + } else result.push_back(Pair("error","couldnt get all params")); if ( rawtx.size() > 0 ) result.push_back(Pair("hex",rawtx)); else result.push_back(Pair("error","couldnt finalize CCtx")); From 81f9d7046ed823231c2e4e473a484042f61a4139 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 29 Jan 2019 08:04:49 -1100 Subject: [PATCH 64/80] Test --- src/cc/sudoku.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/cc/sudoku.cpp b/src/cc/sudoku.cpp index e7861fa97..113ee11b5 100644 --- a/src/cc/sudoku.cpp +++ b/src/cc/sudoku.cpp @@ -782,13 +782,6 @@ UniValue sudoku_solution(uint64_t txfee,struct CCcontract_info *cp,cJSON *params { if ( (n= cJSON_GetArraySize(params)) > 2 && n < (sizeof(timestamps)/sizeof(*timestamps))+2 ) { - if ( (txidstr= jstri(params,0)) != 0 ) - { - decode_hex((uint8_t *)&txid,32,txidstr); - txid = revuint256(txid); - result.push_back(Pair("txid",txid.GetHex())); - // get tx and validate solution is for that txid - } for (i=2; i= balance ) { From b399529ec84274978dcb01c1154f141630caa69f Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 29 Jan 2019 08:08:29 -1100 Subject: [PATCH 65/80] Ignore --- src/cc/sudoku.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cc/sudoku.cpp b/src/cc/sudoku.cpp index 113ee11b5..3f0052d3b 100644 --- a/src/cc/sudoku.cpp +++ b/src/cc/sudoku.cpp @@ -803,9 +803,9 @@ UniValue sudoku_solution(uint64_t txfee,struct CCcontract_info *cp,cJSON *params { result.push_back(Pair("result","error")); result.push_back(Pair("error","captcha failure")); - return(result); + //return(result); } - else + //else { if ( (txidstr= jstri(params,0)) != 0 ) { From 07131cab6035386d141af0662c710509dc921e8b Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 29 Jan 2019 08:12:05 -1100 Subject: [PATCH 66/80] Disable --- src/cc/sudoku.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cc/sudoku.cpp b/src/cc/sudoku.cpp index 3f0052d3b..267504120 100644 --- a/src/cc/sudoku.cpp +++ b/src/cc/sudoku.cpp @@ -799,13 +799,13 @@ UniValue sudoku_solution(uint64_t txfee,struct CCcontract_info *cp,cJSON *params result.push_back(Pair("sudokuaddr",CCaddr)); balance = CCaddress_balance(CCaddr); result.push_back(Pair("amount",ValueFromAmount(balance))); - if ( sudoku_captcha(timestamps) < 0 ) + if ( 0 && sudoku_captcha(timestamps) < 0 ) { result.push_back(Pair("result","error")); result.push_back(Pair("error","captcha failure")); - //return(result); + return(result); } - //else + else { if ( (txidstr= jstri(params,0)) != 0 ) { From 5cdd5f8722ace517a5283da7f22611ee35adf3ae Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 29 Jan 2019 08:14:03 -1100 Subject: [PATCH 67/80] Reenable captcha --- src/cc/sudoku.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc/sudoku.cpp b/src/cc/sudoku.cpp index 267504120..113ee11b5 100644 --- a/src/cc/sudoku.cpp +++ b/src/cc/sudoku.cpp @@ -799,7 +799,7 @@ UniValue sudoku_solution(uint64_t txfee,struct CCcontract_info *cp,cJSON *params result.push_back(Pair("sudokuaddr",CCaddr)); balance = CCaddress_balance(CCaddr); result.push_back(Pair("amount",ValueFromAmount(balance))); - if ( 0 && sudoku_captcha(timestamps) < 0 ) + if ( sudoku_captcha(timestamps) < 0 ) { result.push_back(Pair("result","error")); result.push_back(Pair("error","captcha failure")); From 0a61cd4e2ec409f73655c0c254c4eebd6cd64624 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 29 Jan 2019 08:20:29 -1100 Subject: [PATCH 68/80] +err print --- src/cc/sudoku.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc/sudoku.cpp b/src/cc/sudoku.cpp index 113ee11b5..3024f821c 100644 --- a/src/cc/sudoku.cpp +++ b/src/cc/sudoku.cpp @@ -820,7 +820,7 @@ UniValue sudoku_solution(uint64_t txfee,struct CCcontract_info *cp,cJSON *params mtx.vout.push_back(CTxOut(balance,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG)); CCaddr2set(cp,cp->evalcode,pk,priv32,CCaddr); rawtx = FinalizeCCTx(0,cp,mtx,pubkey2pk(Mypubkey()),txfee,sudoku_solutionopret(solution,timestamps)); - } + } else result.push_back(Pair("error","couldnt find funds in solution address")); } } result.push_back(Pair("result","success")); From 51721e30bb9c9d4f3788593f061a206bba60ca51 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 29 Jan 2019 08:28:21 -1100 Subject: [PATCH 69/80] Mixup errors --- src/cc/sudoku.cpp | 44 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 35 insertions(+), 9 deletions(-) diff --git a/src/cc/sudoku.cpp b/src/cc/sudoku.cpp index 3024f821c..c844e1591 100644 --- a/src/cc/sudoku.cpp +++ b/src/cc/sudoku.cpp @@ -752,11 +752,12 @@ UniValue sudoku_pending(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) UniValue sudoku_solution(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) { CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); - UniValue result(UniValue::VOBJ); int32_t i,j,ind,n; uint256 txid; char *jsonstr,*newstr,*txidstr,coinaddr[64],CCaddr[64],*solution=0; CPubKey pk,mypk; uint8_t vals9[9][9],priv32[32],pub33[33]; uint32_t timestamps[81]; uint64_t balance,inputsum; std::string rawtx; CTransaction tx; + UniValue result(UniValue::VOBJ); int32_t i,j,good,ind,n,numvouts; uint256 txid; char *jsonstr,*newstr,*txidstr,coinaddr[64],CCaddr[64],*solution=0; CPubKey pk,mypk; uint8_t vals9[9][9],priv32[32],pub33[33],unsolved[81]; uint32_t timestamps[81]; uint64_t balance,inputsum; std::string rawtx; CTransaction tx; uint256 hashBlock; mypk = pubkey2pk(Mypubkey()); memset(timestamps,0,sizeof(timestamps)); result.push_back(Pair("name","sudoku")); result.push_back(Pair("method","solution")); + good = 0; if ( params != 0 ) { if ( (jsonstr= jprint(params,0)) != 0 ) @@ -812,21 +813,46 @@ UniValue sudoku_solution(uint64_t txfee,struct CCcontract_info *cp,cJSON *params decode_hex((uint8_t *)&txid,32,txidstr); txid = revuint256(txid); result.push_back(Pair("txid",txid.GetHex())); - // get tx and validate solution is for that txid + if ( CCgettxout(txid,0,1) < 0 ) + result.push_back(Pair("error","already solved")); + else if ( GetTransaction(txid,tx,hashBlock,false) != 0 && (numvouts= tx.vout.size()) > 1 ) + { + if ( sudoku_genopreturndecode(unsolved,tx.vout[numvouts-1].scriptPubKey) == 'G' ) + { + for (i=0; i<81; i++) + { + if ( unsolved[i] == 0 ) + continue; + else if ( unsolved[i] != solution[i]-'0' ) + { + printf("i.%d %d != %d\n",i,unsolved[i],solution[i]-'0'); + result.push_back(Pair("error","wrong sudoku solved")); + break; + } + } + if ( i == 81 ) + good = 1; + } else result.push_back(Pair("error","cant decode sudoku")); + } else result.push_back(Pair("error","couldnt find sudoku")); } - mtx.vin.push_back(CTxIn(txid,0,CScript())); - if ( (inputsum= AddCClibInputs(cp,mtx,pk,balance,16,CCaddr)) >= balance ) + if ( good != 0 ) { - mtx.vout.push_back(CTxOut(balance,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG)); - CCaddr2set(cp,cp->evalcode,pk,priv32,CCaddr); - rawtx = FinalizeCCTx(0,cp,mtx,pubkey2pk(Mypubkey()),txfee,sudoku_solutionopret(solution,timestamps)); - } else result.push_back(Pair("error","couldnt find funds in solution address")); + mtx.vin.push_back(CTxIn(txid,0,CScript())); + if ( (inputsum= AddCClibInputs(cp,mtx,pk,balance,16,CCaddr)) >= balance ) + { + mtx.vout.push_back(CTxOut(balance,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG)); + CCaddr2set(cp,cp->evalcode,pk,priv32,CCaddr); + rawtx = FinalizeCCTx(0,cp,mtx,pubkey2pk(Mypubkey()),txfee,sudoku_solutionopret(solution,timestamps)); + } else result.push_back(Pair("error","couldnt find funds in solution address")); + } } } - result.push_back(Pair("result","success")); } else result.push_back(Pair("error","couldnt get all params")); if ( rawtx.size() > 0 ) + { + result.push_back(Pair("result","success")); result.push_back(Pair("hex",rawtx)); + } else result.push_back(Pair("error","couldnt finalize CCtx")); //printf("params.(%s)\n",jprint(params,0)); return(result); From 892d237b03b1f19c3ba355b4287f296cceba2c52 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 29 Jan 2019 08:30:04 -1100 Subject: [PATCH 70/80] ,unsolved[81] --- src/cc/sudoku.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cc/sudoku.cpp b/src/cc/sudoku.cpp index c844e1591..3cb9469f1 100644 --- a/src/cc/sudoku.cpp +++ b/src/cc/sudoku.cpp @@ -752,7 +752,7 @@ UniValue sudoku_pending(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) UniValue sudoku_solution(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) { CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); - UniValue result(UniValue::VOBJ); int32_t i,j,good,ind,n,numvouts; uint256 txid; char *jsonstr,*newstr,*txidstr,coinaddr[64],CCaddr[64],*solution=0; CPubKey pk,mypk; uint8_t vals9[9][9],priv32[32],pub33[33],unsolved[81]; uint32_t timestamps[81]; uint64_t balance,inputsum; std::string rawtx; CTransaction tx; uint256 hashBlock; + UniValue result(UniValue::VOBJ); int32_t i,j,good,ind,n,numvouts; uint256 txid; char *jsonstr,*newstr,*txidstr,coinaddr[64],CCaddr[64],*solution=0,unsolved[82]; CPubKey pk,mypk; uint8_t vals9[9][9],priv32[32],pub33[33]; uint32_t timestamps[81]; uint64_t balance,inputsum; std::string rawtx; CTransaction tx; uint256 hashBlock; mypk = pubkey2pk(Mypubkey()); memset(timestamps,0,sizeof(timestamps)); result.push_back(Pair("name","sudoku")); @@ -823,9 +823,9 @@ UniValue sudoku_solution(uint64_t txfee,struct CCcontract_info *cp,cJSON *params { if ( unsolved[i] == 0 ) continue; - else if ( unsolved[i] != solution[i]-'0' ) + else if ( unsolved[i] != solution[i] ) { - printf("i.%d %d != %d\n",i,unsolved[i],solution[i]-'0'); + printf("i.%d [%c] != [%c]\n",i,unsolved[i],solution[i]); result.push_back(Pair("error","wrong sudoku solved")); break; } From 70df4c1acf569c5db05480d0a0a1987d37b08246 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 29 Jan 2019 21:39:11 -1100 Subject: [PATCH 71/80] '-' --- src/cc/sudoku.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc/sudoku.cpp b/src/cc/sudoku.cpp index 3cb9469f1..06bc35db6 100644 --- a/src/cc/sudoku.cpp +++ b/src/cc/sudoku.cpp @@ -821,7 +821,7 @@ UniValue sudoku_solution(uint64_t txfee,struct CCcontract_info *cp,cJSON *params { for (i=0; i<81; i++) { - if ( unsolved[i] == 0 ) + if ( unsolved[i] < '1' || unsolved[i] > '9') continue; else if ( unsolved[i] != solution[i] ) { From 3ba832b6bc8828594ad666ac84bafb781db2864a Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 29 Jan 2019 21:48:26 -1100 Subject: [PATCH 72/80] Pending object --- src/cc/CCinclude.h | 1 + src/cc/sudoku.cpp | 13 ++++++++++--- src/komodo_bitcoind.h | 8 ++++++++ 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/cc/CCinclude.h b/src/cc/CCinclude.h index 5d847800a..4da696547 100644 --- a/src/cc/CCinclude.h +++ b/src/cc/CCinclude.h @@ -134,6 +134,7 @@ int32_t CCgetspenttxid(uint256 &spenttxid,int32_t &vini,int32_t &height,uint256 void CCclearvars(struct CCcontract_info *cp); UniValue CClib(struct CCcontract_info *cp,char *method,cJSON *params); UniValue CClib_info(struct CCcontract_info *cp); +CBlockIndex *komodo_blockindex(uint256 hash); static const uint256 zeroid; bool myGetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock); diff --git a/src/cc/sudoku.cpp b/src/cc/sudoku.cpp index 06bc35db6..4b6a6e749 100644 --- a/src/cc/sudoku.cpp +++ b/src/cc/sudoku.cpp @@ -667,7 +667,7 @@ UniValue sudoku_generate(uint64_t txfee,struct CCcontract_info *cp,cJSON *params UniValue sudoku_txidinfo(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) { - UniValue result(UniValue::VOBJ); int32_t numvouts; char str[65],*txidstr; uint256 txid,hashBlock; CTransaction tx; char unsolved[82]; + UniValue result(UniValue::VOBJ); int32_t numvouts; char str[65],*txidstr; uint256 txid,hashBlock; CTransaction tx; char unsolved[82]; CBlockIndex *pindex; if ( params != 0 ) { result.push_back(Pair("result","success")); @@ -687,6 +687,8 @@ UniValue sudoku_txidinfo(uint64_t txfee,struct CCcontract_info *cp,cJSON *params if ( sudoku_genopreturndecode(unsolved,tx.vout[numvouts-1].scriptPubKey) == 'G' ) { result.push_back(Pair("result","success")); + if ( (pindex= komodo_blockindex(hashBlock)) != 0 ) + result.push_back(Pair("height",pindex->nHeight)); result.push_back(Pair("amount",ValueFromAmount(tx.vout[1].nValue))); result.push_back(Pair("unsolved",unsolved)); } @@ -716,7 +718,7 @@ UniValue sudoku_txidinfo(uint64_t txfee,struct CCcontract_info *cp,cJSON *params UniValue sudoku_pending(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) { UniValue result(UniValue::VOBJ),a(UniValue::VARR); - char coinaddr[64],unsolved[82]; int64_t nValue,total=0; uint256 txid,hashBlock; CTransaction tx; int32_t vout,numvouts; CPubKey sudokupk; + char coinaddr[64],unsolved[82]; int64_t nValue,total=0; uint256 txid,hashBlock; CTransaction tx; int32_t vout,numvouts; CPubKey sudokupk; CBlockIndex *pindex; std::vector > unspentOutputs; sudokupk = GetUnspendable(cp,0); GetCCaddress(cp,coinaddr,sudokupk); @@ -734,7 +736,12 @@ UniValue sudoku_pending(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) { if ( sudoku_genopreturndecode(unsolved,tx.vout[numvouts-1].scriptPubKey) == 'G' ) { - a.push_back(txid.GetHex()); + UniValue obj(UniValue::VOBJ); + if ( (pindex= komodo_blockindex(hashBlock)) != 0 ) + obj.push_back(Pair("height",pindex->nHeight)); + obj.push_back(Pair("amount",ValueFromAmount(tx.vout[1].nValue))); + obj.push_back(Pair("txid",txid.GetHex())); + a.push_back(obj); total += tx.vout[1].nValue; } } diff --git a/src/komodo_bitcoind.h b/src/komodo_bitcoind.h index c530db4fb..b3248d7d4 100644 --- a/src/komodo_bitcoind.h +++ b/src/komodo_bitcoind.h @@ -1033,6 +1033,14 @@ int32_t komodo_MoM(int32_t *notarized_heightp,uint256 *MoMp,uint256 *kmdtxidp,in return(depth); } +CBlockIndex *komodo_blockindex(uint256 hash) +{ + BlockMap::const_iterator it; CBlockIndex *pindex = 0; + if ( (it = mapBlockIndex.find(hash)) != mapBlockIndex.end() ) + pindex = it->second; + return(pindex); +} + int32_t komodo_checkpoint(int32_t *notarized_heightp,int32_t nHeight,uint256 hash) { int32_t notarized_height,MoMdepth; uint256 MoM,notarized_hash,notarized_desttxid; CBlockIndex *notary,*pindex; From 86aafb3761a8d86f8b87ae82bc550ace48d91061 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 29 Jan 2019 21:49:05 -1100 Subject: [PATCH 73/80] GetHeight() --- src/cc/sudoku.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cc/sudoku.cpp b/src/cc/sudoku.cpp index 4b6a6e749..dea9cb007 100644 --- a/src/cc/sudoku.cpp +++ b/src/cc/sudoku.cpp @@ -688,7 +688,7 @@ UniValue sudoku_txidinfo(uint64_t txfee,struct CCcontract_info *cp,cJSON *params { result.push_back(Pair("result","success")); if ( (pindex= komodo_blockindex(hashBlock)) != 0 ) - result.push_back(Pair("height",pindex->nHeight)); + result.push_back(Pair("height",pindex->GetHeight())); result.push_back(Pair("amount",ValueFromAmount(tx.vout[1].nValue))); result.push_back(Pair("unsolved",unsolved)); } @@ -738,7 +738,7 @@ UniValue sudoku_pending(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) { UniValue obj(UniValue::VOBJ); if ( (pindex= komodo_blockindex(hashBlock)) != 0 ) - obj.push_back(Pair("height",pindex->nHeight)); + obj.push_back(Pair("height",pindex->GetHeight())); obj.push_back(Pair("amount",ValueFromAmount(tx.vout[1].nValue))); obj.push_back(Pair("txid",txid.GetHex())); a.push_back(obj); From 1d4236867120cf28952c1f7287335ac6375f860f Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 29 Jan 2019 21:56:50 -1100 Subject: [PATCH 74/80] +print --- src/cc/sudoku.cpp | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/cc/sudoku.cpp b/src/cc/sudoku.cpp index dea9cb007..10667461d 100644 --- a/src/cc/sudoku.cpp +++ b/src/cc/sudoku.cpp @@ -850,18 +850,22 @@ UniValue sudoku_solution(uint64_t txfee,struct CCcontract_info *cp,cJSON *params mtx.vout.push_back(CTxOut(balance,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG)); CCaddr2set(cp,cp->evalcode,pk,priv32,CCaddr); rawtx = FinalizeCCTx(0,cp,mtx,pubkey2pk(Mypubkey()),txfee,sudoku_solutionopret(solution,timestamps)); + if ( rawtx.size() > 0 ) + { + result.push_back(Pair("result","success")); + result.push_back(Pair("hex",rawtx)); + } + else result.push_back(Pair("error","couldnt finalize CCtx")); } else result.push_back(Pair("error","couldnt find funds in solution address")); } } } - } else result.push_back(Pair("error","couldnt get all params")); - if ( rawtx.size() > 0 ) - { - result.push_back(Pair("result","success")); - result.push_back(Pair("hex",rawtx)); } - else result.push_back(Pair("error","couldnt finalize CCtx")); - //printf("params.(%s)\n",jprint(params,0)); + else + { + printf("n.%d params.(%s)\n",n,jprint(params,0)); + result.push_back(Pair("error","couldnt get all params")); + } return(result); } else From b006656f9f0171045ea9647ca205408ee9943241 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 29 Jan 2019 21:58:04 -1100 Subject: [PATCH 75/80] Off by 1 --- src/cc/sudoku.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc/sudoku.cpp b/src/cc/sudoku.cpp index 10667461d..59eb83309 100644 --- a/src/cc/sudoku.cpp +++ b/src/cc/sudoku.cpp @@ -788,7 +788,7 @@ UniValue sudoku_solution(uint64_t txfee,struct CCcontract_info *cp,cJSON *params } else params = 0; if ( params != 0 ) { - if ( (n= cJSON_GetArraySize(params)) > 2 && n < (sizeof(timestamps)/sizeof(*timestamps))+2 ) + if ( (n= cJSON_GetArraySize(params)) > 2 && n <= (sizeof(timestamps)/sizeof(*timestamps))+2 ) { for (i=2; i Date: Wed, 30 Jan 2019 01:15:44 -1100 Subject: [PATCH 76/80] Check address --- src/cc/sudoku.cpp | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/cc/sudoku.cpp b/src/cc/sudoku.cpp index 59eb83309..841a67d81 100644 --- a/src/cc/sudoku.cpp +++ b/src/cc/sudoku.cpp @@ -667,7 +667,7 @@ UniValue sudoku_generate(uint64_t txfee,struct CCcontract_info *cp,cJSON *params UniValue sudoku_txidinfo(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) { - UniValue result(UniValue::VOBJ); int32_t numvouts; char str[65],*txidstr; uint256 txid,hashBlock; CTransaction tx; char unsolved[82]; CBlockIndex *pindex; + UniValue result(UniValue::VOBJ); int32_t numvouts; char CCaddr[64],str[65],*txidstr; uint256 txid,hashBlock; CTransaction tx; char unsolved[82]; CBlockIndex *pindex; if ( params != 0 ) { result.push_back(Pair("result","success")); @@ -689,6 +689,8 @@ UniValue sudoku_txidinfo(uint64_t txfee,struct CCcontract_info *cp,cJSON *params result.push_back(Pair("result","success")); if ( (pindex= komodo_blockindex(hashBlock)) != 0 ) result.push_back(Pair("height",pindex->GetHeight())); + Getscriptaddress(CCaddr,tx.vout[1].scriptPubKey); + result.push_back(Pair("sudokuaddr",CCaddr)); result.push_back(Pair("amount",ValueFromAmount(tx.vout[1].nValue))); result.push_back(Pair("unsolved",unsolved)); } @@ -759,7 +761,7 @@ UniValue sudoku_pending(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) UniValue sudoku_solution(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) { CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); - UniValue result(UniValue::VOBJ); int32_t i,j,good,ind,n,numvouts; uint256 txid; char *jsonstr,*newstr,*txidstr,coinaddr[64],CCaddr[64],*solution=0,unsolved[82]; CPubKey pk,mypk; uint8_t vals9[9][9],priv32[32],pub33[33]; uint32_t timestamps[81]; uint64_t balance,inputsum; std::string rawtx; CTransaction tx; uint256 hashBlock; + UniValue result(UniValue::VOBJ); int32_t i,j,good,ind,n,numvouts; uint256 txid; char *jsonstr,*newstr,*txidstr,coinaddr[64],checkaddr[64],CCaddr[64],*solution=0,unsolved[82]; CPubKey pk,mypk; uint8_t vals9[9][9],priv32[32],pub33[33]; uint32_t timestamps[81]; uint64_t balance,inputsum; std::string rawtx; CTransaction tx; uint256 hashBlock; mypk = pubkey2pk(Mypubkey()); memset(timestamps,0,sizeof(timestamps)); result.push_back(Pair("name","sudoku")); @@ -804,6 +806,15 @@ UniValue sudoku_solution(uint64_t txfee,struct CCcontract_info *cp,cJSON *params priv2addr(coinaddr,pub33,priv32); pk = buf2pk(pub33); GetCCaddress(cp,CCaddr,pk); + Getscriptaddress(checkaddr,tx.vout[1].scriptPubKey); + if ( strcmp(checkaddr,CCaddr) != 0 ) + { + result.push_back(Pair("result","error")); + result.push_back(Pair("error","wrong solution")); + result.push_back(Pair("yours",CCaddr)); + result.push_back(Pair("sudokuaddr",checkaddr)); + return(result); + } result.push_back(Pair("sudokuaddr",CCaddr)); balance = CCaddress_balance(CCaddr); result.push_back(Pair("amount",ValueFromAmount(balance))); From 15663f6fa93923676ab24c100ee2320b4dfb4a00 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 30 Jan 2019 02:34:33 -1100 Subject: [PATCH 77/80] Make sure sudoku has just one solution and set amount to difficulty score --- src/cc/cclib.cpp | 4 +- src/cc/sudoku.cpp | 2014 ++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 2012 insertions(+), 6 deletions(-) diff --git a/src/cc/cclib.cpp b/src/cc/cclib.cpp index 69d8d4aaa..dd79d22d9 100644 --- a/src/cc/cclib.cpp +++ b/src/cc/cclib.cpp @@ -44,10 +44,10 @@ CClib_methods[] = { { (char *)"faucet2", (char *)"fund", (char *)"amount", 1, 1, 'F', EVAL_FAUCET2 }, { (char *)"faucet2", (char *)"get", (char *)"", 0, 0, 'G', EVAL_FAUCET2 }, - { (char *)"sudoku", (char *)"gen", (char *)"amount", 1, 1, 'G', EVAL_SUDOKU }, + { (char *)"sudoku", (char *)"gen", (char *)"", 1, 1, 'G', EVAL_SUDOKU }, { (char *)"sudoku", (char *)"txidinfo", (char *)"txid", 1, 1, 'T', EVAL_SUDOKU }, { (char *)"sudoku", (char *)"pending", (char *)"", 0, 0, 'U', EVAL_SUDOKU }, - { (char *)"sudoku", (char *)"solution", (char *)"solution timestamps[]", 2, 2, 'S', EVAL_SUDOKU }, + { (char *)"sudoku", (char *)"solution", (char *)"txid solution timestamps[]", 2, 2, 'S', EVAL_SUDOKU }, }; std::string CClib_rawtxgen(struct CCcontract_info *cp,uint8_t funcid,cJSON *params); diff --git a/src/cc/sudoku.cpp b/src/cc/sudoku.cpp index 841a67d81..b34eccd39 100644 --- a/src/cc/sudoku.cpp +++ b/src/cc/sudoku.cpp @@ -1,3 +1,1997 @@ +// start https://github.com/attractivechaos/plb/blob/master/sudoku/incoming/sudoku_solver.c +/************************************************************************************/ +/* */ +/* Author: Bill DuPree */ +/* Name: sudoku_solver.c */ +/* Language: C */ +/* Date: Feb. 25, 2006 */ +/* Copyright (C) Feb. 25, 2006, All rights reserved. */ +/* */ +/* This is a program that solves Su Doku (aka Sudoku, Number Place, etc.) puzzles */ +/* primarily using deductive logic. It will only resort to trial-and-error and */ +/* backtracking approaches upon exhausting all of its deductive moves. */ +/* */ +/* Puzzles must be of the standard 9x9 variety using the (ASCII) characters '1' */ +/* through '9' for the puzzle solution set. Puzzles should be submitted as 81 */ +/* character strings which, when read left-to-right will fill a 9x9 Sudoku grid */ +/* from left-to-right and top-to-bottom. In the puzzle specification, the */ +/* characters 1 - 9 represent the puzzle "givens" or clues. Any other non-blank */ +/* character represents an unsolved cell. */ +/* */ +/* The puzzle solving algorithm is "home grown." I did not borrow any of the usual */ +/* techniques from the literature, e.g. Donald Knuth's "Dancing Links." Instead */ +/* I "rolled my own" from scratch. As such, its performance can only be blamed */ +/* on yours truly. Still, I feel it is quite fast. On a 333 MHz Pentium II Linux */ +/* box it solves typical medium force puzzles in approximately 800 microseconds or */ +/* about 1,200 puzzles per second, give or take. On an Athlon XP 3000 (Barton core) */ +/* it solves about 6,600 puzzles per sec. */ +/* */ +/* DESCRIPTION OF ALGORITHM: */ +/* */ +/* The puzzle algorithm initially assumes every unsolved cell can assume every */ +/* possible value. It then uses the placement of the givens to refine the choices */ +/* available to each cell. I call this the markup phase. */ +/* */ +/* After markup completes, the algorithm then looks for "singleton" cells with */ +/* values that, due to constraints imposed by the row, column, or 3x3 region, may */ +/* only assume one possible value. Once these cells are assigned values, the */ +/* algorithm returns to the markup phase to apply these changes to the remaining */ +/* candidate solutions. The markup/singleton phases alternate until either no more */ +/* changes occur, or the puzzle is solved. I call the markup/singleton elimination */ +/* loop the "Simple Solver" because in a large percentage of cases it solves the */ +/* puzzle. */ +/* */ +/* If the simple solver portion of the algorithm doesn't produce a solution, then */ +/* more advanced deductive rules are applied. I've implemented two additional rules */ +/* as part of the deductive puzzle solver. The first is subset elimination wherein */ +/* a row/column/region is scanned for X number of cells with X number of matching */ +/* candidate solutions. If such subsets are found in the row, column, or region, */ +/* then the candidates values from the subset may be eliminated from all other */ +/* unsolved cells within the row, column, or region, respectively. */ +/* */ +/* The second advanced deductive rule examines each region looking for candidate */ +/* values that exclusively align themselves along a single row or column, i.e. a */ +/* a vector. If such candidate values are found, then they may be eliminated from */ +/* the cells outside of the region that are part of the aligned row or column. */ +/* */ +/* Note that each of the advanced deductive rules calls all preceeding rules, in */ +/* order, if that advanced rule has effected a change in puzzle markup. */ +/* */ +/* Finally, if no solution is found after iteratively applying all deductive rules, */ +/* then we begin trial-and-error using recursion for backtracking. A working copy */ +/* is created from our puzzle, and using this copy the first cell with the */ +/* smallest number of candidate solutions is chosen. One of the solutions values is */ +/* assigned to that cell, and the solver algorithm is called using this working */ +/* copy as its starting point. Eventually, either a solution, or an impasse is */ +/* reached. */ +/* */ +/* If we reach an impasse, the recursion unwinds and the next trial solution is */ +/* attempted. If a solution is found (at any point) the values for the solution are */ +/* added to a list. Again, so long as we are examining all possibilities, the */ +/* recursion unwinds so that the next trial may be attempted. It is in this manner */ +/* that we enumerate puzzles with multiple solutions. */ +/* */ +/* Note that it is certainly possible to add to the list of applied deductive */ +/* rules. The techniques known as "X-Wing" and "Swordfish" come to mind. On the */ +/* other hand, adding these additional rules will, in all likelihood, slow the */ +/* solver down by adding to the computational burden while producing very few */ +/* results. I've seen the law of diminishing returns even in some of the existing */ +/* rules, e.g. in subset elimination I only look at two and three valued subsets */ +/* because taking it any further than that degraded performance. */ +/* */ +/* PROGRAM INVOCATION: */ +/* */ +/* This program is a console (or command line) based utility and has the following */ +/* usage: */ +/* */ +/* sudoku_solver {-p puzzle | -f } [-o ] */ +/* [-r ] [-1][-a][-c][-g][-l][-m][-n][-s] */ +/* */ +/* where: */ +/* */ +/* -1 Search for first solution, otherwise all solutions are returned */ +/* -a Requests that the answer (solution) be printed */ +/* -c Print a count of solutions for each puzzle */ +/* -d Print the recursive trial depth required to solve the puzzle */ +/* -e Print a step-by-step explanation of the solution(s) */ +/* -f Takes an argument which specifes an input file */ +/* containing one or more unsolved puzzles (default: stdin) */ +/* -G Print the puzzle solution(s) in a 9x9 grid format */ +/* -g Print the number of given clues */ +/* -l Print the recursive trial depth required to solve the puzzle */ +/* -m Print an octal mask for the puzzle givens */ +/* -n Number each result */ +/* -o Specifies an output file for the solutions (default: stdout) */ +/* -p Takes an argument giving a single inline puzzle to be solved */ +/* -r Specifies an output file for unsolvable puzzles */ +/* (default: stderr) */ +/* -s Print the puzzle's score or difficulty rating */ +/* -? Print usage information */ +/* */ +/* The return code is zero if all puzzles had unique solutions, */ +/* (or have one or more solutions when -1 is specified) and non-zero */ +/* when no unique solution exists. */ +/* */ +/* PUZZLE SCORING */ +/* */ +/* A word about puzzle scoring, i.e. rating a puzzle's difficulty, is in order. */ +/* Rating Sudoku puzzles is a rather subjective thing, and thus it is difficult to */ +/* really develop an objective puzzle rating system. I, however, have attempted */ +/* this feat (several times with varying degrees of success ;-) and I think the */ +/* heuristics I'm currently applying aren't too bad for rating the relative */ +/* difficulty of solving a puzzle. */ +/* */ +/* The following is a brief rundown of how it works. The initial puzzle markup is */ +/* a "free" operation, i.e. no points are scored for the first markup pass. I feel */ +/* this is appropriate because a person solving a puzzle will always have to do */ +/* their own eyeballing and scanning of the puzzle. Subsequent passes are */ +/* scored at one point per candidate eliminated because these passes indicate */ +/* that more deductive work is required. Secondly, the "reward" for solving a cell */ +/* is set to one point, and as long as the solution only requires simple markup */ +/* and elimination of singletons, this level of reward remains unchanged. */ +/* */ +/* This reward changes, however, when advanced solving rules are required. Puzzles */ +/* that remain unsolved after the first pass through the simple solver phase have */ +/* a higher "reward", i.e. it is incremented by two. Thus, if subset or vector */ +/* elimination is required, all subsequently solved cells score higher bounties. */ +/* In addition, the successful application of these deductive techniques score */ +/* their own penalties. */ +/* */ +/* Finally, if a trial-and-error approach is called for, then the "reward" is */ +/* incremented by another five points. Thus, the total penalty for each level of */ +/* recursion is an additional seven points per solved cell, i.e. */ +/* (recursive_depth * 7) + 1 points per solved cell. Trial solutions are also */ +/* penalized by a weighting factor that is based upon the number of unsolved cells */ +/* that remain upon reentry to the solver and the depth of recursion. (I've seen a */ +/* pathological puzzle from the "Minimum Sudoku" web site require 16 levels of */ +/* recursion and score a whopping 228,642 points using this scoring system!) */ +/* */ +/* And that brings me to this topic: What do all these points mean? */ +/* */ +/* Well, who knows? This is still subjective, and the weighting system I've chosen */ +/* for point scoring is is largely arbitrary. But based upon feedback from a number */ +/* of individuals, a rough scale of difficulty plays out as follows: */ +/* */ +/* DEGREE OF DIFFICULTY | SCORE */ +/* -------------------------+------------------------------------------ */ +/* TRIVIAL | 80 points or less */ +/* EASY | 81 - 150 points */ +/* MEDIUM | 151 - 250 points */ +/* HARD | 251 - 400 points */ +/* VERY HARD | 401 - 900 points */ +/* DIABOLICAL | 901 and up */ +/* */ +/* Experience shows that puzzles in the HARD category, in a few cases, will */ +/* require a small amount of trial-and-error. The VERY HARD puzzles will likely */ +/* require trial-and-error, and in some cases more than one level of trial-and- */ +/* error. As for the DIABOLICAL puzzles--why waste your time? These are best left */ +/* to masochists, savants and automated solvers. YMMV. */ +/* */ +/* LICENSE: */ +/* */ +/* This program is free software; you can redistribute it and/or modify */ +/* it under the terms of the GNU General Public License as published by */ +/* the Free Software Foundation; either version 2 of the License, or */ +/* (at your option) any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, */ +/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ +/* GNU General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU General Public License */ +/* along with this program; if not, write to the Free Software */ +/* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +/* */ +/* CONTACT: */ +/* */ +/* Email: bdupree@techfinesse.com */ +/* Post: Bill DuPree, 609 Wenonah Ave, Oak Park, IL 60304 USA */ +/* */ +/************************************************************************************/ +/* */ +/* CHANGE LOG: */ +/* */ +/* Rev. Date Init. Description */ +/* -------------------------------------------------------------------------------- */ +/* 1.00 2006-02-25 WD Initial version. */ +/* 1.01 2006-03-13 WD Fixed return code calc. Added signon message. */ +/* 1.10 2006-03-20 WD Added explain option, add'l speed optimizations */ +/* 1.11 2006-03-23 WD More simple speed optimizations, cleanup, bug fixes */ +/* */ +/************************************************************************************/ + +#include +#include +#include +#include +#include +#include + +#define VERSION "1.11" + +#define PUZZLE_ORDER 3 +#define PUZZLE_DIM (PUZZLE_ORDER*PUZZLE_ORDER) +#define PUZZLE_CELLS (PUZZLE_DIM*PUZZLE_DIM) + +/* Command line options */ +#ifdef EXPLAIN +#define OPTIONS "?1acdef:Ggmno:p:r:s" +#else +#define OPTIONS "?1acdf:Ggmno:p:r:s" +#endif +extern char *optarg; +extern int optind, opterr, optopt; + +static char *myname; /* Name that we were invoked under */ + +static FILE *solnfile, *rejects; + +/* This is the list of cell coordinates specified on a row basis */ + +static int const row[PUZZLE_DIM][PUZZLE_DIM] = { + { 0, 1, 2, 3, 4, 5, 6, 7, 8 }, + { 9, 10, 11, 12, 13, 14, 15, 16, 17 }, + { 18, 19, 20, 21, 22, 23, 24, 25, 26 }, + { 27, 28, 29, 30, 31, 32, 33, 34, 35 }, + { 36, 37, 38, 39, 40, 41, 42, 43, 44 }, + { 45, 46, 47, 48, 49, 50, 51, 52, 53 }, + { 54, 55, 56, 57, 58, 59, 60, 61, 62 }, + { 63, 64, 65, 66, 67, 68, 69, 70, 71 }, + { 72, 73, 74, 75, 76, 77, 78, 79, 80 }}; + +/* This is the list of cell coordinates specified on a column basis */ + +static int const col[PUZZLE_DIM][PUZZLE_DIM] = { + { 0, 9, 18, 27, 36, 45, 54, 63, 72 }, + { 1, 10, 19, 28, 37, 46, 55, 64, 73 }, + { 2, 11, 20, 29, 38, 47, 56, 65, 74 }, + { 3, 12, 21, 30, 39, 48, 57, 66, 75 }, + { 4, 13, 22, 31, 40, 49, 58, 67, 76 }, + { 5, 14, 23, 32, 41, 50, 59, 68, 77 }, + { 6, 15, 24, 33, 42, 51, 60, 69, 78 }, + { 7, 16, 25, 34, 43, 52, 61, 70, 79 }, + { 8, 17, 26, 35, 44, 53, 62, 71, 80 }}; + +/* This is the list of cell coordinates specified on a 3x3 region basis */ + +static int const region[PUZZLE_DIM][PUZZLE_DIM] = { + { 0, 1, 2, 9, 10, 11, 18, 19, 20 }, + { 3, 4, 5, 12, 13, 14, 21, 22, 23 }, + { 6, 7, 8, 15, 16, 17, 24, 25, 26 }, + { 27, 28, 29, 36, 37, 38, 45, 46, 47 }, + { 30, 31, 32, 39, 40, 41, 48, 49, 50 }, + { 33, 34, 35, 42, 43, 44, 51, 52, 53 }, + { 54, 55, 56, 63, 64, 65, 72, 73, 74 }, + { 57, 58, 59, 66, 67, 68, 75, 76, 77 }, + { 60, 61, 62, 69, 70, 71, 78, 79, 80 }}; + +/* Flags for cellflags member */ +#define GIVEN 1 +#define FOUND 2 +#define STUCK 3 + +/* Return codes for funcs that modify puzzle markup */ +#define NOCHANGE 0 +#define CHANGE 1 + +typedef struct grd { + short cellflags[PUZZLE_CELLS]; + short solved[PUZZLE_CELLS]; + short cell[PUZZLE_CELLS]; + short tail, givens, exposed, maxlvl, inc, reward; + unsigned int score, solncount; + struct grd *next; +} grid; + +typedef int (*return_soln)(grid *g); + +static grid *soln_list = NULL; + +typedef struct { + short row, col, region; +} cellmap; + +/* Array structure to help map cell index back to row, column, and region */ +static cellmap const map[PUZZLE_CELLS] = { + { 0, 0, 0 }, + { 0, 1, 0 }, + { 0, 2, 0 }, + { 0, 3, 1 }, + { 0, 4, 1 }, + { 0, 5, 1 }, + { 0, 6, 2 }, + { 0, 7, 2 }, + { 0, 8, 2 }, + { 1, 0, 0 }, + { 1, 1, 0 }, + { 1, 2, 0 }, + { 1, 3, 1 }, + { 1, 4, 1 }, + { 1, 5, 1 }, + { 1, 6, 2 }, + { 1, 7, 2 }, + { 1, 8, 2 }, + { 2, 0, 0 }, + { 2, 1, 0 }, + { 2, 2, 0 }, + { 2, 3, 1 }, + { 2, 4, 1 }, + { 2, 5, 1 }, + { 2, 6, 2 }, + { 2, 7, 2 }, + { 2, 8, 2 }, + { 3, 0, 3 }, + { 3, 1, 3 }, + { 3, 2, 3 }, + { 3, 3, 4 }, + { 3, 4, 4 }, + { 3, 5, 4 }, + { 3, 6, 5 }, + { 3, 7, 5 }, + { 3, 8, 5 }, + { 4, 0, 3 }, + { 4, 1, 3 }, + { 4, 2, 3 }, + { 4, 3, 4 }, + { 4, 4, 4 }, + { 4, 5, 4 }, + { 4, 6, 5 }, + { 4, 7, 5 }, + { 4, 8, 5 }, + { 5, 0, 3 }, + { 5, 1, 3 }, + { 5, 2, 3 }, + { 5, 3, 4 }, + { 5, 4, 4 }, + { 5, 5, 4 }, + { 5, 6, 5 }, + { 5, 7, 5 }, + { 5, 8, 5 }, + { 6, 0, 6 }, + { 6, 1, 6 }, + { 6, 2, 6 }, + { 6, 3, 7 }, + { 6, 4, 7 }, + { 6, 5, 7 }, + { 6, 6, 8 }, + { 6, 7, 8 }, + { 6, 8, 8 }, + { 7, 0, 6 }, + { 7, 1, 6 }, + { 7, 2, 6 }, + { 7, 3, 7 }, + { 7, 4, 7 }, + { 7, 5, 7 }, + { 7, 6, 8 }, + { 7, 7, 8 }, + { 7, 8, 8 }, + { 8, 0, 6 }, + { 8, 1, 6 }, + { 8, 2, 6 }, + { 8, 3, 7 }, + { 8, 4, 7 }, + { 8, 5, 7 }, + { 8, 6, 8 }, + { 8, 7, 8 }, + { 8, 8, 8 } +}; + +static const short symtab[1<= '1') && (c <= '9'); } + +#if defined(DEBUG) +static void mypause() +{ + char buf[8]; + printf("\tPress enter -> "); + fgets(buf, 8, stdin); +} +#endif + +#if 0 +/* Generic (and slow) bitcount function */ +static int bitcount(short cell) +{ + int i, count, mask; + + mask = 1; + for (i = count = 0; i < 16; i++) { + if (mask & cell) count++; + mask <<= 1; + } + return count; +} +#endif + +/*****************************************************/ +/* Return the number of '1' bits in a cell. */ +/* Rather than count bits, do a quick table lookup. */ +/* Warning: Only valid for 9 low order bits. */ +/*****************************************************/ + +static inline short bitcount(short cell) +{ + static const short bcounts[512] = { + 0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5, + 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, + 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, + 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, + 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, + 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, + 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, + 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, + 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, + 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, + 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, + 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, + 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, + 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, + 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, + 4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9}; + + return bcounts[cell]; +} + +#ifdef EXPLAIN + +/**************************************************/ +/* Indent two spaces for each level of recursion. */ +/**************************************************/ +static inline void explain_indent(FILE *h) +{ + int i; + + for (i = 0; i < lvl-1; i++) fprintf(h, " "); +} + +/******************************************************************/ +/* Construct a string representing the possible values a cell may */ +/* contain according to current markup. */ +/******************************************************************/ +static char *clues(short cell) +{ + int i, m, multi, mask; + static char buf[64], *p; + + multi = m = bitcount(cell); + + if (!multi) return "NULL"; + + if (multi > 1) { + strcpy(buf, "tuple ("); + } + else { + strcpy(buf, "value "); + } + + p = buf + strlen(buf); + + for (mask = i = 1; i <= PUZZLE_DIM; i++) { + if (mask & cell) { + *p++ = symtab[mask]; + multi -= 1; + if (multi) { *p++ = ','; *p++ = ' '; } + } + mask <<= 1; + } + if (m > 1) *p++ = ')'; + *p = 0; + return buf; +} + +/*************************************************************/ +/* Explain removal of a candidate value from a changed cell. */ +/*************************************************************/ +static void explain_markup_elim(grid *g, int chgd, int clue) +{ + int chgd_row, chgd_col, clue_row, clue_col; + + chgd_row = map[chgd].row+1; + chgd_col = map[chgd].col+1; + clue_row = map[clue].row+1; + clue_col = map[clue].col+1; + + explain_indent(solnfile); + fprintf(solnfile, "Candidate %s removed from row %d, col %d because of cell at row %d, col %d\n", + clues(g->cell[clue]), chgd_row, chgd_col, clue_row, clue_col); +} + +/*****************************************/ +/* Dump the state of the current markup. */ +/*****************************************/ +static void explain_current_markup(grid *g) +{ + if (g->exposed >= PUZZLE_CELLS) return; + + fprintf(solnfile, "\n"); + explain_indent(solnfile); + fprintf(solnfile, "Current markup is as follows:"); + diagnostic_grid(g, solnfile); + fprintf(solnfile, "\n"); +} + +/****************************************/ +/* Explain the solving of a given cell. */ +/****************************************/ +static void explain_solve_cell(grid *g, int chgd) +{ + int chgd_row, chgd_col; + + chgd_row = map[chgd].row+1; + chgd_col = map[chgd].col+1; + + explain_indent(solnfile); + fprintf(solnfile, "Cell at row %d, col %d solved with %s\n", + chgd_row, chgd_col, clues(g->cell[chgd])); +} + +/******************************************************************/ +/* Explain the current impasse reached during markup elimination. */ +/******************************************************************/ +static void explain_markup_impasse(grid *g, int chgd, int clue) +{ + int chgd_row, chgd_col, clue_row, clue_col; + + chgd_row = map[chgd].row+1; + chgd_col = map[chgd].col+1; + clue_row = map[clue].row+1; + clue_col = map[clue].col+1; + + explain_indent(solnfile); + fprintf(solnfile, "Impasse for cell at row %d, col %d because cell at row %d, col %d removes last candidate\n", + chgd_row, chgd_col, clue_row, clue_col); + explain_current_markup(g); +} + +/****************************************/ +/* Explain naked and/or hidden singles. */ +/****************************************/ +static void explain_singleton(grid *g, int chgd, int mask, char *vdesc) +{ + int chgd_row, chgd_col, chgd_reg; + + chgd_row = map[chgd].row+1; + chgd_col = map[chgd].col+1; + chgd_reg = map[chgd].region+1; + + explain_indent(solnfile); + fprintf(solnfile, "Cell of region %d at row %d, col %d will only solve for %s in this %s\n", + chgd_reg, chgd_row, chgd_col, clues(mask), vdesc); + explain_solve_cell(g, chgd); +} + +/*********************************/ +/* Explain initial puzzle state. */ +/*********************************/ +static void explain_markup() +{ + fprintf(solnfile, "\n"); + explain_indent(solnfile); + fprintf(solnfile, "Assume all cells may contain any values in the range: [1 - 9]\n"); +} + +/************************/ +/* Explain given clues. */ +/************************/ +static void explain_given(int cell, char val) +{ + int cell_row, cell_col; + + cell_row = map[cell].row+1; + cell_col = map[cell].col+1; + + explain_indent(solnfile); + fprintf(solnfile, "Cell at row %d, col %d is given clue value %c\n", cell_row, cell_col, val); +} + +/*******************************************/ +/* Explain region/row/column interactions. */ +/*******************************************/ +static void explain_vector_elim(char *desc, int i, int cell, int val, int region) +{ + int cell_row, cell_col; + + cell_row = map[cell].row+1; + cell_col = map[cell].col+1; + + explain_indent(solnfile); + fprintf(solnfile, "Candidate %s removed from cell at row %d, col %d because it aligns along %s %d in region %d\n", + clues(val), cell_row, cell_col, desc, i+1, region+1); +} + +/******************************************************************/ +/* Explain the current impasse reached during vector elimination. */ +/******************************************************************/ +static void explain_vector_impasse(grid *g, char *desc, int i, int cell, int val, int region) +{ + int cell_row, cell_col; + + cell_row = map[cell].row+1; + cell_col = map[cell].col+1; + + explain_indent(solnfile); + fprintf(solnfile, "Impasse at cell at row %d, col %d because candidate %s aligns along %s %d in region %d\n", + cell_row, cell_col, clues(val), desc, i+1, region+1); + explain_current_markup(g); +} + +/*****************************************************************/ +/* Explain the current impasse reached during tuple elimination. */ +/*****************************************************************/ +static void explain_tuple_impasse(grid *g, char *desc, int elt, int tuple, int count, int bits) +{ + explain_indent(solnfile); + fprintf(solnfile, "Impasse in %s %d because too many (%d) cells have %d-valued %s\n", + desc, elt+1, count, bits, clues(tuple)); + explain_current_markup(g); +} + +/*********************************************************************/ +/* Explain the removal of a tuple of candidate solutions from a cell */ +/*********************************************************************/ +static void explain_tuple_elim(char *desc, int elt, int tuple, int cell) +{ + explain_indent(solnfile); + fprintf(solnfile, "Values of %s in %s %d removed from cell at row %d, col %d\n", + clues(tuple), desc, elt+1, map[cell].row+1, map[cell].col+1); + +} + +/**************************************************/ +/* Indicate that a viable solution has been found */ +/**************************************************/ +static void explain_soln_found(grid *g) +{ + char buf[90]; + + fprintf(solnfile, "\n"); + explain_indent(solnfile); + fprintf(solnfile, "Solution found: %s\n", format_answer(g, buf)); + print_grid(buf, solnfile); + fprintf(solnfile, "\n"); +} + +/***************************/ +/* Show the initial puzzle */ +/***************************/ +static void explain_grid(grid *g) +{ + char buf[90]; + + fprintf(solnfile, "Initial puzzle: %s\n", format_answer(g, buf)); + print_grid(buf, solnfile); + explain_current_markup(g); + fprintf(solnfile, "\n"); +} + +/*************************************************/ +/* Explain attempt at a trial and error solution */ +/*************************************************/ +static void explain_trial(int cell, int value) +{ + explain_indent(solnfile); + fprintf(solnfile, "Attempt trial where cell at row %d, col %d is assigned value %s\n", + map[cell].row+1, map[cell].col+1, clues(value)); +} + +/**********************************************/ +/* Explain back out of current trial solution */ +/**********************************************/ +static void explain_backtrack() +{ + if (lvl <= 1) return; + + explain_indent(solnfile); + fprintf(solnfile, "Backtracking\n\n"); +} + +#define EXPLAIN_MARKUP if (explain) explain_markup() +#define EXPLAIN_CURRENT_MARKUP(g) if (explain) explain_current_markup((g)) +#define EXPLAIN_GIVEN(cell, val) if (explain) explain_given((cell), (val)) +#define EXPLAIN_MARKUP_ELIM(g, chgd, clue) if (explain) explain_markup_elim((g), (chgd), (clue)) +#define EXPLAIN_MARKUP_SOLVE(g, cell) if (explain) explain_solve_cell((g), (cell)) +#define EXPLAIN_MARKUP_IMPASSE(g, chgd, clue) if (explain) explain_markup_impasse((g), (chgd), (clue)) +#define EXPLAIN_SINGLETON(g, chgd, mask, vdesc) if (explain) explain_singleton((g), (chgd), (mask), (vdesc)) +#define EXPLAIN_VECTOR_ELIM(desc, i, cell, v, r) if (explain) explain_vector_elim((desc), (i), (cell), (v), (r)) +#define EXPLAIN_VECTOR_IMPASSE(g, desc, i, cell, v, r) if (explain) explain_vector_impasse((g), (desc), (i), (cell), (v), (r)) +#define EXPLAIN_VECTOR_SOLVE(g, cell) if (explain) explain_solve_cell((g), (cell)) +#define EXPLAIN_TUPLE_IMPASSE(g, desc, j, c, count, i) if (explain) explain_tuple_impasse((g), (desc), (j), (c), (count), (i)) +#define EXPLAIN_TUPLE_ELIM(desc, j, c, cell) if (explain) explain_tuple_elim((desc), (j), (c), (cell)) +#define EXPLAIN_TUPLE_SOLVE(g, cell) if (explain) explain_solve_cell((g), (cell)) +#define EXPLAIN_SOLN_FOUND(g) if (explain) explain_soln_found((g)); +#define EXPLAIN_GRID(g) if (explain) explain_grid((g)); +#define EXPLAIN_TRIAL(cell, val) if (explain) explain_trial((cell), (val)); +#define EXPLAIN_BACKTRACK if (explain) explain_backtrack(); +#define EXPLAIN_INDENT(h) if (explain) explain_indent((h)) + +#else + +#define EXPLAIN_MARKUP +#define EXPLAIN_CURRENT_MARKUP(g) +#define EXPLAIN_GIVEN(cell, val) +#define EXPLAIN_MARKUP_ELIM(g, chgd, clue) +#define EXPLAIN_MARKUP_SOLVE(g, cell) +#define EXPLAIN_MARKUP_IMPASSE(g, chgd, clue) +#define EXPLAIN_SINGLETON(g, chgd, mask, vdesc); +#define EXPLAIN_VECTOR_ELIM(desc, i, cell, v, r) +#define EXPLAIN_VECTOR_IMPASSE(g, desc, i, cell, v, r) +#define EXPLAIN_VECTOR_SOLVE(g, cell) +#define EXPLAIN_TUPLE_IMPASSE(g, desc, j, c, count, i) +#define EXPLAIN_TUPLE_ELIM(desc, j, c, cell) +#define EXPLAIN_TUPLE_SOLVE(g, cell) +#define EXPLAIN_SOLN_FOUND(g) +#define EXPLAIN_GRID(g) +#define EXPLAIN_TRIAL(cell, val) +#define EXPLAIN_BACKTRACK +#define EXPLAIN_INDENT(h) + +#endif + + +/*****************************************************/ +/* Initialize a grid to an empty state. */ +/* At the start, all cells can have any value */ +/* so set all 9 lower order bits in each cell. */ +/* In effect, the 9x9 grid now has markup that */ +/* specifies that each cell can assume any value */ +/* of 1 through 9. */ +/*****************************************************/ + +static void init_grid(grid *g) +{ + int i; + + for (i = 0; i < PUZZLE_CELLS; i++) g->cell[i] = 0x01ff; + memset(g->cellflags, 0, PUZZLE_CELLS*sizeof(g->cellflags[0])); + g->exposed = 0; + g->givens = 0; + g->inc = 0; + g->maxlvl = 0; + g->score = 0; + g->solncount = 0; + g->reward = 1; + g->next = NULL; + g->tail = 0; + EXPLAIN_MARKUP; +} + +/*****************************************************/ +/* Convert a puzzle from the input format, */ +/* i.e. a string of 81 non-blank characters */ +/* with ASCII digits '1' thru '9' specified */ +/* for the givens, and non-numeric characters */ +/* for the remaining cells. The string, read */ +/* left-to-right fills the 9x9 Sudoku grid */ +/* in left-to-right, top-to-bottom order. */ +/*****************************************************/ + +static void cvt_to_grid(grid *g, char *game) +{ + int i; + + init_grid(g); + + for (i = 0; i < PUZZLE_CELLS; i++) { + if (is_given(game[i])) { + /* warning -- ASCII charset assumed */ + g->cell[i] = 1 << (game[i] - '1'); + g->cellflags[i] = GIVEN; + g->givens += 1; + g->solved[g->exposed++] = i; + EXPLAIN_GIVEN(i, game[i]); + } + } + EXPLAIN_GRID(g); +} + +/****************************************************************/ +/* Print the partially solved puzzle and all associated markup */ +/* in 9x9 fashion. */ +/****************************************************************/ + +static void diagnostic_grid(grid *g, FILE *h) +{ + int i, j, flag; + short c; + char line1[40], line2[40], line3[40], cbuf1[5], cbuf2[5], cbuf3[5], outbuf[PUZZLE_CELLS+1]; + + /* Sanity check */ + for (flag = 1, i = 0; flag && i < PUZZLE_CELLS; i++) { + if (bitcount(g->cell[i]) != 1) { + flag = 0; + } + } + + /* Don't need to print grid with diagnostic markup? */ + if (flag) { + format_answer(g, outbuf); + print_grid(outbuf, h); + fflush(h); + return; + } + + strcpy(cbuf1, " |"); + strcpy(cbuf2, cbuf1); + strcpy(cbuf3, cbuf1); + fprintf(h, "\n"); + + for (i = 0; i < PUZZLE_DIM; i++) { + + *line1 = *line2 = *line3 = 0; + + for (j = 0; j < PUZZLE_DIM; j++) { + + c = g->cell[row[i][j]]; + + if (bitcount(c) == 1) { + strcpy(cbuf1, " |"); + strcpy(cbuf2, cbuf1); + strcpy(cbuf3, cbuf1); + cbuf2[1] = symtab[c]; + } + else { + if (c & 1) cbuf1[0] = '*'; else cbuf1[0] = '.'; + if (c & 2) cbuf1[1] = '*'; else cbuf1[1] = '.'; + if (c & 4) cbuf1[2] = '*'; else cbuf1[2] = '.'; + if (c & 8) cbuf2[0] = '*'; else cbuf2[0] = '.'; + if (c & 16) cbuf2[1] = '*'; else cbuf2[1] = '.'; + if (c & 32) cbuf2[2] = '*'; else cbuf2[2] = '.'; + if (c & 64) cbuf3[0] = '*'; else cbuf3[0] = '.'; + if (c & 128) cbuf3[1] = '*'; else cbuf3[1] = '.'; + if (c & 256) cbuf3[2] = '*'; else cbuf3[2] = '.'; + } + + strcat(line1, cbuf1); + strcat(line2, cbuf2); + strcat(line3, cbuf3); + } + + EXPLAIN_INDENT(h); + fprintf(h, "+---+---+---+---+---+---+---+---+---+\n"); + EXPLAIN_INDENT(h); + fprintf(h, "|%s\n", line1); + EXPLAIN_INDENT(h); + fprintf(h, "|%s\n", line2); + EXPLAIN_INDENT(h); + fprintf(h, "|%s\n", line3); + } + EXPLAIN_INDENT(h); + fprintf(h, "+---+---+---+---+---+---+---+---+---+\n"); fflush(h); +} + +/***********************************************************************/ +/* Validate that a sudoku grid contains a valid solution. Return 1 if */ +/* true, 0 if false. If the verbose argument is non-zero, then print */ +/* reasons for invalidating the solution to stderr. */ +/***********************************************************************/ + +static int validate(grid *g, int verbose) +{ + int i, j, regmask, rowmask, colmask, flag = 1; + + /* Sanity check */ + for (i = 0; i < PUZZLE_CELLS; i++) { + if (bitcount(g->cell[i]) != 1) { + if (verbose) { + fprintf(rejects, "Cell %d at row %d, col %d has no unique soln.\n", 1+i, 1+map[i].row, 1+map[i].col); fflush(rejects); + flag = 0; + } else return 0; + } + } + + /* Check rows */ + for (i = 0; i < PUZZLE_DIM; i++) { + for (rowmask = j = 0; j < PUZZLE_DIM; j++) { + if (bitcount(g->cell[row[i][j]]) == 1) rowmask |= g->cell[row[i][j]]; + } + if (rowmask != 0x01ff) { + if (verbose) { + fprintf(rejects, "Row %d is inconsistent.\n", 1+i); fflush(rejects); + flag = 0; + } else return 0; + } + } + + /* Check columns */ + for (i = 0; i < PUZZLE_DIM; i++) { + for (colmask = j = 0; j < PUZZLE_DIM; j++) { + if (bitcount(g->cell[col[i][j]]) == 1) colmask |= g->cell[col[i][j]]; + } + if (colmask != 0x01ff) { + if (verbose) { + fprintf(rejects, "Column %d is inconsistent.\n", 1+i); fflush(rejects); + flag = 0; + } else return 0; + } + } + + /* Check 3x3 regions */ + for (i = 0; i < PUZZLE_DIM; i++) { + for (regmask = j = 0; j < PUZZLE_DIM; j++) { + if (bitcount(g->cell[region[i][j]]) == 1) regmask |= g->cell[region[i][j]]; + } + if (regmask != 0x01ff) { + if (verbose) { + fprintf(rejects, "Region %d is inconsistent.\n", 1+i); fflush(rejects); + flag = 0; + } else return 0; + } + } + + return flag; +} + +/********************************************************************************/ +/* This function uses the cells with unique values, i.e. the given */ +/* or subsequently discovered solution values, to eliminate said values */ +/* as candidates in other as yet unsolved cells in the associated */ +/* rows, columns, and 3x3 regions. */ +/* */ +/* The function has three possible return values: */ +/* NOCHANGE - Markup did not change during the last pass, */ +/* CHANGE - Markup was modified, and */ +/* STUCK - Markup results are invalid, i.e. a cell has no candidate values */ +/********************************************************************************/ + +static int mark_cells(grid *g) +{ + int i, chgflag, bc; + int const *r, *c, *reg; + short elt, mask, before; + + + chgflag = NOCHANGE; + + while (g->tail < g->exposed) { + + elt = g->solved[g->tail++]; + + r = row[map[elt].row]; + c = col[map[elt].col]; + reg = region[map[elt].region]; + + mask = ~g->cell[elt]; + + for (i = 0; i < PUZZLE_DIM; i++) { + + if (r[i] != elt) { + + /* Get the cell value */ + before = g->cell[r[i]]; + + /* Eliminate this candidate value whilst preserving other candidate values */ + g->cell[r[i]] &= mask; + + /* Did the cell change value? */ + if (before != g->cell[r[i]]) { + + chgflag |= CHANGE; /* Flag that puzzle markup was changed */ + g->score += g->inc; /* More work means higher scoring */ + + if (!(bc = bitcount(g->cell[r[i]]))) { + EXPLAIN_MARKUP_IMPASSE(g, r[i], elt); + return STUCK; /* Crap out if no candidates remain */ + } + + EXPLAIN_MARKUP_ELIM(g, r[i], elt); + + /* Check if we solved for this cell, i.e. bit count indicates a unique value */ + if (bc == 1) { + g->cellflags[r[i]] = FOUND; /* Mark cell as found */ + g->score += g->reward; /* Add to puzzle score */ + g->solved[g->exposed++] = r[i]; + EXPLAIN_MARKUP_SOLVE(g, r[i]); + } + } + } + + if (c[i] != elt) { + + /* Get the cell value */ + before = g->cell[c[i]]; + + /* Eliminate this candidate value whilst preserving other candidate values */ + g->cell[c[i]] &= mask; + + /* Did the cell change value? */ + if (before != g->cell[c[i]]) { + + chgflag |= CHANGE; /* Flag that puzzle markup was changed */ + g->score += g->inc; /* More work means higher scoring */ + + if (!(bc = bitcount(g->cell[c[i]]))) { + EXPLAIN_MARKUP_IMPASSE(g, c[i], elt); + return STUCK; /* Crap out if no candidates remain */ + } + + EXPLAIN_MARKUP_ELIM(g, c[i], elt); + + /* Check if we solved for this cell, i.e. bit count indicates a unique value */ + if (bc == 1) { + g->cellflags[c[i]] = FOUND; /* Mark cell as found */ + g->score += g->reward; /* Add to puzzle score */ + g->solved[g->exposed++] = c[i]; + EXPLAIN_MARKUP_SOLVE(g, c[i]); + } + } + } + + if (reg[i] != elt) { + + /* Get the cell value */ + before = g->cell[reg[i]]; + + /* Eliminate this candidate value whilst preserving other candidate values */ + g->cell[reg[i]] &= mask; + + /* Did the cell change value? */ + if (before != g->cell[reg[i]]) { + + chgflag |= CHANGE; /* Flag that puzzle markup was changed */ + g->score += g->inc; /* More work means higher scoring */ + + if (!(bc = bitcount(g->cell[reg[i]]))) { + EXPLAIN_MARKUP_IMPASSE(g, reg[i], elt); + return STUCK; /* Crap out if no candidates remain */ + } + + EXPLAIN_MARKUP_ELIM(g, reg[i], elt); + + /* Check if we solved for this cell, i.e. bit count indicates a unique value */ + if (bc == 1) { + g->cellflags[reg[i]] = FOUND; /* Mark cell as found */ + g->score += g->reward; /* Add to puzzle score */ + g->solved[g->exposed++] = reg[i]; + EXPLAIN_MARKUP_SOLVE(g, reg[i]); + } + } + } + + } + } + + return chgflag; +} + + +/*******************************************************************/ +/* Identify and "solve" all cells that, by reason of their markup, */ +/* can only assume one specific value, i.e. the cell is the only */ +/* one in a row/column/region (specified by vector) that is */ +/* able to assume a particular value. */ +/* */ +/* The function has two possible return values: */ +/* NOCHANGE - Markup did not change during the last pass, */ +/* CHANGE - Markup was modified. */ +/*******************************************************************/ + +static int find_singletons(grid *g, int const *vector, char *vdesc) +{ + int i, j, mask, hist[PUZZLE_DIM], value[PUZZLE_DIM], found = NOCHANGE; + + /* We are going to create a histogram of cell candidate values */ + /* for the specified cell vector (row/column/region). */ + /* First set all buckets to zero. */ + memset(hist, 0, sizeof(hist[0])*PUZZLE_DIM); + + /* For each cell in the vector... */ + for (i = 0; i < PUZZLE_DIM; i++) { + + /* For each possible candidate value... */ + for (mask = 1, j = 0; j < PUZZLE_DIM; j++) { + + /* If the cell may possibly assume this value... */ + if (g->cell[vector[i]] & mask) { + + value[j] = vector[i]; /* Save the cell coordinate */ + hist[j] += 1; /* Bump bucket in histogram */ + } + + mask <<= 1; /* Next candidate value */ + } + } + + /* Examine each bucket in the histogram... */ + for (mask = 1, i = 0; i < PUZZLE_DIM; i++) { + + /* If the bucket == 1 and the cell is not already solved, */ + /* then the cell has a unique solution specified by "mask" */ + if (hist[i] == 1 && !g->cellflags[value[i]]) { + + found = CHANGE; /* Indicate that markup has been changed */ + g->cell[value[i]] = mask; /* Assign solution value to cell */ + g->cellflags[value[i]] = FOUND; /* Mark cell as solved */ + g->score += g->reward; /* Bump puzzle score */ + g->solved[g->exposed++] = value[i]; + EXPLAIN_SINGLETON(g, value[i], mask, vdesc); + } + + mask <<= 1; /* Get next candidate value */ + } + + return found; +} + + +/*******************************************************************/ +/* Find all cells with unique solutions (according to markup) */ +/* and mark them as found. Do this for each row, column, and */ +/* region. */ +/* */ +/* The function has two possible return values: */ +/* NOCHANGE - Markup did not change during the last pass, */ +/* CHANGE - Markup was modified. */ +/*******************************************************************/ + +static int eliminate_singles(grid *g) +{ + int i, found = NOCHANGE; + + /* Do rows */ + for (i = 0; i < PUZZLE_DIM; i++) { + found |= find_singletons(g, row[i], "row"); + } + + /* Do columns */ + for (i = 0; i < PUZZLE_DIM; i++) { + found |= find_singletons(g, col[i], "column"); + } + + /* Do regions */ + for (i = 0; i < PUZZLE_DIM; i++) { + found |= find_singletons(g, region[i], "region"); + } + + return found; +} + +/********************************************************************************/ +/* Solves simple puzzles, i.e. single elimination */ +/* */ +/* The function has three possible return values: */ +/* NOCHANGE - Markup did not change during the last pass, */ +/* CHANGE - Markup was modified, and */ +/* STUCK - Markup results are invalid, i.e. a cell has no candidate values */ +/********************************************************************************/ +static int simple_solver(grid *g) +{ + int flag = NOCHANGE; + + /* Mark the unsolved cells with candidate solutions based upon the current set of "givens" and solved cells */ + while ((flag |= mark_cells(g)) == CHANGE) { + + g->inc = 1; /* After initial markup, we start scoring for additional markup work */ + + EXPLAIN_CURRENT_MARKUP(g); + + /* Continue to eliminate cells with unique candidate solutions from the game until */ + /* elimination and repeated markup efforts produce no changes in the remaining */ + /* candidate solutions. */ + if (eliminate_singles(g) == NOCHANGE) break; + + EXPLAIN_CURRENT_MARKUP(g); + } + + return flag; +} + +/************************************************************************************/ +/* Test a region to see if the candidate solutions for a paticular number */ +/* are confined to one row or column, and if so, eliminate */ +/* their occurences in the remainder of the given row or column. */ +/* */ +/* The function has three possible return values: */ +/* NOCHANGE - Markup did not change during the last pass, */ +/* CHANGE - Markup was modified, and */ +/* STUCK - Markup results are invalid, i.e. a cell has no candidate values */ +/************************************************************************************/ + +static int region_vector_elim(grid *g, int region_no, int num) +{ + int i, j, r, c, mask, t, found; + short rowhist[PUZZLE_DIM], colhist[PUZZLE_DIM]; + + /* Init */ + found = NOCHANGE; + memset(rowhist, 0, sizeof(rowhist[0])*PUZZLE_DIM); + memset(colhist, 0, sizeof(colhist[0])*PUZZLE_DIM); + + mask = 1 << num; + + /* Create histograms for row and column placements for the value being checked */ + for (i = 0; i < PUZZLE_DIM; i++) { + j = region[region_no][i]; + if ((g->cell[j] & mask)) { + rowhist[map[j].row] += 1; + colhist[map[j].col] += 1; + } + } + + /* Figure out if this number lies in only one row or column */ + + /* Check rows first*/ + r = c = -1; + for (i = 0; i < PUZZLE_DIM; i++) { + if (rowhist[i]) { + if (r < 0) { + r = i; + } + else { + r = -1; + break; + } + } + } + + /* Now check columns */ + for (i = 0; i < PUZZLE_DIM; i++) { + if (colhist[i]) { + if (c < 0) { + c = i; + } + else { + c = -1; + break; + } + } + } + + /* If the number is only in one row, then eliminate this number from the cells in the row outside of this region */ + if (r >= 0) { + for (i = 0; i < PUZZLE_DIM; i++) { + j = row[r][i]; + if (map[j].region != region_no && !g->cellflags[j]) { + t = g->cell[j]; + if ((g->cell[j] &= ~mask) == 0) { + EXPLAIN_VECTOR_IMPASSE(g, "row", r, j, mask, region_no); + g->score += 10; + return STUCK; + } + if (t != g->cell[j]) { + found = CHANGE; + g->score += g->inc; + EXPLAIN_VECTOR_ELIM("row", r, j, mask, region_no); + if (bitcount(g->cell[j]) == 1) { + g->cellflags[j] = FOUND; + g->score += g->reward; + g->solved[g->exposed++] = j; + EXPLAIN_VECTOR_SOLVE(g, j); + } + } + } + } + } + + /* If the number is only in one column, then eliminate this number from the cells in the column outside of this region */ + else if (c >= 0) { + for (i = 0; i < PUZZLE_DIM; i++) { + j = col[c][i]; + if (map[j].region != region_no && !g->cellflags[j]) { + t = g->cell[j]; + if ((g->cell[j] &= ~mask) == 0) { + EXPLAIN_VECTOR_IMPASSE(g, "column", c, j, mask, region_no); + g->score += 10; + return STUCK; + } + if (t != g->cell[j]) { + found = CHANGE; + g->score += g->inc; + EXPLAIN_VECTOR_ELIM("column", c, j, mask, region_no); + if (bitcount(g->cell[j]) == 1) { + g->cellflags[j] = FOUND; + g->score += g->reward; + g->solved[g->exposed++] = j; + EXPLAIN_VECTOR_SOLVE(g, j); + } + } + } + } + } + + if (found == CHANGE) { + g->score += 10; /* Bump score for sucessfully invoking this rule */ + } + + return found; +} + +/**********************************************************************************/ +/* Test all regions to see if the possibilities for a number */ +/* are confined to specific rows or columns, and if so, eliminate */ +/* the occurence of candidate solutions from the remainder of the */ +/* specified row or column. */ +/* */ +/* The function has three possible return values: */ +/* NOCHANGE - Markup did not change during the last pass, */ +/* CHANGE - Markup was modified, and */ +/* STUCK - Markup results are invalid, i.e. a cell has no candidate values */ +/**********************************************************************************/ + +static int vector_elimination(grid *g) +{ + int i, j, rc; + + /* For each region... */ + for (rc = NOCHANGE, i = 0; i < PUZZLE_DIM && rc != STUCK; i++) { + + /* For each digit... */ + for (j = 0; j < PUZZLE_DIM && rc != STUCK; j++) { + + /* Eliminate candidates outside of regions when a particular */ + /* candidate value aligns itself to a row or column within */ + /* a 3x3 region. */ + rc |= region_vector_elim(g, i, j); + } + } + + return rc; +} + +/**********************************************************************************/ +/* This function implements the rule that when a subset of cells */ +/* in a row/column/region contain matching subsets of candidate */ +/* solutions, i.e. 2 matching possibilities for 2 cells, 3 */ +/* matching possibilities for 3 cells, etc., then those */ +/* candidates may be eliminated from the other cells in the */ +/* row, column, or region. */ +/* */ +/* The function has three possible return values: */ +/* NOCHANGE - Markup did not change during the last pass, */ +/* CHANGE - Markup was modified, and */ +/* STUCK - Markup results are invalid, i.e. a cell has no candidate values */ +/**********************************************************************************/ + +static int elim_matches(grid *g, int const *cell_list, char *desc, int ndx) +{ + int i, j, k, e, count, rc, flag; + short c, mask, tmp, elts[PUZZLE_DIM], eliminated[PUZZLE_DIM]; + static int counts[1<cell[k]; /* Copy original cell candidates */ + + if (bitcount(g->cell[k]) == i) { + counts[g->cell[k]] += 1; /* The bucket records the number of cells with this subset */ + } + } + + /* For each cell in the list... */ + for (e = j = 0; j < PUZZLE_DIM; j++) { + + c = g->cell[cell_list[j]]; /* Get cell's candidates */ + + /* Check to see if we've already eliminated this subset */ + for (k = 0; k < e; k++) + if (c == eliminated[k]) break; + if (e && k < e) continue; + + /* Get count from histogram bucket */ + count = (int) (counts[c]); + + /* If too few solution candidates for the number of cells, then we're stuck */ + if (count > i) { + EXPLAIN_TUPLE_IMPASSE(g, desc, ndx, c, count, i); + /* Clean up static array */ + for (k = 0; k < 9; k++) counts[elts[k]] = 0; + g->score += 10; + return STUCK; + } + + /* Do candidate and cell counts match? */ + if (count == i) { + + /* Compute mask used to eliminate candidates from other cells */ + mask = ~c; + + /* Record (for later) the values being eliminated */ + eliminated[e++] = c; + + /* Eliminate candidates from the other cells in the list */ + + /* For each cell... */ + for (k = 0; k < PUZZLE_DIM; k++) { + + /* If the cell candidates do not exactly match the current subset... */ + if (c != g->cell[cell_list[k]] && !g->cellflags[cell_list[k]]) { + + /* Get cell candidates */ + tmp = g->cell[cell_list[k]]; + + /* Eliminate candidates with our mask */ + g->cell[cell_list[k]] &= mask; + + /* Did the elimination change the candidates? */ + if (tmp != g->cell[cell_list[k]]) { + + /* Note the change and bump the score */ + flag = CHANGE; + g->score += i; + + EXPLAIN_TUPLE_ELIM(desc, ndx, c, cell_list[k]); + + /* Did we solve the cell under consideration? */ + if (bitcount(g->cell[cell_list[k]]) == 1) { + + /* Mark cell as found and bump the score */ + g->cellflags[cell_list[k]] = FOUND; + g->score += g->reward; + g->solved[g->exposed++] = cell_list[k]; + EXPLAIN_TUPLE_SOLVE(g, cell_list[k]); + } + } + } + } + } + } + + /* Cleanup the static histogram array */ + for (j = 0; j < PUZZLE_DIM; j++) counts[elts[j]] = 0; + + rc |= flag; + } + + return rc; +} + +/**********************************************************************************/ +/* Eliminate subsets from rows, columns, and regions. */ +/* */ +/* The function has three possible return values: */ +/* NOCHANGE - Markup did not change during the last pass, */ +/* CHANGE - Markup was modified, and */ +/* STUCK - Markup results are invalid, i.e. a cell has no candidate values */ +/**********************************************************************************/ + +static int mult_elimination(grid *g) +{ + int i, rc = NOCHANGE; + + /* Eliminate subsets from rows */ + for (i = 0; i < PUZZLE_DIM; i++) { + rc |= elim_matches(g, row[i], "row", i); + } + + /* Eliminate subsets from columns */ + for (i = 0; i < PUZZLE_DIM; i++) { + rc |= elim_matches(g, col[i], "column", i); + } + + /* Eliminate subsets from regions */ + for (i = 0; i < PUZZLE_DIM; i++) { + rc |= elim_matches(g, region[i], "region", i); + } + + return rc; +} + +/**************************************************/ +/* Entry point to the recursive solver algorithm. */ +/**************************************************/ +static int rsolve(grid *g, return_soln soln_callback) +{ + int i, j, min, c, weight, mask, flag = 0; + grid mygrid; + + /* Keep track of recursive depth */ + lvl += 1; + if (lvl > g->maxlvl) g->maxlvl = lvl; + + for (;;) { + + /* Attempt a simple solution */ + if (simple_solver(g) == STUCK) break; + + /* Check for solution */ + if (g->exposed >= PUZZLE_CELLS) break; + + g->reward += 2; /* Bump reward as we graduate to more "advanced" solving techniques */ + + /* Eliminate tuples */ + if ((flag = mult_elimination(g)) == CHANGE) { + EXPLAIN_CURRENT_MARKUP(g); + continue; + } + + /* Check if impasse */ + if (flag == STUCK) break; + + /* Check for solution */ + if (g->exposed >= PUZZLE_CELLS) break; + + /* Eliminate clues aligned within regions from exterior cells in rows or columns */ + if ((flag = vector_elimination(g)) == CHANGE) { + EXPLAIN_CURRENT_MARKUP(g); + continue; + } + + /* Check if impasse */ + if (flag == STUCK) break; + + /* Check for solution */ + if (g->exposed >= PUZZLE_CELLS) break; + + g->reward += 5; /* Bump reward as we are about to start trial soutions */ + + /* Attempt a trial solution */ + memcpy(&mygrid, g, sizeof(grid)); /* Make working copy of puzzle */ + + /* Find the first cell with the smallest number of alternatives */ + for (weight= 0, c = -1, min = PUZZLE_DIM, i = 0; i < PUZZLE_CELLS; i++) { + if (!mygrid.cellflags[i]) { + j = bitcount(mygrid.cell[i]); + weight += 1; + if (j < min) { + min = j; + c = i; + } + } + } + + mygrid.score += weight; /* Add penalty to score */ + + /* Cell at index 'c' will be our starting point */ + if (c >= 0) for (mask = 1, i = 0; i < PUZZLE_DIM; i++) { + + /* Is this a candidate? */ + if (mask & g->cell[c]) { + + EXPLAIN_TRIAL(c, mask); + + mygrid.score += (int)(((50.0 * lvl * weight) / (double)(PUZZLE_CELLS)) + 0.5); /* Add'l penalty */ + + /* Try one of the possible candidates for this cell */ + mygrid.cell[c] = mask; + mygrid.cellflags[c] = FOUND; + mygrid.solved[mygrid.exposed++] = c; + + EXPLAIN_CURRENT_MARKUP(&mygrid); + flag = rsolve(&mygrid, soln_callback); /* Recurse with working copy of puzzle */ + + /* Did we find a solution? */ + if (flag == FOUND && !enumerate_all) { + EXPLAIN_BACKTRACK; + lvl -= 1; + return FOUND; + } + + /* Preserve score, solution count and recursive depth as we back out of recursion */ + g->score = mygrid.score; + g->solncount = mygrid.solncount; + g->maxlvl = mygrid.maxlvl; + memcpy(&mygrid, g, sizeof(grid)); + } + mask <<= 1; /* Get next possible candidate */ + } + + break; + } + + if (g->exposed == PUZZLE_CELLS && validate(g, 0)) { + soln_callback(g); + g->solncount += 1; + EXPLAIN_SOLN_FOUND(g); + EXPLAIN_BACKTRACK; + lvl -= 1; + flag = FOUND; + } else { + EXPLAIN_BACKTRACK; + lvl -= 1; + flag = STUCK; + if (!lvl && !g->solncount) validate(g, 1); /* Print verbose diagnostic for insoluble puzzle */ + } + + return flag; +} + +/*****************************************************************/ +/* Add a puzzle solution to the singly linked list of solutions. */ +/* Crap out if no memory available. */ +/*****************************************************************/ + +static int add_soln(grid *g) +{ + grid *tmp; + + if ((tmp = malloc(sizeof(grid))) == NULL) { + fprintf(stderr, "Out of memory.\n"); + exit(1); + } + memcpy(tmp, g, sizeof(grid)); + tmp->next = soln_list; + soln_list = tmp; + return 0; +} + +/************************************/ +/* Print hints as to command usage. */ +/************************************/ + +static void usage() +{ + fprintf(stderr, "Usage:\n\t%s {-p puzzle | -f } [-o ]\n", myname); + fprintf(stderr, "\t\t[-r ] [-1][-a][-c][-G][-g][-l][-m][-n][-s]\n"); + fprintf(stderr, "where:\n\t-1\tSearch for first solution, otherwise all solutions are returned\n" + "\t-a\tRequests that the answer (solution) be printed\n" + "\t-c\tPrint a count of solutions for each puzzle\n" + "\t-d\tPrint the recursive trial depth required to solve the puzzle\n" +#ifdef EXPLAIN + "\t-e\tPrint a step-by-step explanation of the solution(s)\n" +#endif + "\t-f\tTakes an argument which specifes an input file\n\t\tcontaining one or more unsolved puzzles (default: stdin)\n" + "\t-G\tPrint the puzzle solution(s) in a 9x9 grid format\n" + "\t-g\tPrint the number of given clues\n" + "\t-m\tPrint an octal mask for the puzzle givens\n" + "\t-n\tNumber each result\n" + "\t-o\tSpecifies an output file for the solutions (default: stdout)\n" + "\t-p\tTakes an argument giving a single inline puzzle to be solved\n" + "\t-r\tSpecifies an output file for unsolvable puzzles\n\t\t(default: stderr)\n" + "\t-s\tPrint the puzzle's score or difficulty rating\n" + "\t-?\tPrint usage information\n\n"); + fprintf(stderr, "The return code is zero if all puzzles had unique solutions,\n" + "(or have one or more solutions when -1 is specified) and non-zero\n" + "when no unique solution exists.\n"); +} + +/********************************************************/ +/* Print the puzzle as an 81 character string of digits */ +/********************************************************/ + +static char *format_answer(grid *g, char *outbuf) +{ + int i; + + for (i = 0; i < PUZZLE_CELLS; i++) + outbuf[i] = symtab[g->cell[i]]; + outbuf[i] = 0; + + return outbuf; +} + +/*******************************************/ +/* Print the puzzle as a standard 9x9 grid */ +/*******************************************/ + +static void print_grid(char *sud, FILE *h) +{ + + fprintf(h, "\n"); + EXPLAIN_INDENT(h); + fprintf(h, "+---+---+---+\n"); + + EXPLAIN_INDENT(h); + fprintf(h, "|%*.*s|%*.*s|%*.*s|\n", PUZZLE_ORDER, PUZZLE_ORDER, sud, PUZZLE_ORDER, PUZZLE_ORDER, sud+3, PUZZLE_ORDER, PUZZLE_ORDER, sud+6); + EXPLAIN_INDENT(h); + fprintf(h, "|%*.*s|%*.*s|%*.*s|\n", PUZZLE_ORDER, PUZZLE_ORDER, sud+9, PUZZLE_ORDER, PUZZLE_ORDER, sud+12, PUZZLE_ORDER, PUZZLE_ORDER, sud+15); + EXPLAIN_INDENT(h); + fprintf(h, "|%*.*s|%*.*s|%*.*s|\n", PUZZLE_ORDER, PUZZLE_ORDER, sud+18, PUZZLE_ORDER, PUZZLE_ORDER, sud+21, PUZZLE_ORDER, PUZZLE_ORDER, sud+24); + + EXPLAIN_INDENT(h); + fprintf(h, "+---+---+---+\n"); + + EXPLAIN_INDENT(h); + fprintf(h, "|%*.*s|%*.*s|%*.*s|\n", PUZZLE_ORDER, PUZZLE_ORDER, sud+27, PUZZLE_ORDER, PUZZLE_ORDER, sud+30, PUZZLE_ORDER, PUZZLE_ORDER, sud+33); + EXPLAIN_INDENT(h); + fprintf(h, "|%*.*s|%*.*s|%*.*s|\n", PUZZLE_ORDER, PUZZLE_ORDER, sud+36, PUZZLE_ORDER, PUZZLE_ORDER, sud+39, PUZZLE_ORDER, PUZZLE_ORDER, sud+42); + EXPLAIN_INDENT(h); + fprintf(h, "|%*.*s|%*.*s|%*.*s|\n", PUZZLE_ORDER, PUZZLE_ORDER, sud+45, PUZZLE_ORDER, PUZZLE_ORDER, sud+48, PUZZLE_ORDER, PUZZLE_ORDER, sud+51); + + EXPLAIN_INDENT(h); + fprintf(h, "+---+---+---+\n"); + + EXPLAIN_INDENT(h); + fprintf(h, "|%*.*s|%*.*s|%*.*s|\n", PUZZLE_ORDER, PUZZLE_ORDER, sud+54, PUZZLE_ORDER, PUZZLE_ORDER, sud+57, PUZZLE_ORDER, PUZZLE_ORDER, sud+60); + EXPLAIN_INDENT(h); + fprintf(h, "|%*.*s|%*.*s|%*.*s|\n", PUZZLE_ORDER, PUZZLE_ORDER, sud+63, PUZZLE_ORDER, PUZZLE_ORDER, sud+66, PUZZLE_ORDER, PUZZLE_ORDER, sud+69); + EXPLAIN_INDENT(h); + fprintf(h, "|%*.*s|%*.*s|%*.*s|\n", PUZZLE_ORDER, PUZZLE_ORDER, sud+72, PUZZLE_ORDER, PUZZLE_ORDER, sud+75, PUZZLE_ORDER, PUZZLE_ORDER, sud+78); + + EXPLAIN_INDENT(h); + fprintf(h, "+---+---+---+\n"); +} + +/*****************************************************/ +/* Based upon the Left-to-Right-Top-to-Bottom puzzle */ +/* presented in "sbuf", create a 27 octal digit */ +/* mask of the givens in the 28 character buffer */ +/* pointed to by "mbuf." Return a pointer to mbuf. */ +/*****************************************************/ + +static char *cvt_to_mask(char *mbuf, char *sbuf) +{ + char *mask_buf = mbuf; + static const char *maskchar = "01234567"; + int i, m; + + mask_buf[PUZZLE_DIM*3] = 0; + for (i = 0; i < PUZZLE_CELLS; i += 3) { + m = 0; + if (is_given(sbuf[i])) { + m |= 4; + } + else { + sbuf[i] = '0'; + } + if (is_given(sbuf[i+1])) { + m |= 2; + } + else { + sbuf[i+1] = '0'; + } + if (is_given(sbuf[i+2])) { + m |= 1; + } + else { + sbuf[i+2] = '0'; + } + *mask_buf++ = maskchar[m]; + } + return mbuf; +} + +/*******************/ +/* Mainline logic. */ +/*******************/ + +int dupree_solver(int32_t *scorep,char *puzzle) +{ + int argc; char *argv[4]; + int i, rc, bog, count, solved, unsolved, solncount=0, flag, prt_count, prt_num, prt_score, prt_answer, prt_depth, prt_grid, prt_mask, prt_givens, prt, len; + char *infile=0, *outfile=0, *rejectfile=0, inbuf[128], outbuf[128], mbuf[28]; + grid g, *s=0; + FILE *h=0; + soln_list = NULL; + /* Get our command name from invoking command line */ + if ((myname = strrchr(argv[0], '/')) == NULL) + myname = argv[0]; + else + myname++; + /*argc = 3; + argv[1] = "-p"; + argv[2] = puzzle; + argv[3] = 0;*/ + /* Print sign-on message to console */ + //fprintf(stderr, "%s version %s\n", myname, VERSION); fflush(stderr); + argc = 1; + /* Init */ + h = 0;//stdin; + solnfile = stdout; + rejects = stderr; + rejectfile = infile = outfile = NULL; + rc = bog = prt_mask = prt_grid = prt_score = prt_depth = prt_answer = prt_count = prt_num = prt_givens = 0; + *inbuf = 0; +#ifdef skip + /* Parse command line options */ + while ((opt = getopt(argc, argv, OPTIONS)) != -1) { + switch (opt) { + case '1': + enumerate_all = 0; /* only find first soln */ + break; + case 'a': + prt_answer = 1; /* print solution */ + break; + case 'c': + prt_count = 1; /* number solutions */ + break; + case 'd': + prt_depth = 1; + break; +#ifdef EXPLAIN + case 'e': + explain = 1; + break; +#endif + case 'f': + if (*inbuf) { // -p and -f options are mutually exclusive + fprintf(stderr, "The -p and -f options are mutually exclusive\n"); + usage(); + exit(1); + } + infile = optarg; // get name of input file + break; + case 'G': + prt_grid = 1; + break; + case 'g': + prt_givens = 1; + break; + case 'm': + prt_mask = 1; + break; + case 'n': + prt_num = 1; + break; + case 'o': + outfile = optarg; + break; + case 'p': + if (infile) { + fprintf(stderr, "The -p and -f options are mutually exclusive\n"); + usage(); + exit(1); + } + if (strlen(optarg) == PUZZLE_CELLS) { + strcpy(inbuf, optarg); + } + else { + fprintf(stderr, "Invalid puzzle specified: %s\n", optarg); + usage(); + exit(1); + } + h = NULL; + break; + case 'r': + rejectfile = optarg; + break; + case 's': + prt_score = 1; + break; + default: + case '?': + usage(); + exit(1); + } + } +#endif + prt_answer = 1; /* print solution */ + //prt_count = 1; /* number solutions */ + prt_score = 1; + prt_givens = 1; + prt_num = 1; + /* Set prt flag if we're printing anything at all */ + prt = prt_mask | prt_grid | prt_score | prt_depth | prt_answer | prt_num | prt_givens; + + /* Anthing else on the command line is bogus */ + if (argc > optind) { + fprintf(stderr, "Extraneous args: "); + for (i = optind; i < argc; i++) { + fprintf(stderr, "%s ", argv[i]); + } + fprintf(stderr, "\n\n"); + usage(); + exit(1); + } + + if (!enumerate_all && prt_score) { + fprintf(stderr, "Scoring is meaningless when multi-solution mode is disabled.\n"); + } + + if (rejectfile && !(rejects = fopen(rejectfile, "w"))) { + fprintf(stderr, "Failed to open reject output file: %s\n", rejectfile); + exit(1); + } + + if (outfile && !(solnfile = fopen(outfile, "w"))) { + fprintf(stderr, "Failed to open solution output file: %s\n", outfile); + exit(1); + } + + /*if (infile && strcmp(infile, "-") && !(h = fopen(infile, "r"))) { + fprintf(stderr, "Failed to open input game file: %s\n", infile); + exit(1); + } + if (h) fgets(inbuf, 128, h);*/ + strcpy(inbuf,puzzle); + count = solved = unsolved = 0; + //printf("inbuf.(%s)\n",inbuf); + while (*inbuf) { + + if ((len = (int32_t)strlen(inbuf)) && inbuf[len-1] == '\n') { + len -= 1; + inbuf[len] = 0; + } + + count += 1; + if (len != PUZZLE_CELLS) { + fprintf(rejects, "%d: %s bogus puzzle format\n", count, inbuf); fflush(rejects); + *inbuf = 0; + bog += 1; + if (h) fgets(inbuf, 128, h); + continue; + } + + cvt_to_grid(&g, inbuf); + if (g.givens < 17) { + fprintf(rejects, "%d: %*.*s bogus puzzle has less than 17 givens\n", count, PUZZLE_CELLS, PUZZLE_CELLS, inbuf); fflush(rejects); + *inbuf = 0; + bog += 1; + if (h) fgets(inbuf, 128, h); + continue; + } + + for (s = soln_list; s;) { + s = soln_list->next; + free(soln_list); + soln_list = s; + } + + flag = rsolve(&g, add_soln); + if (soln_list) { + solved++; + for (solncount = 0, s = soln_list; s; s = s->next) { + solncount += 1; + if (prt_num) { + char nbuf[32]; + if (!enumerate_all) + sprintf(nbuf, "%d: ", count); + else + sprintf(nbuf, "%d:%d ", count, solncount); + fprintf(solnfile, "%-s", nbuf); + } + if (solncount > 1 || !enumerate_all) g.score = 0; + if (prt_score) fprintf(solnfile, "score: %-7d ", g.score); + if (prt_depth) fprintf(solnfile, "depth: %-3d ", g.maxlvl); + if (prt_answer || prt_grid) format_answer(s, outbuf); + if (prt_answer) fprintf(solnfile, "%s", outbuf); + if (prt_mask) fprintf(solnfile, " %s", cvt_to_mask(mbuf, inbuf)); + if (prt_givens) fprintf(solnfile, " %d", g.givens); + if (prt_grid) print_grid(outbuf, solnfile); + if (prt) fprintf(solnfile, "\n"); + if (s->next == NULL && prt_count) fprintf(solnfile, "count: %d\n", solncount); + } + if (solncount > 1 && enumerate_all) { + rc |= 1; + } + } + else { + unsolved++; + rc |= 1; + fprintf(rejects, "%d: %*.*s unsolved\n", count, PUZZLE_CELLS, PUZZLE_CELLS, inbuf); fflush(rejects); + diagnostic_grid(&g, rejects); +#if defined(DEBUG) + mypause(); +#endif + } + + *inbuf = 0; + if (h) fgets(inbuf, 128, h); + } + + //if (prt) fprintf(solnfile, "\nPuzzles: %d, Solved: %d, Unsolved: %d, Bogus: %d\n", count, solved, unsolved, bog); + *scorep = g.score; + return solncount; +} +// end https://github.com/attractivechaos/plb/blob/master/sudoku/incoming/sudoku_solver.c // start https://github.com/mentalmove/SudokuGenerator // @@ -605,9 +2599,9 @@ uint8_t sudoku_genopreturndecode(char *unsolved,CScript scriptPubKey) UniValue sudoku_generate(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) { CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); - UniValue result(UniValue::VOBJ); CPubKey sudokupk,pk; uint8_t privkey[32],unsolved[9][9],pub33[33]; uint32_t srandi; uint256 hash; char coinaddr[64],*jsonstr; uint64_t inputsum,amount,change=0; std::string rawtx; + UniValue result(UniValue::VOBJ); CPubKey sudokupk,pk; uint8_t privkey[32],unsolved[9][9],pub33[33]; uint32_t srandi; int32_t i,score; uint256 hash; char coinaddr[64],str[82],*jsonstr; uint64_t inputsum,amount,change=0; std::string rawtx; amount = COIN; - if ( params != 0 ) + /*if ( params != 0 ) { if ( (jsonstr= jprint(params,0)) != 0 ) { @@ -618,14 +2612,26 @@ UniValue sudoku_generate(uint64_t txfee,struct CCcontract_info *cp,cJSON *params } amount = atof(jsonstr) * COIN + 0.0000000049; } - } + }*/ result.push_back(Pair("result","success")); result.push_back(Pair("name","sudoku")); result.push_back(Pair("method","gen")); hash = chainActive.LastTip()->GetBlockHash(); memcpy(&srandi,&hash,sizeof(srandi)); srandi ^= (uint32_t)time(NULL); - sudoku_gen(privkey,unsolved,srandi); + while ( 1 ) + { + sudoku_gen(privkey,unsolved,srandi); + for (i=0; i Date: Wed, 30 Jan 2019 02:36:44 -1100 Subject: [PATCH 78/80] syntax --- src/cc/sudoku.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/cc/sudoku.cpp b/src/cc/sudoku.cpp index b34eccd39..02c47ef97 100644 --- a/src/cc/sudoku.cpp +++ b/src/cc/sudoku.cpp @@ -1160,17 +1160,17 @@ static int eliminate_singles(grid *g) /* Do rows */ for (i = 0; i < PUZZLE_DIM; i++) { - found |= find_singletons(g, row[i], "row"); + found |= find_singletons(g, row[i], (char *)"row"); } /* Do columns */ for (i = 0; i < PUZZLE_DIM; i++) { - found |= find_singletons(g, col[i], "column"); + found |= find_singletons(g, col[i], (char *)"column"); } /* Do regions */ for (i = 0; i < PUZZLE_DIM; i++) { - found |= find_singletons(g, region[i], "region"); + found |= find_singletons(g, region[i], (char *)"region"); } return found; @@ -1489,17 +1489,17 @@ static int mult_elimination(grid *g) /* Eliminate subsets from rows */ for (i = 0; i < PUZZLE_DIM; i++) { - rc |= elim_matches(g, row[i], "row", i); + rc |= elim_matches(g, row[i], (char *)"row", i); } /* Eliminate subsets from columns */ for (i = 0; i < PUZZLE_DIM; i++) { - rc |= elim_matches(g, col[i], "column", i); + rc |= elim_matches(g, col[i], (char *)"column", i); } /* Eliminate subsets from regions */ for (i = 0; i < PUZZLE_DIM; i++) { - rc |= elim_matches(g, region[i], "region", i); + rc |= elim_matches(g, region[i], (char *)"region", i); } return rc; @@ -1633,7 +1633,7 @@ static int add_soln(grid *g) { grid *tmp; - if ((tmp = malloc(sizeof(grid))) == NULL) { + if ((tmp = (grid *)malloc(sizeof(grid))) == NULL) { fprintf(stderr, "Out of memory.\n"); exit(1); } @@ -2623,7 +2623,7 @@ UniValue sudoku_generate(uint64_t txfee,struct CCcontract_info *cp,cJSON *params { sudoku_gen(privkey,unsolved,srandi); for (i=0; i Date: Wed, 30 Jan 2019 03:35:35 -1100 Subject: [PATCH 79/80] Check for illegal solution --- src/cc/cclib.cpp | 6 +++--- src/cc/sudoku.cpp | 8 ++++++++ 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/cc/cclib.cpp b/src/cc/cclib.cpp index dd79d22d9..000245e56 100644 --- a/src/cc/cclib.cpp +++ b/src/cc/cclib.cpp @@ -37,17 +37,17 @@ char *CClib_name() { return((char *)MYCCLIBNAME.c_str()); } struct CClib_rpcinfo { char *CCname,*method,*help; - int32_t numrequiredargs,maxargs; // frontloaded with required + int32_t numrequiredargs,maxargs; uint8_t funcid,evalcode; } CClib_methods[] = { { (char *)"faucet2", (char *)"fund", (char *)"amount", 1, 1, 'F', EVAL_FAUCET2 }, { (char *)"faucet2", (char *)"get", (char *)"", 0, 0, 'G', EVAL_FAUCET2 }, - { (char *)"sudoku", (char *)"gen", (char *)"", 1, 1, 'G', EVAL_SUDOKU }, + { (char *)"sudoku", (char *)"gen", (char *)"", 0, 0, 'G', EVAL_SUDOKU }, { (char *)"sudoku", (char *)"txidinfo", (char *)"txid", 1, 1, 'T', EVAL_SUDOKU }, { (char *)"sudoku", (char *)"pending", (char *)"", 0, 0, 'U', EVAL_SUDOKU }, - { (char *)"sudoku", (char *)"solution", (char *)"txid solution timestamps[]", 2, 2, 'S', EVAL_SUDOKU }, + { (char *)"sudoku", (char *)"solution", (char *)"txid solution timestamps[81]", 83, 83, 'S', EVAL_SUDOKU }, }; std::string CClib_rawtxgen(struct CCcontract_info *cp,uint8_t funcid,cJSON *params); diff --git a/src/cc/sudoku.cpp b/src/cc/sudoku.cpp index 02c47ef97..e3cf7095d 100644 --- a/src/cc/sudoku.cpp +++ b/src/cc/sudoku.cpp @@ -2807,7 +2807,15 @@ UniValue sudoku_solution(uint64_t txfee,struct CCcontract_info *cp,cJSON *params { for (i=ind=0; i<9; i++) for (j=0; j<9; j++) + { + if ( solution[ind] < '1' || solution[ind] > '9' ) + { + result.push_back(Pair("result","error")); + result.push_back(Pair("error","illegal solution")); + return(result); + } vals9[i][j] = solution[ind++] - '0'; + } sudoku_privkey(priv32,vals9); priv2addr(coinaddr,pub33,priv32); pk = buf2pk(pub33); From a4055d478a079721e2b43a9d31578478ff03e9a5 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 30 Jan 2019 03:45:50 -1100 Subject: [PATCH 80/80] Move sudokuaddr check --- src/cc/sudoku.cpp | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/cc/sudoku.cpp b/src/cc/sudoku.cpp index e3cf7095d..5968f59d9 100644 --- a/src/cc/sudoku.cpp +++ b/src/cc/sudoku.cpp @@ -2507,6 +2507,8 @@ void sudoku_gen(uint8_t key32[32],uint8_t unsolved[9][9],uint32_t srandi) "result": "success", "hex": "0400008085202f8901328455ce926086f00be1b2adac0ba9adc22067a30948c71572f3da80adc1135d010000007b4c79a276a072a26ba067a565802102c57d40c1ddc92a5246a937bd7338823f1e8c916b137f2092d38cf250d74cb5ab8140f92d54f611aa3cb3d187eaadd56b06f3a8c0f5fba23956b26fdefc6038d9b6282de38525f72ebd8945a7994cef63ebca711ecf8fe6baeefcc218cf58efb59dc2a100af03800111a10001ffffffff02f0b9f505000000002321039433dc3749aece1bd568f374a45da3b0bc6856990d7da3cd175399577940a775ac0000000000000000fd9f016a4d9b01115351343639383233373135383735393631323334323331343537363938393134363735383233363533313832343739373832333934313536333436323139353837353238373336393431313937353438333632fd4401000000005c5078355c50783600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000" } + + cclib solution 17 \"[%224d50336780d5a300a1f01b12fe36f46a82f3b9935bb115e01e0113dc4f337aae%22,%22234791685716258943589643712865934127341827596927516438492375861178462359653189274%22,0,0,1548859143,1548859146,0,1548859146,0,1548859148,1548859149,0,1548859151,1548859152,0,1548859154,1548859155,1548859158,1548859159,0,0,0,1548859161,1548859163,0,1548859164,1548859168,0,1548859168,1548859170,1548859172,1548859172,1548859175,0,0,1548859176,0,0,1548859178,1548859178,0,0,1548859180,1548859181,1548859183,1548859184,1548859185,1548859186,1548859188,1548859190,1548859191,1548859192,1548859192,0,0,1548859195,1548859196,1548859197,1548859198,0,0,1548859199,1548859202,1548859202,0,1548859204,1548859205,1548859206,1548859209,1548859210,1548859211,1548859212,0,1548859214,1548859216,0,1548859217,1548859218,1548859219,1548859220,0,1548859222,1548859222]\" */ int32_t sudoku_captcha(uint32_t timestamps[81]) @@ -2820,15 +2822,6 @@ UniValue sudoku_solution(uint64_t txfee,struct CCcontract_info *cp,cJSON *params priv2addr(coinaddr,pub33,priv32); pk = buf2pk(pub33); GetCCaddress(cp,CCaddr,pk); - Getscriptaddress(checkaddr,tx.vout[1].scriptPubKey); - if ( strcmp(checkaddr,CCaddr) != 0 ) - { - result.push_back(Pair("result","error")); - result.push_back(Pair("error","wrong solution")); - result.push_back(Pair("yours",CCaddr)); - result.push_back(Pair("sudokuaddr",checkaddr)); - return(result); - } result.push_back(Pair("sudokuaddr",CCaddr)); balance = CCaddress_balance(CCaddr); result.push_back(Pair("amount",ValueFromAmount(balance))); @@ -2849,6 +2842,14 @@ UniValue sudoku_solution(uint64_t txfee,struct CCcontract_info *cp,cJSON *params result.push_back(Pair("error","already solved")); else if ( GetTransaction(txid,tx,hashBlock,false) != 0 && (numvouts= tx.vout.size()) > 1 ) { + Getscriptaddress(checkaddr,tx.vout[1].scriptPubKey); + if ( strcmp(checkaddr,CCaddr) != 0 ) + { + result.push_back(Pair("result","error")); + result.push_back(Pair("error","wrong solution")); + result.push_back(Pair("yours",CCaddr)); + return(result); + } if ( sudoku_genopreturndecode(unsolved,tx.vout[numvouts-1].scriptPubKey) == 'G' ) { for (i=0; i<81; i++)