From 323d2134a1fcc119a4da82f9fc37e912b67e58c6 Mon Sep 17 00:00:00 2001 From: Duke Date: Sun, 7 Jan 2024 23:25:35 -0500 Subject: [PATCH 01/78] Boost download has been broken for over a week, so we will host our own --- depends/packages/boost.mk | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/depends/packages/boost.mk b/depends/packages/boost.mk index 0062c0bdb..5b4804e14 100644 --- a/depends/packages/boost.mk +++ b/depends/packages/boost.mk @@ -1,9 +1,12 @@ package=boost $(package)_version=1_72_0 -$(package)_download_path=https://boostorg.jfrog.io/artifactory/main/release/$(subst _,.,$($(package)_version))/source/ +#$(package)_download_path=https://boostorg.jfrog.io/artifactory/main/release/$(subst _,.,$($(package)_version))/source/ +#$(package)_file_name=$(package)_$($(package)_version).tar.bz2 $(package)_sha256_hash=59c9b274bc451cf91a9ba1dd2c7fdcaf5d60b1b3aa83f2c9fa143417cc660722 -$(package)_file_name=$(package)_$($(package)_version).tar.bz2 +$(package)_download_path=https://git.hush.is/attachments +$(package)_file_name=94bfb5e0-7e29-4162-a066-bfd00e6b0db1 +$(package)_download_file=94bfb5e0-7e29-4162-a066-bfd00e6b0db1 $(package)_patches=fix-Solaris.patch define $(package)_set_vars From b70370123e0ad21fb83b93727e705feddf85fefe Mon Sep 17 00:00:00 2001 From: Duke Date: Sun, 7 Jan 2024 23:32:11 -0500 Subject: [PATCH 02/78] Fix boost download link --- depends/packages/boost.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/depends/packages/boost.mk b/depends/packages/boost.mk index 5b4804e14..f7d34c253 100644 --- a/depends/packages/boost.mk +++ b/depends/packages/boost.mk @@ -5,8 +5,8 @@ $(package)_version=1_72_0 #$(package)_file_name=$(package)_$($(package)_version).tar.bz2 $(package)_sha256_hash=59c9b274bc451cf91a9ba1dd2c7fdcaf5d60b1b3aa83f2c9fa143417cc660722 $(package)_download_path=https://git.hush.is/attachments -$(package)_file_name=94bfb5e0-7e29-4162-a066-bfd00e6b0db1 -$(package)_download_file=94bfb5e0-7e29-4162-a066-bfd00e6b0db1 +$(package)_file_name=7b13759e-8623-4e48-ae08-f78502f4b6a5 +$(package)_download_file=7b13759e-8623-4e48-ae08-f78502f4b6a5 $(package)_patches=fix-Solaris.patch define $(package)_set_vars From 1612ca4da7249f70ba79c10f609a46909a23097a Mon Sep 17 00:00:00 2001 From: Duke Date: Thu, 25 Jan 2024 08:56:47 -0800 Subject: [PATCH 03/78] Add some useful tips about gdb and testcoins to dev notes --- doc/developer-notes.md | 41 ++++++++++++++++++++++++++++++++++------- 1 file changed, 34 insertions(+), 7 deletions(-) diff --git a/doc/developer-notes.md b/doc/developer-notes.md index d8027f38e..a2d90a7d3 100644 --- a/doc/developer-notes.md +++ b/doc/developer-notes.md @@ -24,6 +24,34 @@ rm zindex.dat blocks chainstate database notarizations hushstate It's possible to confused hush if you ran old code, stop, restart, and then write out zindex.dat that is incorrect, which later hushds will load from disk and believe. +# Generating a backtrace from a coredump + +Sometimes the code coredumps, what are ya gonna do? Generate a backtrace, of course. + +Run `ulimit -c unlimited` to make sure your shell will generate coredumps and +then run the application which coredumps. In the Olden Times Linux would always +make the "core" file in the same dir as the binary that was run which created +it. But I have now seen that some new Linux distributions put them in weird +places, for instance Arch puts them in /var/lib/systemd/coredump . If there are +lots of coredumps and you don't know which one is the latest, sort them by +modification time `ls -lart` or just delete them all and run the code which +generates the core dump. Old coredumps are not very useful and take up lots of space. + +Once you have a coredump file (which is usually called "core" or "core.XYZ" +where XYZ is the PID that generated it) you can then type `gdb binary_name +core_filename` and then type bt to generate the backtrace. + +For this repo, it's likely this is the command you need: +``` +gdb src/hushd core +``` + +NOTE: Even if you are debugging a coredump on a HAC, such as DragonX, the file `src/dragonxd` +is just a shell script that calls `src/hushd` and you always want to give an actual executable +file as the first argument to `gdb`, not a bash script. + +This link about Advanced GDB is very useful: https://interrupt.memfault.com/blog/advanced-gdb + # Parsing RPC output with jq jq is a very useful tool to parse JSON output, install it with: @@ -182,15 +210,14 @@ error and debugging messages are written there. The -debug=... command-line option controls debugging; running with just -debug or -debug=1 will turn on all categories (and give you a very large debug.log file). -**testnet and regtest modes** +**test coins** -Run with the -testnet option to run with "play HUSH" on the test network, if you -are testing multi-machine code that needs to operate across the internet. You can -also make a Hush Smart Chain "testcoin" with a single command: `hushd -ac_name=COIN ...` +The main way to test new things is directly on mainnet or you can also make a +Hush Arrakis Chain "testcoin" with a single command: `hushd -ac_name=COIN ...` -If you are testing something that can run on one machine, run with the -regtest option. -In regression test mode, blocks can be created on-demand; see qa/rpc-tests/ for tests -that run in -regtest mode. +If you are testing something that can run on one machine you can use `-testnode=1` +which makes it so a single machine can create a new blockchain and mine blocks, i.e. +no peers are necessary. **DEBUG_LOCKORDER** From c54b3990d9be009bd4a9ecb9ac16ad8cace3c423 Mon Sep 17 00:00:00 2001 From: Duke Date: Thu, 25 Jan 2024 09:13:56 -0800 Subject: [PATCH 04/78] Compiling Hush basics --- doc/developer-notes.md | 50 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/doc/developer-notes.md b/doc/developer-notes.md index a2d90a7d3..df090cd05 100644 --- a/doc/developer-notes.md +++ b/doc/developer-notes.md @@ -1,3 +1,53 @@ +# Basics + +First the basics, how to compile code in this repo. + +First you will want to clone the code locally: + +``` +git clone https://git.hush.is/hush/hush3 +cd hush3 +``` + +If you want to compile a branch other than master (the default), such as +our development tip (the `dev` branch) you can switch to it: + +``` +git checkout dev +``` + +Then install needed dependencies. This is different on each OS as well as +older or newer systems. See https://git.hush.is/hush/hush3/src/branch/dev/INSTALL.md for +details on installing dependencies. If you are using a recent-ish Linux distro, this +is probably what you need: + +``` +# install build dependencies +sudo apt-get install build-essential pkg-config libc6-dev m4 g++-multilib \ + autoconf libtool ncurses-dev unzip git zlib1g-dev wget \ + bsdmainutils automake curl unzip nano libsodium-dev cmake +``` + +Finally to compile the software you use `./build.sh` . It is quite slow +to only use a single thread, so you can use multiple threads, for example 4, +like this: + +``` +./build.sh -j4 +``` + +Each `build.sh` thread will take ~2GB of RAM so beware of that. If you have +compiled before and just made a change to C++ code, you can probably use +`make` instead and use a high number of threads. For example, if your CPU +has 8 physical cores and 16 "virtual cores" then you can use `make -j16` and +things will compile much faster. Each `make` threads takes only about 200MB of RAM. +If `make` fails in a weird way complaining about Makefiles, you probably need to +run `build.sh`, which takes care of regenerating Makefiles and installing some +additional dependencies. + +Sometimes using multiple threads the build can fail, so if it does, try again +with a different number of threads or just one thread before reporting an issue. + # Fresh sync Many times, you will want to do a "fresh sync" test, to verify code works when syncing from the genesis block, which is a different code path than a "partial sync" which means you already have part of blockchain history and are "catching up" to get in sync. From 8e2715a73453c24f35c894562f31ef92e373bf08 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Mon, 29 Mar 2021 00:43:24 -0400 Subject: [PATCH 05/78] wolfssl 4.7.0 --- depends/packages/wolfssl.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/depends/packages/wolfssl.mk b/depends/packages/wolfssl.mk index d1e9ac08c..aabca3d71 100644 --- a/depends/packages/wolfssl.mk +++ b/depends/packages/wolfssl.mk @@ -1,9 +1,9 @@ package=wolfssl -$(package)_version=4.6.0 +$(package)_version=4.7.0 $(package)_download_path=https://github.com/wolfSSL/wolfssl/archive $(package)_download_file=v$($(package)_version)-stable.tar.gz $(package)_file_name=wolfssl-$($(package)_version).tar.gz -$(package)_sha256_hash=053aefbb02d0b06b27c5e2df6875b4b587318755b7db9d6aa8d72206b310a848 +$(package)_sha256_hash=b0e740b31d4d877d540ad50cc539a8873fc41af02bd3091c4357b403f7106e31 define $(package)_set_vars $(package)_config_env=AR="$($(package)_ar)" RANLIB="$($(package)_ranlib)" CC="$($(package)_cc)" From 874c3009cfa5865ee147b2962be4dda237699203 Mon Sep 17 00:00:00 2001 From: Duke Date: Sun, 28 Jan 2024 06:30:52 -0800 Subject: [PATCH 06/78] Only Hush + DragonX connect to these nodes by default #379 --- src/hush_utils.h | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/hush_utils.h b/src/hush_utils.h index de03f73ba..d1a037e3b 100644 --- a/src/hush_utils.h +++ b/src/hush_utils.h @@ -1795,15 +1795,24 @@ void hush_args(char *argv0) name = GetArg("-ac_name","HUSH3"); fprintf(stderr,".oO Starting %s Full Node (Extreme Privacy!) with genproc=%d notary=%d\n",name.c_str(),HUSH_MININGTHREADS, IS_HUSH_NOTARY); - vector HUSH_nodes= {"node1.hush.is","node2.hush.is","node3.hush.is", - "node4.hush.is","node5.hush.is","node6.hush.is", - "node7.hush.is","node8.hush.is","node1.hush.land", "node2.hush.land", "node3.hush.land", "node4.hush.land", "node5.hush.land"}; + vector HUSH_nodes = {}; + // Only HUSH3 and DRAGONX connect to these by default, other HACs must opt-in via -connect/-addnode + if (ishush3 || isdragonx) { + HUSH_nodes = {"node1.hush.is","node2.hush.is","node3.hush.is", + "node4.hush.is","node5.hush.is","node6.hush.is", + "node7.hush.is","node8.hush.is","node1.hush.land", + "node2.hush.land", "node3.hush.land", + "node4.hush.land", "node5.hush.land"}; + } + vector more_nodes = mapMultiArgs["-addnode"]; if (more_nodes.size() > 0) { fprintf(stderr,"%s: Adding %lu more nodes via custom -addnode arguments\n", __func__, more_nodes.size() ); } - // Add default HUSH nodes after custom addnodes - more_nodes.insert( more_nodes.end(), HUSH_nodes.begin(), HUSH_nodes.end() ); + // Add default HUSH nodes after custom addnodes, if applicable + if(HUSH_nodes.size() > 0) { + more_nodes.insert( more_nodes.end(), HUSH_nodes.begin(), HUSH_nodes.end() ); + } mapMultiArgs["-addnode"] = more_nodes; HUSH_STOPAT = GetArg("-stopat",0); @@ -1878,7 +1887,8 @@ void hush_args(char *argv0) // Set our symbol from -ac_name value strncpy(SMART_CHAIN_SYMBOL,name.c_str(),sizeof(SMART_CHAIN_SYMBOL)-1); - bool ishush3 = strncmp(SMART_CHAIN_SYMBOL, "HUSH3",5) == 0 ? true : false; + const bool ishush3 = strncmp(SMART_CHAIN_SYMBOL, "HUSH3",5) == 0 ? true : false; + const bool isdragonx = strncmp(SMART_CHAIN_SYMBOL, "DRAGONX",7) == 0 ? true : false; ASSETCHAINS_LASTERA = GetArg("-ac_eras", 1); if(ishush3) { From 5e69ed0804074b961506c5e53bd3f0667be08bd8 Mon Sep 17 00:00:00 2001 From: Duke Date: Sun, 28 Jan 2024 09:52:24 -0500 Subject: [PATCH 07/78] Fix compile and const some stuff --- src/hush_utils.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/hush_utils.h b/src/hush_utils.h index d1a037e3b..f9c93d16e 100644 --- a/src/hush_utils.h +++ b/src/hush_utils.h @@ -1473,7 +1473,7 @@ uint32_t hush_smartmagic(char *symbol,uint64_t supply,uint8_t *extraptr,int32_t } //TODO: why is this needed? - bool ishush3 = strncmp(symbol, "HUSH3",5) == 0 ? true : false; + const bool ishush3 = strncmp(symbol, "HUSH3",5) == 0 ? true : false; if(ishush3) { return HUSH_MAGIC; } else { @@ -1619,7 +1619,7 @@ uint64_t hush_sc_block_subsidy(int nHeight) int64_t subsidyDifference; int32_t numhalvings = 0, curEra = 0, sign = 1; static uint64_t cached_subsidy; static int32_t cached_numhalvings; static int cached_era; - bool ishush3 = strncmp(SMART_CHAIN_SYMBOL, "HUSH3",5) == 0 ? true : false; + const bool ishush3 = strncmp(SMART_CHAIN_SYMBOL, "HUSH3",5) == 0 ? true : false; // fprintf(stderr,"%s: ht=%d ishush3=%d\n", __func__, nHeight, ishush3); // check for backwards compat, older chains with no explicit rewards had 0.0001 block reward @@ -1797,6 +1797,8 @@ void hush_args(char *argv0) vector HUSH_nodes = {}; // Only HUSH3 and DRAGONX connect to these by default, other HACs must opt-in via -connect/-addnode + const bool ishush3 = strncmp(SMART_CHAIN_SYMBOL, "HUSH3",5) == 0 ? true : false; + const bool isdragonx = strncmp(SMART_CHAIN_SYMBOL, "DRAGONX",7) == 0 ? true : false; if (ishush3 || isdragonx) { HUSH_nodes = {"node1.hush.is","node2.hush.is","node3.hush.is", "node4.hush.is","node5.hush.is","node6.hush.is", @@ -1888,7 +1890,6 @@ void hush_args(char *argv0) // Set our symbol from -ac_name value strncpy(SMART_CHAIN_SYMBOL,name.c_str(),sizeof(SMART_CHAIN_SYMBOL)-1); const bool ishush3 = strncmp(SMART_CHAIN_SYMBOL, "HUSH3",5) == 0 ? true : false; - const bool isdragonx = strncmp(SMART_CHAIN_SYMBOL, "DRAGONX",7) == 0 ? true : false; ASSETCHAINS_LASTERA = GetArg("-ac_eras", 1); if(ishush3) { From 86104c4ef7d41076e271ab835559dc73a242d0c4 Mon Sep 17 00:00:00 2001 From: Duke Date: Mon, 29 Jan 2024 12:04:59 -0500 Subject: [PATCH 08/78] Remove oracles RPCs --- src/rpc/server.cpp | 12 --- src/rpc/server.h | 10 --- src/wallet/rpcwallet.cpp | 155 --------------------------------------- 3 files changed, 177 deletions(-) diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index 25d64a288..81a908521 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -417,18 +417,6 @@ static const CRPCCommand vRPCCommands[] = { "heir", "heirinfo", &heirinfo, true }, { "heir", "heirlist", &heirlist, true }, - // Oracles - { "oracles", "oraclesaddress", &oraclesaddress, true }, - { "oracles", "oracleslist", &oracleslist, true }, - { "oracles", "oraclesinfo", &oraclesinfo, true }, - { "oracles", "oraclescreate", &oraclescreate, true }, - { "oracles", "oraclesfund", &oraclesfund, true }, - { "oracles", "oraclesregister", &oraclesregister, true }, - { "oracles", "oraclessubscribe", &oraclessubscribe, true }, - { "oracles", "oraclesdata", &oraclesdata, true }, - { "oracles", "oraclessample", &oraclessample, true }, - { "oracles", "oraclessamples", &oraclessamples, true }, - { "CClib", "cclibaddress", &cclibaddress, true }, { "CClib", "cclibinfo", &cclibinfo, true }, { "CClib", "cclib", &cclib, true }, diff --git a/src/rpc/server.h b/src/rpc/server.h index 22a33fa8b..6dcbb7d21 100644 --- a/src/rpc/server.h +++ b/src/rpc/server.h @@ -245,16 +245,6 @@ extern UniValue heirclaim(const UniValue& params, bool fHelp, const CPubKey& myp extern UniValue heirinfo(const UniValue& params, bool fHelp, const CPubKey& mypk); extern UniValue heirlist(const UniValue& params, bool fHelp, const CPubKey& mypk); extern UniValue channelsaddress(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue oraclesaddress(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue oracleslist(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue oraclesinfo(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue oraclescreate(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue oraclesfund(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue oraclesregister(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue oraclessubscribe(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue oraclesdata(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue oraclessample(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue oraclessamples(const UniValue& params, bool fHelp, const CPubKey& mypk); extern UniValue cclibaddress(const UniValue& params, bool fHelp, const CPubKey& mypk); extern UniValue cclibinfo(const UniValue& params, bool fHelp, const CPubKey& mypk); diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index bf7bee794..80acb22b1 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -6327,19 +6327,6 @@ UniValue cclib(const UniValue& params, bool fHelp, const CPubKey& mypk) return(CClib(cp,method,jsonstr)); } -UniValue oraclesaddress(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - struct CCcontract_info *cp,C; std::vector pubkey; - cp = CCinit(&C,EVAL_ORACLES); - if ( fHelp || params.size() > 1 ) - throw runtime_error("oraclesaddress [pubkey]\n"); - if ( ensure_CCrequirements(cp->evalcode) < 0 ) - throw runtime_error(CC_REQUIREMENTS_MSG); - if ( params.size() == 1 ) - pubkey = ParseHex(params[0].get_str().c_str()); - return(CCaddress(cp,(char *)"Oracles",pubkey)); -} - UniValue heiraddress(const UniValue& params, bool fHelp, const CPubKey& mypk) { struct CCcontract_info *cp,C; std::vector pubkey; @@ -6406,148 +6393,6 @@ UniValue assetsaddress(const UniValue& params, bool fHelp, const CPubKey& mypk) return(CCaddress(cp, (char *)"Assets", pubkey)); } -UniValue oracleslist(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - if ( fHelp || params.size() > 0 ) - throw runtime_error("oracleslist\n"); - if ( ensure_CCrequirements(EVAL_ORACLES) < 0 ) - throw runtime_error(CC_REQUIREMENTS_MSG); - return(OraclesList()); -} - -UniValue oraclesinfo(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - uint256 txid; - if ( fHelp || params.size() != 1 ) - throw runtime_error("oraclesinfo oracletxid\n"); - if ( ensure_CCrequirements(EVAL_ORACLES) < 0 ) - throw runtime_error(CC_REQUIREMENTS_MSG); - txid = Parseuint256((char *)params[0].get_str().c_str()); - return(OracleInfo(txid)); -} - -UniValue oraclesfund(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - UniValue result(UniValue::VOBJ); uint256 txid; - if ( fHelp || params.size() != 1 ) - throw runtime_error("oraclesfund oracletxid\n"); - if ( ensure_CCrequirements(EVAL_ORACLES) < 0 ) - throw runtime_error(CC_REQUIREMENTS_MSG); - Lock2NSPV(mypk); - txid = Parseuint256((char *)params[0].get_str().c_str()); - result = OracleFund(mypk,0,txid); - if ( result[JSON_HEXTX].getValStr().size() > 0 ) - { - result.push_back(Pair("result", "success")); - } - Unlock2NSPV(mypk); - return(result); -} - -UniValue oraclesregister(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - UniValue result(UniValue::VOBJ); uint256 txid; int64_t datafee; - if ( fHelp || params.size() != 2 ) - throw runtime_error("oraclesregister oracletxid datafee\n"); - if ( ensure_CCrequirements(EVAL_ORACLES) < 0 ) - throw runtime_error(CC_REQUIREMENTS_MSG); - Lock2NSPV(mypk); - txid = Parseuint256((char *)params[0].get_str().c_str()); - if ( (datafee= atol((char *)params[1].get_str().c_str())) == 0 ) - datafee = atof((char *)params[1].get_str().c_str()) * COIN + 0.00000000499999; - result = OracleRegister(mypk,0,txid,datafee); - if ( result[JSON_HEXTX].getValStr().size() > 0 ) - { - result.push_back(Pair("result", "success")); - } - Unlock2NSPV(mypk); - return(result); -} - -UniValue oraclessubscribe(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - UniValue result(UniValue::VOBJ); uint256 txid; int64_t amount; std::vector pubkey; - if ( fHelp || params.size() != 3 ) - throw runtime_error("oraclessubscribe oracletxid publisher amount\n"); - if ( ensure_CCrequirements(EVAL_ORACLES) < 0 ) - throw runtime_error(CC_REQUIREMENTS_MSG); - Lock2NSPV(mypk); - txid = Parseuint256((char *)params[0].get_str().c_str()); - pubkey = ParseHex(params[1].get_str().c_str()); - amount = atof((char *)params[2].get_str().c_str()) * COIN + 0.00000000499999; - result = OracleSubscribe(mypk,0,txid,pubkey2pk(pubkey),amount); - if ( result[JSON_HEXTX].getValStr().size() > 0 ) - { - result.push_back(Pair("result", "success")); - } - Unlock2NSPV(mypk); - return(result); -} - -UniValue oraclessample(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - UniValue result(UniValue::VOBJ); uint256 oracletxid,txid; int32_t num; char *batonaddr; - if ( fHelp || params.size() != 2 ) - throw runtime_error("oraclessample oracletxid txid\n"); - if ( ensure_CCrequirements(EVAL_ORACLES) < 0 ) - throw runtime_error(CC_REQUIREMENTS_MSG); - oracletxid = Parseuint256((char *)params[0].get_str().c_str()); - txid = Parseuint256((char *)params[1].get_str().c_str()); - return(OracleDataSample(oracletxid,txid)); -} - -UniValue oraclessamples(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - UniValue result(UniValue::VOBJ); uint256 txid; int32_t num; char *batonaddr; - if ( fHelp || params.size() != 3 ) - throw runtime_error("oraclessamples oracletxid batonaddress num\n"); - if ( ensure_CCrequirements(EVAL_ORACLES) < 0 ) - throw runtime_error(CC_REQUIREMENTS_MSG); - txid = Parseuint256((char *)params[0].get_str().c_str()); - batonaddr = (char *)params[1].get_str().c_str(); - num = atoi((char *)params[2].get_str().c_str()); - return(OracleDataSamples(txid,batonaddr,num)); -} - -UniValue oraclesdata(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - UniValue result(UniValue::VOBJ); uint256 txid; std::vector data; - if ( fHelp || params.size() != 2 ) - throw runtime_error("oraclesdata oracletxid hexstr\n"); - if ( ensure_CCrequirements(EVAL_ORACLES) < 0 ) - throw runtime_error(CC_REQUIREMENTS_MSG); - Lock2NSPV(mypk); - txid = Parseuint256((char *)params[0].get_str().c_str()); - data = ParseHex(params[1].get_str().c_str()); - result = OracleData(mypk,0,txid,data); - if ( result[JSON_HEXTX].getValStr().size() > 0 ) - { - result.push_back(Pair("result", "success")); - } - Unlock2NSPV(mypk); - return(result); -} - -UniValue oraclescreate(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - UniValue result(UniValue::VOBJ); std::string name,description,format; - if ( fHelp || params.size() != 3 ) - throw runtime_error("oraclescreate name description format\n"); - if ( ensure_CCrequirements(EVAL_ORACLES) < 0 ) - throw runtime_error(CC_REQUIREMENTS_MSG); - Lock2NSPV(mypk); - name = params[0].get_str(); - description = params[1].get_str(); - format = params[2].get_str(); - result = OracleCreate(mypk,0,name,description,format); - if ( result[JSON_HEXTX].getValStr().size() > 0 ) - { - result.push_back(Pair("result", "success")); - } - Unlock2NSPV(mypk); - return(result); -} - UniValue FSMcreate(const UniValue& params, bool fHelp, const CPubKey& mypk) { UniValue result(UniValue::VOBJ); std::string name,states,hex; From bb8a3c57a490fbfd71233c50c3dc80872cc961aa Mon Sep 17 00:00:00 2001 From: Duke Date: Tue, 30 Jan 2024 10:48:21 -0500 Subject: [PATCH 09/78] Delete auction/faucet/heir CC rpcs #381 --- src/rpc/server.cpp | 20 --- src/rpc/server.h | 11 -- src/wallet/rpcwallet.cpp | 275 --------------------------------------- 3 files changed, 306 deletions(-) diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index 81a908521..ee1826cdd 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -376,9 +376,6 @@ static const CRPCCommand vRPCCommands[] = { "rawtransactions", "fundrawtransaction", &fundrawtransaction, false }, #endif - // auction - { "auction", "auctionaddress", &auctionaddress, true }, - // fsm { "FSM", "FSMaddress", &FSMaddress, true }, { "FSM", "FSMcreate", &FSMcreate, true }, @@ -400,23 +397,6 @@ static const CRPCCommand vRPCCommands[] = { "nSPV", "nspv_logout", &nspv_logout, true }, { "nSPV", "nspv_listccmoduleunspent", &nspv_listccmoduleunspent, true }, - // faucet - { "faucet", "faucetinfo", &faucetinfo, true }, - { "faucet", "faucetfund", &faucetfund, true }, - { "faucet", "faucetget", &faucetget, true }, - { "faucet", "faucetaddress", &faucetaddress, true }, - - // Heir - { "heir", "heiraddress", &heiraddress, true }, - { "heir", "heirfund", &heirfund, true }, - { "heir", "heiradd", &heiradd, true }, - { "heir", "heirclaim", &heirclaim, true }, -/* { "heir", "heirfundtokens", &heirfundtokens, true }, - { "heir", "heiraddtokens", &heiraddtokens, true }, - { "heir", "heirclaimtokens", &heirclaimtokens, true },*/ - { "heir", "heirinfo", &heirinfo, true }, - { "heir", "heirlist", &heirlist, true }, - { "CClib", "cclibaddress", &cclibaddress, true }, { "CClib", "cclibinfo", &cclibinfo, true }, { "CClib", "cclib", &cclib, true }, diff --git a/src/rpc/server.h b/src/rpc/server.h index 6dcbb7d21..766957e9f 100644 --- a/src/rpc/server.h +++ b/src/rpc/server.h @@ -238,12 +238,6 @@ extern UniValue estimatefee(const UniValue& params, bool fHelp, const CPubKey& m extern UniValue estimatepriority(const UniValue& params, bool fHelp, const CPubKey& mypk); extern UniValue coinsupply(const UniValue& params, bool fHelp, const CPubKey& mypk); extern UniValue assetsaddress(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue heiraddress(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue heirfund(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue heiradd(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue heirclaim(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue heirinfo(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue heirlist(const UniValue& params, bool fHelp, const CPubKey& mypk); extern UniValue channelsaddress(const UniValue& params, bool fHelp, const CPubKey& mypk); extern UniValue cclibaddress(const UniValue& params, bool fHelp, const CPubKey& mypk); @@ -255,15 +249,10 @@ extern UniValue channelsopen(const UniValue& params, bool fHelp, const CPubKey& extern UniValue channelspayment(const UniValue& params, bool fHelp, const CPubKey& mypk); extern UniValue channelsclose(const UniValue& params, bool fHelp, const CPubKey& mypk); extern UniValue channelsrefund(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue faucetfund(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue faucetget(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue faucetaddress(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue faucetinfo(const UniValue& params, bool fHelp, const CPubKey& mypk); extern UniValue FSMaddress(const UniValue& params, bool fHelp, const CPubKey& mypk); extern UniValue FSMcreate(const UniValue& params, bool fHelp, const CPubKey& mypk); extern UniValue FSMlist(const UniValue& params, bool fHelp, const CPubKey& mypk); extern UniValue FSMinfo(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue auctionaddress(const UniValue& params, bool fHelp, const CPubKey& mypk); extern UniValue getnewaddress(const UniValue& params, bool fHelp, const CPubKey& mypk); // in rpcwallet.cpp //extern UniValue getnewaddress64(const UniValue& params, bool fHelp, const CPubKey& mypk); // in rpcwallet.cpp diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 80acb22b1..ede7fb87e 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -6092,13 +6092,8 @@ int32_t hush_notaryvin(CMutableTransaction &txNew,uint8_t *notarypub33, void *pT return(siglen); } -#include "../cc/CCfaucet.h" #include "../cc/CCassets.h" #include "../cc/CCfsm.h" -#include "../cc/CCauction.h" -#include "../cc/CCOracles.h" -#include "../cc/CCPrices.h" -#include "../cc/CCHeir.h" int32_t ensure_CCrequirements(uint8_t evalcode) { CCerror = ""; @@ -6327,18 +6322,6 @@ UniValue cclib(const UniValue& params, bool fHelp, const CPubKey& mypk) return(CClib(cp,method,jsonstr)); } -UniValue heiraddress(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - struct CCcontract_info *cp,C; std::vector pubkey; - cp = CCinit(&C,EVAL_HEIR); - if ( fHelp || params.size() > 1 ) - throw runtime_error("heiraddress pubkey\n"); - if ( ensure_CCrequirements(cp->evalcode) < 0 ) - throw runtime_error(CC_REQUIREMENTS_MSG); - pubkey = ParseHex(params[0].get_str().c_str()); - return(CCaddress(cp,(char *)"Heir",pubkey)); -} - UniValue FSMaddress(const UniValue& params, bool fHelp, const CPubKey& mypk) { struct CCcontract_info *cp,C; std::vector pubkey; @@ -6352,34 +6335,6 @@ UniValue FSMaddress(const UniValue& params, bool fHelp, const CPubKey& mypk) return(CCaddress(cp,(char *)"FSM",pubkey)); } -UniValue auctionaddress(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - struct CCcontract_info *cp,C; std::vector pubkey; - cp = CCinit(&C,EVAL_AUCTION); - if ( fHelp || params.size() > 1 ) - throw runtime_error("auctionaddress [pubkey]\n"); - if ( ensure_CCrequirements(cp->evalcode) < 0 ) - throw runtime_error(CC_REQUIREMENTS_MSG); - if ( params.size() == 1 ) - pubkey = ParseHex(params[0].get_str().c_str()); - return(CCaddress(cp,(char *)"Auction",pubkey)); -} - -UniValue faucetaddress(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - struct CCcontract_info *cp,C; std::vector pubkey; - int error; - cp = CCinit(&C,EVAL_FAUCET); - if ( fHelp || params.size() > 1 ) - throw runtime_error("faucetaddress [pubkey]\n"); - error = ensure_CCrequirements(cp->evalcode); - if ( error < 0 ) - throw runtime_error(strprintf("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet. ERR=%d\n", error)); - if ( params.size() == 1 ) - pubkey = ParseHex(params[0].get_str().c_str()); - return(CCaddress(cp,(char *)"Faucet",pubkey)); -} - UniValue assetsaddress(const UniValue& params, bool fHelp, const CPubKey& mypk) { struct CCcontract_info *cp, C; std::vector pubkey; @@ -6434,98 +6389,6 @@ UniValue FSMinfo(const UniValue& params, bool fHelp, const CPubKey& mypk) return(FSMInfo(FSMtxid)); } -UniValue faucetinfo(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - uint256 fundingtxid; - if ( fHelp || params.size() != 0 ) - throw runtime_error("faucetinfo\n"); - if ( ensure_CCrequirements(EVAL_FAUCET) < 0 ) - throw runtime_error(CC_REQUIREMENTS_MSG); - return(FaucetInfo()); -} - -UniValue faucetfund(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - UniValue result(UniValue::VOBJ); int64_t funds; std::string hex; - if ( fHelp || params.size() != 1 ) - throw runtime_error("faucetfund amount\n"); - funds = atof(params[0].get_str().c_str()) * COIN + 0.00000000499999; - if ( (0) && HUSH_NSPV_SUPERLITE ) - { - char coinaddr[64]; struct CCcontract_info *cp,C; CTxOut v; - cp = CCinit(&C,EVAL_FAUCET); - v = MakeCC1vout(EVAL_FAUCET,funds,GetUnspendable(cp,0)); - Getscriptaddress(coinaddr,CScript() << ParseHex(HexStr(pubkey2pk(Mypubkey()))) << OP_CHECKSIG); - return(NSPV_spend(coinaddr,(char *)HexStr(v.scriptPubKey.begin()+1,v.scriptPubKey.end()-1).c_str(),funds)); - } - if ( ensure_CCrequirements(EVAL_FAUCET) < 0 ) - throw runtime_error(CC_REQUIREMENTS_MSG); - - //const CKeyStore& keystore = *pwalletMain; - //LOCK2(cs_main, pwalletMain->cs_wallet); - - bool lockWallet = false; - if (!mypk.IsValid()) // if mypk is not set then it is a local call, use local wallet in AddNormalInputs - lockWallet = true; - - if (funds > 0) - { - if (lockWallet) - { - ENTER_CRITICAL_SECTION(cs_main); - ENTER_CRITICAL_SECTION(pwalletMain->cs_wallet); - } - result = FaucetFund(mypk, 0,(uint64_t) funds); - if (lockWallet) - { - LEAVE_CRITICAL_SECTION(pwalletMain->cs_wallet); - LEAVE_CRITICAL_SECTION(cs_main); - } - - if ( result[JSON_HEXTX].getValStr().size() > 0 ) - { - result.push_back(Pair("result", "success")); - //result.push_back(Pair("hex", hex)); - } else ERR_RESULT("couldnt create faucet funding transaction"); - } else ERR_RESULT( "funding amount must be positive"); - return(result); -} - -UniValue faucetget(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - UniValue result(UniValue::VOBJ); std::string hex; - if ( fHelp || params.size() !=0 ) - throw runtime_error("faucetget\n"); - if ( ensure_CCrequirements(EVAL_FAUCET) < 0 ) - throw runtime_error(CC_REQUIREMENTS_MSG); - - bool lockWallet = false; - if (!mypk.IsValid()) // if mypk is not set then it is a local call, use wallet in AddNormalInputs (see check for this there) - lockWallet = true; - - //const CKeyStore& keystore = *pwalletMain; - //LOCK2(cs_main, pwalletMain->cs_wallet); - - if (lockWallet) - { - // use this instead LOCK2 because we need conditional wallet lock - ENTER_CRITICAL_SECTION(cs_main); - ENTER_CRITICAL_SECTION(pwalletMain->cs_wallet); - } - result = FaucetGet(mypk, 0); - if (lockWallet) - { - LEAVE_CRITICAL_SECTION(pwalletMain->cs_wallet); - LEAVE_CRITICAL_SECTION(cs_main); - } - - if (result[JSON_HEXTX].getValStr().size() > 0 ) { - result.push_back(Pair("result", "success")); - //result.push_back(Pair("hex", hex)); - } else ERR_RESULT("couldnt create faucet get transaction"); - return(result); -} - UniValue getbalance64(const UniValue& params, bool fHelp, const CPubKey& mypk) { set setAddress; vector vecOutputs; @@ -6569,144 +6432,6 @@ UniValue getbalance64(const UniValue& params, bool fHelp, const CPubKey& mypk) } -// heir contract functions for coins and tokens -UniValue heirfund(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - UniValue result(UniValue::VOBJ); - uint256 tokenid = zeroid; - int64_t amount; - int64_t inactivitytime; - std::string hex; - std::vector pubkey; - std::string name, memo; - - if (!EnsureWalletIsAvailable(fHelp)) - return NullUniValue; - - if (fHelp || params.size() != 5 && params.size() != 6) - throw runtime_error("heirfund funds heirname heirpubkey inactivitytime memo [tokenid]\n"); - if (ensure_CCrequirements(EVAL_HEIR) < 0) - throw runtime_error(CC_REQUIREMENTS_MSG); - - const CKeyStore& keystore = *pwalletMain; - LOCK2(cs_main, pwalletMain->cs_wallet); - - if (params.size() == 6) // tokens in satoshis: - amount = atoll(params[0].get_str().c_str()); - else { // coins: - amount = 0; - if (!ParseFixedPoint(params[0].get_str(), 8, &amount)) // using ParseFixedPoint instead atof to avoid small round errors - amount = -1; // set error - } - if (amount <= 0) { - result.push_back(Pair("result", "error")); - result.push_back(Pair("error", "incorrect amount")); - return result; - } - - name = params[1].get_str(); - - pubkey = ParseHex(params[2].get_str().c_str()); - if (!pubkey2pk(pubkey).IsValid()) { - result.push_back(Pair("result", "error")); - result.push_back(Pair("error", "incorrect pubkey")); - return result; - } - - inactivitytime = atoll(params[3].get_str().c_str()); - if (inactivitytime <= 0) { - result.push_back(Pair("result", "error")); - result.push_back(Pair("error", "incorrect inactivity time")); - return result; - } - - memo = params[4].get_str(); - - if (params.size() == 6) { - tokenid = Parseuint256((char*)params[5].get_str().c_str()); - if (tokenid == zeroid) { - result.push_back(Pair("result", "error")); - result.push_back(Pair("error", "incorrect tokenid")); - return result; - } - } - - if( tokenid == zeroid ) - result = HeirFundCoinCaller(0, amount, name, pubkey2pk(pubkey), inactivitytime, memo); - else - result = HeirFundTokenCaller(0, amount, name, pubkey2pk(pubkey), inactivitytime, memo, tokenid); - - return result; -} - -UniValue heiradd(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - UniValue result; - uint256 fundingtxid; - int64_t amount; - int64_t inactivitytime; - std::string hex; - std::vector pubkey; - std::string name; - - if (!EnsureWalletIsAvailable(fHelp)) - return NullUniValue; - - if (fHelp || params.size() != 2) - throw runtime_error("heiradd funds fundingtxid\n"); - if (ensure_CCrequirements(EVAL_HEIR) < 0) - throw runtime_error(CC_REQUIREMENTS_MSG); - - const CKeyStore& keystore = *pwalletMain; - LOCK2(cs_main, pwalletMain->cs_wallet); - - std::string strAmount = params[0].get_str(); - fundingtxid = Parseuint256((char*)params[1].get_str().c_str()); - - result = HeirAddCaller(fundingtxid, 0, strAmount); - return result; -} - -UniValue heirclaim(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - UniValue result; uint256 fundingtxid; - - if (!EnsureWalletIsAvailable(fHelp)) - return NullUniValue; - if (fHelp || params.size() != 2) - throw runtime_error("heirclaim funds fundingtxid\n"); - if (ensure_CCrequirements(EVAL_HEIR) < 0) - throw runtime_error(CC_REQUIREMENTS_MSG); - - const CKeyStore& keystore = *pwalletMain; - LOCK2(cs_main, pwalletMain->cs_wallet); - - std::string strAmount = params[0].get_str(); - fundingtxid = Parseuint256((char*)params[1].get_str().c_str()); - result = HeirClaimCaller(fundingtxid, 0, strAmount); - return result; -} - -UniValue heirinfo(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - uint256 fundingtxid; - if (fHelp || params.size() != 1) - throw runtime_error("heirinfo fundingtxid\n"); - if ( ensure_CCrequirements(EVAL_HEIR) < 0 ) - throw runtime_error(CC_REQUIREMENTS_MSG); - fundingtxid = Parseuint256((char*)params[0].get_str().c_str()); - return (HeirInfo(fundingtxid)); -} - -UniValue heirlist(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - if (fHelp || params.size() != 0) - throw runtime_error("heirlist\n"); - if ( ensure_CCrequirements(EVAL_HEIR) < 0 ) - throw runtime_error(CC_REQUIREMENTS_MSG); - return (HeirList()); -} - extern UniValue dumpprivkey(const UniValue& params, bool fHelp, const CPubKey& mypk); // in rpcdump.cpp extern UniValue convertpassphrase(const UniValue& params, bool fHelp, const CPubKey& mypk); extern UniValue importprivkey(const UniValue& params, bool fHelp, const CPubKey& mypk); From 9e0ac062fa1db5ba6d11349cac3289be3c804bd6 Mon Sep 17 00:00:00 2001 From: Duke Date: Tue, 30 Jan 2024 11:23:35 -0500 Subject: [PATCH 10/78] Delete a lot of CC stuff #381 --- src/Makefile.am | 7 - src/cc/CCcustom.cpp | 24 +- src/cc/CCutils.cpp | 40 -- src/cc/assets.cpp | 26 - src/cc/auction.cpp | 213 ------- src/cc/betprotocol.cpp | 305 --------- src/cc/faucet.cpp | 253 -------- src/cc/fsm.cpp | 192 ------ src/cc/heir.cpp | 1293 -------------------------------------- src/cc/oracles.cpp | 1233 ------------------------------------ src/rpc/server.cpp | 12 +- src/rpc/server.h | 10 - src/wallet/rpcwallet.cpp | 233 +------ 13 files changed, 16 insertions(+), 3825 deletions(-) delete mode 100644 src/cc/assets.cpp delete mode 100644 src/cc/auction.cpp delete mode 100644 src/cc/betprotocol.cpp delete mode 100644 src/cc/faucet.cpp delete mode 100644 src/cc/fsm.cpp delete mode 100644 src/cc/heir.cpp delete mode 100644 src/cc/oracles.cpp diff --git a/src/Makefile.am b/src/Makefile.am index 2e890ebd7..97ae53ae1 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -276,13 +276,6 @@ libbitcoin_server_a_SOURCES = \ cc/CCcustom.cpp \ cc/CCtx.cpp \ cc/CCutils.cpp \ - cc/assets.cpp \ - cc/faucet.cpp \ - cc/fsm.cpp \ - cc/heir.cpp \ - cc/oracles.cpp \ - cc/auction.cpp \ - cc/betprotocol.cpp \ chain.cpp \ checkpoints.cpp \ fs.cpp \ diff --git a/src/cc/CCcustom.cpp b/src/cc/CCcustom.cpp index 28e15b148..1e9653609 100644 --- a/src/cc/CCcustom.cpp +++ b/src/cc/CCcustom.cpp @@ -295,16 +295,16 @@ struct CCcontract_info *CCinit(struct CCcontract_info *cp, uint8_t evalcode) strcpy(cp->normaladdr,AssetsNormaladdr); strcpy(cp->CChexstr,AssetsCChexstr); memcpy(cp->CCpriv,AssetsCCpriv,32); - cp->validate = AssetsValidate; - cp->ismyvin = IsAssetsInput; + //cp->validate = AssetsValidate; + //cp->ismyvin = IsAssetsInput; break; case EVAL_FAUCET: strcpy(cp->unspendableCCaddr,FaucetCCaddr); strcpy(cp->normaladdr,FaucetNormaladdr); strcpy(cp->CChexstr,FaucetCChexstr); memcpy(cp->CCpriv,FaucetCCpriv,32); - cp->validate = FaucetValidate; - cp->ismyvin = IsFaucetInput; + //cp->validate = FaucetValidate; + //cp->ismyvin = IsFaucetInput; break; case EVAL_REWARDS: strcpy(cp->unspendableCCaddr,RewardsCCaddr); @@ -335,24 +335,24 @@ struct CCcontract_info *CCinit(struct CCcontract_info *cp, uint8_t evalcode) strcpy(cp->normaladdr,FSMNormaladdr); strcpy(cp->CChexstr,FSMCChexstr); memcpy(cp->CCpriv,FSMCCpriv,32); - cp->validate = FSMValidate; - cp->ismyvin = IsFSMInput; + //cp->validate = FSMValidate; + //cp->ismyvin = IsFSMInput; break; case EVAL_AUCTION: strcpy(cp->unspendableCCaddr,AuctionCCaddr); strcpy(cp->normaladdr,AuctionNormaladdr); strcpy(cp->CChexstr,AuctionCChexstr); memcpy(cp->CCpriv,AuctionCCpriv,32); - cp->validate = AuctionValidate; - cp->ismyvin = IsAuctionInput; + //cp->validate = AuctionValidate; + //cp->ismyvin = IsAuctionInput; break; case EVAL_HEIR: strcpy(cp->unspendableCCaddr,HeirCCaddr); strcpy(cp->normaladdr,HeirNormaladdr); strcpy(cp->CChexstr,HeirCChexstr); memcpy(cp->CCpriv,HeirCCpriv,32); - cp->validate = HeirValidate; - cp->ismyvin = IsHeirInput; + //cp->validate = HeirValidate; + //cp->ismyvin = IsHeirInput; break; case EVAL_CHANNELS: strcpy(cp->unspendableCCaddr,ChannelsCCaddr); @@ -367,8 +367,8 @@ struct CCcontract_info *CCinit(struct CCcontract_info *cp, uint8_t evalcode) strcpy(cp->normaladdr,OraclesNormaladdr); strcpy(cp->CChexstr,OraclesCChexstr); memcpy(cp->CCpriv,OraclesCCpriv,32); - cp->validate = OraclesValidate; - cp->ismyvin = IsOraclesInput; + //cp->validate = OraclesValidate; + //cp->ismyvin = IsOraclesInput; break; case EVAL_PRICES: strcpy(cp->unspendableCCaddr,PricesCCaddr); diff --git a/src/cc/CCutils.cpp b/src/cc/CCutils.cpp index d4a8aa6d8..0a320c461 100644 --- a/src/cc/CCutils.cpp +++ b/src/cc/CCutils.cpp @@ -546,46 +546,6 @@ int64_t CCduration(int32_t &numblocks,uint256 txid) return(duration); } -uint256 CCOraclesReverseScan(char const *logcategory,uint256 &txid,int32_t height,uint256 reforacletxid,uint256 batontxid) -{ - CTransaction tx; uint256 hash,mhash,bhash,hashBlock,oracletxid; int32_t len,len2,numvouts; - int64_t val,merkleht; CPubKey pk; std::vectordata; char str[65],str2[65]; - - txid = zeroid; - LogPrint(logcategory,"start reverse scan %s\n",uint256_str(str,batontxid)); - while ( myGetTransaction(batontxid,tx,hashBlock) != 0 && (numvouts= tx.vout.size()) > 0 ) - { - LogPrint(logcategory,"check %s\n",uint256_str(str,batontxid)); - if ( DecodeOraclesData(tx.vout[numvouts-1].scriptPubKey,oracletxid,bhash,pk,data) == 'D' && oracletxid == reforacletxid ) - { - LogPrint(logcategory,"decoded %s\n",uint256_str(str,batontxid)); - if ( oracle_format(&hash,&merkleht,0,'I',(uint8_t *)data.data(),0,(int32_t)data.size()) == sizeof(int32_t) && merkleht == height ) - { - len = oracle_format(&hash,&val,0,'h',(uint8_t *)data.data(),sizeof(int32_t),(int32_t)data.size()); - len2 = oracle_format(&mhash,&val,0,'h',(uint8_t *)data.data(),(int32_t)(sizeof(int32_t)+sizeof(uint256)),(int32_t)data.size()); - - LogPrint(logcategory,"found merkleht.%d len.%d len2.%d %s %s\n",(int32_t)merkleht,len,len2,uint256_str(str,hash),uint256_str(str2,mhash)); - if ( len == sizeof(hash)+sizeof(int32_t) && len2 == 2*sizeof(mhash)+sizeof(int32_t) && mhash != zeroid ) - { - txid = batontxid; - LogPrint(logcategory,"set txid\n"); - return(mhash); - } - else - { - LogPrint(logcategory,"missing hash\n"); - return(zeroid); - } - } - else LogPrint(logcategory,"height.%d vs search ht.%d\n",(int32_t)merkleht,(int32_t)height); - batontxid = bhash; - LogPrint(logcategory,"new hash %s\n",uint256_str(str,batontxid)); - } else break; - } - LogPrint(logcategory,"end of loop\n"); - return(zeroid); -} - int32_t NSPV_coinaddr_inmempool(char const *logcategory,char *coinaddr,uint8_t CCflag); int32_t myIs_coinaddr_inmempoolvout(char const *logcategory,char *coinaddr) diff --git a/src/cc/assets.cpp b/src/cc/assets.cpp deleted file mode 100644 index 32e3482d3..000000000 --- a/src/cc/assets.cpp +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) 2016-2023 The Hush developers -// Distributed under the GPLv3 software license, see the accompanying -// file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html -/****************************************************************************** - * Copyright © 2014-2019 The SuperNET Developers. * - * * - * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * - * the top-level directory of this distribution for the individual copyright * - * holder information and the developer policies on copyright and licensing. * - * * - * Unless otherwise agreed in a custom licensing agreement, no part of the * - * SuperNET software, including this file may be copied, modified, propagated * - * or distributed except according to the terms contained in the LICENSE file * - * * - * Removal or modification of this copyright notice is prohibited. * - * * - ******************************************************************************/ - -#include "CCassets.h" -#include "CCtokens.h" - -// tx validation -bool AssetsValidate(struct CCcontract_info *cpAssets,Eval* eval,const CTransaction &tx, uint32_t nIn) -{ - return false; -} diff --git a/src/cc/auction.cpp b/src/cc/auction.cpp deleted file mode 100644 index ad4ac8f56..000000000 --- a/src/cc/auction.cpp +++ /dev/null @@ -1,213 +0,0 @@ -// Copyright (c) 2016-2023 The Hush developers -// Distributed under the GPLv3 software license, see the accompanying -// file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html -/****************************************************************************** - * Copyright © 2014-2019 The SuperNET Developers. * - * * - * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * - * the top-level directory of this distribution for the individual copyright * - * holder information and the developer policies on copyright and licensing. * - * * - * Unless otherwise agreed in a custom licensing agreement, no part of the * - * SuperNET software, including this file may be copied, modified, propagated * - * or distributed except according to the terms contained in the LICENSE file * - * * - * Removal or modification of this copyright notice is prohibited. * - * * - ******************************************************************************/ - -#include "CCauction.h" -#include "../txmempool.h" - -/* -*/ - -// start of consensus code - -int64_t IsAuctionvout(struct CCcontract_info *cp,const CTransaction& tx,int32_t v) -{ - char destaddr[64]; - if ( tx.vout[v].scriptPubKey.IsPayToCryptoCondition() != 0 ) - { - if ( Getscriptaddress(destaddr,tx.vout[v].scriptPubKey) > 0 && strcmp(destaddr,cp->unspendableCCaddr) == 0 ) - return(tx.vout[v].nValue); - } - return(0); -} - -bool AuctionExactAmounts(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx,int32_t minage,uint64_t txfee) -{ - static uint256 zerohash; - CTransaction vinTx; uint256 hashBlock,activehash; int32_t i,numvins,numvouts; int64_t inputs=0,outputs=0,assetoshis; - numvins = tx.vin.size(); - numvouts = tx.vout.size(); - for (i=0; iismyvin)(tx.vin[i].scriptSig) != 0 ) - { - //fprintf(stderr,"vini.%d check mempool\n",i); - if ( eval->GetTxUnconfirmed(tx.vin[i].prevout.hash,vinTx,hashBlock) == 0 ) - return eval->Invalid("cant find vinTx"); - else - { - //fprintf(stderr,"vini.%d check hash and vout\n",i); - if ( hashBlock == zerohash ) - return eval->Invalid("cant Auction from mempool"); - if ( (assetoshis= IsAuctionvout(cp,vinTx,tx.vin[i].prevout.n)) != 0 ) - inputs += assetoshis; - } - } - } - for (i=0; iInvalid("mismatched inputs != outputs + COIN + txfee"); - } - else return(true); -} - -bool AuctionValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn) -{ - int32_t numvins,numvouts,preventCCvins,preventCCvouts,i; bool retval; - return eval->Invalid("no validation yet"); - numvins = tx.vin.size(); - numvouts = tx.vout.size(); - preventCCvins = preventCCvouts = -1; - if ( numvouts < 1 ) - return eval->Invalid("no vouts"); - else - { - //fprintf(stderr,"check vins\n"); - for (i=0; iInvalid("illegal normal vini"); - } - } - //fprintf(stderr,"check amounts\n"); - if ( AuctionExactAmounts(cp,eval,tx,1,10000) == false ) - { - fprintf(stderr,"Auctionget invalid amount\n"); - return false; - } - else - { - preventCCvouts = 1; - if ( IsAuctionvout(cp,tx,0) != 0 ) - { - preventCCvouts++; - i = 1; - } else i = 0; - if ( tx.vout[i].nValue != COIN ) - return eval->Invalid("invalid Auction output"); - retval = PreventCC(eval,tx,preventCCvins,numvins,preventCCvouts,numvouts); - if ( retval != 0 ) - fprintf(stderr,"Auctionget validated\n"); - else fprintf(stderr,"Auctionget invalid\n"); - return(retval); - } - } -} -// end of consensus code - -// helper functions for rpc calls in rpcwallet.cpp - -int64_t AddAuctionInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,int64_t total,int32_t maxinputs) -{ - // add threshold check - char coinaddr[64]; int64_t nValue,price,totalinputs = 0; uint256 txid,hashBlock; std::vector origpubkey; CTransaction vintx; int32_t n = 0; - std::vector > unspentOutputs; - GetCCaddress(cp,coinaddr,pk); - SetCCunspents(unspentOutputs,coinaddr,true); - for (std::vector >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++) - { - txid = it->first.txhash; - // prevent dup - if ( it->second.satoshis < 1000000 ) - continue; - if ( myGetTransaction(txid,vintx,hashBlock) != 0 ) - { - if ( (nValue= IsAuctionvout(cp,vintx,(int32_t)it->first.index)) > 0 ) - { - if ( total != 0 && maxinputs != 0 ) - mtx.vin.push_back(CTxIn(txid,(int32_t)it->first.index,CScript())); - nValue = it->second.satoshis; - totalinputs += nValue; - n++; - if ( (total > 0 && totalinputs >= total) || (maxinputs > 0 && n >= maxinputs) ) - break; - } - } - } - return(totalinputs); -} - -std::string AuctionBid(uint64_t txfee,uint256 itemhash,int64_t amount) -{ - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), hush_nextheight()); - CPubKey mypk,Auctionpk; CScript opret; int64_t inputs,CCchange=0,nValue=COIN; struct CCcontract_info *cp,C; - cp = CCinit(&C,EVAL_AUCTION); - if ( txfee == 0 ) - txfee = 10000; - Auctionpk = GetUnspendable(cp,0); - mypk = pubkey2pk(Mypubkey()); - if ( (inputs= AddAuctionInputs(cp,mtx,Auctionpk,nValue+txfee,60)) > 0 ) - { - if ( inputs > nValue ) - CCchange = (inputs - nValue - txfee); - if ( CCchange != 0 ) - mtx.vout.push_back(MakeCC1vout(EVAL_AUCTION,CCchange,Auctionpk)); - mtx.vout.push_back(CTxOut(nValue,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG)); - return(FinalizeCCTx(-1LL,cp,mtx,mypk,txfee,opret)); - } else fprintf(stderr,"cant find Auction inputs\n"); - return(""); -} - -std::string AuctionDeliver(uint64_t txfee,uint256 itemhash,uint256 bidtxid) -{ - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), hush_nextheight()); - CPubKey mypk,Auctionpk; CScript opret; int64_t inputs,CCchange=0,nValue=COIN; struct CCcontract_info *cp,C; - cp = CCinit(&C,EVAL_AUCTION); - if ( txfee == 0 ) - txfee = 10000; - Auctionpk = GetUnspendable(cp,0); - mypk = pubkey2pk(Mypubkey()); - if ( (inputs= AddAuctionInputs(cp,mtx,Auctionpk,nValue+txfee,60)) > 0 ) - { - if ( inputs > nValue ) - CCchange = (inputs - nValue - txfee); - if ( CCchange != 0 ) - mtx.vout.push_back(MakeCC1vout(EVAL_AUCTION,CCchange,Auctionpk)); - mtx.vout.push_back(CTxOut(nValue,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG)); - return(FinalizeCCTx(-1LL,cp,mtx,mypk,txfee,opret)); - } else fprintf(stderr,"cant find Auction inputs\n"); - return(""); -} - -std::string AuctionPost(uint64_t txfee,uint256 itemhash,int64_t minbid,char *title,char *description) -{ - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), hush_nextheight()); - CPubKey mypk,Auctionpk; int64_t funds = 0; CScript opret; struct CCcontract_info *cp,C; - cp = CCinit(&C,EVAL_AUCTION); - if ( txfee == 0 ) - txfee = 10000; - mypk = pubkey2pk(Mypubkey()); - Auctionpk = GetUnspendable(cp,0); - if ( AddNormalinputs(mtx,mypk,txfee,64) > 0 ) - { - mtx.vout.push_back(MakeCC1vout(EVAL_AUCTION,funds,Auctionpk)); - return(FinalizeCCTx(0,cp,mtx,mypk,txfee,opret)); - } - return(""); -} - - diff --git a/src/cc/betprotocol.cpp b/src/cc/betprotocol.cpp deleted file mode 100644 index fc6b98dc3..000000000 --- a/src/cc/betprotocol.cpp +++ /dev/null @@ -1,305 +0,0 @@ -// Copyright (c) 2016-2023 The Hush developers -// Distributed under the GPLv3 software license, see the accompanying -// file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html -/****************************************************************************** - * Copyright © 2014-2019 The SuperNET Developers. * - * * - * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * - * the top-level directory of this distribution for the individual copyright * - * holder information and the developer policies on copyright and licensing. * - * * - * Unless otherwise agreed in a custom licensing agreement, no part of the * - * SuperNET software, including this file may be copied, modified, propagated * - * or distributed except according to the terms contained in the LICENSE file * - * * - * Removal or modification of this copyright notice is prohibited. * - * * - ******************************************************************************/ - -#include - -#include "hash.h" -#include "main.h" -#include "chain.h" -#include "streams.h" -#include "script/cc.h" -#include "cc/betprotocol.h" -#include "cc/eval.h" -#include "cc/utils.h" -#include "primitives/transaction.h" - -int32_t hush_nextheight(); - -std::vector BetProtocol::PlayerConditions() -{ - std::vector subs; - for (int i=0; i result(vmResultHash.begin(), vmResultHash.begin()+32); - mtx.vout.push_back(CTxOut(0, CScript() << OP_RETURN << result)); - return mtx; -} - - -CMutableTransaction BetProtocol::MakePostEvidenceTx(uint256 signedSessionTxHash, - int playerIdx, std::vector state) -{ - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), hush_nextheight()); - - mtx.vin.push_back(CTxIn(signedSessionTxHash, playerIdx+1, CScript())); - mtx.vout.push_back(CTxOut(0, CScript() << OP_RETURN << state)); - - return mtx; -} - - -CC* BetProtocol::MakePayoutCond(uint256 signedSessionTxHash) -{ - // TODO: 2/3 majority - CC* agree = CCNewThreshold(players.size(), PlayerConditions()); - - CC *import; - { - CC *importEval = CCNewEval(E_MARSHAL( - ss << EVAL_IMPORTPAYOUT << signedSessionTxHash; - )); - - CC *oneof = CCNewThreshold(1, PlayerConditions()); - - import = CCNewThreshold(2, {oneof, importEval}); - } - - return CCNewThreshold(1, {agree, import}); -} - - -CMutableTransaction BetProtocol::MakeStakeTx(CAmount totalPayout, uint256 signedSessionTxHash) -{ - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), hush_nextheight()); - - CC *payoutCond = MakePayoutCond(signedSessionTxHash); - mtx.vout.push_back(CTxOut(totalPayout, CCPubKey(payoutCond))); - cc_free(payoutCond); - - return mtx; -} - - -CMutableTransaction BetProtocol::MakeAgreePayoutTx(std::vector payouts, - uint256 signedStakeTxHash) -{ - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), hush_nextheight()); - mtx.vin.push_back(CTxIn(signedStakeTxHash, 0, CScript())); - mtx.vout = payouts; - return mtx; -} - - -CMutableTransaction BetProtocol::MakeImportPayoutTx(std::vector payouts, - CTransaction signedDisputeTx, uint256 signedStakeTxHash, MoMProof momProof) -{ - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), hush_nextheight()); - mtx.vin.push_back(CTxIn(signedStakeTxHash, 0, CScript())); - mtx.vout = payouts; - CScript proofData; - proofData << OP_RETURN << E_MARSHAL(ss << momProof << signedDisputeTx); - mtx.vout.insert(mtx.vout.begin(), CTxOut(0, proofData)); - return mtx; -} - - -bool GetOpReturnHash(CScript script, uint256 &hash) -{ - std::vector vHash; - GetOpReturnData(script, vHash); - if (vHash.size() != 32) return false; - hash = uint256(vHash); - return true; -} - - -/* - * Crypto-Condition EVAL method that verifies a payout against a transaction - * notarized on another chain. - * - * IN: params - condition params - * IN: importTx - Payout transaction on value chain (HUSH) - * IN: nIn - index of input of stake - * - * importTx: Spends stakeTx with payouts from asset chain - * - * in 0: Spends Stake TX and contains ImportPayout CC - * out 0: OP_RETURN MomProof, disputeTx - * out 1-: arbitrary payouts - * - * disputeTx: Spends sessionTx.0 (opener on asset chain) - * - * in 0: spends sessionTx.0 - * in 1-: anything - * out 0: OP_RETURN hash of payouts - * out 1-: anything - */ -bool Eval::ImportPayout(const std::vector params, const CTransaction &importTx, unsigned int nIn) -{ - if (importTx.vout.size() == 0) return Invalid("no-vouts"); - - // load data from vout[0] - MoMProof proof; - CTransaction disputeTx; - { - std::vector vopret; - GetOpReturnData(importTx.vout[0].scriptPubKey, vopret); - if (!E_UNMARSHAL(vopret, ss >> proof; ss >> disputeTx)) - return Invalid("invalid-payload"); - } - - // Check disputeTx.0 shows correct payouts - { - uint256 givenPayoutsHash; - GetOpReturnHash(disputeTx.vout[0].scriptPubKey, givenPayoutsHash); - std::vector payouts(importTx.vout.begin() + 1, importTx.vout.end()); - if (givenPayoutsHash != SerializeHash(payouts)) - return Invalid("wrong-payouts"); - } - - // Check disputeTx spends sessionTx.0 - // condition ImportPayout params is session ID from other chain - { - uint256 sessionHash; - if (!E_UNMARSHAL(params, ss >> sessionHash)) - return Invalid("malformed-params"); - if (disputeTx.vin[0].prevout != COutPoint(sessionHash, 0)) - return Invalid("wrong-session"); - } - - // Check disputeTx solves momproof from vout[0] - { - NotarizationData data(0); - if (!GetNotarizationData(proof.notarizationHash, data)) - return Invalid("coudnt-load-mom"); - - if (data.MoM != proof.branch.Exec(disputeTx.GetHash())) - return Invalid("mom-check-fail"); - } - - return Valid(); -} - - -/* - * Crypto-Condition EVAL method that resolves a dispute of a session - * - * IN: vm - AppVM virtual machine to verify states - * IN: params - condition params - * IN: disputeTx - transaction attempting to resolve dispute - * IN: nIn - index of input of dispute tx - * - * disputeTx: attempt to resolve a dispute - * - * in 0: Spends Session TX first output, reveals DisputeHeader - * out 0: OP_RETURN hash of payouts - */ -bool Eval::DisputePayout(AppVM &vm, std::vector params, const CTransaction &disputeTx, unsigned int nIn) -{ - if (disputeTx.vout.size() == 0) return Invalid("no-vouts"); - - // get payouts hash - uint256 payoutHash; - if (!GetOpReturnHash(disputeTx.vout[0].scriptPubKey, payoutHash)) - return Invalid("invalid-payout-hash"); - - // load params - uint16_t waitBlocks; - std::vector vmParams; - if (!E_UNMARSHAL(params, ss >> VARINT(waitBlocks); ss >> vmParams)) - return Invalid("malformed-params"); - - // ensure that enough time has passed - { - CTransaction sessionTx; - CBlockIndex sessionBlock; - - // if unconformed its too soon - if (!GetTxConfirmed(disputeTx.vin[0].prevout.hash, sessionTx, sessionBlock)) - return Error("couldnt-get-parent"); - - if (GetCurrentHeight() < sessionBlock.GetHeight() + waitBlocks) - return Invalid("dispute-too-soon"); // Not yet - } - - // get spends - std::vector spends; - if (!GetSpendsConfirmed(disputeTx.vin[0].prevout.hash, spends)) - return Error("couldnt-get-spends"); - - // verify result from VM - int maxLength = -1; - uint256 bestPayout; - for (int i=1; i vmState; - if (spends[i].vout.size() == 0) continue; - if (!GetOpReturnData(spends[i].vout[0].scriptPubKey, vmState)) continue; - auto out = vm.evaluate(vmParams, vmState); - uint256 resultHash = SerializeHash(out.second); - if (out.first > maxLength) { - maxLength = out.first; - bestPayout = resultHash; - } - // The below means that if for any reason there is a draw, the first dispute wins - else if (out.first == maxLength) { - if (bestPayout != payoutHash) { - fprintf(stderr, "WARNING: VM has multiple solutions of same length\n"); - bestPayout = resultHash; - } - } - } - - if (maxLength == -1) return Invalid("no-evidence"); - - return bestPayout == payoutHash ? Valid() : Invalid("wrong-payout"); -} diff --git a/src/cc/faucet.cpp b/src/cc/faucet.cpp deleted file mode 100644 index 8142fc472..000000000 --- a/src/cc/faucet.cpp +++ /dev/null @@ -1,253 +0,0 @@ -// Copyright (c) 2016-2023 The Hush developers -// Distributed under the GPLv3 software license, see the accompanying -// file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html -/****************************************************************************** - * Copyright © 2014-2019 The SuperNET Developers. * - * * - * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * - * the top-level directory of this distribution for the individual copyright * - * holder information and the developer policies on copyright and licensing. * - * * - * Unless otherwise agreed in a custom licensing agreement, no part of the * - * SuperNET software, including this file may be copied, modified, propagated * - * or distributed except according to the terms contained in the LICENSE file * - * * - * Removal or modification of this copyright notice is prohibited. * - * * - ******************************************************************************/ - -#include "CCfaucet.h" -#include "../txmempool.h" - -/* - This file implements a simple CC faucet as an example of how to make a new CC contract. It wont have any fancy sybil protection but will serve the purpose of a fully automated faucet. - - In order to implement a faucet, we need to have it funded. Once it is funded, anybody should be able to get some reasonable small amount. - - This leads to needing to lock the funding in a CC protected output. And to put a spending limit. We can do a per transaction spending limit quite easily with vout constraints. However, that would allow anybody to issue thousands of transactions per block, so we also need to add a rate limiter. - - To implement this, we can simply make any faucet vout fund the faucet. Then we can limit the number of confirmed utxo by combining faucet outputs and then only using utxo which are confirmed. This combined with a vout size limit will drastically limit the funds that can be withdrawn from the faucet. -*/ - -// start of consensus code - -int64_t IsFaucetvout(struct CCcontract_info *cp,const CTransaction& tx,int32_t v) -{ - char destaddr[64]; - if ( tx.vout[v].scriptPubKey.IsPayToCryptoCondition() != 0 ) - { - if ( Getscriptaddress(destaddr,tx.vout[v].scriptPubKey) > 0 && strcmp(destaddr,cp->unspendableCCaddr) == 0 ) - return(tx.vout[v].nValue); - //else fprintf(stderr,"dest.%s vs (%s)\n",destaddr,cp->unspendableCCaddr); - } - return(0); -} - -bool FaucetExactAmounts(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx,int32_t minage,uint64_t txfee) -{ - static uint256 zerohash; - CTransaction vinTx; uint256 hashBlock,activehash; int32_t i,numvins,numvouts; int64_t inputs=0,outputs=0,assetoshis; - numvins = tx.vin.size(); - numvouts = tx.vout.size(); - for (i=0; iismyvin)(tx.vin[i].scriptSig) != 0 ) - { - //fprintf(stderr,"vini.%d check mempool\n",i); - if ( eval->GetTxUnconfirmed(tx.vin[i].prevout.hash,vinTx,hashBlock) == 0 ) - return eval->Invalid("cant find vinTx"); - else - { - //fprintf(stderr,"vini.%d check hash and vout\n",i); - if ( hashBlock == zerohash ) - return eval->Invalid("cant faucet from mempool"); - if ( (assetoshis= IsFaucetvout(cp,vinTx,tx.vin[i].prevout.n)) != 0 ) - inputs += assetoshis; - } - } - } - for (i=0; iInvalid("mismatched inputs != outputs + FAUCETSIZE + txfee"); - } - else return(true); -} - -bool FaucetValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn) -{ - int32_t numvins,numvouts,preventCCvins,preventCCvouts,i,numblocks; bool retval; uint256 txid; uint8_t hash[32]; char str[65],destaddr[64]; - std::vector > txids; - numvins = tx.vin.size(); - numvouts = tx.vout.size(); - preventCCvins = preventCCvouts = -1; - if ( numvouts < 1 ) - return eval->Invalid("no vouts"); - else - { - for (i=0; iInvalid("illegal normal vini"); - } - } - //fprintf(stderr,"check amounts\n"); - if ( FaucetExactAmounts(cp,eval,tx,1,10000) == false ) - { - fprintf(stderr,"faucetget invalid amount\n"); - return false; - } - else - { - preventCCvouts = 1; - if ( IsFaucetvout(cp,tx,0) != 0 ) - { - preventCCvouts++; - i = 1; - } else i = 0; - txid = tx.GetHash(); - memcpy(hash,&txid,sizeof(hash)); - fprintf(stderr,"check faucetget txid %s %02x/%02x\n",uint256_str(str,txid),hash[0],hash[31]); - if ( tx.vout[i].nValue != FAUCETSIZE ) - return eval->Invalid("invalid faucet output"); - else if ( (hash[0] & 0xff) != 0 || (hash[31] & 0xff) != 0 ) - return eval->Invalid("invalid faucetget txid"); - Getscriptaddress(destaddr,tx.vout[i].scriptPubKey); - SetCCtxids(txids,destaddr,tx.vout[i].scriptPubKey.IsPayToCryptoCondition()); - for (std::vector >::const_iterator it=txids.begin(); it!=txids.end(); it++) - { - //int height = it->first.blockHeight; - if ( CCduration(numblocks,it->first.txhash) > 0 && numblocks > 3 ) - { - return eval->Invalid("faucet is only for brand new addresses"); - } - //fprintf(stderr,"txid %s numblocks.%d ago\n",uint256_str(str,it->first.txhash),numblocks); - } - retval = PreventCC(eval,tx,preventCCvins,numvins,preventCCvouts,numvouts); - if ( retval != 0 ) - fprintf(stderr,"faucetget validated\n"); - else fprintf(stderr,"faucetget invalid\n"); - return(retval); - } - } -} -// end of consensus code - -// helper functions for rpc calls in rpcwallet.cpp - -int64_t AddFaucetInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,int64_t total,int32_t maxinputs) -{ - 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; - GetCCaddress(cp,coinaddr,pk); - SetCCunspents(unspentOutputs,coinaddr,true); - if ( maxinputs > CC_MAXVINS ) - maxinputs = CC_MAXVINS; - if ( maxinputs > 0 ) - threshold = total/maxinputs; - else threshold = total; - for (std::vector >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++) - { - txid = it->first.txhash; - vout = (int32_t)it->first.index; - 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 ( myGetTransaction(txid,vintx,hashBlock) != 0 ) - { - if ( (nValue= IsFaucetvout(cp,vintx,vout)) > 1000000 && myIsutxo_spentinmempool(ignoretxid,ignorevin,txid,vout) == 0 ) - { - if ( total != 0 && maxinputs != 0 ) - mtx.vin.push_back(CTxIn(txid,vout,CScript())); - nValue = it->second.satoshis; - totalinputs += nValue; - n++; - if ( (total > 0 && totalinputs >= total) || (maxinputs > 0 && n >= maxinputs) ) - break; - } else fprintf(stderr,"vout.%d nValue %.8f too small or already spent in mempool\n",vout,(double)nValue/COIN); - } else fprintf(stderr,"couldn't get tx\n"); - } - return(totalinputs); -} - -UniValue FaucetGet(const CPubKey& pk, uint64_t txfee) -{ - CMutableTransaction tmpmtx,mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), hush_nextheight()); - CPubKey faucetpk; int64_t inputs,CCchange=0,nValue=FAUCETSIZE; struct CCcontract_info *cp,C; std::string rawhex; uint32_t j; int32_t i,len; uint8_t buf[32768]; bits256 hash; - cp = CCinit(&C,EVAL_FAUCET); - if ( txfee == 0 ) - txfee = 10000; - faucetpk = GetUnspendable(cp,0); - CPubKey mypk = pk.IsValid()?pk:pubkey2pk(Mypubkey()); - if ( (inputs= AddFaucetInputs(cp,mtx,faucetpk,nValue+txfee,60)) > 0 ) - { - if ( inputs > nValue ) - CCchange = (inputs - nValue - txfee); - if ( CCchange != 0 ) - mtx.vout.push_back(MakeCC1vout(EVAL_FAUCET,CCchange,faucetpk)); - mtx.vout.push_back(CTxOut(nValue,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG)); - fprintf(stderr,"start at %u\n",(uint32_t)time(NULL)); - j = rand() & 0xfffffff; - for (i=0; i<1000000; i++,j++) - { - tmpmtx = mtx; - UniValue result = FinalizeCCTxExt(pk.IsValid (),-1LL,cp,tmpmtx,mypk,txfee,CScript() << OP_RETURN << E_MARSHAL(ss << (uint8_t)EVAL_FAUCET << (uint8_t)'G' << j)); - if ( (len= (int32_t)result[JSON_HEXTX].getValStr().size()) > 0 && len < 65536 ) - { - len >>= 1; - decode_hex(buf,len,(char *)result[JSON_HEXTX].getValStr().c_str()); - hash = bits256_doublesha256(0,buf,len); - if ( (hash.bytes[0] & 0xff) == 0 && (hash.bytes[31] & 0xff) == 0 ) - { - fprintf(stderr,"found valid txid after %d iterations %u\n",i,(uint32_t)time(NULL)); - return result; - } - //fprintf(stderr,"%02x%02x ",hash.bytes[0],hash.bytes[31]); - } - } - CCERR_RESULT("faucet",CCLOG_ERROR, stream << "couldn't generate valid txid " << (uint32_t)time(NULL)); - } else CCERR_RESULT("faucet",CCLOG_ERROR, stream << "can't find faucet inputs"); -} - -UniValue FaucetFund(const CPubKey& pk, uint64_t txfee,int64_t funds) -{ - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), hush_nextheight()); - CPubKey faucetpk; CScript opret; struct CCcontract_info *cp,C; - - cp = CCinit(&C,EVAL_FAUCET); - if ( txfee == 0 ) - txfee = 10000; - CPubKey mypk = pk.IsValid()?pk:pubkey2pk(Mypubkey()); - faucetpk = GetUnspendable(cp,0); - if ( AddNormalinputs(mtx,mypk,funds+txfee,64,pk.IsValid()) > 0 ) - { - mtx.vout.push_back(MakeCC1vout(EVAL_FAUCET,funds,faucetpk)); - return(FinalizeCCTxExt(pk.IsValid(),0,cp,mtx,mypk,txfee,opret)); - } - CCERR_RESULT("faucet",CCLOG_ERROR, stream << "can't find normal inputs"); -} - -UniValue FaucetInfo() -{ - UniValue result(UniValue::VOBJ); char numstr[64]; - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), hush_nextheight()); - CPubKey faucetpk; struct CCcontract_info *cp,C; int64_t funding; - result.push_back(Pair("result","success")); - result.push_back(Pair("name","Faucet")); - cp = CCinit(&C,EVAL_FAUCET); - faucetpk = GetUnspendable(cp,0); - funding = AddFaucetInputs(cp,mtx,faucetpk,0,0); - sprintf(numstr,"%.8f",(double)funding/COIN); - result.push_back(Pair("funding",numstr)); - return(result); -} diff --git a/src/cc/fsm.cpp b/src/cc/fsm.cpp deleted file mode 100644 index d2998a388..000000000 --- a/src/cc/fsm.cpp +++ /dev/null @@ -1,192 +0,0 @@ -// Copyright (c) 2016-2023 The Hush developers -// Distributed under the GPLv3 software license, see the accompanying -// file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html -/****************************************************************************** - * Copyright © 2014-2019 The SuperNET Developers. * - * * - * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * - * the top-level directory of this distribution for the individual copyright * - * holder information and the developer policies on copyright and licensing. * - * * - * Unless otherwise agreed in a custom licensing agreement, no part of the * - * SuperNET software, including this file may be copied, modified, propagated * - * or distributed except according to the terms contained in the LICENSE file * - * * - * Removal or modification of this copyright notice is prohibited. * - * * - ******************************************************************************/ - -#include "CCfsm.h" -#include "../txmempool.h" - -/* - FSM CC is a highlevel CC contract that mostly uses other CC contracts. A finite state machine is defined, which combines triggers, payments and whatever other events/actions into a state machine - -*/ - -// start of consensus code - -int64_t IsFSMvout(struct CCcontract_info *cp,const CTransaction& tx,int32_t v) -{ - char destaddr[64]; - if ( tx.vout[v].scriptPubKey.IsPayToCryptoCondition() != 0 ) - { - if ( Getscriptaddress(destaddr,tx.vout[v].scriptPubKey) > 0 && strcmp(destaddr,cp->unspendableCCaddr) == 0 ) - return(tx.vout[v].nValue); - } - return(0); -} - -bool FSMExactAmounts(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx,int32_t minage,uint64_t txfee) -{ - static uint256 zerohash; - CTransaction vinTx; uint256 hashBlock,activehash; int32_t i,numvins,numvouts; int64_t inputs=0,outputs=0,assetoshis; - numvins = tx.vin.size(); - numvouts = tx.vout.size(); - for (i=0; iismyvin)(tx.vin[i].scriptSig) != 0 ) - { - //fprintf(stderr,"vini.%d check mempool\n",i); - if ( eval->GetTxUnconfirmed(tx.vin[i].prevout.hash,vinTx,hashBlock) == 0 ) - return eval->Invalid("cant find vinTx"); - else - { - //fprintf(stderr,"vini.%d check hash and vout\n",i); - if ( hashBlock == zerohash ) - return eval->Invalid("cant FSM from mempool"); - if ( (assetoshis= IsFSMvout(cp,vinTx,tx.vin[i].prevout.n)) != 0 ) - inputs += assetoshis; - } - } - } - for (i=0; iInvalid("mismatched inputs != outputs + COIN + txfee"); - } - else return(true); -} - -bool FSMValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn) -{ - int32_t numvins,numvouts,preventCCvins,preventCCvouts,i; bool retval; - return eval->Invalid("no validation yet"); - numvins = tx.vin.size(); - numvouts = tx.vout.size(); - preventCCvins = preventCCvouts = -1; - if ( numvouts < 1 ) - return eval->Invalid("no vouts"); - else - { - //fprintf(stderr,"check vins\n"); - for (i=0; iInvalid("illegal normal vini"); - } - } - //fprintf(stderr,"check amounts\n"); - if ( FSMExactAmounts(cp,eval,tx,1,10000) == false ) - { - fprintf(stderr,"fsmget invalid amount\n"); - return false; - } - else - { - preventCCvouts = 1; - if ( IsFSMvout(cp,tx,0) != 0 ) - { - preventCCvouts++; - i = 1; - } else i = 0; - if ( tx.vout[i].nValue != COIN ) - return eval->Invalid("invalid fsm output"); - retval = PreventCC(eval,tx,preventCCvins,numvins,preventCCvouts,numvouts); - if ( retval != 0 ) - fprintf(stderr,"fsmget validated\n"); - else fprintf(stderr,"fsmget invalid\n"); - return(retval); - } - } -} -// end of consensus code - -// helper functions for rpc calls in rpcwallet.cpp - -int64_t AddFSMInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,int64_t total,int32_t maxinputs) -{ - // add threshold check - char coinaddr[64]; int64_t nValue,price,totalinputs = 0; uint256 txid,hashBlock; std::vector origpubkey; CTransaction vintx; int32_t n = 0; - std::vector > unspentOutputs; - GetCCaddress(cp,coinaddr,pk); - SetCCunspents(unspentOutputs,coinaddr,true); - for (std::vector >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++) - { - txid = it->first.txhash; - // prevent dup - if ( it->second.satoshis < 1000000 ) - continue; - if ( myGetTransaction(txid,vintx,hashBlock) != 0 ) - { - if ( (nValue= IsFSMvout(cp,vintx,(int32_t)it->first.index)) > 0 ) - { - if ( total != 0 && maxinputs != 0 ) - mtx.vin.push_back(CTxIn(txid,(int32_t)it->first.index,CScript())); - nValue = it->second.satoshis; - totalinputs += nValue; - n++; - if ( (total > 0 && totalinputs >= total) || (maxinputs > 0 && n >= maxinputs) ) - break; - } - } - } - return(totalinputs); -} - -std::string FSMList() -{ - return(""); -} - -std::string FSMCreate(uint64_t txfee,std::string name,std::string states) -{ - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), hush_nextheight()); - CPubKey mypk,fsmpk; CScript opret; int64_t inputs,CCchange=0,nValue=COIN; struct CCcontract_info *cp,C; - cp = CCinit(&C,EVAL_FSM); - if ( txfee == 0 ) - txfee = 10000; - fsmpk = GetUnspendable(cp,0); - mypk = pubkey2pk(Mypubkey()); - if ( (inputs= AddFSMInputs(cp,mtx,fsmpk,nValue+txfee,60)) > 0 ) - { - if ( inputs > nValue ) - CCchange = (inputs - nValue - txfee); - if ( CCchange != 0 ) - mtx.vout.push_back(MakeCC1vout(EVAL_FSM,CCchange,fsmpk)); - mtx.vout.push_back(CTxOut(nValue,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG)); - return(FinalizeCCTx(-1LL,cp,mtx,mypk,txfee,opret)); - } else fprintf(stderr,"cant find fsm inputs\n"); - return(""); -} - -std::string FSMInfo(uint256 fsmtxid) -{ - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), hush_nextheight()); - CPubKey mypk,fsmpk; int64_t funds = 0; CScript opret; struct CCcontract_info *cp,C; - cp = CCinit(&C,EVAL_FSM); - mypk = pubkey2pk(Mypubkey()); - fsmpk = GetUnspendable(cp,0); - return(""); -} - - diff --git a/src/cc/heir.cpp b/src/cc/heir.cpp deleted file mode 100644 index 859d28656..000000000 --- a/src/cc/heir.cpp +++ /dev/null @@ -1,1293 +0,0 @@ -// Copyright (c) 2016-2023 The Hush developers -// Distributed under the GPLv3 software license, see the accompanying -// file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html -/****************************************************************************** - * Copyright © 2014-2019 The SuperNET Developers. * - * * - * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * - * the top-level directory of this distribution for the individual copyright * - * holder information and the developer policies on copyright and licensing. * - * * - * Unless otherwise agreed in a custom licensing agreement, no part of the * - * SuperNET software, including this file may be copied, modified, propagated * - * or distributed except according to the terms contained in the LICENSE file * - * * - * Removal or modification of this copyright notice is prohibited. * - * * - ******************************************************************************/ - -#include "CCHeir.h" -#include "heir_validate.h" -#include - -class CoinHelper; -class TokenHelper; - -/* - The idea of Heir CC is to allow crypto inheritance. - A special 1of2 CC address is created that is freely spendable by the creator (funds owner). - The owner may add additional funds to this 1of2 address. - The heir is only allowed to spend after "the specified amount of idle blocks" (changed to "the owner inactivityTime"). - The idea is that if the address doesnt spend any funds for a year (or whatever amount set), then it is time to allow the heir to spend. - "The design requires the heir to spend all the funds at once" (this requirement was changed to "after the inactivity time both the heir and owner may freely spend available funds") - After the first heir spending a flag is set that spending is allowed for the heir whether the owner adds more funds or spends them. - This Heir contract supports both coins and tokens. - */ - -// tx validation code - -// Plan validation runner, it may be called twice - for coins and tokens -// (sadly we cannot have yet 'templatized' lambdas, if we could we could capture all these params inside HeirValidation()...) -template bool RunValidationPlans(uint8_t funcId, struct CCcontract_info* cp, Eval* eval, const CTransaction& tx, uint256 latestTxid, CScript fundingOpretScript, uint8_t hasHeirSpendingBegun) -{ - int32_t numvins = tx.vin.size(); - int32_t numvouts = tx.vout.size(); - - // setup validation framework (please see its description in heir_validate.h): - // validation 'plans': - CInputValidationPlan vinPlan; - COutputValidationPlan voutPlan; - - // vin 'identifiers' - CNormalInputIdentifier normalInputIdentifier(cp); - CCCInputIdentifier ccInputIdentifier(cp); - - // vin and vout 'validators' - // not used, too strict for 2 pubkeys: CMyPubkeyVoutValidator normalInputValidator(cp, fundingOpretScript, true); // check normal input for this opret cause this is first tx - CCC1of2AddressValidator cc1of2ValidatorThis(cp, fundingOpretScript, "checking this tx opreturn:"); // 1of2add validator with pubkeys from this tx opreturn - CHeirSpendValidator heirSpendValidator(cp, fundingOpretScript, latestTxid, hasHeirSpendingBegun); // check if heir allowed to spend - - // only for tokens: - CMyPubkeyVoutValidator ownerCCaddrValidator(cp, fundingOpretScript, false); // check if this correct owner's cc user addr corresponding to opret - COpRetValidator opRetValidator(cp, fundingOpretScript); // compare opRets in this and last tx - CMarkerValidator markerValidator(cp); // initial tx marker spending protection - CNullValidator nullValidator(cp); - - switch (funcId) { - case 'F': // fund tokens (only for tokens) - // vin validation plan: - vinPlan.pushValidators((CInputIdentifierBase*)&normalInputIdentifier, &nullValidator); // txfee vin - vinPlan.pushValidators((CInputIdentifierBase*)&ccInputIdentifier, &markerValidator, &ownerCCaddrValidator); // check cc owner addr - - // vout validation plan: - voutPlan.pushValidators(0, &cc1of2ValidatorThis); // check 1of2 addr funding - // do not check change at this time - // no checking for opret yet - break; - - case 'A': // add tokens (only for tokens) - // vin validation plan: - vinPlan.pushValidators((CInputIdentifierBase*)&normalInputIdentifier, &nullValidator); // txfee vin - vinPlan.pushValidators((CInputIdentifierBase*)&ccInputIdentifier, &markerValidator, &ownerCCaddrValidator); // check cc owner addr - - // vout validation plan: - voutPlan.pushValidators(0, &cc1of2ValidatorThis); // check 1of2 addr funding - // do not check change at this time - voutPlan.pushValidators(numvouts - 1, &opRetValidator); // opreturn check, NOTE: only for C or A: - break; - - case 'C': // spend coins or tokens - // vin validation plan: - vinPlan.pushValidators((CInputIdentifierBase*)&normalInputIdentifier, &nullValidator); // txfee vin - vinPlan.pushValidators((CInputIdentifierBase*)&ccInputIdentifier, &markerValidator, &cc1of2ValidatorThis); // cc1of2 funding addr - - // vout validation plan: - voutPlan.pushValidators(0, &heirSpendValidator); // check if heir is allowed to spend - voutPlan.pushValidators(numvouts - 1, &opRetValidator); // opreturn check, NOTE: only for C or A - break; - } - - // call vin/vout validation - if (!vinPlan.validate(tx, eval)) - return false; - if (!voutPlan.validate(tx, eval)) - return false; - - return true; -} - -/** - * Tx validation entry function - */ -bool HeirValidate(struct CCcontract_info* cpHeir, Eval* eval, const CTransaction& tx, uint32_t nIn) -{ - int32_t numvins = tx.vin.size(); - int32_t numvouts = tx.vout.size(); - //int32_t preventCCvins = -1; - //int32_t preventCCvouts = -1; - - struct CCcontract_info *cpTokens, tokensC; - cpTokens = CCinit(&tokensC, EVAL_TOKENS); - - if (numvouts < 1) - return eval->Invalid("no vouts"); - - //if (chainActive.Height() < 741) - // return true; - - uint256 fundingTxidInOpret = zeroid, latestTxid = zeroid, dummyTokenid, tokenidThis, tokenid = zeroid; - - CScript fundingTxOpRetScript; - uint8_t hasHeirSpendingBegun = 0, hasHeirSpendingBegunDummy; - - CScript opret = (tx.vout.size() > 0) ? tx.vout[tx.vout.size() - 1].scriptPubKey : CScript(); // check boundary - uint8_t funcId = DecodeHeirEitherOpRet(opret, tokenidThis, fundingTxidInOpret, hasHeirSpendingBegunDummy, true); - if (funcId == 0) - return eval->Invalid("invalid opreturn format"); - - if (funcId != 'F') { - if (fundingTxidInOpret == zeroid) { - return eval->Invalid("incorrect tx opreturn: no fundingtxid present"); - } - latestTxid = FindLatestFundingTx(fundingTxidInOpret, tokenid, fundingTxOpRetScript, hasHeirSpendingBegun); - - if( tokenid != zeroid && tokenid != tokenidThis ) - return eval->Invalid("incorrect tx tokenid"); - - if (latestTxid == zeroid) { - return eval->Invalid("no fundingtx found"); - } - } - else { - fundingTxOpRetScript = opret; - } - - std::cerr << "HeirValidate funcid=" << (char)funcId << " evalcode=" << (int)cpHeir->evalcode << std::endl; - - //////////////// temp //////////////////////// - ///return true; - - switch (funcId) { - case 'F': - // fund coins: - // vins.*: normal inputs - // ----------------------------- - // vout.0: funding CC 1of2 addr for the owner and heir - // vout.1: txfee for CC addr used as a marker - // vout.2: normal change - // vout.n-1: opreturn 'F' ownerpk heirpk inactivitytime heirname - - // fund tokens: - // vin.0: normal inputs txfee - // vins.1+: user's CC addr inputs - // ----------------------- - // vout.0: funding heir CC 1of2 addr for the owner and heir - // vout.1: txfee for CC addr used as a marker - // vout.2: normal change - // vout.n-1: opreturn 't' tokenid 'F' ownerpk heirpk inactivitytime heirname tokenid - if (tokenid != zeroid) - return RunValidationPlans(funcId, cpTokens, eval, tx, latestTxid, fundingTxOpRetScript, hasHeirSpendingBegun); - else - return eval->Invalid("unexpected HeirValidate for heirfund"); - // break; - - case 'A': - // add funding coins: - // vins.*: normal inputs - // ------------------------ - // vout.0: funding CC 1of2 addr for the owner and heir - // vout.1: normal change - // vout.n-1: opreturn 'A' ownerpk heirpk inactivitytime fundingtx - - // add funding tokens: - // vins.0: normal inputs txfee - // vins.1+: user's CC addr inputs - // ------------------------ - // vout.0: funding CC 1of2 addr for the owner and heir - // vout.1: normal change - // vout.n-1: opreturn 't' tokenid 'A' ownerpk heirpk inactivitytime fundingtx - if (tokenid != zeroid) - return RunValidationPlans(funcId, cpTokens, eval, tx, latestTxid, fundingTxOpRetScript, hasHeirSpendingBegun); - else - return eval->Invalid("unexpected HeirValidate for heiradd"); - //break; - - case 'C': - // claim coins: - // vin.0: normal input txfee - // vin.1+: input from CC 1of2 addr - // ------------------------------------- - // vout.0: normal output to owner or heir address - // vout.1: change to CC 1of2 addr - // vout.2: change to user's addr from txfee input if any - // vout.n-1: opreturn 'C' ownerpk heirpk inactivitytime fundingtx - - // claim tokens: - // vin.0: normal input txfee - // vin.1+: input from CC 1of2 addr - // -------------------------------------------- - // vout.0: output to user's cc address - // vout.1: change to CC 1of2 addr - // vout.2: change to normal from txfee input if any - // vout.n-1: opreturn 't' tokenid 'C' ownerpk heirpk inactivitytime fundingtx - if (tokenid != zeroid) - return RunValidationPlans(funcId, cpTokens, eval, tx, latestTxid, fundingTxOpRetScript, hasHeirSpendingBegun); - else - return RunValidationPlans(funcId, cpHeir, eval, tx, latestTxid, fundingTxOpRetScript, hasHeirSpendingBegun); - // break; - - default: - std::cerr << "HeirValidate() illegal heir funcid=" << (char)funcId << std::endl; - return eval->Invalid("unexpected HeirValidate funcid"); - // break; - } - return eval->Invalid("unexpected"); // (PreventCC(eval, tx, preventCCvins, numvins, preventCCvouts, numvouts)); -} -// end of consensus code - - -// helper functions used in implementations of rpc calls (in rpcwallet.cpp) or validation code - -/** - * Checks if vout is to cryptocondition address - * @return vout value in satoshis - */ -template int64_t IsHeirFundingVout(struct CCcontract_info* cp, const CTransaction& tx, int32_t voutIndex, CPubKey ownerPubkey, CPubKey heirPubkey) -{ - char destaddr[65], heirFundingAddr[65]; - - Helper::GetCoinsOrTokensCCaddress1of2(cp, heirFundingAddr, ownerPubkey, heirPubkey); - if (tx.vout[voutIndex].scriptPubKey.IsPayToCryptoCondition() != 0) { - // NOTE: dimxy it was unsafe 'Getscriptaddress(destaddr,tx.vout[voutIndex].scriptPubKey) > 0' here: - if (Getscriptaddress(destaddr, tx.vout[voutIndex].scriptPubKey) && strcmp(destaddr, heirFundingAddr) == 0) - return (tx.vout[voutIndex].nValue); - else - std::cerr << "IsHeirFundingVout() heirFundingAddr=" << heirFundingAddr << " not equal to destaddr=" << destaddr << std::endl; - } - return (0); -} - -// makes coin initial tx opret -vscript_t EncodeHeirCreateOpRet(uint8_t funcid, CPubKey ownerPubkey, CPubKey heirPubkey, int64_t inactivityTimeSec, std::string heirName, std::string memo) -{ - uint8_t evalcode = EVAL_HEIR; - - return /*CScript() << OP_RETURN <<*/ E_MARSHAL(ss << evalcode << funcid << ownerPubkey << heirPubkey << inactivityTimeSec << heirName << memo); -} - -// makes coin additional tx opret -vscript_t EncodeHeirOpRet(uint8_t funcid, uint256 fundingtxid, uint8_t hasHeirSpendingBegun) -{ - uint8_t evalcode = EVAL_HEIR; - - fundingtxid = revuint256(fundingtxid); - return /*CScript() << OP_RETURN <<*/ E_MARSHAL(ss << evalcode << funcid << fundingtxid << hasHeirSpendingBegun); -} - - -// decode opret vout for Heir contract -uint8_t _DecodeHeirOpRet(vscript_t vopret, CPubKey& ownerPubkey, CPubKey& heirPubkey, int64_t& inactivityTime, std::string& heirName, std::string& memo, uint256& fundingTxidInOpret, uint8_t &hasHeirSpendingBegun, bool noLogging) -{ - uint8_t evalCodeInOpret = 0; - uint8_t heirFuncId = 0; - - fundingTxidInOpret = zeroid; //to init - - evalCodeInOpret = vopret.begin()[0]; - - if (vopret.size() > 1 && evalCodeInOpret == EVAL_HEIR) { - // NOTE: it unmarshals for all F, A and C - uint8_t heirFuncId = 0; - hasHeirSpendingBegun = 0; - - bool result = E_UNMARSHAL(vopret, { ss >> evalCodeInOpret; ss >> heirFuncId; - if (heirFuncId == 'F') { - ss >> ownerPubkey; ss >> heirPubkey; ss >> inactivityTime; ss >> heirName; ss >> memo; - } - else { - ss >> fundingTxidInOpret >> hasHeirSpendingBegun; - } - }); - - if (!result) { - if (!noLogging) std::cerr << "_DecodeHeirOpRet() could not unmarshal opret, evalCode=" << (int)evalCodeInOpret << std::endl; - return (uint8_t)0; - } - - /* std::cerr << "DecodeHeirOpRet()" - << " heirFuncId=" << (char)(heirFuncId ? heirFuncId : ' ') - << " ownerPubkey=" << HexStr(ownerPubkey) - << " heirPubkey=" << HexStr(heirPubkey) - << " heirName=" << heirName << " inactivityTime=" << inactivityTime - << " hasHeirSpendingBegun=" << (int)hasHeirSpendingBegun << std::endl; */ - - if (isMyFuncId(heirFuncId)) { - fundingTxidInOpret = revuint256(fundingTxidInOpret); - return heirFuncId; - } - else { - if(!noLogging) std::cerr << "_DecodeHeirOpRet() unexpected opret type, heirFuncId=" << (char)(heirFuncId ? heirFuncId : ' ') << std::endl; - } - } - else { - if (!noLogging) std::cerr << "_DecodeHeirOpRet() not a heir opret, vopretExtra.size() == 0 or not EVAL_HEIR evalcode=" << (int)evalCodeInOpret << std::endl; - } - return (uint8_t)0; -} - -// decode combined opret: -uint8_t _DecodeHeirEitherOpRet(CScript scriptPubKey, uint256 &tokenid, CPubKey& ownerPubkey, CPubKey& heirPubkey, int64_t& inactivityTime, std::string& heirName, std::string& memo, uint256& fundingTxidInOpret, uint8_t &hasHeirSpendingBegun, bool noLogging) -{ - uint8_t evalCodeTokens = 0; - std::vector voutPubkeysDummy; - std::vector> oprets; - vscript_t vopretExtra /*, vopretStripped*/; - - - if (DecodeTokenOpRet(scriptPubKey, evalCodeTokens, tokenid, voutPubkeysDummy, oprets) != 0 && GetOpretBlob(oprets, OPRETID_HEIRDATA, vopretExtra)) { - /* if (vopretExtra.size() > 1) { - // restore the second opret: - - /* unmarshalled in DecodeTokenOpRet: - if (!E_UNMARSHAL(vopretExtra, { ss >> vopretStripped; })) { //strip string size - if (!noLogging) std::cerr << "_DecodeHeirEitherOpret() could not unmarshal vopretStripped" << std::endl; - return (uint8_t)0; - } - } */ - if (vopretExtra.size() < 1) { - if (!noLogging) std::cerr << "_DecodeHeirEitherOpret() empty vopretExtra" << std::endl; - return (uint8_t)0; - } - } - else { - GetOpReturnData(scriptPubKey, vopretExtra); - } - - return _DecodeHeirOpRet(vopretExtra, ownerPubkey, heirPubkey, inactivityTime, heirName, memo, fundingTxidInOpret, hasHeirSpendingBegun, noLogging); -} - -// overload to decode opret in fundingtxid: -uint8_t DecodeHeirEitherOpRet(CScript scriptPubKey, uint256 &tokenid, CPubKey& ownerPubkey, CPubKey& heirPubkey, int64_t& inactivityTime, std::string& heirName, std::string& memo, bool noLogging) { - uint256 dummyFundingTxidInOpret; - uint8_t dummyHasHeirSpendingBegun; - - return _DecodeHeirEitherOpRet(scriptPubKey, tokenid, ownerPubkey, heirPubkey, inactivityTime, heirName, memo, dummyFundingTxidInOpret, dummyHasHeirSpendingBegun, noLogging); -} - -// overload to decode opret in A and C heir tx: -uint8_t DecodeHeirEitherOpRet(CScript scriptPubKey, uint256 &tokenid, uint256 &fundingTxidInOpret, uint8_t &hasHeirSpendingBegun, bool noLogging) { - CPubKey dummyOwnerPubkey, dummyHeirPubkey; - int64_t dummyInactivityTime; - std::string dummyHeirName, dummyMemo; - - return _DecodeHeirEitherOpRet(scriptPubKey, tokenid, dummyOwnerPubkey, dummyHeirPubkey, dummyInactivityTime, dummyHeirName, dummyMemo, fundingTxidInOpret, hasHeirSpendingBegun, noLogging); -} - -// check if pubkey is in vins -void CheckVinPubkey(std::vector vins, CPubKey pubkey, bool &hasPubkey, bool &hasOtherPubkey) { - - hasPubkey = false; - hasOtherPubkey = false; - - for (auto vin : vins) { - CPubKey vinPubkey = check_signing_pubkey(vin.scriptSig); - if (vinPubkey.IsValid()) { - if (vinPubkey == pubkey) - hasPubkey = true; - if (vinPubkey != pubkey) - hasOtherPubkey = true; - } - } -} - -/** - * find the latest funding tx: it may be the first F tx or one of A or C tx's - * Note: this function is also called from validation code (use non-locking calls) - */ -uint256 _FindLatestFundingTx(uint256 fundingtxid, uint8_t& funcId, uint256 &tokenid, CPubKey& ownerPubkey, CPubKey& heirPubkey, int64_t& inactivityTime, std::string& heirName, std::string& memo, CScript& fundingOpretScript, uint8_t &hasHeirSpendingBegun) -{ - CTransaction fundingtx; - uint256 hashBlock; - const bool allowSlow = false; - - //char markeraddr[64]; - //CCtxidaddr(markeraddr, fundingtxid); - //SetCCunspents(unspentOutputs, markeraddr,true); - - hasHeirSpendingBegun = 0; - funcId = 0; - - // get initial funding tx and set it as initial lasttx: - if (myGetTransaction(fundingtxid, fundingtx, hashBlock) && fundingtx.vout.size()) { - - CScript heirScript = (fundingtx.vout.size() > 0) ? fundingtx.vout[fundingtx.vout.size() - 1].scriptPubKey : CScript(); - uint8_t funcId = DecodeHeirEitherOpRet(heirScript, tokenid, ownerPubkey, heirPubkey, inactivityTime, heirName, memo, true); - if (funcId != 0) { - // found at least funding tx! - //std::cerr << "FindLatestFundingTx() lasttx currently is fundingtx, txid=" << fundingtxid.GetHex() << " opreturn type=" << (char)funcId << '\n'; - fundingOpretScript = fundingtx.vout[fundingtx.vout.size() - 1].scriptPubKey; - } else { - std::cerr << "FindLatestFundingTx() could not decode opreturn for fundingtxid=" << fundingtxid.GetHex() << '\n'; - return zeroid; - } - } else { - std::cerr << "FindLatestFundingTx() could not find funding tx for fundingtxid=" << fundingtxid.GetHex() << '\n'; - return zeroid; - } - - // TODO: correct cc addr: - std::vector> unspentOutputs; - struct CCcontract_info *cp, C; - cp = CCinit(&C, EVAL_HEIR); - char coinaddr[64]; - GetCCaddress1of2(cp, coinaddr, ownerPubkey, heirPubkey); // get the address of cryptocondition '1 of 2 pubkeys' - - SetCCunspents(unspentOutputs, coinaddr,true); // get vector with tx's with unspent vouts of 1of2pubkey address: - //std::cerr << "FindLatestFundingTx() using 1of2address=" << coinaddr << " unspentOutputs.size()=" << unspentOutputs.size() << '\n'; - - int32_t maxBlockHeight = 0; // max block height - uint256 latesttxid = fundingtxid; - - // try to find the last funding or spending tx by checking fundingtxid in 'opreturn': - for (std::vector>::const_iterator it = unspentOutputs.begin(); it != unspentOutputs.end(); it++) { - CTransaction regtx; - uint256 hash; - - uint256 txid = it->first.txhash; - //std::cerr << "FindLatestFundingTx() checking unspents for txid=" << txid.GetHex() << '\n'; - - int32_t blockHeight = (int32_t)it->second.blockHeight; - - //NOTE: maybe called from validation code: - if (myGetTransaction(txid, regtx, hash)) { - //std::cerr << "FindLatestFundingTx() found tx for txid=" << txid.GetHex() << " blockHeight=" << blockHeight << " maxBlockHeight=" << maxBlockHeight << '\n'; - uint256 fundingTxidInOpret; - uint256 tokenidInOpret; // not to contaminate the tokenid from the params! - uint8_t tmpFuncId; - uint8_t hasHeirSpendingBegunInOpret; - - CScript heirScript = (regtx.vout.size() > 0) ? regtx.vout[regtx.vout.size() - 1].scriptPubKey : CScript(); - tmpFuncId = DecodeHeirEitherOpRet(heirScript, tokenidInOpret, fundingTxidInOpret, hasHeirSpendingBegunInOpret, true); - if (tmpFuncId != 0 && fundingtxid == fundingTxidInOpret && (tokenid == zeroid || tokenid == tokenidInOpret)) { // check tokenid also - - if (blockHeight > maxBlockHeight) { - - // check owner pubkey in vins - bool isOwner = false; - bool isNonOwner = false; - - CheckVinPubkey(regtx.vin, ownerPubkey, isOwner, isNonOwner); - - // we ignore 'donations' tx (with non-owner inputs) for calculating if heir is allowed to spend: - if (isOwner && !isNonOwner) { - hasHeirSpendingBegun = hasHeirSpendingBegunInOpret; - maxBlockHeight = blockHeight; - latesttxid = txid; - funcId = tmpFuncId; - } - - //std::cerr << "FindLatestFundingTx() txid=" << latesttxid.GetHex() << " at blockHeight=" << maxBlockHeight - // << " opreturn type=" << (char)(funcId ? funcId : ' ') << " hasHeirSpendingBegun=" << (int)hasHeirSpendingBegun << " - set as current lasttxid" << '\n'; - } - } - } - } - - return latesttxid; -} - -// overload for validation code -uint256 FindLatestFundingTx(uint256 fundingtxid, uint256 &tokenid, CScript& opRetScript, uint8_t &hasHeirSpendingBegun) -{ - uint8_t funcId; - CPubKey ownerPubkey; - CPubKey heirPubkey; - int64_t inactivityTime; - std::string heirName, memo; - - return _FindLatestFundingTx(fundingtxid, funcId, tokenid, ownerPubkey, heirPubkey, inactivityTime, heirName, memo, opRetScript, hasHeirSpendingBegun); -} - -// overload for transaction creation code -uint256 FindLatestFundingTx(uint256 fundingtxid, uint8_t& funcId, uint256 &tokenid, CPubKey& ownerPubkey, CPubKey& heirPubkey, int64_t& inactivityTime, std::string& heirName, std::string& memo, uint8_t &hasHeirSpendingBegun) -{ - CScript opRetScript; - - return _FindLatestFundingTx(fundingtxid, funcId, tokenid, ownerPubkey, heirPubkey, inactivityTime, heirName, memo, opRetScript, hasHeirSpendingBegun); -} - -// add inputs of 1 of 2 cc address -template int64_t Add1of2AddressInputs(struct CCcontract_info* cp, uint256 fundingtxid, CMutableTransaction& mtx, CPubKey ownerPubkey, CPubKey heirPubkey, int64_t total, int32_t maxinputs) -{ - // TODO: add threshold check - int64_t nValue, voutValue, totalinputs = 0; - CTransaction heirtx; - int32_t n = 0; - std::vector> unspentOutputs; - - char coinaddr[64]; - Helper::GetCoinsOrTokensCCaddress1of2(coinaddr, ownerPubkey, heirPubkey); // get address of cryptocondition '1 of 2 pubkeys' - SetCCunspents(unspentOutputs, coinaddr,true); - - // char markeraddr[64]; - // CCtxidaddr(markeraddr, fundingtxid); - // SetCCunspents(unspentOutputs, markeraddr,true); - - std::cerr << "Add1of2AddressInputs() using 1of2addr=" << coinaddr << " unspentOutputs.size()=" << unspentOutputs.size() << std::endl; - - for (std::vector>::const_iterator it = unspentOutputs.begin(); it != unspentOutputs.end(); it++) { - uint256 txid = it->first.txhash; - uint256 hashBlock; - int32_t voutIndex = (int32_t)it->first.index; - // no need to prevent dup - // dimxy: maybe it is good to put tx's in cache? - - //std::cerr << "Add1of2AddressInputs() txid=" << txid.GetHex() << std::endl; - - if (myGetTransaction(txid, heirtx, hashBlock) != 0) { - uint256 tokenid; - uint256 fundingTxidInOpret; - uint8_t hasHeirSpendingBegunDummy; - - CScript heirScript = (heirtx.vout.size() > 0) ? heirtx.vout[heirtx.vout.size() - 1].scriptPubKey : CScript(); // check boundary - uint8_t funcId = DecodeHeirEitherOpRet(heirScript, tokenid, fundingTxidInOpret, hasHeirSpendingBegunDummy, false); - - if ((txid == fundingtxid || fundingTxidInOpret == fundingtxid) && - funcId != 0 && - isMyFuncId(funcId) && - (typeid(Helper) != typeid(TokenHelper) ) && // token validation logic - //(voutValue = IsHeirFundingVout(cp, heirtx, voutIndex, ownerPubkey, heirPubkey)) > 0 && // heir contract vout validation logic - not used since we moved to 2-eval vouts - !myIsutxo_spentinmempool(ignoretxid,ignorevin,txid, voutIndex)) - { - std::cerr << "Add1of2AddressInputs() satoshis=" << it->second.satoshis << std::endl; - if (total != 0 && maxinputs != 0) - mtx.vin.push_back(CTxIn(txid, voutIndex, CScript())); - nValue = it->second.satoshis; - totalinputs += nValue; - n++; - if ((total > 0 && totalinputs >= total) || (maxinputs > 0 && n >= maxinputs)) - break; - } - } - } - return totalinputs; -} - -/** - * enumerate all tx's sending to CCHeir 1of2address and calc total lifetime funds - */ -template int64_t LifetimeHeirContractFunds(struct CCcontract_info* cp, uint256 fundingtxid, CPubKey ownerPubkey, CPubKey heirPubkey) -{ - char coinaddr[64]; - Helper::GetCoinsOrTokensCCaddress1of2(coinaddr, ownerPubkey, heirPubkey); // get the address of cryptocondition '1 of 2 pubkeys' - - std::vector> addressIndexes; - SetCCtxids(addressIndexes, coinaddr,true); - - //fprintf(stderr,"LifetimeHeirContractFunds() scan lifetime of %s\n",coinaddr); - int64_t total = 0; - for (std::vector>::const_iterator it = addressIndexes.begin(); it != addressIndexes.end(); it++) { - uint256 hashBlock; - uint256 txid = it->first.txhash; - CTransaction heirtx; - - // TODO: check all funding tx should contain unspendable markers - if (myGetTransaction(txid, heirtx, hashBlock) && heirtx.vout.size() > 0) { - uint256 tokenid; - uint256 fundingTxidInOpret; - uint8_t hasHeirSpendingBegunDummy; - const int32_t ivout = 0; - - CScript heirScript = (heirtx.vout.size() > 0) ? heirtx.vout[heirtx.vout.size() - 1].scriptPubKey : CScript(); // check boundary - uint8_t funcId = DecodeHeirEitherOpRet(heirScript, tokenid, fundingTxidInOpret, hasHeirSpendingBegunDummy, false); - - //std::cerr << "LifetimeHeirContractFunds() found tx=" << txid.GetHex() << " vout[0].nValue=" << subtx.vout[ccVoutIdx].nValue << " opreturn=" << (char)funcId << '\n'; - - if (funcId != 0 && - (txid == fundingtxid || fundingTxidInOpret == fundingtxid) && - isMyFuncId(funcId) && !isSpendingTx(funcId) && - (typeid(Helper) != typeid(TokenHelper) ) && - !myIsutxo_spentinmempool(ignoretxid,ignorevin,txid, ivout)) // exclude tx in mempool - { - total += it->second; // dont do this: tx.vout[ivout].nValue; // in vin[0] always is the pay to 1of2 addr (funding or change) - //std::cerr << "LifetimeHeirContractFunds() added tx=" << txid.GetHex() << " it->second=" << it->second << " vout[0].nValue=" << tx.vout[ivout].nValue << " opreturn=" << (char)funcId << '\n'; - } - } - } - return (total); -} - -/* rpc functions' implementation: */ - -/** - * heirfund rpc call implementation - * creates tx for initial funds deposit on cryptocondition address which locks funds for spending by either of address. - * and also for setting spending plan for the funds' owner and heir - * @return fundingtxid handle for subsequent references to this heir funding plan - */ -template UniValue _HeirFund(int64_t txfee, int64_t amount, std::string heirName, CPubKey heirPubkey, int64_t inactivityTimeSec, std::string memo, uint256 tokenid) -{ - UniValue result(UniValue::VOBJ); - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), hush_nextheight()); - struct CCcontract_info *cp, C; - - cp = CCinit(&C, Helper::getMyEval()); - if (txfee == 0) - txfee = 10000; - - int64_t markerfee = 10000; - - //std::cerr << "HeirFund() amount=" << amount << " txfee=" << txfee << " heirPubkey IsValid()=" << heirPubkey.IsValid() << " inactivityTime(sec)=" << inactivityTimeSec << " tokenid=" << tokenid.GetHex() << std::endl; - - CPubKey myPubkey = pubkey2pk(Mypubkey()); - - if (!tokenid.IsNull()) // add normals only for tokens - { - if (AddNormalinputs(mtx, myPubkey, txfee + markerfee, 4) < txfee + markerfee) - { - std::cerr << "HeirFund() could not find normal inputs for txfee" << std::endl; - result.push_back(Pair("result", "error")); - result.push_back(Pair("error", "could not find normal inputs for txfee")); - return result; - } - } - - int64_t inputs; - int64_t addAmount = tokenid.IsNull() ? (txfee + markerfee + amount) : amount; // for coins add txfee markerfee amount in one call - if ((inputs=Helper::addOwnerInputs(tokenid, mtx, myPubkey, addAmount, (int32_t)64)) >= addAmount) - { - mtx.vout.push_back(Helper::make1of2Vout(amount, myPubkey, heirPubkey)); - - // add a marker for finding all plans in HeirList() - // TODO: change marker either to cc or normal txidaddr unspendable - struct CCcontract_info *cpHeir, heirC; - cpHeir = CCinit(&heirC, EVAL_HEIR); - CPubKey heirUnspendablePubKey = GetUnspendable(cpHeir, 0); - // mtx.vout.push_back(CTxOut(txfee, CScript() << ParseHex(HexStr(heirUnspendablePubKey)) << OP_CHECKSIG)); <-- bad marker cause it was spendable by anyone - mtx.vout.push_back(MakeCC1vout(EVAL_HEIR, markerfee, heirUnspendablePubKey)); // this marker spending is disabled in the validation code - - if (!tokenid.IsNull()) - { - int64_t ccChange = 0; - // calc and add token change vout: - if (inputs > amount) - ccChange = (inputs - amount); // -txfee <-- txfee pays user - - //std::cerr << "HeirFund() inputs=" << inputs << " amount=" << amount << " txfee=" << txfee << " change=" << change << '\n'; - - if (ccChange != 0) - mtx.vout.push_back(Helper::makeUserVout(ccChange, myPubkey)); - } - - // check owner pubkey in vins - bool hasMypubkey = false; - bool hasNotMypubkey = false; - - CheckVinPubkey(mtx.vin, myPubkey, hasMypubkey, hasNotMypubkey); - - // for initial funding do not allow to sign by non-owner key: - if (hasNotMypubkey) { - result.push_back(Pair("result", "error")); - result.push_back(Pair("error", "using non-owner inputs not allowed")); - return result; - } - - // add 1of2 vout token validation pubkeys - used only for tokens - std::vector voutTokenPubkeys; - voutTokenPubkeys.push_back(myPubkey); - voutTokenPubkeys.push_back(heirPubkey); - - // add change for txfee and opreturn vouts and sign tx: - std::string rawhextx = FinalizeCCTx(0, cp, mtx, myPubkey, txfee, - Helper::makeCreateOpRet(tokenid, voutTokenPubkeys, myPubkey, heirPubkey, inactivityTimeSec, heirName, memo)); - if (!rawhextx.empty()) { - result.push_back(Pair("result", "success")); - result.push_back(Pair("hex", rawhextx)); - } - else { - std::cerr << "HeirAdd error in FinalizeCCtx" << std::endl; - result.push_back(Pair("result", "error")); - result.push_back(Pair("error", "sign error")); - } - } - else { // TODO: need result return unification with heiradd and claim - std::cerr << "HeirFund() could not find owner inputs for amount (normal inputs for coins, cc inputs for tokens)" << std::endl; - result.push_back(Pair("result", "error")); - result.push_back(Pair("error", "could not find owner inputs")); - } - return result; -} - -// if no these callers - it could not link -UniValue HeirFundCoinCaller(int64_t txfee, int64_t coins, std::string heirName, CPubKey heirPubkey, int64_t inactivityTimeSec, std::string memo){ - return _HeirFund(txfee, coins, heirName, heirPubkey, inactivityTimeSec, memo, zeroid); -} - -UniValue HeirFundTokenCaller(int64_t txfee, int64_t satoshis, std::string heirName, CPubKey heirPubkey, int64_t inactivityTimeSec, std::string memo, uint256 tokenid) { - return _HeirFund(txfee, satoshis, heirName, heirPubkey, inactivityTimeSec, memo, tokenid); -} - -/** - * heiradd rpc call implementation - * creates tx to add more funds to cryptocondition address for spending by either funds' owner or heir - * @return result object with raw tx or error text - */ -template UniValue _HeirAdd(uint256 fundingtxid, int64_t txfee, int64_t amount, uint256 latesttxid, uint8_t funcId, uint256 tokenid, CPubKey ownerPubkey, CPubKey heirPubkey, int64_t inactivityTimeSec, uint8_t hasHeirSpendingBegun) -{ - UniValue result(UniValue::VOBJ); - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), hush_nextheight()); - struct CCcontract_info *cp, C; - std::string rawhex; - - cp = CCinit(&C, Helper::getMyEval()); // for tokens shoud be EVAL_TOKENS to sign it correctly! - - if (txfee == 0) - txfee = 10000; - - int64_t markerfee = 10000; - - CPubKey myPubkey = pubkey2pk(Mypubkey()); - - // check if it is the owner - if (myPubkey != ownerPubkey) { - result.push_back(Pair("result", "error")); - result.push_back(Pair("error", "adding funds is only allowed for the owner of this contract")); - return result; - } - - if (!tokenid.IsNull()) // add normals only for tokens - { - if (AddNormalinputs(mtx, myPubkey, txfee + markerfee, 4) < txfee + markerfee) - { - std::cerr << "HeirFund() could not find normal inputs for txfee" << std::endl; - result.push_back(Pair("result", "error")); - result.push_back(Pair("error", "could not find normal inputs for txfee")); - return result; - } - } - - int64_t inputs; - int64_t addAmount = tokenid.IsNull() ? (txfee + markerfee + amount) : amount; // for coins add txfee markerfee amount in one call - if ((inputs = Helper::addOwnerInputs(tokenid, mtx, myPubkey, addAmount, 64)) >= addAmount) { // TODO: why 64 max inputs? - - // we do not use markers anymore - storing data in opreturn is better - // add marker vout: - /* char markeraddr[64]; - CPubKey markerpubkey = CCtxidaddr(markeraddr, fundingtxid); - mtx.vout.push_back(CTxOut(txfee, CScript() << ParseHex(HexStr(markerpubkey)) << OP_CHECKSIG)); // txfee 1, txfee 2 - for miners - std::cerr << "HeirAdd() adding markeraddr=" << markeraddr << '\n'; */ - - // add cryptocondition to spend this funded amount for either pk - mtx.vout.push_back(Helper::make1of2Vout(amount, ownerPubkey, heirPubkey)); - - char markeraddr[64]; - CPubKey markerPubkey = CCtxidaddr(markeraddr, fundingtxid); - mtx.vout.push_back(CTxOut(markerfee, CScript() << ParseHex(HexStr(markerPubkey)) << OP_CHECKSIG)); // marker to prevent archiving of the funds add vouts - - if (!tokenid.IsNull()) - { - int64_t ccChange = 0; - - if (inputs > amount) - ccChange = (inputs - amount); // -txfee <-- txfee pays user - //std::cerr << "HeirAdd() inputs=" << inputs << " amount=" << amount << " txfee=" << txfee << " change=" << change << '\n'; - - if (ccChange != 0) - mtx.vout.push_back(Helper::makeUserVout(ccChange, myPubkey)); - } - - // check owner pubkey in vins - bool hasMypubkey = false; - bool hasNotMypubkey = false; - - CheckVinPubkey(mtx.vin, myPubkey, hasMypubkey, hasNotMypubkey); - - // for additional funding do not allow to sign by both owner and non-owner keys (is this a donation or not?): - if (hasMypubkey && hasNotMypubkey) { - result.push_back(Pair("result", "error")); - result.push_back(Pair("error", "using both owner and non-owner inputs is not allowed")); - return result; - } - - // warn the user he's making a donation if this is all non-owner keys: - if (hasNotMypubkey) { - result.push_back(Pair("result", "warning")); - result.push_back(Pair("warning", "you are about to make a donation to heir fund")); - } - else { - result.push_back(Pair("result", "success")); - } - - // add 1of2 vout validation pubkeys - needed only for tokens: - std::vector voutTokenPubkeys; - voutTokenPubkeys.push_back(ownerPubkey); - voutTokenPubkeys.push_back(heirPubkey); - - // add opreturn 'A' and sign tx: - std::string rawhextx = (FinalizeCCTx(0, cp, mtx, myPubkey, txfee, - Helper::makeAddOpRet(tokenid, voutTokenPubkeys, fundingtxid, hasHeirSpendingBegun))); - - if (!rawhextx.empty()) { - result.push_back(Pair("hex", rawhextx)); - } - else { - std::cerr << "HeirAdd error in FinalizeCCtx" << std::endl; - result.clear(); - result.push_back(Pair("result", "error")); - result.push_back(Pair("error", "sign error")); - } - } - else { - std::cerr << "HeirAdd cannot find owner inputs for amount (normal inputs for coins, cc inputs for tokens)" << std::endl; - result.push_back(Pair("result", "error")); - result.push_back(Pair("error", "can't find owner inputs")); - } - return result; -} - - -UniValue HeirAddCaller(uint256 fundingtxid, int64_t txfee, std::string strAmount) { - - CPubKey ownerPubkey, heirPubkey; - int64_t inactivityTimeSec; - - uint256 latesttxid, tokenid = zeroid; - uint8_t funcId; - std::string heirName, memo; - uint8_t hasHeirSpendingBegun = 0; - - // get latest tx to see if it is a token or coin - if ((latesttxid = FindLatestFundingTx(fundingtxid, funcId, tokenid, ownerPubkey, heirPubkey, inactivityTimeSec, heirName, memo, hasHeirSpendingBegun)) != zeroid) - { - if (tokenid == zeroid) { - int64_t amount = 0; - if (!ParseFixedPoint(strAmount, 8, &amount) || amount <= 0 ) { - UniValue result(UniValue::VOBJ); - result.push_back(Pair("result", "error")); - result.push_back(Pair("error", "invalid amount")); - return result; - } - return _HeirAdd(fundingtxid, txfee, amount, latesttxid, funcId, tokenid, ownerPubkey, heirPubkey, inactivityTimeSec, hasHeirSpendingBegun); - } - else - { - int64_t amount = atoll(strAmount.c_str()); - if (amount <= 0) { - UniValue result(UniValue::VOBJ); - result.push_back(Pair("result", "error")); - result.push_back(Pair("error", "invalid amount")); - return result; - } - return _HeirAdd(fundingtxid, txfee, amount, latesttxid, funcId, tokenid, ownerPubkey, heirPubkey, inactivityTimeSec, hasHeirSpendingBegun); - } - } - else { - UniValue result(UniValue::VOBJ); - - fprintf(stderr, "HeirAdd() can't find any heir CC funding tx's\n"); - result.push_back(Pair("result", "error")); - result.push_back(Pair("error", "can't find any heir CC funding transactions")); - return result; - } -} - - -/** - * heirclaim rpc call implementation - * creates tx to spend funds from cryptocondition address by either funds' owner or heir - * @return result object with raw tx or error text - */ -template UniValue _HeirClaim(uint256 fundingtxid, int64_t txfee, int64_t amount, uint256 latesttxid, uint8_t funcId, uint256 tokenid, CPubKey ownerPubkey, CPubKey heirPubkey, int64_t inactivityTimeSec, uint8_t hasHeirSpendingBegun) -{ - UniValue result(UniValue::VOBJ); - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), hush_nextheight()); - CPubKey myPubkey; - int64_t inputs, change = 0; - struct CCcontract_info *cp, C; - - cp = CCinit(&C, EVAL_HEIR); - if (txfee == 0) - txfee = 10000; - - int32_t numblocks; - uint64_t durationSec = 0; - - // we do not need to find duration if spending already has begun - if (!hasHeirSpendingBegun) { - durationSec = CCduration(numblocks, latesttxid); - std::cerr << "HeirClaim() duration=" << durationSec << " inactivityTime=" << inactivityTimeSec << " numblocks=" << numblocks << std::endl; - } - - // spending is allowed if there is already spending tx or inactivity time - //bool isAllowedToHeir = (funcId == 'C' || durationSec > inactivityTimeSec) ? true : false; - bool isAllowedToHeir = (hasHeirSpendingBegun || durationSec > inactivityTimeSec) ? true : false; - myPubkey = pubkey2pk(Mypubkey()); - - // if it is the heir, check if spending not allowed to heir yet - if (myPubkey == heirPubkey && !isAllowedToHeir) { - result.push_back(Pair("result", "error")); - result.push_back(Pair("error", "spending is not allowed yet for the heir")); - return result; - } - - // we do not use markers any more: - // we allow owner to spend funds at any time: - // if it is the owner, check if spending already allowed to heir - /* if (myPubkey == ownerPubkey && isAllowedToHeir) { - result.push_back(Pair("result", "spending is not already allowed for the owner")); - return result; - } */ - - // add spending txfee from the calling user - if (AddNormalinputs(mtx, myPubkey, txfee, 3) > 0) { - - // add spending from cc 1of2 address - if ((inputs = Add1of2AddressInputs(cp, fundingtxid, mtx, ownerPubkey, heirPubkey, amount, 60)) >= amount) // TODO: why only 60 inputs? - { - /*if (inputs < amount) { - std::cerr << "HeirClaim() cant find enough HeirCC 1of2 inputs, found=" << inputs << " required=" << amount << std::endl; - result.push_back(Pair("result", "error")); - result.push_back(Pair("error", "can't find heir CC funding")); - - return result; - }*/ - - // add vout with amount to claiming address - mtx.vout.push_back(Helper::makeUserVout(amount, myPubkey)); // vout[0] - - // calc and add change vout: - if (inputs > amount) - change = (inputs - amount); // -txfee <-- txfee pays user - - //std::cerr << "HeirClaim() inputs=" << inputs << " amount=" << amount << " txfee=" << txfee << " change=" << change << '\n'; - - // change to 1of2 funding addr: - if (change != 0) { // vout[1] - mtx.vout.push_back(Helper::make1of2Vout(change, ownerPubkey, heirPubkey)); // using always pubkeys from OP_RETURN in order to not mixing them up! - } - - // add marker vout: - /*char markeraddr[64]; - CPubKey markerpubkey = CCtxidaddr(markeraddr, fundingtxid); - // NOTE: amount = 0 is not working: causes error code: -26, error message : 64 : dust - mtx.vout.push_back(CTxOut(txfee, CScript() << ParseHex(HexStr(markerpubkey)) << OP_CHECKSIG)); // txfee 1, txfee 2 - for miners - std::cerr << "HeirClaim() adding markeraddr=" << markeraddr << '\n'; */ - - // get address of 1of2 cond - char coinaddr[64]; - Helper::GetCoinsOrTokensCCaddress1of2(coinaddr, ownerPubkey, heirPubkey); - - // retrieve priv key addresses for FinalizeCCtx: - uint8_t myprivkey[32]; - Myprivkey(myprivkey); - - // set pubkeys for finding 1of2 cc in FinalizeCCtx to sign it: - Helper::CCaddrCoinsOrTokens1of2set(cp, ownerPubkey, heirPubkey, coinaddr); - - // add 1of2 vout validation pubkeys (this is for tokens): - std::vector voutTokenPubkeys; - voutTokenPubkeys.push_back(ownerPubkey); - voutTokenPubkeys.push_back(heirPubkey); - - // add opreturn 'C' and sign tx: // this txfee will be ignored - std::string rawhextx = FinalizeCCTx(0, cp, mtx, myPubkey, txfee, - Helper::makeClaimOpRet(tokenid, voutTokenPubkeys, fundingtxid, (myPubkey == heirPubkey) ? 1 : hasHeirSpendingBegun)); // forward isHeirSpending to the next latest tx - - memset(myprivkey,0,sizeof(myprivkey)); - if (!rawhextx.empty()) { - result.push_back(Pair("result", "success")); - result.push_back(Pair("hex", rawhextx)); - } - else { - std::cerr << "HeirAdd error in FinalizeCCtx" << std::endl; - result.push_back(Pair("result", "error")); - result.push_back(Pair("error", "sign error")); - } - - } else { - fprintf(stderr, "HeirClaim() cant find Heir CC inputs\n"); - result.push_back(Pair("result", "error")); - result.push_back(Pair("error", "can't find heir CC funding")); - } - } else { - fprintf(stderr, "HeirClaim() cant find sufficient user inputs for tx fee\n"); - result.push_back(Pair("result", "error")); - result.push_back(Pair("error", "can't find sufficient user inputs to pay transaction fee")); - } - - - return result; -} - -UniValue HeirClaimCaller(uint256 fundingtxid, int64_t txfee, std::string strAmount) { - - CPubKey ownerPubkey, heirPubkey; - int64_t inactivityTimeSec; - - uint256 latesttxid, tokenid = zeroid; - uint8_t funcId; - std::string heirName, memo; - uint8_t hasHeirSpendingBegun = 0; - - // find latest tx to see if it is a token or coin: - if ((latesttxid = FindLatestFundingTx(fundingtxid, funcId, tokenid, ownerPubkey, heirPubkey, inactivityTimeSec, heirName, memo, hasHeirSpendingBegun)) != zeroid) - { - if (tokenid == zeroid) - { - int64_t amount = 0; - if (!ParseFixedPoint(strAmount, 8, &amount) || amount <= 0) { // using ParseFixedPoint instead atof to avoid round errors - UniValue result(UniValue::VOBJ); - result.push_back(Pair("result", "error")); - result.push_back(Pair("error", "invalid amount")); - return result; - } - return _HeirClaim(fundingtxid, txfee, amount, latesttxid, funcId, tokenid, ownerPubkey, heirPubkey, inactivityTimeSec, hasHeirSpendingBegun); - } - else { - int64_t amount = atoll(strAmount.c_str()); - if (amount <= 0) { - UniValue result(UniValue::VOBJ); - result.push_back(Pair("result", "error")); - result.push_back(Pair("error", "invalid amount")); - return result; - } - return _HeirClaim(fundingtxid, txfee, amount, latesttxid, funcId, tokenid, ownerPubkey, heirPubkey, inactivityTimeSec, hasHeirSpendingBegun); - } - - } - else { - UniValue result(UniValue::VOBJ); - - fprintf(stderr, "HeirClaim() can't find any heir CC funding tx's\n"); - result.push_back(Pair("result", "error")); - result.push_back(Pair("error", "can't find any heir CC funding transactions")); - return result; - } -} - - -/** - * heirinfo rpc call implementation - * returns some information about heir CC contract plan by a handle of initial fundingtxid: - * plan name, owner and heir pubkeys, funds deposited and available, flag if spending is enabled for the heir - * @return heir info data - */ -UniValue HeirInfo(uint256 fundingtxid) -{ - UniValue result(UniValue::VOBJ); - - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), hush_nextheight()); - CTransaction fundingtx; - uint256 hashBlock; - const bool allowSlow = false; - - //char markeraddr[64]; - //CCtxidaddr(markeraddr, fundingtxid); - //SetCCunspents(unspentOutputs, markeraddr,true); - - // get initial funding tx and set it as initial lasttx: - if (myGetTransaction(fundingtxid, fundingtx, hashBlock) && fundingtx.vout.size()) { - - CPubKey ownerPubkey, heirPubkey; - uint256 dummyTokenid, tokenid = zeroid; // important to clear tokenid - std::string heirName, memo; - int64_t inactivityTimeSec; - const bool noLogging = false; - uint8_t funcId; - - /*CScript opret = fundingtx.vout.size() > 0 ? fundingtx.vout[fundingtx.vout.size() - 1].scriptPubKey : CScript(); - uint8_t funcId = DecodeHeirEitherOpRet(opret, tokenid, ownerPubkey, heirPubkey, inactivityTimeSec, heirName, true); - if (funcId == 0) { - std::cerr << "HeirInfo() this fundingtx is incorrect" << std::endl; - result.push_back(Pair("result", "error")); - result.push_back(Pair("error", "initial tx F not found")); - return result; - }*/ - - struct CCcontract_info *cp, C; - cp = CCinit(&C, EVAL_HEIR); - - uint8_t hasHeirSpendingBegun = 0; - - uint256 latestFundingTxid = FindLatestFundingTx(fundingtxid, funcId, tokenid, ownerPubkey, heirPubkey, inactivityTimeSec, heirName, memo, hasHeirSpendingBegun); - - if (latestFundingTxid != zeroid) { - int32_t numblocks; - uint64_t durationSec = 0; - - //std::cerr << "HeirInfo() latesttxid=" << latestFundingTxid.GetHex() << '\n'; - - std::ostringstream stream; - std::string msg; - - //sleep(10); - - result.push_back(Pair("fundingtxid", fundingtxid.GetHex())); - result.push_back(Pair("name", heirName.c_str())); - - if (tokenid != zeroid) { // tokens - stream << tokenid.GetHex(); - msg = "tokenid"; - result.push_back(Pair(msg, stream.str().c_str())); - stream.str(""); - stream.clear(); - } - - char hexbuf[67]; - stream << pubkey33_str(hexbuf, (uint8_t*)ownerPubkey.begin()); - result.push_back(Pair("owner", stream.str().c_str())); - stream.str(""); - stream.clear(); - - stream << pubkey33_str(hexbuf, (uint8_t*)heirPubkey.begin()); - result.push_back(Pair("heir", stream.str().c_str())); - stream.str(""); - stream.clear(); - - int64_t total; - if (tokenid == zeroid) - total = LifetimeHeirContractFunds(cp, fundingtxid, ownerPubkey, heirPubkey); - else - total = LifetimeHeirContractFunds(cp, fundingtxid, ownerPubkey, heirPubkey); - - msg = "type"; - if (tokenid == zeroid) { - stream << "coins"; - } - else { - stream << "tokens"; - } - result.push_back(Pair(msg, stream.str().c_str())); - stream.str(""); - stream.clear(); - - msg = "lifetime"; - if (tokenid == zeroid) { - stream << std::fixed << std::setprecision(8) << (double)total / COIN; - } - else { - stream << total; - } - result.push_back(Pair(msg, stream.str().c_str())); - stream.str(""); - stream.clear(); - - int64_t inputs; - if (tokenid == zeroid) - inputs = Add1of2AddressInputs(cp, fundingtxid, mtx, ownerPubkey, heirPubkey, 0, 60); //NOTE: amount = 0 means all unspent inputs - else - inputs = Add1of2AddressInputs(cp, fundingtxid, mtx, ownerPubkey, heirPubkey, 0, 60); - - msg = "available"; - if (tokenid == zeroid) { - stream << std::fixed << std::setprecision(8) << (double)inputs / COIN; - } - else { - stream << inputs; - } - result.push_back(Pair(msg, stream.str().c_str())); - stream.str(""); - stream.clear(); - - if (tokenid != zeroid) { - int64_t ownerInputs = TokenHelper::addOwnerInputs(tokenid, mtx, ownerPubkey, 0, (int32_t)64); - stream << ownerInputs; - msg = "OwnerRemainderTokens"; - result.push_back(Pair(msg, stream.str().c_str())); - stream.str(""); - stream.clear(); - } - - stream << inactivityTimeSec; - result.push_back(Pair("InactivityTimeSetting", stream.str().c_str())); - stream.str(""); - stream.clear(); - - if (!hasHeirSpendingBegun) { // we do not need find duration if the spending already has begun - durationSec = CCduration(numblocks, latestFundingTxid); - std::cerr << "HeirInfo() duration (sec)=" << durationSec << " inactivityTime (sec)=" << inactivityTimeSec << " numblocks=" << numblocks << '\n'; - } - - stream << std::boolalpha << (hasHeirSpendingBegun || durationSec > inactivityTimeSec); - result.push_back(Pair("IsHeirSpendingAllowed", stream.str().c_str())); - stream.str(""); - stream.clear(); - - // adding owner current inactivity time: - if (!hasHeirSpendingBegun && durationSec <= inactivityTimeSec) { - stream << durationSec; - result.push_back(Pair("InactivityTime", stream.str().c_str())); - stream.str(""); - stream.clear(); - } - - result.push_back(Pair("memo", memo.c_str())); - - result.push_back(Pair("result", "success")); - } - else { - result.push_back(Pair("result", "error")); - result.push_back(Pair("error", "could not find heir cc plan for this txid")); - } - } - else { - result.push_back(Pair("result", "error")); - result.push_back(Pair("error", "could not find heir cc plan for this txid (no initial tx)")); - } - return (result); -} - -/** - * heirlist rpc call implementation - * @return list of heir plan handles (fundingtxid) - */ - -void _HeirList(struct CCcontract_info *cp, UniValue &result) -{ - std::vector> unspentOutputs; - char markeraddr[64]; - - GetCCaddress(cp, markeraddr, GetUnspendable(cp, NULL)); - SetCCunspents(unspentOutputs, markeraddr,true); - - //std::cerr << "HeirList() finding heir marker from unspendable addr=" << markeraddr << " unspentOutputs.size()=" << unspentOutputs.size() << '\n'; - - // TODO: move marker to special cc addr to prevent checking all tokens - for (std::vector>::const_iterator it = unspentOutputs.begin(); it != unspentOutputs.end(); it++) { - uint256 hashBlock; - uint256 txid = it->first.txhash; - uint256 tokenid; - int32_t vout = (int32_t)it->first.index; - - //std::cerr << "HeirList() checking txid=" << txid.GetHex() << " vout=" << vout << '\n'; - - CTransaction fundingtx; - if (myGetTransaction(txid, fundingtx, hashBlock)) { - CPubKey ownerPubkey, heirPubkey; - std::string heirName, memo; - int64_t inactivityTimeSec; - const bool noLogging = true; - uint256 tokenid; - - CScript opret = (fundingtx.vout.size() > 0) ? fundingtx.vout[fundingtx.vout.size() - 1].scriptPubKey : CScript(); - uint8_t funcId = DecodeHeirEitherOpRet(opret, tokenid, ownerPubkey, heirPubkey, inactivityTimeSec, heirName, memo, true); - - // note: if it is not Heir token funcId would be equal to 0 - if (funcId == 'F') { - //result.push_back(Pair("fundingtxid kind name", txid.GetHex() + std::string(" ") + (typeid(Helper) == typeid(TokenHelper) ? std::string("token") : std::string("coin")) + std::string(" ") + heirName)); - result.push_back( txid.GetHex() ); - } - else { - std::cerr << "HeirList() this is not the initial F transaction=" << txid.GetHex() << std::endl; - } - } - else { - std::cerr << "HeirList() could not load transaction=" << txid.GetHex() << std::endl; - } - } -} - - -UniValue HeirList() -{ - UniValue result(UniValue::VARR); - //result.push_back(Pair("result", "success")); - //result.push_back(Pair("name", "Heir List")); - - struct CCcontract_info *cpHeir, heirC; - - cpHeir = CCinit(&heirC, EVAL_HEIR); - _HeirList(cpHeir, result); - - return result; -} diff --git a/src/cc/oracles.cpp b/src/cc/oracles.cpp deleted file mode 100644 index e1307810b..000000000 --- a/src/cc/oracles.cpp +++ /dev/null @@ -1,1233 +0,0 @@ -// Copyright (c) 2016-2023 The Hush developers -// Distributed under the GPLv3 software license, see the accompanying -// file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html -/****************************************************************************** - * Copyright © 2014-2019 The SuperNET Developers. * - * * - * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * - * the top-level directory of this distribution for the individual copyright * - * holder information and the developer policies on copyright and licensing. * - * * - * Unless otherwise agreed in a custom licensing agreement, no part of the * - * SuperNET software, including this file may be copied, modified, propagated * - * or distributed except according to the terms contained in the LICENSE file * - * * - * Removal or modification of this copyright notice is prohibited. * - * * - ******************************************************************************/ - -#include "CCOracles.h" -#include - -/* - An oracles CC has the purpose of converting offchain data into onchain data - simplest would just be to have a pubkey(s) that are trusted to provide such data, but this wont need to have a CC involved at all and can just be done by convention - - That begs the question, "what would an oracles CC do?" - A couple of things come to mind, ie. payments to oracles for future offchain data and maybe some sort of dispute/censoring ability - - first step is to define the data that the oracle is providing. A simple name:description tx can be created to define the name and description of the oracle data. - linked to this txid would be two types of transactions: - a) oracle providers - b) oracle data users - - In order to be resistant to sybil attacks, the feedback mechanism needs to have a cost. combining with the idea of payments for data, the oracle providers will be ranked by actual payments made to each oracle for each data type. - - Implementation notes: - In order to maintain good performance even under heavy usage, special marker utxo are used. Actually a pair of them. When a provider registers to be a data provider, a special unspendable normal output is created to allow for quick scanning. Since the marker is based on the oracletxid, it becomes a single address where all the providers can be found. - - A convention is used so that the datafee can be changed by registering again. it is assumed that there wont be too many of these datafee changes. if more than one from the same provider happens in the same block, the lower price is used. - - The other efficiency issue is finding the most recent data point. We want to create a linked list of all data points, going back to the first one. In order to make this efficient, a special and unique per provider/oracletxid baton utxo is used. This should have exactly one utxo, so the search would be a direct lookup and it is passed on from one data point to the next. There is some small chance that the baton utxo is spent in a non-data transaction, so provision is made to allow for recreating a baton utxo in case it isnt found. The baton utxo is a convenience and doesnt affect validation - - Required transactions: - 0) create oracle description -> just needs to create txid for oracle data - 1) register as oracle data provider with price -> become a registered oracle data provider - 2) pay provider for N oracle data points -> lock funds for oracle provider - 3) publish oracle data point -> publish data and collect payment - - The format string is a set of chars with the following meaning: - 's' -> <256 char string - 'S' -> <65536 char string - 'd' -> <256 binary data - 'D' -> <65536 binary data - 'c' -> 1 byte signed little endian number, 'C' unsigned - 't' -> 2 byte signed little endian number, 'T' unsigned - 'i' -> 4 byte signed little endian number, 'I' unsigned - 'l' -> 8 byte signed little endian number, 'L' unsigned - 'h' -> 32 byte hash - - create: - vins.*: normal inputs - vout.0: txfee tag to oracle normal address - vout.1: change, if any - vout.n-1: opreturn with name and description and format for data - - register: - vins.*: normal inputs - vout.0: txfee tag to normal marker address - vout.1: baton CC utxo - vout.2: change, if any - vout.n-1: opreturn with oracletxid, pubkey and price per data point - - subscribe: - vins.*: normal inputs - vout.0: subscription fee to publishers CC address - vout.1: change, if any - vout.n-1: opreturn with oracletxid, registered provider's pubkey, amount - - data: - vin.0: normal input - vin.1: baton CC utxo (most of the time) - vin.2+: subscription or data vout.0 - vout.0: change to publishers CC address - vout.1: baton CC utxo - vout.2: payment for dataprovider - vout.3: change, if any - vout.n-1: opreturn with oracletxid, prevbatontxid and data in proper format - - data (without payment) this is not needed as publisher can pay themselves! - vin.0: normal input - vin.1: baton CC utxo - vout.0: txfee to publishers normal address - vout.1: baton CC utxo - vout.2: change, if any - vout.n-1: opreturn with oracletxid, prevbatontxid and data in proper format - -*/ -extern int32_t hush_get_current_height(); -#define PUBKEY_SPOOFING_FIX_ACTIVATION 1563148800 -#define CC_MARKER_VALUE 10000 - -// start of consensus code -CScript EncodeOraclesCreateOpRet(uint8_t funcid,std::string name,std::string description,std::string format) -{ - CScript opret; uint8_t evalcode = EVAL_ORACLES; - opret << OP_RETURN << E_MARSHAL(ss << evalcode << funcid << name << format << description); - return(opret); -} - -uint8_t DecodeOraclesCreateOpRet(const CScript &scriptPubKey,std::string &name,std::string &description,std::string &format) -{ - std::vector vopret; uint8_t *script,e,f,funcid; - GetOpReturnData(scriptPubKey,vopret); - script = (uint8_t *)vopret.data(); - if ( vopret.size() > 2 && script[0] == EVAL_ORACLES ) - { - if ( script[1] == 'C' ) - { - if ( E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> name; ss >> format; ss >> description) != 0 ) - { - return(script[1]); - } else fprintf(stderr,"DecodeOraclesCreateOpRet unmarshal error for C\n"); - } - } - return(0); -} - -CScript EncodeOraclesOpRet(uint8_t funcid,uint256 oracletxid,CPubKey pk,int64_t num) -{ - CScript opret; uint8_t evalcode = EVAL_ORACLES; - - opret << OP_RETURN << E_MARSHAL(ss << evalcode << funcid << oracletxid << pk << num); - return(opret); -} - -uint8_t DecodeOraclesOpRet(const CScript &scriptPubKey,uint256 &oracletxid,CPubKey &pk,int64_t &num) -{ - std::vector vopret; uint8_t *script,e,f; - - GetOpReturnData(scriptPubKey,vopret); - script = (uint8_t *)vopret.data(); - if ( vopret.size() > 2 && script[0] == EVAL_ORACLES ) - { - if (script[0] == EVAL_ORACLES && (script[1]== 'R' || script[1] == 'S' || script[1] == 'F') && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> oracletxid; ss >> pk; ss >> num)!=0) - return(f); - else return(script[1]); - } - return(0); -} - -CScript EncodeOraclesData(uint8_t funcid,uint256 oracletxid,uint256 batontxid,CPubKey pk,std::vector data) -{ - CScript opret; uint8_t evalcode = EVAL_ORACLES; - opret << OP_RETURN << E_MARSHAL(ss << evalcode << funcid << oracletxid << batontxid << pk << data); - return(opret); -} - -uint8_t DecodeOraclesData(const CScript &scriptPubKey,uint256 &oracletxid,uint256 &batontxid,CPubKey &pk,std::vector &data) -{ - std::vector vopret; uint8_t *script,e,f; - GetOpReturnData(scriptPubKey,vopret); - script = (uint8_t *)vopret.data(); - if ( vopret.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> oracletxid; ss >> batontxid; ss >> pk; ss >> data) != 0 ) - { - if ( e == EVAL_ORACLES && f == 'D' ) - return(f); - //else fprintf(stderr,"DecodeOraclesData evalcode.%d f.%c\n",e,f); - } //else fprintf(stderr,"DecodeOraclesData not enough opereturn data\n"); - return(0); -} - -CPubKey OracleBatonPk(char *batonaddr,struct CCcontract_info *cp) -{ - static secp256k1_context *ctx; - size_t clen = CPubKey::PUBLIC_KEY_SIZE; - secp256k1_pubkey pubkey; CPubKey batonpk; uint8_t priv[32]; int32_t i; - if ( ctx == 0 ) - ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN); - Myprivkey(priv); - cp->unspendableEvalcode2 = EVAL_ORACLES; - for (i=0; i<32; i++) - cp->unspendablepriv2[i] = (priv[i] ^ cp->CCpriv[i]); - while ( secp256k1_ec_seckey_verify(ctx,cp->unspendablepriv2) == 0 ) - { - for (i=0; i<32; i++) - fprintf(stderr,"%02x",cp->unspendablepriv2[i]); - fprintf(stderr," invalid privkey\n"); - if ( secp256k1_ec_privkey_tweak_add(ctx,cp->unspendablepriv2,priv) != 0 ) - break; - } - if ( secp256k1_ec_pubkey_create(ctx,&pubkey,cp->unspendablepriv2) != 0 ) - { - secp256k1_ec_pubkey_serialize(ctx,(unsigned char*)batonpk.begin(),&clen,&pubkey,SECP256K1_EC_COMPRESSED); - cp->unspendablepk2 = batonpk; - Getscriptaddress(batonaddr,MakeCC1vout(cp->evalcode,0,batonpk).scriptPubKey); - //fprintf(stderr,"batonpk.(%s) -> %s\n",(char *)HexStr(batonpk).c_str(),batonaddr); - strcpy(cp->unspendableaddr2,batonaddr); - } else fprintf(stderr,"error creating pubkey\n"); - memset(priv,0,sizeof(priv)); - return(batonpk); -} - -int64_t OracleCurrentDatafee(uint256 reforacletxid,char *markeraddr,CPubKey publisher) -{ - uint256 txid,oracletxid,hashBlock; int64_t datafee=0,dfee; int32_t dheight=0,vout,height,numvouts; CTransaction tx; CPubKey pk; - std::vector > unspentOutputs; - SetCCunspents(unspentOutputs,markeraddr,false); - for (std::vector >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++) - { - txid = it->first.txhash; - vout = (int32_t)it->first.index; - height = (int32_t)it->second.blockHeight; - if ( myGetTransaction(txid,tx,hashBlock) != 0 && (numvouts= tx.vout.size()) > 0 ) - { - if ( DecodeOraclesOpRet(tx.vout[numvouts-1].scriptPubKey,oracletxid,pk,dfee) == 'R' ) - { - if ( oracletxid == reforacletxid && pk == publisher ) - { - if ( height > dheight || (height == dheight && dfee < datafee) ) - { - dheight = height; - datafee = dfee; - if ( 0 && dheight != 0 ) - fprintf(stderr,"set datafee %.8f height.%d\n",(double)datafee/COIN,height); - } - } - } - } - } - return(datafee); -} - -int64_t OracleDatafee(CScript &scriptPubKey,uint256 oracletxid,CPubKey publisher) -{ - CTransaction oracletx; char markeraddr[64]; uint256 hashBlock; std::string name,description,format; int32_t numvouts; int64_t datafee = 0; - if ( myGetTransaction(oracletxid,oracletx,hashBlock) != 0 && (numvouts= oracletx.vout.size()) > 0 ) - { - if ( DecodeOraclesCreateOpRet(oracletx.vout[numvouts-1].scriptPubKey,name,description,format) == 'C' ) - { - CCtxidaddr(markeraddr,oracletxid); - datafee = OracleCurrentDatafee(oracletxid,markeraddr,publisher); - } - else - { - fprintf(stderr,"Could not decode op_ret from transaction %s\nscriptPubKey: %s\n", oracletxid.GetHex().c_str(), oracletx.vout[numvouts-1].scriptPubKey.ToString().c_str()); - } - } - return(datafee); -} - -static uint256 myIs_baton_spentinmempool(uint256 batontxid,int32_t batonvout) -{ - std::vector tmp_txs; - myGet_mempool_txs(tmp_txs,EVAL_ORACLES,'D'); - for (std::vector::const_iterator it=tmp_txs.begin(); it!=tmp_txs.end(); it++) - { - const CTransaction &tx = *it; - if ( tx.vout.size() > 0 && tx.vin.size() > 1 && batontxid == tx.vin[1].prevout.hash && batonvout == tx.vin[1].prevout.n ) - { - const uint256 &txid = tx.GetHash(); - //char str[65]; fprintf(stderr,"found baton spent in mempool %s\n",uint256_str(str,txid)); - return(txid); - } - } - return(batontxid); -} - -uint256 OracleBatonUtxo(uint64_t txfee,struct CCcontract_info *cp,uint256 reforacletxid,char *batonaddr,CPubKey publisher,std::vector &dataarg) -{ - uint256 txid,oracletxid,hashBlock,btxid,batontxid = zeroid; int64_t dfee; int32_t dheight=0,vout,height,numvouts; CTransaction tx; CPubKey pk; uint8_t *ptr; std::vector vopret,data; - std::vector > unspentOutputs; - SetCCunspents(unspentOutputs,batonaddr,true); - for (std::vector >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++) - { - txid = it->first.txhash; - vout = (int32_t)it->first.index; - height = (int32_t)it->second.blockHeight; - if ( it->second.satoshis != txfee ) - { - fprintf(stderr,"it->second.satoshis %llu != %llu txfee\n",(long long)it->second.satoshis,(long long)txfee); - continue; - } - if ( myGetTransaction(txid,tx,hashBlock) != 0 && (numvouts= tx.vout.size()) > 0 ) - { - GetOpReturnData(tx.vout[numvouts-1].scriptPubKey,vopret); - if ( vopret.size() > 2 ) - { - ptr = (uint8_t *)vopret.data(); - if ( (ptr[1] == 'D' && DecodeOraclesData(tx.vout[numvouts-1].scriptPubKey,oracletxid,btxid,pk,data) == 'D') || (ptr[1] == 'R' && DecodeOraclesOpRet(tx.vout[numvouts-1].scriptPubKey,oracletxid,pk,dfee) == 'R') ) - { - if ( oracletxid == reforacletxid && pk == publisher ) - { - if ( height > dheight ) - { - dheight = height; - batontxid = txid; - if ( ptr[1] == 'D' ) - dataarg = data; - //char str[65]; fprintf(stderr,"set batontxid %s height.%d\n",uint256_str(str,batontxid),height); - } - } - } - } - } - } - while ( myIsutxo_spentinmempool(ignoretxid,ignorevin,batontxid,1) != 0 ) - batontxid = myIs_baton_spentinmempool(batontxid,1); - return(batontxid); -} - -uint256 OraclesBatontxid(uint256 reforacletxid,CPubKey refpk) -{ - std::vector > unspentOutputs; - CTransaction regtx; uint256 hash,txid,batontxid,oracletxid; CPubKey pk; int32_t numvouts,height,maxheight=0; int64_t datafee; char markeraddr[64],batonaddr[64]; std::vector data; struct CCcontract_info *cp,C; - batontxid = zeroid; - cp = CCinit(&C,EVAL_ORACLES); - CCtxidaddr(markeraddr,reforacletxid); - SetCCunspents(unspentOutputs,markeraddr,false); - //char str[67]; fprintf(stderr,"markeraddr.(%s) %s\n",markeraddr,pubkey33_str(str,(uint8_t *)&refpk)); - for (std::vector >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++) - { - txid = it->first.txhash; - //fprintf(stderr,"check %s\n",uint256_str(str,txid)); - height = (int32_t)it->second.blockHeight; - if ( myGetTransaction(txid,regtx,hash) != 0 ) - { - if ( regtx.vout.size() > 0 && DecodeOraclesOpRet(regtx.vout[regtx.vout.size()-1].scriptPubKey,oracletxid,pk,datafee) == 'R' && oracletxid == reforacletxid && pk == refpk ) - { - Getscriptaddress(batonaddr,regtx.vout[1].scriptPubKey); - batontxid = OracleBatonUtxo(10000,cp,oracletxid,batonaddr,pk,data); - break; - } - } - } - return(batontxid); -} - -int32_t oracle_format(uint256 *hashp,int64_t *valp,char *str,uint8_t fmt,uint8_t *data,int32_t offset,int32_t datalen) -{ - char _str[65]; int32_t sflag = 0,i,val32,len = 0,slen = 0,dlen = 0; uint32_t uval32; uint16_t uval16; int16_t val16; int64_t val = 0; uint64_t uval = 0; - *valp = 0; - *hashp = zeroid; - if ( str != 0 ) - str[0] = 0; - switch ( fmt ) - { - case 's': slen = data[offset++]; break; - case 'S': slen = data[offset++]; slen |= ((int32_t)data[offset++] << 8); break; - case 'd': dlen = data[offset++]; break; - case 'D': dlen = data[offset++]; dlen |= ((int32_t)data[offset++] << 8); break; - case 'c': len = 1; sflag = 1; break; - case 'C': len = 1; break; - case 't': len = 2; sflag = 1; break; - case 'T': len = 2; break; - case 'i': len = 4; sflag = 1; break; - case 'I': len = 4; break; - case 'l': len = 8; sflag = 1; break; - case 'L': len = 8; break; - case 'h': len = 32; break; - default: return(-1); break; - } - if ( slen != 0 ) - { - if ( str != 0 ) - { - if ( slen < DRAGON_MAXSCRIPTSIZE && offset+slen <= datalen ) - { - for (i=0; i data,std::string format) -{ - int64_t offset=0,len=0; char fmt; - - for (int i=0; idata.size()-offset) return (0); - if (fmt=='S' || fmt=='s') - { - for (int j=offset;j127) return (0); - } - offset+=len; - } - if (offset!=data.size()) return (0); - else return (offset); -} - -int64_t _correlate_price(int64_t *prices,int32_t n,int64_t price) -{ - int32_t i,count = 0; int64_t diff,threshold = (price >> 8); - for (i=0; i> 1) ) - return(0); - else return(price); -} - -int64_t correlate_price(int32_t height,int64_t *prices,int32_t n) -{ - int32_t i,j; int64_t price = 0; - if ( n == 1 ) - return(prices[0]); - for (i=0; i %llu ht.%d\n",(long long)price,height); - return(price); -} - -int64_t OracleCorrelatedPrice(int32_t height,std::vector origprices) -{ - std::vector sorted; int32_t i,n; int64_t *prices,price; - if ( (n= origprices.size()) == 1 ) - return(origprices[0]); - std::sort(origprices.begin(), origprices.end()); - prices = (int64_t *)calloc(n,sizeof(*prices)); - i = 0; - for (std::vector::const_iterator it=sorted.begin(); it!=sorted.end(); it++) - prices[i++] = *it; - price = correlate_price(height,prices,i); - free(prices); - return(price); -} - -int32_t oracleprice_add(std::vector &publishers,CPubKey pk,int32_t height,std::vector data,int32_t maxheight) -{ - struct oracleprice_info item; int32_t flag = 0; - for (std::vector::iterator it=publishers.begin(); it!=publishers.end(); it++) - { - if ( pk == it->pk ) - { - flag = 1; - if ( height > it->height ) - { - it->height = height; - it->data = data; - return(height); - } - } - } - if ( flag == 0 ) - { - item.pk = pk; - item.data = data; - item.height = height; - publishers.push_back(item); - return(height); - } else return(0); -} - -/*int64_t OraclePrice(int32_t height,uint256 reforacletxid,char *markeraddr,char *format) -{ - std::vector > unspentOutputs; - CTransaction regtx; uint256 hash,txid,oracletxid,batontxid; CPubKey pk; int32_t i,ht,maxheight=0; int64_t datafee,price; char batonaddr[64]; std::vector data; struct CCcontract_info *cp,C; std::vector publishers; std::vector prices; - if ( format[0] != 'L' ) - return(0); - cp = CCinit(&C,EVAL_ORACLES); - SetCCunspents(unspentOutputs,markeraddr,false); - for (std::vector >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++) - { - txid = it->first.txhash; - ht = (int32_t)it->second.blockHeight; - if ( myGetTransaction(txid,regtx,hash) != 0 ) - { - if ( regtx.vout.size() > 0 && DecodeOraclesOpRet(regtx.vout[regtx.vout.size()-1].scriptPubKey,oracletxid,pk,datafee) == 'R' && oracletxid == reforacletxid ) - { - Getscriptaddress(batonaddr,regtx.vout[1].scriptPubKey); - batontxid = OracleBatonUtxo(10000,cp,oracletxid,batonaddr,pk,data); - if ( batontxid != zeroid && (ht= oracleprice_add(publishers,pk,ht,data,maxheight)) > maxheight ) - maxheight = ht; - } - } - } - if ( maxheight > 10 ) - { - for (std::vector::const_iterator it=publishers.begin(); it!=publishers.end(); it++) - { - if ( it->height >= maxheight-10 ) - { - oracle_format(&hash,&price,0,'L',(uint8_t *)it->data.data(),0,(int32_t)it->data.size()); - if ( price != 0 ) - prices.push_back(price); - } - } - return(OracleCorrelatedPrice(height,prices)); - } - return(0); -}*/ - -int64_t IsOraclesvout(struct CCcontract_info *cp,const CTransaction& tx,int32_t v) -{ - //char destaddr[64]; - if ( tx.vout[v].scriptPubKey.IsPayToCryptoCondition() != 0 ) - { - //if ( Getscriptaddress(destaddr,tx.vout[v].scriptPubKey) > 0 && strcmp(destaddr,cp->unspendableCCaddr) == 0 ) - return(tx.vout[v].nValue); - } - return(0); -} - -bool OraclesDataValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx,uint256 oracletxid,CPubKey publisher,int64_t datafee) -{ - static uint256 zerohash; - CTransaction vinTx; uint256 hashBlock,activehash; int32_t i,numvins,numvouts; int64_t inputs=0,outputs=0,assetoshis; CScript scriptPubKey; - numvins = tx.vin.size(); - numvouts = tx.vout.size(); - if ( OracleDatafee(scriptPubKey,oracletxid,publisher) != datafee ) - return eval->Invalid("mismatched datafee"); - scriptPubKey = MakeCC1vout(cp->evalcode,0,publisher).scriptPubKey; - for (i=0; iismyvin)(tx.vin[i].scriptSig) != 0 ) - { - if ( i == 0 ) - return eval->Invalid("unexpected vin.0 is CC"); - //fprintf(stderr,"vini.%d check mempool\n",i); - else if ( eval->GetTxUnconfirmed(tx.vin[i].prevout.hash,vinTx,hashBlock) == 0 ) - return eval->Invalid("cant find vinTx"); - else - { - //fprintf(stderr,"vini.%d check hash and vout\n",i); - //if ( hashBlock == zerohash ) - // return eval->Invalid("cant Oracles from mempool"); - if ( (assetoshis= IsOraclesvout(cp,vinTx,tx.vin[i].prevout.n)) != 0 ) - { - if ( i == 1 && vinTx.vout[1].scriptPubKey != tx.vout[1].scriptPubKey ) - return eval->Invalid("baton violation"); - else if ( i != 1 && scriptPubKey == vinTx.vout[tx.vin[i].prevout.n].scriptPubKey ) - inputs += assetoshis; - } - } - } - } - for (i=0; iInvalid("invalid CC vout CC destination"); - } - } - } - } - if ( inputs != outputs+datafee ) - { - fprintf(stderr,"inputs %llu vs outputs %llu + datafee %llu\n",(long long)inputs,(long long)outputs,(long long)datafee); - return eval->Invalid("mismatched inputs != outputs + datafee"); - } - else return(true); -} - -/*nt32_t GetLatestTimestamp(int32_t height) -{ - if ( HUSH_NSPV_SUPERLITE ) return (NSPV_blocktime(height)); - return(hush_heightstamp(height)); -} */ - -bool OraclesValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn) -{ - uint256 oracletxid,batontxid,txid; uint64_t txfee=10000; int32_t numvins,numvouts,preventCCvins,preventCCvouts; int64_t amount; uint256 hashblock; - uint8_t *script; std::vector vopret,data; CPubKey publisher,tmppk,oraclespk; char tmpaddress[64],vinaddress[64],oraclesaddr[64]; - CTransaction tmptx; std::string name,desc,format; - - numvins = tx.vin.size(); - numvouts = tx.vout.size(); - preventCCvins = preventCCvouts = -1; - if ( numvouts < 1 ) - return eval->Invalid("no vouts"); - else - { - GetOpReturnData(tx.vout[numvouts-1].scriptPubKey,vopret); - if ( vopret.size() > 2 ) - { - oraclespk=GetUnspendable(cp,0); - Getscriptaddress(oraclesaddr,CScript() << ParseHex(HexStr(oraclespk)) << OP_CHECKSIG); - script = (uint8_t *)vopret.data(); - switch ( script[1] ) - { - case 'C': // create - // vins.*: normal inputs - // vout.0: txfee tag to oracle normal address - // vout.1: change, if any - // vout.n-1: opreturn with name and description and format for data - return eval->Invalid("unexpected OraclesValidate for create"); - break; - case 'F': // fund (activation on Jul 15th 2019 00:00) - // vins.*: normal inputs - // vout.0: txfee to oracle CC address of users pubkey - // vout.1: change, if any - // vout.n-1: opreturn with createtxid, pubkey and amount - return eval->Invalid("unexpected OraclesValidate for create"); - break; - case 'R': // register - // vin.0: normal inputs - // vin.n-1: CC input from pubkeys oracle CC addres - to prove that register came from pubkey that is registred (activation on Jul 15th 2019 00:00) - // vout.0: txfee tag to normal marker address - // vout.1: baton CC utxo - // vout.2: marker from oraclesfund tx to normal pubkey address (activation on Jul 15th 2019 00:00) - // vout.n-2: change, if any - // vout.n-1: opreturn with createtxid, pubkey and price per data point - if (GetLatestTimestamp(eval->GetCurrentHeight())>PUBKEY_SPOOFING_FIX_ACTIVATION) - { - if ((numvouts=tx.vout.size()) < 1 || DecodeOraclesOpRet(tx.vout[numvouts-1].scriptPubKey,oracletxid,tmppk,amount)!='R') - return eval->Invalid("invalid oraclesregister OP_RETURN data!"); - else if (myGetTransaction(oracletxid,tmptx,hashblock) == 0) - return eval->Invalid("invalid oraclescreate txid!"); - else if ((numvouts=tmptx.vout.size()) < 1 || DecodeOraclesCreateOpRet(tmptx.vout[numvouts-1].scriptPubKey,name,desc,format)!='C') - return eval->Invalid("invalid oraclescreate OP_RETURN data!"); - else if ( IsCCInput(tmptx.vin[0].scriptSig) != 0 ) - return eval->Invalid("vin.0 is normal for oraclescreate!"); - else if (ConstrainVout(tmptx.vout[0],0,oraclesaddr,txfee)==0) - return eval->Invalid("invalid marker for oraclescreate!"); - else if ( IsCCInput(tx.vin[0].scriptSig) != 0 ) - return eval->Invalid("vin.0 is normal for oraclesregister!"); - else if ((*cp->ismyvin)(tx.vin[1].scriptSig) == 0 && (*cp->ismyvin)(tx.vin[tx.vin.size()-1].scriptSig) == 0) - return eval->Invalid("there is no CC vin from oraclesfund tx"); - else if ((*cp->ismyvin)(tx.vin[1].scriptSig) == 1 && (myGetTransaction(tx.vin[1].prevout.hash,tmptx,hashblock)==0 || DecodeOraclesOpRet(tmptx.vout[tmptx.vout.size()-1].scriptPubKey,txid,tmppk,amount)!='F' - || tmptx.vout[tx.vin[1].prevout.n].nValue!=CC_MARKER_VALUE || !Getscriptaddress(vinaddress,tmptx.vout[tx.vin[1].prevout.n].scriptPubKey) - || !GetCCaddress(cp,tmpaddress,tmppk) || strcmp(tmpaddress,vinaddress)!=0) || oracletxid!=txid) - return eval->Invalid("invalid vin.1 for oraclesregister, it must be CC vin or pubkey not same as vin pubkey, register and fund tx must be done from owner of pubkey that registers to oracle!!"); - else if ((*cp->ismyvin)(tx.vin[tx.vin.size()-1].scriptSig) == 1 && (myGetTransaction(tx.vin[tx.vin.size()-1].prevout.hash,tmptx,hashblock)==0 || DecodeOraclesOpRet(tmptx.vout[tmptx.vout.size()-1].scriptPubKey,txid,tmppk,amount)!='F' - || tmptx.vout[tx.vin[tx.vin.size()-1].prevout.n].nValue!=CC_MARKER_VALUE || !Getscriptaddress(vinaddress,tmptx.vout[tx.vin[tx.vin.size()-1].prevout.n].scriptPubKey) - || !GetCCaddress(cp,tmpaddress,tmppk) || strcmp(tmpaddress,vinaddress)!=0) || oracletxid!=txid) - return eval->Invalid("invalid vin."+std::to_string(tx.vin.size()-1)+" for oraclesregister, it must be CC vin or pubkey not same as vin pubkey, register and fund tx must be done from owner of pubkey that registers to oracle!!"); - else if (CCtxidaddr(tmpaddress,oracletxid).IsValid() && ConstrainVout(tx.vout[0],0,tmpaddress,txfee)==0) - return eval->Invalid("invalid marker for oraclesregister!"); - else if (!Getscriptaddress(tmpaddress,CScript() << ParseHex(HexStr(tmppk)) << OP_CHECKSIG) || ConstrainVout(tx.vout[2],0,tmpaddress,CC_MARKER_VALUE)==0) - return eval->Invalid("pubkey in OP_RETURN and in vout.2 not matching, register must be done from owner of pubkey that registers to oracle!"); - } - else return eval->Invalid("unexpected OraclesValidate for register"); - break; - case 'S': // subscribe - // vins.*: normal inputs - // vout.0: subscription fee to publishers CC address - // vout.1: change, if any - // vout.n-1: opreturn with createtxid, registered provider's pubkey, amount - return eval->Invalid("unexpected OraclesValidate for subscribe"); - break; - case 'D': // data - // vin.0: normal input - // vin.1: baton CC utxo (most of the time) - // vin.2+: subscription vout.0 - // vout.0: change to publishers CC address - // vout.1: baton CC utxo - // vout.2: payment for dataprovider - // vout.3: change, if any - if ( numvins >= 2 && numvouts >= 3 && DecodeOraclesData(tx.vout[numvouts-1].scriptPubKey,oracletxid,batontxid,publisher,data) == 'D' ) - { - if ( OraclesDataValidate(cp,eval,tx,oracletxid,publisher,tx.vout[2].nValue) != 0 ) - { - return(true); - } else return(false); - } - return eval->Invalid("unexpected OraclesValidate 'D' tx invalid"); - break; - default: - fprintf(stderr,"illegal oracles funcid.(%c)\n",script[1]); - return eval->Invalid("unexpected OraclesValidate funcid"); - break; - } - } else return eval->Invalid("unexpected oracles missing funcid"); - return(PreventCC(eval,tx,preventCCvins,numvins,preventCCvouts,numvouts)); - } - return(true); -} -// end of consensus code - -// helper functions for rpc calls in rpcwallet.cpp - -int64_t AddOracleInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,uint256 oracletxid,CPubKey pk,int64_t total,int32_t maxinputs) -{ - char coinaddr[64],funcid; int64_t nValue,price,totalinputs = 0; uint256 tmporacletxid,tmpbatontxid,txid,hashBlock; std::vector origpubkey,data; CTransaction vintx; int32_t numvouts,vout,n = 0; - std::vector > unspentOutputs; CPubKey tmppk; int64_t tmpnum; - GetCCaddress(cp,coinaddr,pk); - SetCCunspents(unspentOutputs,coinaddr,true); - //fprintf(stderr,"addoracleinputs from (%s)\n",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,"oracle check %s/v%d\n",uint256_str(str,txid),vout); - if ( myGetTransaction(txid,vintx,hashBlock) != 0 && (numvouts=vintx.vout.size()-1)>0) - { - if ((funcid=DecodeOraclesOpRet(vintx.vout[numvouts].scriptPubKey,tmporacletxid,tmppk,tmpnum))!=0 && (funcid=='S' || funcid=='D')) - { - if (funcid=='D' && DecodeOraclesData(vintx.vout[numvouts].scriptPubKey,tmporacletxid,tmpbatontxid,tmppk,data)==0) - fprintf(stderr,"invalid oraclesdata transaction \n"); - else if (tmporacletxid==oracletxid) - { - // get valid CC payments - if ( (nValue= IsOraclesvout(cp,vintx,vout)) >= 10000 && myIsutxo_spentinmempool(ignoretxid,ignorevin,txid,vout) == 0 ) - { - if ( total != 0 && maxinputs != 0 ) - mtx.vin.push_back(CTxIn(txid,vout,CScript())); - nValue = it->second.satoshis; - totalinputs += nValue; - n++; - if ( (total > 0 && totalinputs >= total) || (maxinputs > 0 && n >= maxinputs) ) - break; - } //else fprintf(stderr,"nValue %.8f or utxo memspent\n",(double)nValue/COIN); - } - } - } else fprintf(stderr,"couldnt find transaction\n"); - } - return(totalinputs); -} - -int64_t LifetimeOraclesFunds(struct CCcontract_info *cp,uint256 oracletxid,CPubKey publisher) -{ - char coinaddr[64]; CPubKey pk; int64_t total=0,num; uint256 txid,hashBlock,subtxid; CTransaction subtx; - std::vector txids; - GetCCaddress(cp,coinaddr,publisher); - SetCCtxids(txids,coinaddr,true,cp->evalcode,oracletxid,'S'); - //fprintf(stderr,"scan lifetime of %s\n",coinaddr); - for (std::vector::const_iterator it=txids.begin(); it!=txids.end(); it++) - { - txid = *it; - if ( myGetTransaction(txid,subtx,hashBlock) != 0 ) - { - if ( subtx.vout.size() > 0 && DecodeOraclesOpRet(subtx.vout[subtx.vout.size()-1].scriptPubKey,subtxid,pk,num) == 'S' && subtxid == oracletxid && pk == publisher ) - { - total += subtx.vout[0].nValue; - } - } - } - return(total); -} - -int64_t AddMyOraclesFunds(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,uint256 oracletxid) -{ - char coinaddr[64],funcid; int64_t nValue,tmpamount; uint256 tmporacletxid,txid,hashBlock,ignoretxid; int32_t numvouts,vout,ignorevin; - std::vector > unspentOutputs; CTransaction vintx; CPubKey tmppk; - - GetCCaddress(cp,coinaddr,pk); - SetCCunspents(unspentOutputs,coinaddr,true); - for (std::vector >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++) - { - txid = it->first.txhash; - vout = (int32_t)it->first.index; - nValue = it->second.satoshis; - if ( myGetTransaction(txid,vintx,hashBlock) != 0 && (numvouts=vintx.vout.size())>0) - { - if ((funcid=DecodeOraclesOpRet(vintx.vout[numvouts-1].scriptPubKey,tmporacletxid,tmppk,tmpamount))!=0 && funcid=='F' && tmppk==pk - && tmporacletxid==oracletxid && tmpamount==nValue && myIsutxo_spentinmempool(ignoretxid,ignorevin,txid,vout)==0) - { - mtx.vin.push_back(CTxIn(txid,vout,CScript())); - return (nValue); - } - } else fprintf(stderr,"couldnt find transaction\n"); - } - - std::vector tmp_txs; - myGet_mempool_txs(tmp_txs,EVAL_ORACLES,'F'); - for (std::vector::const_iterator it=tmp_txs.begin(); it!=tmp_txs.end(); it++) - { - const CTransaction &txmempool = *it; - const uint256 &hash = txmempool.GetHash(); - nValue=txmempool.vout[0].nValue; - - if ((funcid=DecodeOraclesOpRet(txmempool.vout[txmempool.vout.size()-1].scriptPubKey,tmporacletxid,tmppk,tmpamount))!=0 && funcid=='F' - && tmppk==pk && tmporacletxid==oracletxid && tmpamount==nValue && myIsutxo_spentinmempool(ignoretxid,ignorevin,hash,0)==0) - { - mtx.vin.push_back(CTxIn(hash,0,CScript())); - return (nValue); - } - } - return (0); -} - -UniValue OracleCreate(const CPubKey& pk, int64_t txfee,std::string name,std::string description,std::string format) -{ - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), hush_nextheight()); - CPubKey mypk,Oraclespk; struct CCcontract_info *cp,C; char fmt; - - cp = CCinit(&C,EVAL_ORACLES); - if ( name.size() > 32) - CCERR_RESULT("oraclescc",CCLOG_INFO, stream << "name."<< (int32_t)name.size() << " must be less then 32"); - if (description.size() > 4096) - CCERR_RESULT("oraclescc",CCLOG_INFO, stream << "description."<< (int32_t)description.size() << " must be less then 4096"); - if (format.size() > 4096 ) - CCERR_RESULT("oraclescc",CCLOG_INFO, stream << "format."<< (int32_t)format.size() << " must be less then 4096"); - if ( name.size() == 0 ) - CCERR_RESULT("oraclescc",CCLOG_INFO, stream << "name must not be empty"); - for(int i = 0; i < format.size(); i++) - { - fmt=format[i]; - switch (fmt) - { - case 's': case 'S': case 'd': case 'D': - case 'c': case 'C': case 't': case 'T': - case 'i': case 'I': case 'l': case 'L': - case 'h': break; - default: CCERR_RESULT("oraclescc",CCLOG_INFO, stream << "invalid format type"); - } - } - if ( txfee == 0 ) - txfee = 10000; - mypk = pk.IsValid()?pk:pubkey2pk(Mypubkey()); - Oraclespk = GetUnspendable(cp,0); - if ( AddNormalinputs(mtx,mypk,2*txfee,3,pk.IsValid()) > 0 ) - { - mtx.vout.push_back(CTxOut(txfee,CScript() << ParseHex(HexStr(Oraclespk)) << OP_CHECKSIG)); - return(FinalizeCCTxExt(pk.IsValid(),0,cp,mtx,mypk,txfee,EncodeOraclesCreateOpRet('C',name,description,format))); - } - CCERR_RESULT("oraclescc",CCLOG_INFO, stream << "error adding normal inputs"); -} - -UniValue OracleFund(const CPubKey& pk, int64_t txfee,uint256 oracletxid) -{ - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), hush_nextheight()); CTransaction tx; - CPubKey mypk,oraclespk; struct CCcontract_info *cp,C; std::string name,desc,format; int32_t numvouts; uint256 hashBlock; - - if (GetLatestTimestamp(hush_currentheight())evalcode,CC_MARKER_VALUE,mypk)); - return(FinalizeCCTxExt(pk.IsValid(),0,cp,mtx,mypk,txfee,EncodeOraclesOpRet('F',oracletxid,mypk,CC_MARKER_VALUE))); - } - CCERR_RESULT("oraclescc",CCLOG_INFO, stream << "error adding normal inputs"); -} - -UniValue OracleRegister(const CPubKey& pk, int64_t txfee,uint256 oracletxid,int64_t datafee) -{ - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), hush_nextheight()); - CPubKey mypk,markerpubkey,batonpk,oraclespk; struct CCcontract_info *cp,C; char markeraddr[64],batonaddr[64]; - std::string name,desc,format; int32_t numvouts; uint256 hashBlock; CTransaction tx; - - cp = CCinit(&C,EVAL_ORACLES); - if ( txfee == 0 ) - txfee = 10000; - if (myGetTransaction(oracletxid,tx,hashBlock)==0 || (numvouts=tx.vout.size())<=0) - CCERR_RESULT("oraclecc",CCLOG_INFO, stream << "cant find oracletxid " << oracletxid.GetHex()); - if (DecodeOraclesCreateOpRet(tx.vout[numvouts-1].scriptPubKey,name,desc,format)!='C') - CCERR_RESULT("oraclecc",CCLOG_INFO, stream << "invalid oracletxid " << oracletxid.GetHex()); - if ( datafee < txfee ) - CCERR_RESULT("oraclescc",CCLOG_INFO, stream << "datafee must be txfee or more"); - mypk = pk.IsValid()?pk:pubkey2pk(Mypubkey()); - oraclespk = GetUnspendable(cp,0); - batonpk = OracleBatonPk(batonaddr,cp); - markerpubkey = CCtxidaddr(markeraddr,oracletxid); - if (AddNormalinputs(mtx,mypk,3*txfee,4,pk.IsValid())) - { - if (GetLatestTimestamp(hush_currentheight())>PUBKEY_SPOOFING_FIX_ACTIVATION && AddMyOraclesFunds(cp,mtx,mypk,oracletxid)!=CC_MARKER_VALUE) - CCERR_RESULT("oraclescc",CCLOG_INFO, stream << "error adding inputs from your Oracles CC address, please fund it first with oraclesfund rpc!"); - mtx.vout.push_back(CTxOut(txfee,CScript() << ParseHex(HexStr(markerpubkey)) << OP_CHECKSIG)); - mtx.vout.push_back(MakeCC1vout(cp->evalcode,txfee,batonpk)); - if (GetLatestTimestamp(hush_get_current_height())>PUBKEY_SPOOFING_FIX_ACTIVATION) mtx.vout.push_back(CTxOut(txfee,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG)); - return(FinalizeCCTxExt(pk.IsValid(),0,cp,mtx,mypk,txfee,EncodeOraclesOpRet('R',oracletxid,mypk,datafee))); - } - CCERR_RESULT("oraclescc",CCLOG_INFO, stream << "error adding normal inputs"); -} - -UniValue OracleSubscribe(const CPubKey& pk, int64_t txfee,uint256 oracletxid,CPubKey publisher,int64_t amount) -{ - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), hush_nextheight()); CTransaction tx; - CPubKey mypk,markerpubkey; struct CCcontract_info *cp,C; char markeraddr[64]; std::string name,desc,format; int32_t numvouts; uint256 hashBlock; - cp = CCinit(&C,EVAL_ORACLES); - if ( txfee == 0 ) - txfee = 10000; - if (myGetTransaction(oracletxid,tx,hashBlock)==0 || (numvouts=tx.vout.size())<=0) - CCERR_RESULT("oraclecc",CCLOG_INFO, stream << "cant find oracletxid " << oracletxid.GetHex()); - if (DecodeOraclesCreateOpRet(tx.vout[numvouts-1].scriptPubKey,name,desc,format)!='C') - CCERR_RESULT("oraclecc",CCLOG_INFO, stream << "invalid oracletxid " << oracletxid.GetHex()); - mypk = pk.IsValid()?pk:pubkey2pk(Mypubkey()); - markerpubkey = CCtxidaddr(markeraddr,oracletxid); - if ( AddNormalinputs(mtx,mypk,amount + 2*txfee,64,pk.IsValid()) > 0 ) - { - mtx.vout.push_back(MakeCC1vout(cp->evalcode,amount,publisher)); - mtx.vout.push_back(CTxOut(txfee,CScript() << ParseHex(HexStr(markerpubkey)) << OP_CHECKSIG)); - return(FinalizeCCTxExt(pk.IsValid(),0,cp,mtx,mypk,txfee,EncodeOraclesOpRet('S',oracletxid,mypk,amount))); - } - CCERR_RESULT("oraclescc",CCLOG_INFO, stream << "error adding normal inputs"); -} - -UniValue OracleData(const CPubKey& pk, int64_t txfee,uint256 oracletxid,std::vector data) -{ - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), hush_nextheight()); - CScript pubKey; CPubKey mypk,batonpk; int64_t offset,datafee,inputs,CCchange = 0; struct CCcontract_info *cp,C; uint256 batontxid,hashBlock; - char coinaddr[64],batonaddr[64]; std::vector prevdata; CTransaction tx; std::string name,description,format; int32_t len,numvouts; - - cp = CCinit(&C,EVAL_ORACLES); - mypk = pk.IsValid()?pk:pubkey2pk(Mypubkey()); - if ( data.size() > 8192 ) - CCERR_RESULT("oraclescc",CCLOG_INFO, stream << "datasize " << (int32_t)data.size() << " is too big"); - if ( (datafee= OracleDatafee(pubKey,oracletxid,mypk)) <= 0 ) - CCERR_RESULT("oraclescc",CCLOG_INFO, stream << "datafee " << (double)datafee/COIN << "is illegal"); - if ( myGetTransaction(oracletxid,tx,hashBlock) != 0 && (numvouts=tx.vout.size()) > 0 ) - { - if ( DecodeOraclesCreateOpRet(tx.vout[numvouts-1].scriptPubKey,name,description,format) == 'C' ) - { - if (oracle_parse_data_format(data,format)==0) - CCERR_RESULT("oraclescc",CCLOG_INFO, stream << "data does not match length or content format specification"); - } - else - CCERR_RESULT("oraclescc",CCLOG_INFO, stream << "invalid oracle txid opret data"); - } - else - CCERR_RESULT("oraclescc",CCLOG_INFO, stream << "invalid oracle txid"); - if ( txfee == 0 ) - txfee = 10000; - GetCCaddress(cp,coinaddr,mypk); - if ( AddNormalinputs(mtx,mypk,2*txfee,3,pk.IsValid()) > 0 ) // have enough funds even if baton utxo not there - { - batonpk = OracleBatonPk(batonaddr,cp); - batontxid = OracleBatonUtxo(txfee,cp,oracletxid,batonaddr,mypk,prevdata); - if ( batontxid != zeroid ) // not impossible to fail, but hopefully a very rare event - mtx.vin.push_back(CTxIn(batontxid,1,CScript())); - else fprintf(stderr,"warning: couldnt find baton utxo %s\n",batonaddr); - if ( (inputs= AddOracleInputs(cp,mtx,oracletxid,mypk,datafee,60)) > 0 ) - { - if ( inputs > datafee ) - CCchange = (inputs - datafee); - mtx.vout.push_back(MakeCC1vout(cp->evalcode,CCchange,mypk)); - mtx.vout.push_back(MakeCC1vout(cp->evalcode,CC_MARKER_VALUE,batonpk)); - mtx.vout.push_back(CTxOut(datafee,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG)); - return(FinalizeCCTxExt(pk.IsValid(),0,cp,mtx,mypk,txfee,EncodeOraclesData('D',oracletxid,batontxid,mypk,data))); - } else - CCERR_RESULT("oraclescc",CCLOG_INFO, stream << "couldnt find enough oracle inputs " << coinaddr << ", limit 1 per utxo"); - } - CCERR_RESULT("oraclescc",CCLOG_INFO, stream << "couldnt add normal inputs"); -} - -UniValue OracleFormat(uint8_t *data,int32_t datalen,char *format,int32_t formatlen) -{ - UniValue obj(UniValue::VARR); uint256 hash; int32_t i,j=0; int64_t val; char str[DRAGON_MAXSCRIPTSIZE*2+1]; - for (i=0; i= datalen ) - break; - } - return(obj); -} - -UniValue OracleDataSample(uint256 reforacletxid,uint256 txid) -{ - UniValue result(UniValue::VOBJ); CTransaction tx,oracletx; uint256 hashBlock,btxid,oracletxid; std::string error; - CPubKey pk; std::string name,description,format; int32_t numvouts; std::vector data; char str[67], *formatstr = 0; - - result.push_back(Pair("result","success")); - if ( myGetTransaction(reforacletxid,oracletx,hashBlock) != 0 && (numvouts=oracletx.vout.size()) > 0 ) - { - if ( DecodeOraclesCreateOpRet(oracletx.vout[numvouts-1].scriptPubKey,name,description,format) == 'C' ) - { - if ( myGetTransaction(txid,tx,hashBlock) != 0 && (numvouts=tx.vout.size()) > 0 ) - { - if ( DecodeOraclesData(tx.vout[numvouts-1].scriptPubKey,oracletxid,btxid,pk,data) == 'D' && reforacletxid == oracletxid ) - { - if ( (formatstr= (char *)format.c_str()) == 0 ) - formatstr = (char *)""; - result.push_back(Pair("txid",uint256_str(str,txid))); - result.push_back(Pair("data",OracleFormat((uint8_t *)data.data(),(int32_t)data.size(),formatstr,(int32_t)format.size()))); - return(result); - } - else error="invalid data tx"; - } - else error="cannot find data txid"; - } - else error="invalid oracles txid"; - } - else error="cannot find oracles txid"; - result.push_back(Pair("result","error")); - result.push_back(Pair("error",error)); - return(result); -} - -UniValue OracleDataSamples(uint256 reforacletxid,char* batonaddr,int32_t num) -{ - UniValue result(UniValue::VOBJ),b(UniValue::VARR); CTransaction tx,oracletx; uint256 txid,hashBlock,btxid,oracletxid; - CPubKey pk; std::string name,description,format; int32_t numvouts,n=0,vout; std::vector data; char *formatstr = 0, addr[64]; - std::vector txids; int64_t nValue; - - result.push_back(Pair("result","success")); - if ( myGetTransaction(reforacletxid,oracletx,hashBlock) != 0 && (numvouts=oracletx.vout.size()) > 0 ) - { - if ( DecodeOraclesCreateOpRet(oracletx.vout[numvouts-1].scriptPubKey,name,description,format) == 'C' ) - { - std::vector tmp_txs; - myGet_mempool_txs(tmp_txs,EVAL_ORACLES,'D'); - for (std::vector::const_iterator it=tmp_txs.begin(); it!=tmp_txs.end(); it++) - { - const CTransaction &txmempool = *it; - const uint256 &hash = txmempool.GetHash(); - if ((numvouts=txmempool.vout.size())>0 && txmempool.vout[1].nValue==CC_MARKER_VALUE && DecodeOraclesData(txmempool.vout[numvouts-1].scriptPubKey,oracletxid,btxid,pk,data) == 'D' && reforacletxid == oracletxid ) - { - Getscriptaddress(addr,txmempool.vout[1].scriptPubKey); - if (strcmp(addr,batonaddr)!=0) continue; - if ( (formatstr= (char *)format.c_str()) == 0 ) - formatstr = (char *)""; - UniValue a(UniValue::VOBJ); - a.push_back(Pair("txid",hash.GetHex())); - a.push_back(Pair("data",OracleFormat((uint8_t *)data.data(),(int32_t)data.size(),formatstr,(int32_t)format.size()))); - b.push_back(a); - if ( ++n >= num && num != 0) - { - result.push_back(Pair("samples",b)); - return(result); - } - } - } - SetCCtxids(txids,batonaddr,true,EVAL_ORACLES,reforacletxid,'D'); - if (txids.size()>0) - { - for (std::vector::const_iterator it=txids.end()-1; it!=txids.begin(); it--) - { - txid=*it; - if (myGetTransaction(txid,tx,hashBlock) != 0 && (numvouts=tx.vout.size()) > 0 ) - { - if ( tx.vout[1].nValue==CC_MARKER_VALUE && DecodeOraclesData(tx.vout[numvouts-1].scriptPubKey,oracletxid,btxid,pk,data) == 'D' && reforacletxid == oracletxid ) - { - if ( (formatstr= (char *)format.c_str()) == 0 ) - formatstr = (char *)""; - UniValue a(UniValue::VOBJ); - a.push_back(Pair("txid",txid.GetHex())); - a.push_back(Pair("data",OracleFormat((uint8_t *)data.data(),(int32_t)data.size(),formatstr,(int32_t)format.size()))); - b.push_back(a); - if ( ++n >= num && num != 0) - { - result.push_back(Pair("samples",b)); - return(result); - } - } - } - } - } - } - else - CCERR_RESULT("pegscc",CCLOG_INFO, stream << "invalid oracletxid " << oracletxid.GetHex()); - } - else - CCERR_RESULT("oraclescc",CCLOG_INFO, stream << "cant find oracletxid " << oracletxid.GetHex()); - result.push_back(Pair("samples",b)); - return(result); -} - -UniValue OracleInfo(uint256 origtxid) -{ - UniValue result(UniValue::VOBJ),a(UniValue::VARR); - std::vector > unspentOutputs; int32_t height; - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), hush_nextheight()); - CTransaction tx; std::string name,description,format; uint256 hashBlock,txid,oracletxid,batontxid; CPubKey pk; - struct CCcontract_info *cp,C; int64_t datafee,funding; char str[67],markeraddr[64],numstr[64],batonaddr[64]; std::vector data; - std::map> publishers; - - cp = CCinit(&C,EVAL_ORACLES); - CCtxidaddr(markeraddr,origtxid); - if ( myGetTransaction(origtxid,tx,hashBlock) == 0 ) - { - fprintf(stderr,"cant find oracleid\n"); - result.push_back(Pair("result","error")); - result.push_back(Pair("error","cant find oracleid")); - return(result); - } - if ( myGetTransaction(origtxid,tx,hashBlock) != 0 ) - { - if ( tx.vout.size() > 0 && DecodeOraclesCreateOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,name,description,format) == 'C' ) - { - result.push_back(Pair("result","success")); - result.push_back(Pair("txid",uint256_str(str,origtxid))); - result.push_back(Pair("name",name)); - result.push_back(Pair("description",description)); - result.push_back(Pair("format",format)); - result.push_back(Pair("marker",markeraddr)); - SetCCunspents(unspentOutputs,markeraddr,false); - for (std::vector >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++) - { - txid = it->first.txhash; - height = (int32_t)it->second.blockHeight; - if ( myGetTransaction(txid,tx,hashBlock) != 0 && tx.vout.size() > 0 && - DecodeOraclesOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,oracletxid,pk,datafee) == 'R' && oracletxid == origtxid ) - { - if (publishers.find(pk)==publishers.end() || height>publishers[pk].second) - { - publishers[pk].first=txid; - publishers[pk].second=height; - } - } - } - for (std::map>::iterator it = publishers.begin(); it != publishers.end(); ++it) - { - if ( myGetTransaction(it->second.first,tx,hashBlock) != 0 && DecodeOraclesOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,oracletxid,pk,datafee) == 'R') - { - UniValue obj(UniValue::VOBJ); - obj.push_back(Pair("publisher",pubkey33_str(str,(uint8_t *)pk.begin()))); - Getscriptaddress(batonaddr,tx.vout[1].scriptPubKey); - batontxid = OracleBatonUtxo(10000,cp,oracletxid,batonaddr,pk,data); - obj.push_back(Pair("baton",batonaddr)); - obj.push_back(Pair("batontxid",uint256_str(str,batontxid))); - funding = LifetimeOraclesFunds(cp,oracletxid,pk); - sprintf(numstr,"%.8f",(double)funding/COIN); - obj.push_back(Pair("lifetime",numstr)); - funding = AddOracleInputs(cp,mtx,oracletxid,pk,0,0); - sprintf(numstr,"%.8f",(double)funding/COIN); - obj.push_back(Pair("funds",numstr)); - sprintf(numstr,"%.8f",(double)datafee/COIN); - obj.push_back(Pair("datafee",numstr)); - a.push_back(obj); - } - } - result.push_back(Pair("registered",a)); - } - else - CCERR_RESULT("pegscc",CCLOG_INFO, stream << "invalid oracletxid " << oracletxid.GetHex()); - } - else - CCERR_RESULT("oraclescc",CCLOG_INFO, stream << "cant find oracletxid " << oracletxid.GetHex()); - return(result); -} - -UniValue OraclesList() -{ - UniValue result(UniValue::VARR); std::vector txids; struct CCcontract_info *cp,C; uint256 txid,hashBlock; CTransaction createtx; std::string name,description,format; char str[65]; - cp = CCinit(&C,EVAL_ORACLES); - SetCCtxids(txids,cp->normaladdr,false,cp->evalcode,zeroid,'C'); - for (std::vector::const_iterator it=txids.begin(); it!=txids.end(); it++) - { - txid = *it; - if ( myGetTransaction(txid,createtx,hashBlock) != 0 ) - { - if ( createtx.vout.size() > 0 && DecodeOraclesCreateOpRet(createtx.vout[createtx.vout.size()-1].scriptPubKey,name,description,format) == 'C' ) - { - result.push_back(uint256_str(str,txid)); - } - } - } - return(result); -} diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index ee1826cdd..4cb86d676 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -376,13 +376,7 @@ static const CRPCCommand vRPCCommands[] = { "rawtransactions", "fundrawtransaction", &fundrawtransaction, false }, #endif - // fsm - { "FSM", "FSMaddress", &FSMaddress, true }, - { "FSM", "FSMcreate", &FSMcreate, true }, - { "FSM", "FSMlist", &FSMlist, true }, - { "FSM", "FSMinfo", &FSMinfo, true }, - - // fsm + // nspv { "nSPV", "nspv_getinfo", &nspv_getinfo, true }, { "nSPV", "nspv_login", &nspv_login, true }, { "nSPV", "nspv_listunspent", &nspv_listunspent, true }, @@ -397,10 +391,6 @@ static const CRPCCommand vRPCCommands[] = { "nSPV", "nspv_logout", &nspv_logout, true }, { "nSPV", "nspv_listccmoduleunspent", &nspv_listccmoduleunspent, true }, - { "CClib", "cclibaddress", &cclibaddress, true }, - { "CClib", "cclibinfo", &cclibinfo, true }, - { "CClib", "cclib", &cclib, true }, - /* Address index */ { "addressindex", "getaddressmempool", &getaddressmempool, true }, { "addressindex", "getaddressutxos", &getaddressutxos, false }, diff --git a/src/rpc/server.h b/src/rpc/server.h index 766957e9f..bbce095f5 100644 --- a/src/rpc/server.h +++ b/src/rpc/server.h @@ -243,16 +243,6 @@ extern UniValue channelsaddress(const UniValue& params, bool fHelp, const CPubKe extern UniValue cclibaddress(const UniValue& params, bool fHelp, const CPubKey& mypk); extern UniValue cclibinfo(const UniValue& params, bool fHelp, const CPubKey& mypk); extern UniValue cclib(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue channelslist(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue channelsinfo(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue channelsopen(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue channelspayment(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue channelsclose(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue channelsrefund(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue FSMaddress(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue FSMcreate(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue FSMlist(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue FSMinfo(const UniValue& params, bool fHelp, const CPubKey& mypk); extern UniValue getnewaddress(const UniValue& params, bool fHelp, const CPubKey& mypk); // in rpcwallet.cpp //extern UniValue getnewaddress64(const UniValue& params, bool fHelp, const CPubKey& mypk); // in rpcwallet.cpp diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index ede7fb87e..78dbb1908 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -52,6 +52,8 @@ #include "hush_defs.h" #include #include "rpchushwallet.h" +#include "cc/utils.h" +#include "cc/CCinclude.h" using namespace std; using namespace libzcash; @@ -6092,101 +6094,8 @@ int32_t hush_notaryvin(CMutableTransaction &txNew,uint8_t *notarypub33, void *pT return(siglen); } -#include "../cc/CCassets.h" -#include "../cc/CCfsm.h" - int32_t ensure_CCrequirements(uint8_t evalcode) { - CCerror = ""; - if ( ASSETCHAINS_CCDISABLES[evalcode] != 0 || (evalcode == EVAL_MARMARA && ASSETCHAINS_MARMARA == 0) ) - { - // check if a height activation has been set. - fprintf(stderr, "evalcode.%i activates at height. %i current height.%i\n", evalcode, mapHeightEvalActivate[evalcode], hush_currentheight()); - if ( mapHeightEvalActivate[evalcode] == 0 || hush_currentheight() == 0 || mapHeightEvalActivate[evalcode] > hush_currentheight() ) - { - fprintf(stderr,"evalcode %d disabled\n",evalcode); - return(-1); - } - } - if ( NOTARY_PUBKEY33[0] == 0 ) - { - fprintf(stderr,"no -pubkey set\n"); - return(-1); - } else if ( GetBoolArg("-addressindex", DEFAULT_ADDRESSINDEX) == 0 ) { - fprintf(stderr,"no -addressindex\n"); - return(-1); - } else if ( GetBoolArg("-spentindex", DEFAULT_SPENTINDEX) == 0 ) { - fprintf(stderr,"no -spentindex\n"); - return(-1); - } - else return(0); -} - -UniValue CCaddress(struct CCcontract_info *cp,char *name,std::vector &pubkey) -{ - UniValue result(UniValue::VOBJ); char destaddr[64],str[64]; CPubKey mypk,pk; - pk = GetUnspendable(cp,0); - GetCCaddress(cp,destaddr,pk); - if ( strcmp(destaddr,cp->unspendableCCaddr) != 0 ) - { - uint8_t priv[32]; - Myprivkey(priv); // it is assumed the CC's normal address'es -pubkey was used - fprintf(stderr,"fix mismatched CCaddr %s -> %s\n",cp->unspendableCCaddr,destaddr); - strcpy(cp->unspendableCCaddr,destaddr); - memset(priv,0,32); - } - result.push_back(Pair("result", "success")); - sprintf(str,"%sCCAddress",name); - result.push_back(Pair(str,cp->unspendableCCaddr)); - sprintf(str,"%sCCBalance",name); - result.push_back(Pair(str,ValueFromAmount(CCaddress_balance(cp->unspendableCCaddr,1)))); - sprintf(str,"%sNormalAddress",name); - result.push_back(Pair(str,cp->normaladdr)); - sprintf(str,"%sNormalBalance",name); - result.push_back(Pair(str,ValueFromAmount(CCaddress_balance(cp->normaladdr,0)))); - if (strcmp(name,"Gateways")==0) result.push_back(Pair("GatewaysPubkey","03ea9c062b9652d8eff34879b504eda0717895d27597aaeb60347d65eed96ccb40")); - if ((strcmp(name,"Channels")==0 || strcmp(name,"Heir")==0) && pubkey.size() == 33) - { - sprintf(str,"%sCC1of2Address",name); - mypk = pubkey2pk(Mypubkey()); - GetCCaddress1of2(cp,destaddr,mypk,pubkey2pk(pubkey)); - result.push_back(Pair(str,destaddr)); - if (GetTokensCCaddress1of2(cp,destaddr,mypk,pubkey2pk(pubkey))>0) - { - sprintf(str,"%sCC1of2TokensAddress",name); - result.push_back(Pair(str,destaddr)); - } - } - else if (strcmp(name,"Tokens")!=0) - { - if (GetTokensCCaddress(cp,destaddr,pk)>0) - { - sprintf(str,"%sCCTokensAddress",name); - result.push_back(Pair(str,destaddr)); - } - } - if ( pubkey.size() == 33 ) - { - if ( GetCCaddress(cp,destaddr,pubkey2pk(pubkey)) != 0 ) - { - sprintf(str,"PubkeyCCaddress(%s)",name); - result.push_back(Pair(str,destaddr)); - sprintf(str,"PubkeyCCbalance(%s)",name); - result.push_back(Pair(str,ValueFromAmount(CCaddress_balance(destaddr,0)))); - } - } - if ( GetCCaddress(cp,destaddr,pubkey2pk(Mypubkey())) != 0 ) - { - sprintf(str,"myCCAddress(%s)",name); - result.push_back(Pair(str,destaddr)); - sprintf(str,"myCCbalance(%s)",name); - result.push_back(Pair(str,ValueFromAmount(CCaddress_balance(destaddr,1)))); - } - if ( Getscriptaddress(destaddr,(CScript() << Mypubkey() << OP_CHECKSIG)) != 0 ) - { - result.push_back(Pair("myaddress",destaddr)); - result.push_back(Pair("mybalance",ValueFromAmount(CCaddress_balance(destaddr,0)))); - } - return(result); + return -1; } bool pubkey2addr(char *destaddr,uint8_t *pubkey33); @@ -6253,142 +6162,6 @@ UniValue setpubkey(const UniValue& params, bool fHelp, const CPubKey& mypk) return result; } -UniValue cclibaddress(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - struct CCcontract_info *cp,C; std::vector pubkey; uint8_t evalcode = EVAL_FIRSTUSER; - if ( fHelp || params.size() > 2 ) - throw runtime_error("cclibaddress [evalcode] [pubkey]\n"); - if ( params.size() >= 1 ) - { - evalcode = atoi(params[0].get_str().c_str()); - if ( evalcode < EVAL_FIRSTUSER || evalcode > EVAL_LASTUSER ) - throw runtime_error("evalcode not between EVAL_FIRSTUSER and EVAL_LASTUSER\n"); - if ( params.size() == 2 ) - pubkey = ParseHex(params[1].get_str().c_str()); - } - cp = CCinit(&C,evalcode); - if ( ensure_CCrequirements(cp->evalcode) < 0 ) - throw runtime_error(CC_REQUIREMENTS_MSG); - if ( cp == 0 ) - throw runtime_error("error creating *cp\n"); - return(CCaddress(cp,(char *)"CClib",pubkey)); -} - -UniValue cclibinfo(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - struct CCcontract_info *cp,C; uint8_t evalcode = EVAL_FIRSTUSER; - if ( fHelp || params.size() > 0 ) - throw runtime_error("cclibinfo\n"); - if ( ensure_CCrequirements(0) < 0 ) - throw runtime_error(CC_REQUIREMENTS_MSG); - cp = CCinit(&C,evalcode); - return(CClib_info(cp)); -} - -UniValue cclib(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - struct CCcontract_info *cp,C; char *method,*jsonstr=0; uint8_t evalcode = EVAL_FIRSTUSER; - std::string vobjJsonSerialized; - - if ( fHelp || params.size() > 3 ) - throw runtime_error("cclib method [evalcode] [JSON params]\n"); - if ( ASSETCHAINS_CCLIB.size() == 0 ) - throw runtime_error("no -ac_cclib= specified\n"); - if ( ensure_CCrequirements(0) < 0 ) - throw runtime_error(CC_REQUIREMENTS_MSG); - const CKeyStore& keystore = *pwalletMain; - LOCK2(cs_main, pwalletMain->cs_wallet); - method = (char *)params[0].get_str().c_str(); - if ( params.size() >= 2 ) - { - evalcode = atoi(params[1].get_str().c_str()); - if ( evalcode < EVAL_FIRSTUSER || evalcode > 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 ) - { - if (params[2].getType() == UniValue::VOBJ) { - vobjJsonSerialized = params[2].write(0, 0); - jsonstr = (char *)vobjJsonSerialized.c_str(); - } - else // VSTR assumed - jsonstr = (char *)params[2].get_str().c_str(); - //fprintf(stderr,"params.(%s %s %s)\n",params[0].get_str().c_str(),params[1].get_str().c_str(),jsonstr); - } - } - cp = CCinit(&C,evalcode); - return(CClib(cp,method,jsonstr)); -} - -UniValue FSMaddress(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - struct CCcontract_info *cp,C; std::vector pubkey; - cp = CCinit(&C,EVAL_FSM); - if ( fHelp || params.size() > 1 ) - throw runtime_error("FSMaddress [pubkey]\n"); - if ( ensure_CCrequirements(cp->evalcode) < 0 ) - throw runtime_error(CC_REQUIREMENTS_MSG); - if ( params.size() == 1 ) - pubkey = ParseHex(params[0].get_str().c_str()); - return(CCaddress(cp,(char *)"FSM",pubkey)); -} - -UniValue assetsaddress(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - struct CCcontract_info *cp, C; std::vector pubkey; - cp = CCinit(&C, EVAL_ASSETS); - if (fHelp || params.size() > 1) - throw runtime_error("assetsaddress [pubkey]\n"); - if (ensure_CCrequirements(cp->evalcode) < 0) - throw runtime_error(CC_REQUIREMENTS_MSG); - if (params.size() == 1) - pubkey = ParseHex(params[0].get_str().c_str()); - return(CCaddress(cp, (char *)"Assets", pubkey)); -} - -UniValue FSMcreate(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - UniValue result(UniValue::VOBJ); std::string name,states,hex; - if ( fHelp || params.size() != 2 ) - throw runtime_error("FSMcreate name states\n"); - if ( ensure_CCrequirements(EVAL_FSM) < 0 ) - throw runtime_error(CC_REQUIREMENTS_MSG); - const CKeyStore& keystore = *pwalletMain; - LOCK2(cs_main, pwalletMain->cs_wallet); - name = params[0].get_str(); - states = params[1].get_str(); - hex = FSMCreate(0,name,states); - if ( hex.size() > 0 ) - { - result.push_back(Pair("result", "success")); - result.push_back(Pair("hex", hex)); - } else result.push_back(Pair("error", "couldnt create FSM transaction")); - return(result); -} - -UniValue FSMlist(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - uint256 tokenid; - if ( fHelp || params.size() > 0 ) - throw runtime_error("FSMlist\n"); - if ( ensure_CCrequirements(EVAL_FSM) < 0 ) - throw runtime_error(CC_REQUIREMENTS_MSG); - return(FSMList()); -} - -UniValue FSMinfo(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - uint256 FSMtxid; - if ( fHelp || params.size() != 1 ) - throw runtime_error("FSMinfo fundingtxid\n"); - if ( ensure_CCrequirements(EVAL_FSM) < 0 ) - throw runtime_error(CC_REQUIREMENTS_MSG); - FSMtxid = Parseuint256((char *)params[0].get_str().c_str()); - return(FSMInfo(FSMtxid)); -} - UniValue getbalance64(const UniValue& params, bool fHelp, const CPubKey& mypk) { set setAddress; vector vecOutputs; From 0ad0fac03058215c0261caa8a2c33e73ab589b41 Mon Sep 17 00:00:00 2001 From: Duke Date: Tue, 30 Jan 2024 11:28:13 -0500 Subject: [PATCH 11/78] Delete more CCs #381 --- src/cc/disputepayout.cpp | 102 --------------------------------------- src/cc/importpayout.cpp | 94 ------------------------------------ 2 files changed, 196 deletions(-) delete mode 100644 src/cc/disputepayout.cpp delete mode 100644 src/cc/importpayout.cpp diff --git a/src/cc/disputepayout.cpp b/src/cc/disputepayout.cpp deleted file mode 100644 index d6bc92c8a..000000000 --- a/src/cc/disputepayout.cpp +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright (c) 2016-2023 The Hush developers -// Distributed under the GPLv3 software license, see the accompanying -// file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html -/****************************************************************************** - * Copyright © 2014-2019 The SuperNET Developers. * - * * - * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * - * the top-level directory of this distribution for the individual copyright * - * holder information and the developer policies on copyright and licensing. * - * * - * Unless otherwise agreed in a custom licensing agreement, no part of the * - * SuperNET software, including this file may be copied, modified, propagated * - * or distributed except according to the terms contained in the LICENSE file * - * * - * Removal or modification of this copyright notice is prohibited. * - * * - ******************************************************************************/ - -#include - -#include "hash.h" -#include "chain.h" -#include "version.h" -#include "script/cc.h" -#include "cc/eval.h" -#include "cc/betprotocol.h" -#include "primitives/transaction.h" - - -/* - * Crypto-Condition EVAL method that resolves a dispute of a session - * - * IN: vm - AppVM virtual machine to verify states - * IN: params - condition params - * IN: disputeTx - transaction attempting to resolve dispute - * IN: nIn - index of input of dispute tx - * - * disputeTx: attempt to resolve a dispute - * - * in 0: Spends Session TX first output, reveals DisputeHeader - * out 0: OP_RETURN hash of payouts - */ -bool Eval::DisputePayout(AppVM &vm, std::vector params, const CTransaction &disputeTx, unsigned int nIn) -{ - if (disputeTx.vout.size() == 0) return Invalid("no-vouts"); - - // get payouts hash - uint256 payoutHash; - if (!GetOpReturnHash(disputeTx.vout[0].scriptPubKey, payoutHash)) - return Invalid("invalid-payout-hash"); - - // load params - uint16_t waitBlocks; - std::vector vmParams; - if (!E_UNMARSHAL(params, ss >> VARINT(waitBlocks); ss >> vmParams)) - return Invalid("malformed-params"); - - // ensure that enough time has passed - { - CTransaction sessionTx; - CBlockIndex sessionBlock; - - // if unconformed its too soon - if (!GetTxConfirmed(disputeTx.vin[0].prevout.hash, sessionTx, sessionBlock)) - return Error("couldnt-get-parent"); - - if (GetCurrentHeight() < sessionBlock.GetHeight() + waitBlocks) - return Invalid("dispute-too-soon"); // Not yet - } - - // get spends - std::vector spends; - if (!GetSpendsConfirmed(disputeTx.vin[0].prevout.hash, spends)) - return Error("couldnt-get-spends"); - - // verify result from VM - int maxLength = -1; - uint256 bestPayout; - for (int i=1; i vmState; - if (spends[i].vout.size() == 0) continue; - if (!GetOpReturnData(spends[i].vout[0].scriptPubKey, vmState)) continue; - auto out = vm.evaluate(vmParams, vmState); - uint256 resultHash = SerializeHash(out.second); - if (out.first > maxLength) { - maxLength = out.first; - bestPayout = resultHash; - } - // The below means that if for any reason there is a draw, the first dispute wins - else if (out.first == maxLength) { - if (bestPayout != payoutHash) { - fprintf(stderr, "WARNING: VM has multiple solutions of same length\n"); - bestPayout = resultHash; - } - } - } - - if (maxLength == -1) return Invalid("no-evidence"); - - return bestPayout == payoutHash ? Valid() : Invalid("wrong-payout"); -} diff --git a/src/cc/importpayout.cpp b/src/cc/importpayout.cpp deleted file mode 100644 index 6bc8fc97c..000000000 --- a/src/cc/importpayout.cpp +++ /dev/null @@ -1,94 +0,0 @@ -// Copyright (c) 2016-2023 The Hush developers -// Distributed under the GPLv3 software license, see the accompanying -// file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html -/****************************************************************************** - * Copyright © 2014-2019 The SuperNET Developers. * - * * - * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * - * the top-level directory of this distribution for the individual copyright * - * holder information and the developer policies on copyright and licensing. * - * * - * Unless otherwise agreed in a custom licensing agreement, no part of the * - * SuperNET software, including this file may be copied, modified, propagated * - * or distributed except according to the terms contained in the LICENSE file * - * * - * Removal or modification of this copyright notice is prohibited. * - * * - ******************************************************************************/ - -#include - -#include "main.h" -#include "chain.h" -#include "streams.h" -#include "cc/eval.h" -#include "cc/betprotocol.h" -#include "primitives/transaction.h" - - -/* - * Crypto-Condition EVAL method that verifies a payout against a transaction - * notarized on another chain. - * - * IN: params - condition params - * IN: importTx - Payout transaction on value chain (HUSH) - * IN: nIn - index of input of stake - * - * importTx: Spends stakeTx with payouts from asset chain - * - * in 0: Spends Stake TX and contains ImportPayout CC - * out 0: OP_RETURN MomProof, disputeTx - * out 1-: arbitrary payouts - * - * disputeTx: Spends sessionTx.0 (opener on asset chain) - * - * in 0: spends sessionTx.0 - * in 1-: anything - * out 0: OP_RETURN hash of payouts - * out 1-: anything - */ -bool Eval::ImportPayout(const std::vector params, const CTransaction &importTx, unsigned int nIn) -{ - if (importTx.vout.size() == 0) return Invalid("no-vouts"); - - // load data from vout[0] - MoMProof proof; - CTransaction disputeTx; - { - std::vector vopret; - GetOpReturnData(importTx.vout[0].scriptPubKey, vopret); - if (!E_UNMARSHAL(vopret, ss >> proof; ss >> disputeTx)) - return Invalid("invalid-payload"); - } - - // Check disputeTx.0 shows correct payouts - { - uint256 givenPayoutsHash; - GetOpReturnHash(disputeTx.vout[0].scriptPubKey, givenPayoutsHash); - std::vector payouts(importTx.vout.begin() + 1, importTx.vout.end()); - if (givenPayoutsHash != SerializeHash(payouts)) - return Invalid("wrong-payouts"); - } - - // Check disputeTx spends sessionTx.0 - // condition ImportPayout params is session ID from other chain - { - uint256 sessionHash; - if (!E_UNMARSHAL(params, ss >> sessionHash)) - return Invalid("malformed-params"); - if (disputeTx.vin[0].prevout != COutPoint(sessionHash, 0)) - return Invalid("wrong-session"); - } - - // Check disputeTx solves momproof from vout[0] - { - NotarizationData data; - if (!GetNotarizationData(proof.notarizationHash, data)) - return Invalid("coudnt-load-mom"); - - if (data.MoM != proof.Exec(disputeTx.GetHash())) - return Invalid("mom-check-fail"); - } - - return Valid(); -} From 5a260e8893dc70e45804243b3eda179dcc41c9b3 Mon Sep 17 00:00:00 2001 From: Duke Date: Wed, 31 Jan 2024 13:28:12 -0500 Subject: [PATCH 12/78] Delete more CCs #381 --- src/cc/cclib.cpp | 3 - src/cc/games/prices.c | 292 ------------- src/cc/games/prices.cpp | 283 ------------- src/cc/games/prices.h | 211 ---------- src/cc/games/tetris.c | 907 ---------------------------------------- src/cc/games/tetris.cpp | 88 ---- src/cc/games/tetris.h | 211 ---------- src/cc/gamescc.h | 123 ------ src/cc/musig.cpp | 580 ++----------------------- 9 files changed, 24 insertions(+), 2674 deletions(-) delete mode 100644 src/cc/games/prices.c delete mode 100644 src/cc/games/prices.cpp delete mode 100644 src/cc/games/prices.h delete mode 100644 src/cc/games/tetris.c delete mode 100644 src/cc/games/tetris.cpp delete mode 100644 src/cc/games/tetris.h delete mode 100644 src/cc/gamescc.h diff --git a/src/cc/cclib.cpp b/src/cc/cclib.cpp index e35ec8c9d..c1051b3b7 100644 --- a/src/cc/cclib.cpp +++ b/src/cc/cclib.cpp @@ -35,9 +35,6 @@ std::string MYCCLIBNAME = (char *)"rogue"; #elif BUILD_CUSTOMCC #include "customcc.h" -#elif BUILD_GAMESCC -#include "gamescc.h" - #else #define EVAL_SUDOKU 17 #define EVAL_MUSIG 18 diff --git a/src/cc/games/prices.c b/src/cc/games/prices.c deleted file mode 100644 index 69e3fae95..000000000 --- a/src/cc/games/prices.c +++ /dev/null @@ -1,292 +0,0 @@ -// Copyright (c) 2016-2023 The Hush developers -// Distributed under the GPLv3 software license, see the accompanying -// file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html - -#include "prices.h" -#include -#include -#ifdef BUILD_GAMESCC -#include "../rogue/cursesd.h" -#else -#include -#endif - -#define SATOSHIDEN ((uint64_t)100000000L) -#define issue_curl(cmdstr) bitcoind_RPC(0,(char *)"prices",cmdstr,0,0,0) -extern int64_t Net_change,Betsize; - -int random_tetromino(struct games_state *rs) -{ - rs->seed = _games_rngnext(rs->seed); - return(rs->seed % NUM_TETROMINOS); -} - -int32_t pricesdata(struct games_player *P,void *ptr) -{ - tetris_game *tg = (tetris_game *)ptr; - P->gold = tg->points; - P->dungeonlevel = tg->level; - //fprintf(stderr,"score.%d level.%d\n",tg->points,tg->level); - return(0); -} - -void sleep_milli(int milliseconds) -{ - struct timespec ts; - ts.tv_sec = 0; - ts.tv_nsec = milliseconds * 1000 * 1000; - nanosleep(&ts, NULL); -} - -struct games_state globalR; -extern char Gametxidstr[]; -int32_t issue_games_events(struct games_state *rs,char *gametxidstr,uint32_t eventid,gamesevent c); -uint64_t get_btcusd(); -int32_t issue_bet(struct games_state *rs,int64_t x,int64_t betsize); - -void *gamesiterate(struct games_state *rs) -{ - bool running = true; uint32_t eventid = 0; int64_t price; - if ( rs->guiflag != 0 || rs->sleeptime != 0 ) - { - initscr(); // initialize curses - cbreak(); // pass key presses to program, but not signals - noecho(); // don't echo key presses to screen - timeout(0); - } - while ( running != 0 ) - { - //running = tg_tick(rs,tg,move); - if ( rs->guiflag != 0 || rs->sleeptime != 0 ) - { - } - if ( rs->guiflag != 0 ) - { -#ifdef STANDALONE - price = get_btcusd(); - //fprintf(stderr,"%llu -> t%u %.4f\n",(long long)price,(uint32_t)(price >> 32),(double)(price & 0xffffffff)/10000); - //issue_games_events(rs,Gametxidstr,eventid,price); - issue_bet(rs,price,Betsize); - eventid++; - doupdate(); - sleep(10); - switch ( getch() ) - { - case '+': Net_change++; break; - case '-': Net_change--; break; - case '0': Net_change = 0; break; - case '$': Betsize = SATOSHIDEN; break; - case '^': Betsize += (Betsize >> 3); break; - case '/': Betsize -= (Betsize >> 3); break; - } - /*if ( (counter++ % 10) == 0 ) - doupdate(); - c = games_readevent(rs); - if ( c <= 0x7f || skipcount == 0x3fff ) - { - if ( skipcount > 0 ) - issue_games_events(rs,Gametxidstr,eventid-skipcount,skipcount | 0x4000); - if ( c <= 0x7f ) - issue_games_events(rs,Gametxidstr,eventid,c); - if ( tg->level != prevlevel ) - { - flushkeystrokes(rs,0); - prevlevel = tg->level; - } - skipcount = 0; - } else skipcount++;*/ -#endif - } - else - { - if ( rs->replaydone != 0 ) - break; - if ( rs->sleeptime != 0 ) - { - sleep_milli(1); - } - /*if ( skipcount == 0 ) - { - c = games_readevent(rs); - //fprintf(stderr,"%04x score.%d level.%d\n",c,tg->points,tg->level); - if ( (c & 0x4000) == 0x4000 ) - { - skipcount = (c & 0x3fff); - c = 'S'; - } - } - if ( skipcount > 0 ) - skipcount--;*/ - } - eventid++; - } - return(0); -} - -#ifdef STANDALONE -#include -#include "dapps/dappstd.c" -int64_t Net_change,Betsize = SATOSHIDEN; - -char *send_curl(char *url,char *fname) -{ - char *retstr; - retstr = issue_curl(url); - return(retstr); -} - -cJSON *get_urljson(char *url,char *fname) -{ - char *jsonstr; cJSON *json = 0; - if ( (jsonstr= send_curl(url,fname)) != 0 ) - { - //printf("(%s) -> (%s)\n",url,jsonstr); - json = cJSON_Parse(jsonstr); - free(jsonstr); - } - return(json); -} - -////////////////////////////////////////////// -// start of dapp -////////////////////////////////////////////// - -uint64_t get_btcusd() -{ - cJSON *pjson,*bpi,*usd; char str[512]; uint64_t x,newprice,mult,btcusd = 0; - if ( (pjson= get_urljson((char *)"http://api.coindesk.com/v1/bpi/currentprice.json",(char *)"/tmp/oraclefeed.json")) != 0 ) - { - if ( (bpi= jobj(pjson,(char *)"bpi")) != 0 && (usd= jobj(bpi,(char *)"USD")) != 0 ) - { - btcusd = jdouble(usd,(char *)"rate_float") * SATOSHIDEN; - mult = 10000 + Net_change*10; - newprice = (btcusd * mult) / 10000; - x = ((uint64_t)time(NULL) << 32) | ((newprice / 10000) & 0xffffffff); - sprintf(str,"BTC/USD %.4f -> Betsize %.8f (^ / to change) && %.4f Net %.1f%% [+ - to change]\n",dstr(btcusd),dstr(Betsize),dstr(newprice),(double)100*(mult-10000)/10000); - mvaddstr(0, 0, str); - clrtoeol(); - doupdate(); - } - free_json(pjson); - } - return(x); -} - -char *clonestr(char *str) -{ - char *clone; int32_t len; - if ( str == 0 || str[0] == 0 ) - { - printf("warning cloning nullstr.%p\n",str); -#ifdef __APPLE__ - while ( 1 ) sleep(1); -#endif - str = (char *)""; - } - len = strlen(str); - clone = (char *)calloc(1,len+16); - strcpy(clone,str); - return(clone); -} - -int32_t issue_games_events(struct games_state *rs,char *gametxidstr,uint32_t eventid,gamesevent c) -{ - static FILE *fp; - char params[512],*retstr; cJSON *retjson,*resobj; int32_t retval = -1; - if ( fp == 0 ) - fp = fopen("events.log","wb"); - rs->buffered[rs->num++] = c; - if ( 1 ) - { - if ( sizeof(c) == 1 ) - sprintf(params,"[\"events\",\"17\",\"[%%22%02x%%22,%%22%s%%22,%u]\"]",(uint8_t)c&0xff,gametxidstr,eventid); - else if ( sizeof(c) == 2 ) - sprintf(params,"[\"events\",\"17\",\"[%%22%04x%%22,%%22%s%%22,%u]\"]",(uint16_t)c&0xffff,gametxidstr,eventid); - else if ( sizeof(c) == 4 ) - sprintf(params,"[\"events\",\"17\",\"[%%22%08x%%22,%%22%s%%22,%u]\"]",(uint32_t)c&0xffffffff,gametxidstr,eventid); - else if ( sizeof(c) == 8 ) - sprintf(params,"[\"events\",\"17\",\"[%%22%016llx%%22,%%22%s%%22,%u]\"]",(long long)c,gametxidstr,eventid); - if ( (retstr= hush_issuemethod(USERPASS,(char *)"cclib",params,GAMES_PORT)) != 0 ) - { - if ( (retjson= cJSON_Parse(retstr)) != 0 ) - { - if ( (resobj= jobj(retjson,(char *)"result")) != 0 ) - { - retval = 0; - if ( fp != 0 ) - { - fprintf(fp,"%s\n",jprint(resobj,0)); - fflush(fp); - } - } - free_json(retjson); - } else fprintf(fp,"error parsing %s\n",retstr); - free(retstr); - } else fprintf(fp,"error issuing method %s\n",params); - return(retval); - } else return(0); -} - -int32_t issue_bet(struct games_state *rs,int64_t x,int64_t betsize) -{ - char params[512],hexstr[64],*retstr; cJSON *retjson,*resobj; int32_t i,retval = -1; - memset(hexstr,0,sizeof(hexstr)); - for (i=0; i<8; i++) - { - sprintf(&hexstr[i<<1],"%02x",(uint8_t)(x & 0xff)); - x >>= 8; - } - sprintf(params,"[\"bet\",\"17\",\"[%.8f,%%22%s%%22]\"]",dstr(betsize),hexstr); - if ( (retstr= hush_issuemethod(USERPASS,(char *)"cclib",params,GAMES_PORT)) != 0 ) - { - if ( (retjson= cJSON_Parse(retstr)) != 0 ) - { - if ( (resobj= jobj(retjson,(char *)"result")) != 0 ) - { - retval = 0; - //fprintf(stderr,"%s\n",jprint(resobj,0)); - } - free_json(retjson); - } - free(retstr); - } - return(retval); -} - -int prices(int argc, char **argv) -{ - struct games_state *rs = &globalR; - int32_t c,skipcount=0; uint32_t eventid = 0; - memset(rs,0,sizeof(*rs)); - rs->guiflag = 1; - rs->sleeptime = 1; // non-zero to allow refresh() - if ( argc >= 2 && strlen(argv[2]) == 64 ) - { -#ifdef _WIN32 -#ifdef _MSC_VER - rs->origseed = _strtoui64(argv[1], NULL, 10); -#else - rs->origseed = atol(argv[1]); // windows, but not MSVC -#endif // _MSC_VER -#else - rs->origseed = atol(argv[1]); // non-windows -#endif // _WIN32 - rs->seed = rs->origseed; - if ( argc >= 3 ) - { - strcpy(Gametxidstr,argv[2]); - fprintf(stderr,"setplayerdata %s\n",Gametxidstr); - if ( games_setplayerdata(rs,Gametxidstr) < 0 ) - { - fprintf(stderr,"invalid gametxid, or already started\n"); - return(-1); - } - } - } else rs->seed = 777; - gamesiterate(rs); - //gamesbailout(rs); - return 0; -} - -#endif - diff --git a/src/cc/games/prices.cpp b/src/cc/games/prices.cpp deleted file mode 100644 index a7eac9659..000000000 --- a/src/cc/games/prices.cpp +++ /dev/null @@ -1,283 +0,0 @@ -// Copyright (c) 2016-2023 The Hush developers -// Distributed under the GPLv3 software license, see the accompanying -// file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html -/****************************************************************************** - * Copyright © 2014-2019 The SuperNET Developers. * - * * - * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * - * the top-level directory of this distribution for the individual copyright * - * holder information and the developer policies on copyright and licensing. * - * * - * Unless otherwise agreed in a custom licensing agreement, no part of the * - * SuperNET software, including this file may be copied, modified, propagated * - * or distributed except according to the terms contained in the LICENSE file * - * * - * Removal or modification of this copyright notice is prohibited. * - * * - ******************************************************************************/ - -std::string MYCCLIBNAME = (char *)"prices"; - -#define PRICES_BETPERIOD 3 -UniValue games_rawtxresult(UniValue &result,std::string rawtx,int32_t broadcastflag); -extern uint8_t ASSETCHAINS_OVERRIDE_PUBKEY33[33]; - -#define bstr(x) ((double)((uint32_t)x) / 10000.) - -struct prices_bar -{ - uint64_t open,high,low,close,sum; - int32_t num; -}; - -int32_t prices_barupdate(struct prices_bar *bar,uint64_t pricebits) -{ - uint32_t uprice,timestamp; - timestamp = (uint32_t)(pricebits >> 32); - uprice = (uint32_t)pricebits; - bar->sum += uprice, bar->num++; - if ( bar->open == 0 ) - bar->open = bar->high = bar->low = pricebits; - if ( uprice > (uint32_t)bar->high ) - bar->high = pricebits; - else if ( uprice < (uint32_t)bar->low ) - bar->low = pricebits; - bar->close = pricebits; - return(0); -} - -int64_t prices_bardist(struct prices_bar *bar,uint32_t aveprice,uint64_t pricebits) -{ - int64_t a,dist = 0; - if ( aveprice != 0 ) - { - a = (pricebits & 0xffffffff); - dist = (a - aveprice); - dist *= dist; - //fprintf(stderr,"dist.%lld (u %u - ave %u) %d\n",(long long)dist,uprice,aveprice,uprice-aveprice); - } - return(dist); -} - -void prices_bardisp(struct prices_bar *bar) -{ - if ( bar->num == 0 ) - fprintf(stderr,"BAR null\n"); - else fprintf(stderr,"BAR ave %.4f (O %.4f, H %.4f, L %.4f, C %.4f)\n",bstr(bar->sum/bar->num),bstr(bar->open),bstr(bar->high),bstr(bar->low),bstr(bar->close)); -} - -int64_t prices_blockinfo(int32_t height,char *acaddr) -{ - std::vector vopret; CBlockIndex *pindex; CBlock block; CTransaction tx,vintx; uint64_t pricebits; char destaddr[64]; uint32_t aveprice=0,timestamp,uprice; uint256 hashBlock; int64_t dist,mindist=(1LL<<60),prizefund = 0; int32_t mini=-1,i,n,vini,numvouts,iter; struct prices_bar refbar; - if ( (pindex= hush_chainactive(height)) != 0 ) - { - if ( hush_blockload(block,pindex) == 0 ) - { - n = block.vtx.size(); - vini = 0; - memset(&refbar,0,sizeof(refbar)); - for (iter=0; iter<2; iter++) - { - for (i=0; i= vintx.vout.size() || Getscriptaddress(destaddr,vintx.vout[tx.vin[vini].prevout.n].scriptPubKey) == 0 ) - continue; - else if ( (numvouts= tx.vout.size()) > 1 && tx.vout[numvouts-1].scriptPubKey[0] == 0x6a ) - { - GetOpReturnData(tx.vout[numvouts-1].scriptPubKey,vopret); - if ( vopret.size() == 8 ) - { - E_UNMARSHAL(vopret,ss >> pricebits); - timestamp = (uint32_t)(pricebits >> 32); - uprice = (uint32_t)pricebits; - if ( iter == 0 ) - { - prizefund += tx.vout[0].nValue; - if ( strcmp(acaddr,destaddr) == 0 ) - { - //fprintf(stderr,"REF "); - prices_barupdate(&refbar,pricebits); - } - } - else if ( strcmp(acaddr,destaddr) != 0 ) - { - dist = prices_bardist(&refbar,aveprice,pricebits); - if ( dist < mindist ) - { - mindist = dist; - mini = i; - } - fprintf(stderr,"mini.%d i.%d %.8f t%u %.4f v.%d %s lag.%d i.%d dist.%lld\n",mini,i,(double)tx.vout[0].nValue/COIN,timestamp,(double)uprice/10000,numvouts,destaddr,(int32_t)(pindex->nTime-timestamp),iter,(long long)dist); - } - } else return(-3); - } - } - if ( iter == 0 ) - { - prices_bardisp(&refbar); - if ( refbar.num != 0 ) - aveprice = (uint32_t)refbar.sum / refbar.num; - } - } - return(prizefund); - } else return(-2); - } else return(-1); -} - -UniValue games_settle(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) -{ - UniValue result(UniValue::VOBJ); char acaddr[64]; CPubKey acpk,mypk,gamespk; int64_t prizefund = 0; int32_t height,nextheight = hush_nextheight(); - if ( ASSETCHAINS_OVERRIDE_PUBKEY33[0] == 0 ) - { - result.push_back(Pair("result","error")); - result.push_back(Pair("error"," no -ac_pubkey for price reference")); - return(result); - } - mypk = pubkey2pk(Mypubkey()); - gamespk = GetUnspendable(cp,0); - acpk = buf2pk(ASSETCHAINS_OVERRIDE_PUBKEY33); - Getscriptaddress(acaddr,CScript() << ParseHex(HexStr(acpk)) << OP_CHECKSIG); - if ( params != 0 && cJSON_GetArraySize(params) == 1 ) - { - height = juint(jitem(params,0),0); - result.push_back(Pair("height",(int64_t)height)); - if ( (prizefund= prices_blockinfo(height,acaddr)) < 0 ) - { - result.push_back(Pair("result","error")); - result.push_back(Pair("errorcode",prizefund)); - result.push_back(Pair("error","blockinfo error")); - } - else - { - // display bets - if ( height <= nextheight-PRICES_BETPERIOD ) - { - // settle bets by first nonzero reference bar - } - result.push_back(Pair("prizefund",ValueFromAmount(prizefund))); - result.push_back(Pair("result","success")); - } - } - else - { - result.push_back(Pair("result","error")); - result.push_back(Pair("error","couldnt parse")); - } - return(result); -} - -UniValue games_bet(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) -{ - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), hush_nextheight()); - UniValue result(UniValue::VOBJ); std::string rawtx; int64_t amount,inputsum; uint64_t price; CPubKey gamespk,mypk,acpk; - if ( ASSETCHAINS_OVERRIDE_PUBKEY33[0] == 0 ) - { - result.push_back(Pair("result","error")); - result.push_back(Pair("error"," no -ac_pubkey for price reference")); - return(result); - } - mypk = pubkey2pk(Mypubkey()); - gamespk = GetUnspendable(cp,0); - acpk = buf2pk(ASSETCHAINS_OVERRIDE_PUBKEY33); - if ( params != 0 && cJSON_GetArraySize(params) == 2 ) - { - amount = jdouble(jitem(params,0),0) * COIN + 0.0000000049; - if ( cclib_parsehash((uint8_t *)&price,jitem(params,1),8) < 0 ) - { - result.push_back(Pair("result","error")); - result.push_back(Pair("error","couldnt parsehash")); - return(result); - } - if ( mypk == acpk ) - { - amount = 0; // i am the reference price feed - //fprintf(stderr,"i am the reference\n"); - } - //fprintf(stderr,"amount %llu price %llx\n",(long long)amount,(long long)price); - if ( (inputsum= AddNormalinputs(mtx,mypk,amount+GAMES_TXFEE,64)) >= amount+GAMES_TXFEE ) - { - mtx.vout.push_back(MakeCC1vout(cp->evalcode,amount,gamespk)); - rawtx = FinalizeCCTx(0,cp,mtx,mypk,GAMES_TXFEE,CScript() << OP_RETURN << price); - return(games_rawtxresult(result,rawtx,1)); - } - else - { - result.push_back(Pair("result","error")); - result.push_back(Pair("error","not enough funds")); - } - } - else - { - result.push_back(Pair("result","error")); - result.push_back(Pair("error","couldnt parse")); - } - return(result); -} - -void prices_update(uint32_t timestamp,uint32_t uprice,int32_t ismine) -{ - //fprintf(stderr,"%s t%u %.4f %16llx\n",ismine!=0?"mine":"ext ",timestamp,(double)uprice/10000,(long long)((uint64_t)timestamp<<32) | uprice); -} - -// game specific code for daemon -void games_packitemstr(char *packitemstr,struct games_packitem *item) -{ - strcpy(packitemstr,""); -} - -int64_t games_cashout(struct games_player *P) -{ - int32_t dungeonlevel = P->dungeonlevel; int64_t mult=1000,cashout = 0; - cashout = (uint64_t)P->gold * mult * dungeonlevel * dungeonlevel; - return(cashout); -} - -void pricesplayerjson(UniValue &obj,struct games_player *P) -{ - obj.push_back(Pair("packsize",(int64_t)P->packsize)); - obj.push_back(Pair("hitpoints",(int64_t)P->hitpoints)); - obj.push_back(Pair("strength",(int64_t)(P->strength&0xffff))); - obj.push_back(Pair("maxstrength",(int64_t)(P->strength>>16))); - obj.push_back(Pair("level",(int64_t)P->level)); - obj.push_back(Pair("experience",(int64_t)P->experience)); - obj.push_back(Pair("dungeonlevel",(int64_t)P->dungeonlevel)); -} - -int32_t disp_gamesplayer(char *str,struct games_player *P) -{ - str[0] = 0; - //if ( P->gold <= 0 )//|| P->hitpoints <= 0 || (P->strength&0xffff) <= 0 || P->level <= 0 || P->experience <= 0 || P->dungeonlevel <= 0 ) - // return(-1); - sprintf(str," <- playerdata: gold.%d hp.%d strength.%d/%d level.%d exp.%d dl.%d",P->gold,P->hitpoints,P->strength&0xffff,P->strength>>16,P->level,P->experience,P->dungeonlevel); - return(0); -} - -int32_t games_payloadrecv(CPubKey pk,uint32_t timestamp,std::vector payload) -{ - uint256 gametxid; int32_t i,len; char str[67]; int64_t price; uint32_t eventid = 0; - if ( (len= payload.size()) > 36 ) - { - len -= 36; - for (i=0; i<32; i++) - ((uint8_t *)&gametxid)[i] = payload[len+i]; - eventid = (uint32_t)payload[len+32]; - eventid |= (uint32_t)payload[len+33] << 8; - eventid |= (uint32_t)payload[len+34] << 16; - eventid |= (uint32_t)payload[len+35] << 24; - for (i=0; i> 32),(uint32_t)(price & 0xffffffff),pk == pubkey2pk(Mypubkey())); - //fprintf(stderr,"%llu -> t%u %.4f ",(long long)price,(uint32_t)(price >> 32),(double)(price & 0xffffffff)/10000); - //fprintf(stderr," got payload, from %s %s/e%d\n",pubkey33_str(str,(uint8_t *)&pk),gametxid.GetHex().c_str(),eventid); - return(0); - } else return(-1); -} - -bool games_validate(struct CCcontract_info *cp,int32_t height,Eval *eval,const CTransaction tx) -{ - return(true); -} - diff --git a/src/cc/games/prices.h b/src/cc/games/prices.h deleted file mode 100644 index 1debb9445..000000000 --- a/src/cc/games/prices.h +++ /dev/null @@ -1,211 +0,0 @@ -// Copyright (c) 2016-2023 The Hush developers -// Distributed under the GPLv3 software license, see the accompanying -// file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html - -#ifndef H_PRICES_H -#define H_PRICES_H - -/***************************************************************************/ -/** https://github.com/brenns10/tetris - @file main.c - @author Stephen Brennan - @date Created Wednesday, 10 June 2015 - @brief Main program for tetris. - @copyright Copyright (c) 2015, Stephen Brennan. Released under the Revised - BSD License. See LICENSE.txt for details. - *******************************************************************************/ - -/* - Convert a tetromino type to its corresponding cell. - */ -#define TYPE_TO_CELL(x) ((x)+1) - -/* - Strings for how you would print a tetris board. - */ -#define TC_EMPTY_STR " " -#define TC_BLOCK_STR "\u2588" - -/* - Questions about a tetris cell. - */ -#define TC_IS_EMPTY(x) ((x) == TC_EMPTY) -#define TC_IS_FILLED(x) (!TC_IS_EMPTY(x)) - -/* - How many cells in a tetromino? - */ -#define TETRIS 4 -/* - How many tetrominos? - */ -#define NUM_TETROMINOS 7 -/* - How many orientations of a tetromino? - */ -#define NUM_ORIENTATIONS 4 - -/* - Level constants. - */ -#define MAX_LEVEL 19 -#define LINES_PER_LEVEL 10 - -/* - A "cell" is a 1x1 block within a tetris board. - */ -typedef enum { - TC_EMPTY, TC_CELLI, TC_CELLJ, TC_CELLL, TC_CELLO, TC_CELLS, TC_CELLT, TC_CELLZ -} tetris_cell; - -/* - A "type" is a type/shape of a tetromino. Not including orientation. - */ -typedef enum { - TET_I, TET_J, TET_L, TET_O, TET_S, TET_T, TET_Z -} tetris_type; - -/* - A row,column pair. Negative numbers allowed, because we need them for - offsets. - */ -typedef struct { - int row; - int col; -} tetris_location; - -/* - A "block" is a struct that contains information about a tetromino. - Specifically, what type it is, what orientation it has, and where it is. - */ -typedef struct { - int typ; - int ori; - tetris_location loc; -} tetris_block; - -/* - All possible moves to give as input to the game. - */ -typedef enum { - TM_LEFT, TM_RIGHT, TM_CLOCK, TM_COUNTER, TM_DROP, TM_HOLD, TM_NONE -} tetris_move; - -/* - A game object! - */ -typedef struct { - /* - Game board stuff: - */ - int rows; - int cols; - /* - Scoring information: - */ - int points; - int level; - /* - Falling block is the one currently going down. Next block is the one that - will be falling after this one. Stored is the block that you can swap out. - */ - tetris_block falling; - tetris_block next; - tetris_block stored; - /* - Number of game ticks until the block will move down. - */ - int ticks_till_gravity; - /* - Number of lines until you advance to the next level. - */ - int lines_remaining; - char board[]; -} tetris_game; - -/* - This array stores all necessary information about the cells that are filled by - each tetromino. The first index is the type of the tetromino (i.e. shape, - e.g. I, J, Z, etc.). The next index is the orientation (0-3). The final - array contains 4 tetris_location objects, each mapping to an offset from a - point on the upper left that is the tetromino "origin". - */ -extern const tetris_location TETROMINOS[NUM_TETROMINOS][NUM_ORIENTATIONS][TETRIS]; - -/* - This array tells you how many ticks per gravity by level. Decreases as level - increases, to add difficulty. - */ -extern const int GRAVITY_LEVEL[MAX_LEVEL+1]; - -// Data structure manipulation. -void tg_init(tetris_game *obj, int rows, int cols); -tetris_game *tg_create(struct games_state *rs,int rows, int cols); -void tg_destroy(tetris_game *obj); -void tg_delete(tetris_game *obj); -tetris_game *tg_load(FILE *f); -void tg_save(tetris_game *obj, FILE *f); - -// Public methods not related to memory: -char tg_get(tetris_game *obj, int row, int col); -bool tg_check(tetris_game *obj, int row, int col); -bool tg_tick(struct games_state *rs,tetris_game *obj, tetris_move move); -void tg_print(tetris_game *obj, FILE *f); - -/****************************************************************************** - * Copyright © 2014-2019 The SuperNET Developers. * - * * - * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * - * the top-level directory of this distribution for the individual copyright * - * holder information and the developer policies on copyright and licensing. * - * * - * Unless otherwise agreed in a custom licensing agreement, no part of the * - * SuperNET software, including this file may be copied, modified, propagated * - * or distributed except according to the terms contained in the LICENSE file * - * * - * Removal or modification of this copyright notice is prohibited. * - * * - ******************************************************************************/ -#define GAMENAME "prices" // name of executable -#define GAMEMAIN prices // main program of game -#define GAMEPLAYERJSON pricesplayerjson // displays game specific json -#define GAMEDATA pricesdata // extracts data from game specific variables into games_state -#define CHAINNAME "PRICES" // -ac_name= -typedef uint64_t gamesevent; // can be 8, 16, 32, or 64 bits - -#define MAXPACK 23 -struct games_packitem -{ - int32_t type,launch,count,which,hplus,dplus,arm,flags,group; - char damage[8],hurldmg[8]; -}; - -struct games_player -{ - int32_t gold,hitpoints,strength,level,experience,packsize,dungeonlevel,amulet; - struct games_packitem gamespack[MAXPACK]; -}; - -struct games_state -{ - uint64_t seed,origseed; - char *keystrokeshex; - uint32_t needflush,replaydone; - int32_t numkeys,ind,num,guiflag,counter,sleeptime,playersize,restoring,lastnum; - FILE *logfp; - struct games_player P; - gamesevent buffered[5000],*keystrokes; - uint8_t playerdata[8192]; -}; -extern struct games_state globalR; -void *gamesiterate(struct games_state *rs); -int32_t flushkeystrokes(struct games_state *rs,int32_t waitflag); - -void games_packitemstr(char *packitemstr,struct games_packitem *item); -uint64_t _games_rngnext(uint64_t initseed); -int32_t games_replay2(uint8_t *newdata,uint64_t seed,gamesevent *keystrokes,int32_t num,struct games_player *player,int32_t sleepmillis); -gamesevent games_revendian(gamesevent revx); -int32_t disp_gamesplayer(char *str,struct games_player *P); - -#endif - diff --git a/src/cc/games/tetris.c b/src/cc/games/tetris.c deleted file mode 100644 index d7de6f278..000000000 --- a/src/cc/games/tetris.c +++ /dev/null @@ -1,907 +0,0 @@ -// Copyright (c) 2016-2023 The Hush developers -// Distributed under the GPLv3 software license, see the accompanying -// file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html - -#include "tetris.h" - -/* - In order to port a game into gamesCC, the RNG needs to be seeded with the gametxid seed, also events needs to be broadcast using issue_games_events. Also the game engine needs to be daemonized, preferably by putting all globals into a single data structure. - - also, the standalone game needs to support argv of seed gametxid, along with replay args - */ - -int random_tetromino(struct games_state *rs) -{ - rs->seed = _games_rngnext(rs->seed); - return(rs->seed % NUM_TETROMINOS); -} - -int32_t tetrisdata(struct games_player *P,void *ptr) -{ - tetris_game *tg = (tetris_game *)ptr; - P->gold = tg->points; - P->dungeonlevel = tg->level; - //fprintf(stderr,"score.%d level.%d\n",tg->points,tg->level); - return(0); -} - -/***************************************************************************/ -/** https://github.com/brenns10/tetris - @file main.c - @author Stephen Brennan - @date Created Wednesday, 10 June 2015 - @brief Main program for tetris. - @copyright Copyright (c) 2015, Stephen Brennan. Released under the Revised - BSD License. See LICENSE.txt for details. - *******************************************************************************/ - - -#include // for FILE -#include // for bool -#include -#include -#include -#include -#include -#include - -#ifdef BUILD_GAMESCC -#include "../rogue/cursesd.h" -#else -#include -#endif - - -#define MAX(X,Y) ((X) > (Y) ? (X) : (Y)) -#define MIN(X,Y) ((X) < (Y) ? (X) : (Y)) - -/******************************************************************************* - Array Definitions - *******************************************************************************/ - -const tetris_location TETROMINOS[NUM_TETROMINOS][NUM_ORIENTATIONS][TETRIS] = -{ - // I - {{{1, 0}, {1, 1}, {1, 2}, {1, 3}}, - {{0, 2}, {1, 2}, {2, 2}, {3, 2}}, - {{3, 0}, {3, 1}, {3, 2}, {3, 3}}, - {{0, 1}, {1, 1}, {2, 1}, {3, 1}}}, - // J - {{{0, 0}, {1, 0}, {1, 1}, {1, 2}}, - {{0, 1}, {0, 2}, {1, 1}, {2, 1}}, - {{1, 0}, {1, 1}, {1, 2}, {2, 2}}, - {{0, 1}, {1, 1}, {2, 0}, {2, 1}}}, - // L - {{{0, 2}, {1, 0}, {1, 1}, {1, 2}}, - {{0, 1}, {1, 1}, {2, 1}, {2, 2}}, - {{1, 0}, {1, 1}, {1, 2}, {2, 0}}, - {{0, 0}, {0, 1}, {1, 1}, {2, 1}}}, - // O - {{{0, 1}, {0, 2}, {1, 1}, {1, 2}}, - {{0, 1}, {0, 2}, {1, 1}, {1, 2}}, - {{0, 1}, {0, 2}, {1, 1}, {1, 2}}, - {{0, 1}, {0, 2}, {1, 1}, {1, 2}}}, - // S - {{{0, 1}, {0, 2}, {1, 0}, {1, 1}}, - {{0, 1}, {1, 1}, {1, 2}, {2, 2}}, - {{1, 1}, {1, 2}, {2, 0}, {2, 1}}, - {{0, 0}, {1, 0}, {1, 1}, {2, 1}}}, - // T - {{{0, 1}, {1, 0}, {1, 1}, {1, 2}}, - {{0, 1}, {1, 1}, {1, 2}, {2, 1}}, - {{1, 0}, {1, 1}, {1, 2}, {2, 1}}, - {{0, 1}, {1, 0}, {1, 1}, {2, 1}}}, - // Z - {{{0, 0}, {0, 1}, {1, 1}, {1, 2}}, - {{0, 2}, {1, 1}, {1, 2}, {2, 1}}, - {{1, 0}, {1, 1}, {2, 1}, {2, 2}}, - {{0, 1}, {1, 0}, {1, 1}, {2, 0}}}, -}; - -const int GRAVITY_LEVEL[MAX_LEVEL+1] = { - // 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, - 50, 48, 46, 44, 42, 40, 38, 36, 34, 32, - //10, 11, 12, 13, 14, 15, 16, 17, 18, 19, - 30, 28, 26, 24, 22, 20, 16, 12, 8, 4 -}; - -/******************************************************************************* - Helper Functions for Blocks - *******************************************************************************/ - -void sleep_milli(int milliseconds) -{ - struct timespec ts; - ts.tv_sec = 0; - ts.tv_nsec = milliseconds * 1000 * 1000; - nanosleep(&ts, NULL); -} - -/* - Return the block at the given row and column. - */ -char tg_get(tetris_game *obj, int row, int column) -{ - return obj->board[obj->cols * row + column]; -} - -/* - Set the block at the given row and column. - */ -static void tg_set(tetris_game *obj, int row, int column, char value) -{ - obj->board[obj->cols * row + column] = value; -} - -/* - Check whether a row and column are in bounds. - */ -bool tg_check(tetris_game *obj, int row, int col) -{ - return 0 <= row && row < obj->rows && 0 <= col && col < obj->cols; -} - -/* - Place a block onto the board. - */ -static void tg_put(tetris_game *obj, tetris_block block) -{ - int i; - for (i = 0; i < TETRIS; i++) { - tetris_location cell = TETROMINOS[block.typ][block.ori][i]; - tg_set(obj, block.loc.row + cell.row, block.loc.col + cell.col, - TYPE_TO_CELL(block.typ)); - } -} - -/* - Clear a block out of the board. - */ -static void tg_remove(tetris_game *obj, tetris_block block) -{ - int i; - for (i = 0; i < TETRIS; i++) { - tetris_location cell = TETROMINOS[block.typ][block.ori][i]; - tg_set(obj, block.loc.row + cell.row, block.loc.col + cell.col, TC_EMPTY); - } -} - -/* - Check if a block can be placed on the board. - */ -static bool tg_fits(tetris_game *obj, tetris_block block) -{ - int i, r, c; - for (i = 0; i < TETRIS; i++) { - tetris_location cell = TETROMINOS[block.typ][block.ori][i]; - r = block.loc.row + cell.row; - c = block.loc.col + cell.col; - if (!tg_check(obj, r, c) || TC_IS_FILLED(tg_get(obj, r, c))) { - return false; - } - } - return true; -} - -/* - Create a new falling block and populate the next falling block with a random - one. - */ -static void tg_new_falling(struct games_state *rs,tetris_game *obj) -{ - // Put in a new falling tetromino. - obj->falling = obj->next; - obj->next.typ = random_tetromino(rs); - obj->next.ori = 0; - obj->next.loc.row = 0; - obj->next.loc.col = obj->cols/2 - 2; -} - -/******************************************************************************* - Game Turn Helpers - *******************************************************************************/ - -/* - Tick gravity, and move the block down if gravity should act. - */ -static void tg_do_gravity_tick(struct games_state *rs,tetris_game *obj) -{ - obj->ticks_till_gravity--; - if (obj->ticks_till_gravity <= 0) { - tg_remove(obj, obj->falling); - obj->falling.loc.row++; - if (tg_fits(obj, obj->falling)) { - obj->ticks_till_gravity = GRAVITY_LEVEL[obj->level]; - } else { - obj->falling.loc.row--; - tg_put(obj, obj->falling); - - tg_new_falling(rs,obj); - } - tg_put(obj, obj->falling); - } -} - -/* - Move the falling tetris block left (-1) or right (+1). - */ -static void tg_move(tetris_game *obj, int direction) -{ - tg_remove(obj, obj->falling); - obj->falling.loc.col += direction; - if (!tg_fits(obj, obj->falling)) { - obj->falling.loc.col -= direction; - } - tg_put(obj, obj->falling); -} - -/* - Send the falling tetris block to the bottom. - */ -static void tg_down(struct games_state *rs,tetris_game *obj) -{ - tg_remove(obj, obj->falling); - while (tg_fits(obj, obj->falling)) { - obj->falling.loc.row++; - } - obj->falling.loc.row--; - tg_put(obj, obj->falling); - tg_new_falling(rs,obj); -} - -/* - Rotate the falling block in either direction (+/-1). - */ -static void tg_rotate(tetris_game *obj, int direction) -{ - tg_remove(obj, obj->falling); - - while (true) { - obj->falling.ori = (obj->falling.ori + direction) % NUM_ORIENTATIONS; - - // If the new orientation fits, we're done. - if (tg_fits(obj, obj->falling)) - break; - - // Otherwise, try moving left to make it fit. - obj->falling.loc.col--; - if (tg_fits(obj, obj->falling)) - break; - - // Finally, try moving right to make it fit. - obj->falling.loc.col += 2; - if (tg_fits(obj, obj->falling)) - break; - - // Put it back in its original location and try the next orientation. - obj->falling.loc.col--; - // Worst case, we come back to the original orientation and it fits, so this - // loop will terminate. - } - - tg_put(obj, obj->falling); -} - -/* - Swap the falling block with the block in the hold buffer. - */ -static void tg_hold(struct games_state *rs,tetris_game *obj) -{ - tg_remove(obj, obj->falling); - if (obj->stored.typ == -1) { - obj->stored = obj->falling; - tg_new_falling(rs,obj); - } else { - int typ = obj->falling.typ, ori = obj->falling.ori; - obj->falling.typ = obj->stored.typ; - obj->falling.ori = obj->stored.ori; - obj->stored.typ = typ; - obj->stored.ori = ori; - while (!tg_fits(obj, obj->falling)) { - obj->falling.loc.row--; - if (tg_fits(obj, obj->falling)) { - break; - } - obj->falling.loc.col--; - if (tg_fits(obj, obj->falling)) { - break; - } - obj->falling.loc.col += 2; - } - } - tg_put(obj, obj->falling); -} - -/* - Perform the action specified by the move. - */ -static void tg_handle_move(struct games_state *rs,tetris_game *obj, tetris_move move) -{ - switch (move) { - case TM_LEFT: - //fprintf(stderr,"LEFT "); - tg_move(obj, -1); - break; - case TM_RIGHT: - //fprintf(stderr,"RIGHT "); - tg_move(obj, 1); - break; - case TM_DROP: - tg_down(rs,obj); - break; - case TM_CLOCK: - tg_rotate(obj, 1); - break; - case TM_COUNTER: - tg_rotate(obj, -1); - break; - case TM_HOLD: - tg_hold(rs,obj); - break; - default: - // pass - break; - } -} - -/* - Return true if line i is full. - */ -static bool tg_line_full(tetris_game *obj, int i) -{ - int j; - for (j = 0; j < obj->cols; j++) { - if (TC_IS_EMPTY(tg_get(obj, i, j))) - return false; - } - return true; -} - -/* - Shift every row above r down one. - */ -static void tg_shift_lines(tetris_game *obj, int r) -{ - int i, j; - for (i = r-1; i >= 0; i--) { - for (j = 0; j < obj->cols; j++) { - tg_set(obj, i+1, j, tg_get(obj, i, j)); - tg_set(obj, i, j, TC_EMPTY); - } - } -} - -/* - Find rows that are filled, remove them, shift, and return the number of - cleared rows. - */ -static int tg_check_lines(tetris_game *obj) -{ - int i, nlines = 0; - tg_remove(obj, obj->falling); // don't want to mess up falling block - - for (i = obj->rows-1; i >= 0; i--) { - if (tg_line_full(obj, i)) { - tg_shift_lines(obj, i); - i++; // do this line over again since they're shifted - nlines++; - } - } - - tg_put(obj, obj->falling); // replace - return nlines; -} - -/* - Adjust the score for the game, given how many lines were just cleared. - */ -static void tg_adjust_score(tetris_game *obj, int lines_cleared) -{ - static int line_multiplier[] = {0, 40, 100, 300, 1200}; - obj->points += line_multiplier[lines_cleared] * (obj->level + 1); - if (lines_cleared >= obj->lines_remaining) { - obj->level = MIN(MAX_LEVEL, obj->level + 1); - lines_cleared -= obj->lines_remaining; - obj->lines_remaining = LINES_PER_LEVEL - lines_cleared; - } else { - obj->lines_remaining -= lines_cleared; - } -} - -/* - Return true if the game is over. - */ -static bool tg_game_over(tetris_game *obj) -{ - int i, j; - bool over = false; - tg_remove(obj, obj->falling); - for (i = 0; i < 2; i++) { - for (j = 0; j < obj->cols; j++) { - if (TC_IS_FILLED(tg_get(obj, i, j))) { - over = true; - } - } - } - tg_put(obj, obj->falling); - return over; -} - -/******************************************************************************* - Main Public Functions - *******************************************************************************/ - -/* - Do a single game tick: process gravity, user input, and score. Return true if - the game is still running, false if it is over. - */ -bool tg_tick(struct games_state *rs,tetris_game *obj, tetris_move move) -{ - int lines_cleared; - // Handle gravity. - tg_do_gravity_tick(rs,obj); - - // Handle input. - tg_handle_move(rs,obj, move); - - // Check for cleared lines - lines_cleared = tg_check_lines(obj); - - tg_adjust_score(obj, lines_cleared); - - // Return whether the game will continue (NOT whether it's over) - return !tg_game_over(obj); -} - -void tg_init(struct games_state *rs,tetris_game *obj, int rows, int cols) -{ - // Initialization logic - obj->rows = rows; - obj->cols = cols; - //obj->board = (char *)malloc(rows * cols); - memset(obj->board, TC_EMPTY, rows * cols); - obj->points = 0; - obj->level = 0; - obj->ticks_till_gravity = GRAVITY_LEVEL[obj->level]; - obj->lines_remaining = LINES_PER_LEVEL; - //srand(time(NULL)); - tg_new_falling(rs,obj); - tg_new_falling(rs,obj); - obj->stored.typ = -1; - obj->stored.ori = 0; - obj->stored.loc.row = 0; - obj->next.loc.col = obj->cols/2 - 2; - //printf("%d", obj->falling.loc.col); -} - -tetris_game *tg_create(struct games_state *rs,int rows, int cols) -{ - tetris_game *obj = (tetris_game *)malloc(sizeof(tetris_game) + rows*cols); - tg_init(rs,obj, rows, cols); - return obj; -} - -/*void tg_destroy(tetris_game *obj) -{ - // Cleanup logic - free(obj->board); -}*/ - -void tg_delete(tetris_game *obj) { - //tg_destroy(obj); - free(obj); -} - -/* - Load a game from a file. - -tetris_game *tg_load(FILE *f) -{ - tetris_game *obj = (tetris_game *)malloc(sizeof(tetris_game)); - if (fread(obj, sizeof(tetris_game), 1, f) != 1 ) - { - fprintf(stderr,"read game error\n"); - free(obj); - obj = 0; - } - else - { - obj->board = (char *)malloc(obj->rows * obj->cols); - if (fread(obj->board, sizeof(char), obj->rows * obj->cols, f) != obj->rows * obj->cols ) - { - fprintf(stderr,"fread error\n"); - free(obj->board); - free(obj); - obj = 0; - } - } - return obj; -}*/ - -/* - Save a game to a file. - -void tg_save(tetris_game *obj, FILE *f) -{ - if (fwrite(obj, sizeof(tetris_game), 1, f) != 1 ) - fprintf(stderr,"error writing tetrisgame\n"); - else if (fwrite(obj->board, sizeof(char), obj->rows * obj->cols, f) != obj->rows * obj->cols ) - fprintf(stderr,"error writing board\n"); -}*/ - -/* - Print a game board to a file. Really just for early debugging. - */ -void tg_print(tetris_game *obj, FILE *f) { - int i, j; - for (i = 0; i < obj->rows; i++) { - for (j = 0; j < obj->cols; j++) { - if (TC_IS_EMPTY(tg_get(obj, i, j))) { - fputs(TC_EMPTY_STR, f); - } else { - fputs(TC_BLOCK_STR, f); - } - } - fputc('\n', f); - } -} - -/* - 2 columns per cell makes the game much nicer. - */ -#define COLS_PER_CELL 2 -/* - Macro to print a cell of a specific type to a window. - */ -#define ADD_BLOCK(w,x) waddch((w),' '|A_REVERSE|COLOR_PAIR(x)); \ -waddch((w),' '|A_REVERSE|COLOR_PAIR(x)) -#define ADD_EMPTY(w) waddch((w), ' '); waddch((w), ' ') - -/* - Print the tetris board onto the ncurses window. - */ -void display_board(WINDOW *w, tetris_game *obj) -{ - int i, j; - box(w, 0, 0); - for (i = 0; i < obj->rows; i++) { - wmove(w, 1 + i, 1); - for (j = 0; j < obj->cols; j++) { - if (TC_IS_FILLED(tg_get(obj, i, j))) { - ADD_BLOCK(w,tg_get(obj, i, j)); - } else { - ADD_EMPTY(w); - } - } - } - wnoutrefresh(w); -} - -/* - Display a tetris piece in a dedicated window. - */ -void display_piece(WINDOW *w, tetris_block block) -{ - int b; - tetris_location c; - wclear(w); - box(w, 0, 0); - if (block.typ == -1) { - wnoutrefresh(w); - return; - } - for (b = 0; b < TETRIS; b++) { - c = TETROMINOS[block.typ][block.ori][b]; - wmove(w, c.row + 1, c.col * COLS_PER_CELL + 1); - ADD_BLOCK(w, TYPE_TO_CELL(block.typ)); - } - wnoutrefresh(w); -} - -/* - Display score information in a dedicated window. - */ -void display_score(WINDOW *w, tetris_game *tg) -{ - wclear(w); - box(w, 0, 0); - wprintw(w, (char *)"Score\n%d\n", tg->points); - wprintw(w, (char *)"Level\n%d\n", tg->level); - wprintw(w, (char *)"Lines\n%d\n", tg->lines_remaining); - wnoutrefresh(w); -} - -/* - Save and exit the game. - -void save(tetris_game *game, WINDOW *w) -{ - FILE *f; - - wclear(w); - box(w, 0, 0); // return the border - wmove(w, 1, 1); - wprintw(w, (char *)"Save and exit? [Y/n] "); - wrefresh(w); - timeout(-1); - if (getch() == 'n') { - timeout(0); - return; - } - f = fopen("tetris.save", "w"); - tg_save(game, f); - fclose(f); - tg_delete(game); - endwin(); - fprintf(stderr,"Game saved to \"tetris.save\".\n"); - fprintf(stderr,"Resume by passing the filename as an argument to this program.\n"); - exit(EXIT_SUCCESS); -}*/ - -/* - Do the NCURSES initialization steps for color blocks. - */ -void init_colors(void) -{ - start_color(); - //init_color(COLOR_ORANGE, 1000, 647, 0); - init_pair(TC_CELLI, COLOR_CYAN, COLOR_BLACK); - init_pair(TC_CELLJ, COLOR_BLUE, COLOR_BLACK); - init_pair(TC_CELLL, COLOR_WHITE, COLOR_BLACK); - init_pair(TC_CELLO, COLOR_YELLOW, COLOR_BLACK); - init_pair(TC_CELLS, COLOR_GREEN, COLOR_BLACK); - init_pair(TC_CELLT, COLOR_MAGENTA, COLOR_BLACK); - init_pair(TC_CELLZ, COLOR_RED, COLOR_BLACK); -} - -struct games_state globalR; -extern char Gametxidstr[]; -int32_t issue_games_events(struct games_state *rs,char *gametxidstr,uint32_t eventid,gamesevent c); -gamesevent games_readevent(struct games_state *rs); - -void *gamesiterate(struct games_state *rs) -{ - uint32_t counter = 0; bool running = true; tetris_move move = TM_NONE; - gamesevent c; uint16_t skipcount=0; int32_t prevlevel; uint32_t eventid = 0; tetris_game *tg; - WINDOW *board, *next, *hold, *score; - if ( rs->guiflag != 0 || rs->sleeptime != 0 ) - { - // NCURSES initialization: - initscr(); // initialize curses - cbreak(); // pass key presses to program, but not signals - noecho(); // don't echo key presses to screen - keypad(stdscr, TRUE); // allow arrow keys - timeout(0); // no blocking on getch() - curs_set(0); // set the cursor to invisible - init_colors(); // setup tetris colors - } - tg = tg_create(rs,22, 10); - prevlevel = tg->level; - // Create windows for each section of the interface. - board = newwin(tg->rows + 2, 2 * tg->cols + 2, 0, 0); - next = newwin(6, 10, 0, 2 * (tg->cols + 1) + 1); - hold = newwin(6, 10, 7, 2 * (tg->cols + 1) + 1); - score = newwin(6, 10, 14, 2 * (tg->cols + 1 ) + 1); - while ( running != 0 ) - { - running = tg_tick(rs,tg,move); - if ( 1 && (rs->guiflag != 0 || rs->sleeptime != 0) ) - { - display_board(board,tg); - display_piece(next,tg->next); - display_piece(hold,tg->stored); - display_score(score,tg); - } - if ( rs->guiflag != 0 ) - { -#ifdef STANDALONE - sleep_milli(15); - if ( (counter++ % 10) == 0 ) - doupdate(); - c = games_readevent(rs); - if ( c <= 0x7f || skipcount == 0x3fff ) - { - if ( skipcount > 0 ) - issue_games_events(rs,Gametxidstr,eventid-skipcount,skipcount | 0x4000); - if ( c <= 0x7f ) - issue_games_events(rs,Gametxidstr,eventid,c); - if ( tg->level != prevlevel ) - { - flushkeystrokes(rs,0); - prevlevel = tg->level; - } - skipcount = 0; - } else skipcount++; -#endif - } - else - { - if ( rs->replaydone != 0 ) - break; - if ( rs->sleeptime != 0 ) - { - sleep_milli(1); - if ( (counter++ % 20) == 0 ) - doupdate(); - } - if ( skipcount == 0 ) - { - c = games_readevent(rs); - //fprintf(stderr,"%04x score.%d level.%d\n",c,tg->points,tg->level); - if ( (c & 0x4000) == 0x4000 ) - { - skipcount = (c & 0x3fff); - c = 'S'; - } - } - if ( skipcount > 0 ) - skipcount--; - } - eventid++; - switch ( c ) - { - case 'h': - move = TM_LEFT; - break; - case 'l': - move = TM_RIGHT; - break; - case 'k': - move = TM_CLOCK; - break; - case 'j': - move = TM_DROP; - break; - case 'q': - running = false; - move = TM_NONE; - break; - /*case 'p': - wclear(board); - box(board, 0, 0); - wmove(board, tg->rows/2, (tg->cols*COLS_PER_CELL-6)/2); - wprintw(board, "PAUSED"); - wrefresh(board); - timeout(-1); - getch(); - timeout(0); - move = TM_NONE; - break; - case 's': - save(tg, board); - move = TM_NONE; - break;*/ - case ' ': - move = TM_HOLD; - break; - default: - move = TM_NONE; - } - } - return(tg); -} - -#ifdef STANDALONE -/* - Main tetris game! - */ -#include "dapps/dappstd.c" - - -char *clonestr(char *str) -{ - char *clone; int32_t len; - if ( str == 0 || str[0] == 0 ) - { - printf("warning cloning nullstr.%p\n",str); -#ifdef __APPLE__ - while ( 1 ) sleep(1); -#endif - str = (char *)""; - } - len = strlen(str); - clone = (char *)calloc(1,len+16); - strcpy(clone,str); - return(clone); -} - -int32_t issue_games_events(struct games_state *rs,char *gametxidstr,uint32_t eventid,gamesevent c) -{ - static FILE *fp; - char params[512],*retstr; cJSON *retjson,*resobj; int32_t retval = -1; - if ( fp == 0 ) - fp = fopen("events.log","wb"); - rs->buffered[rs->num++] = c; - if ( 0 ) - { - if ( sizeof(c) == 1 ) - sprintf(params,"[\"events\",\"17\",\"[%%22%02x%%22,%%22%s%%22,%u]\"]",(uint8_t)c&0xff,gametxidstr,eventid); - else if ( sizeof(c) == 2 ) - sprintf(params,"[\"events\",\"17\",\"[%%22%04x%%22,%%22%s%%22,%u]\"]",(uint16_t)c&0xffff,gametxidstr,eventid); - else if ( sizeof(c) == 4 ) - sprintf(params,"[\"events\",\"17\",\"[%%22%08x%%22,%%22%s%%22,%u]\"]",(uint32_t)c&0xffffffff,gametxidstr,eventid); - else if ( sizeof(c) == 8 ) - sprintf(params,"[\"events\",\"17\",\"[%%22%016llx%%22,%%22%s%%22,%u]\"]",(long long)c,gametxidstr,eventid); - if ( (retstr= hush_issuemethod(USERPASS,(char *)"cclib",params,GAMES_PORT)) != 0 ) - { - if ( (retjson= cJSON_Parse(retstr)) != 0 ) - { - if ( (resobj= jobj(retjson,(char *)"result")) != 0 ) - { - retval = 0; - if ( fp != 0 ) - { - fprintf(fp,"%s\n",jprint(resobj,0)); - fflush(fp); - } - } - free_json(retjson); - } else fprintf(fp,"error parsing %s\n",retstr); - free(retstr); - } else fprintf(fp,"error issuing method %s\n",params); - return(retval); - } else return(0); -} - -int tetris(int argc, char **argv) -{ - struct games_state *rs = &globalR; - int32_t c,skipcount=0; uint32_t eventid = 0; tetris_game *tg = 0; - memset(rs,0,sizeof(*rs)); - rs->guiflag = 1; - rs->sleeptime = 1; // non-zero to allow refresh() - if ( argc >= 2 && strlen(argv[2]) == 64 ) - { -#ifdef _WIN32 -#ifdef _MSC_VER - rs->origseed = _strtoui64(argv[1], NULL, 10); -#else - rs->origseed = atol(argv[1]); // windows, but not MSVC -#endif // _MSC_VER -#else - rs->origseed = atol(argv[1]); // non-windows -#endif // _WIN32 - rs->seed = rs->origseed; - if ( argc >= 3 ) - { - strcpy(Gametxidstr,argv[2]); - fprintf(stderr,"setplayerdata %s\n",Gametxidstr); - if ( games_setplayerdata(rs,Gametxidstr) < 0 ) - { - fprintf(stderr,"invalid gametxid, or already started\n"); - return(-1); - } - } - } else rs->seed = 777; - - /* Load file if given a filename. - if (argc >= 2) { - FILE *f = fopen(argv[1], "r"); - if (f == NULL) { - perror("tetris"); - exit(EXIT_FAILURE); - } - tg = tg_load(f); - fclose(f); - } else { - // Otherwise create new game. - tg = tg_create(rs,22, 10); - }*/ - - // Game loop - tg = (tetris_game *)gamesiterate(rs); - gamesbailout(rs); - // Deinitialize NCurses - wclear(stdscr); - endwin(); - // Output ending message. - printf("Game over!\n"); - printf("You finished with %d points on level %d.\n", tg->points, tg->level); - - // Deinitialize Tetris - tg_delete(tg); - return 0; -} - -#endif - diff --git a/src/cc/games/tetris.cpp b/src/cc/games/tetris.cpp deleted file mode 100644 index b0ffaff56..000000000 --- a/src/cc/games/tetris.cpp +++ /dev/null @@ -1,88 +0,0 @@ -// Copyright (c) 2016-2023 The Hush developers - -/****************************************************************************** - * Copyright © 2014-2019 The SuperNET Developers. * - * * - * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * - * the top-level directory of this distribution for the individual copyright * - * holder information and the developer policies on copyright and licensing. * - * * - * Unless otherwise agreed in a custom licensing agreement, no part of the * - * SuperNET software, including this file may be copied, modified, propagated * - * or distributed except according to the terms contained in the LICENSE file * - * * - * Removal or modification of this copyright notice is prohibited. * - * * - ******************************************************************************/ - -std::string MYCCLIBNAME = (char *)"gamescc"; - -// game specific code for daemon -void games_packitemstr(char *packitemstr,struct games_packitem *item) -{ - strcpy(packitemstr,""); -} - -int64_t games_cashout(struct games_player *P) -{ - int32_t dungeonlevel = P->dungeonlevel; int64_t mult=10000,cashout = 0; - cashout = (uint64_t)P->gold * mult; - return(cashout); -} - -void tetrisplayerjson(UniValue &obj,struct games_player *P) -{ - obj.push_back(Pair("packsize",(int64_t)P->packsize)); - obj.push_back(Pair("hitpoints",(int64_t)P->hitpoints)); - obj.push_back(Pair("strength",(int64_t)(P->strength&0xffff))); - obj.push_back(Pair("maxstrength",(int64_t)(P->strength>>16))); - obj.push_back(Pair("level",(int64_t)P->level)); - obj.push_back(Pair("experience",(int64_t)P->experience)); - obj.push_back(Pair("dungeonlevel",(int64_t)P->dungeonlevel)); -} - -int32_t disp_gamesplayer(char *str,struct games_player *P) -{ - str[0] = 0; - //if ( P->gold <= 0 )//|| P->hitpoints <= 0 || (P->strength&0xffff) <= 0 || P->level <= 0 || P->experience <= 0 || P->dungeonlevel <= 0 ) - // return(-1); - sprintf(str," <- playerdata: gold.%d hp.%d strength.%d/%d level.%d exp.%d dl.%d",P->gold,P->hitpoints,P->strength&0xffff,P->strength>>16,P->level,P->experience,P->dungeonlevel); - return(0); -} - -int32_t games_payloadrecv(CPubKey pk,uint32_t timestamp,std::vector payload) -{ - uint256 gametxid; int32_t i,len; char str[67]; uint32_t eventid = 0; - if ( (len= payload.size()) > 36 ) - { - len -= 36; - for (i=0; i<32; i++) - ((uint8_t *)&gametxid)[i] = payload[len+i]; - eventid = (uint32_t)payload[len+32]; - eventid |= (uint32_t)payload[len+33] << 8; - eventid |= (uint32_t)payload[len+34] << 16; - eventid |= (uint32_t)payload[len+35] << 24; - //for (i=0; i -#include -#define GAMES_RNGMULT 11109 -#define GAMES_RNGOFFSET 13849 -#define GAMES_MAXRNGS 10000 - -#ifndef STANDALONE - -#define ENABLE_WALLET -extern CWallet* pwalletMain; - -#include "CCinclude.h" -#include "secp256k1.h" - - -#define EVAL_GAMES (EVAL_FAUCET2+1) -#define GAMES_TXFEE 10000 -#define GAMES_MAXITERATIONS 777 -#define GAMES_MAXKEYSTROKESGAP 60 -#define GAMES_MAXPLAYERS 64 -#define GAMES_REGISTRATIONSIZE (100 * 10000) -#define GAMES_REGISTRATION 1 - - -#define MYCCNAME "games" - -std::string Games_pname; - -#define RPC_FUNCS \ - { (char *)MYCCNAME, (char *)"rng", (char *)"hash,playerid", 1, 2, ' ', EVAL_GAMES }, \ - { (char *)MYCCNAME, (char *)"rngnext", (char *)"seed", 1, 1, ' ', EVAL_GAMES }, \ - { (char *)MYCCNAME, (char *)"fund", (char *)"amount", 1, 1, ' ', EVAL_GAMES }, \ - { (char *)MYCCNAME, (char *)"players", (char *)"no params", 0, 0, ' ', EVAL_GAMES }, \ - { (char *)MYCCNAME, (char *)"games", (char *)"no params", 0, 0, ' ', EVAL_GAMES }, \ - { (char *)MYCCNAME, (char *)"pending", (char *)"no params", 0, 0, ' ', EVAL_GAMES }, \ - { (char *)MYCCNAME, (char *)"setname", (char *)"pname", 1, 1, ' ', EVAL_GAMES }, \ - { (char *)MYCCNAME, (char *)"newgame", (char *)"maxplayers,buyin", 2, 2, 'C', EVAL_GAMES }, \ - { (char *)MYCCNAME, (char *)"playerinfo", (char *)"playertxid", 1, 1, ' ', EVAL_GAMES }, \ - { (char *)MYCCNAME, (char *)"gameinfo", (char *)"gametxid", 1, 1, ' ', EVAL_GAMES }, \ - { (char *)MYCCNAME, (char *)"keystrokes", (char *)"txid,hexstr", 2, 2, 'K', EVAL_GAMES }, \ - { (char *)MYCCNAME, (char *)"bailout", (char *)"gametxid", 1, 1, 'Q', EVAL_GAMES }, \ - { (char *)MYCCNAME, (char *)"highlander", (char *)"gametxid", 1, 1, 'H', EVAL_GAMES }, \ - { (char *)MYCCNAME, (char *)"events", (char *)"eventshex [gametxid [eventid]]", 1, 3, ' ', EVAL_GAMES }, \ - { (char *)MYCCNAME, (char *)"extract", (char *)"gametxid [pubkey]", 1, 2, ' ', EVAL_GAMES }, \ - { (char *)MYCCNAME, (char *)"bet", (char *)"amount hexstr", 2, 2, ' ', EVAL_GAMES }, \ - { (char *)MYCCNAME, (char *)"settle", (char *)"height", 1, 1, ' ', EVAL_GAMES }, \ - { (char *)MYCCNAME, (char *)"register", (char *)"gametxid [playertxid]", 1, 2, 'R', EVAL_GAMES }, - -bool games_validate(struct CCcontract_info *cp,int32_t height,Eval *eval,const CTransaction tx); -UniValue games_rng(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); -UniValue games_rngnext(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); -UniValue games_fund(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); -UniValue games_players(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); -UniValue games_games(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); -UniValue games_pending(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); -UniValue games_setname(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); -UniValue games_newgame(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); -UniValue games_playerinfo(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); -UniValue games_gameinfo(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); -UniValue games_keystrokes(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); -UniValue games_bailout(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); -UniValue games_highlander(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); -UniValue games_events(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); -UniValue games_extract(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); -UniValue games_register(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); -UniValue games_bet(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); -UniValue games_settle(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); - -#define CUSTOM_DISPATCH \ -if ( cp->evalcode == EVAL_GAMES ) \ -{ \ - if ( strcmp(method,"rng") == 0 ) \ - return(games_rng(txfee,cp,params)); \ - else if ( strcmp(method,"rngnext") == 0 ) \ - return(games_rngnext(txfee,cp,params)); \ - else if ( strcmp(method,"newgame") == 0 ) \ - return(games_newgame(txfee,cp,params)); \ - else if ( strcmp(method,"gameinfo") == 0 ) \ - return(games_gameinfo(txfee,cp,params)); \ - else if ( strcmp(method,"register") == 0 ) \ - return(games_register(txfee,cp,params)); \ - else if ( strcmp(method,"events") == 0 ) \ - return(games_events(txfee,cp,params)); \ - else if ( strcmp(method,"players") == 0 ) \ - return(games_players(txfee,cp,params)); \ - else if ( strcmp(method,"games") == 0 ) \ - return(games_games(txfee,cp,params)); \ - else if ( strcmp(method,"pending") == 0 ) \ - return(games_pending(txfee,cp,params)); \ - else if ( strcmp(method,"setname") == 0 ) \ - return(games_setname(txfee,cp,params)); \ - else if ( strcmp(method,"playerinfo") == 0 ) \ - return(games_playerinfo(txfee,cp,params)); \ - else if ( strcmp(method,"keystrokes") == 0 ) \ - return(games_keystrokes(txfee,cp,params)); \ - else if ( strcmp(method,"extract") == 0 ) \ - return(games_extract(txfee,cp,params)); \ - else if ( strcmp(method,"bailout") == 0 ) \ - return(games_bailout(txfee,cp,params)); \ - else if ( strcmp(method,"highlander") == 0 ) \ - return(games_highlander(txfee,cp,params)); \ - else if ( strcmp(method,"fund") == 0 ) \ - return(games_fund(txfee,cp,params)); \ - else if ( strcmp(method,"bet") == 0 ) \ - return(games_bet(txfee,cp,params)); \ - else if ( strcmp(method,"settle") == 0 ) \ - return(games_settle(txfee,cp,params)); \ - else \ - { \ - result.push_back(Pair("result","error")); \ - result.push_back(Pair("error","invalid gamescc method")); \ - return(result); \ - } \ -} -#endif - -#endif diff --git a/src/cc/musig.cpp b/src/cc/musig.cpp index 1c050c112..6aafe5fd5 100644 --- a/src/cc/musig.cpp +++ b/src/cc/musig.cpp @@ -202,14 +202,6 @@ struct secp256k1_context_struct { //#include "../secp256k1/include/secp256k1_schnorrsig.h" #include "../secp256k1/include/secp256k1_musig.h" - -extern "C" int secp256k1_ecmult_multi_var(const secp256k1_ecmult_context *ctx, secp256k1_scratch *scratch, secp256k1_gej *r, const secp256k1_scalar *inp_g_sc, secp256k1_ecmult_multi_callback cb, void *cbdata, size_t n); -extern "C" int secp256k1_schnorrsig_verify(const secp256k1_context* ctx, const secp256k1_schnorrsig *sig, const unsigned char *msg32, const secp256k1_pubkey *pk); -extern "C" int secp256k1_schnorrsig_parse(const secp256k1_context* ctx, secp256k1_schnorrsig* sig, const unsigned char *in64); -extern "C" int secp256k1_musig_pubkey_combine(const secp256k1_context* ctx, secp256k1_scratch_space *scratch, secp256k1_pubkey *combined_pk, unsigned char *pk_hash32, const secp256k1_pubkey *pubkeys, size_t n_pubkeys); -extern "C" int secp256k1_musig_session_initialize(const secp256k1_context* ctx, secp256k1_musig_session *session, secp256k1_musig_session_signer_data *signers, unsigned char *nonce_commitment32, const unsigned char *session_id32, const unsigned char *msg32, const secp256k1_pubkey *combined_pk, const unsigned char *pk_hash32, size_t n_signers, size_t my_index, const unsigned char *seckey); -extern "C" int secp256k1_schnorrsig_serialize(const secp256k1_context* ctx, unsigned char *out64, const secp256k1_schnorrsig* sig); - #define MUSIG_PREVN 0 // for now, just use vout0 for the musig output #define MUSIG_TXFEE 10000 @@ -243,631 +235,107 @@ struct musig_info *musig_infocreate(int32_t myind,int32_t num) void musig_infofree(struct musig_info *mp) { - if ( mp->partial_sig != 0 ) - { - GetRandBytes((uint8_t *)mp->partial_sig,mp->num*sizeof(*mp->partial_sig)); - free(mp->partial_sig); - } - if ( mp->nonces != 0 ) - { - GetRandBytes((uint8_t *)mp->nonces,mp->num*sizeof(*mp->nonces)); - free(mp->nonces); - } - if ( mp->signer_data != 0 ) - { - GetRandBytes((uint8_t *)mp->signer_data,mp->num*sizeof(*mp->signer_data)); - free(mp->signer_data); - } - if ( mp->nonce_commitments != 0 ) - { - GetRandBytes((uint8_t *)mp->nonce_commitments,mp->num*32); - free(mp->nonce_commitments); - } - if ( mp->commitment_ptrs != 0 ) - { - GetRandBytes((uint8_t *)mp->commitment_ptrs,mp->num*sizeof(*mp->commitment_ptrs)); - free(mp->commitment_ptrs); - } - GetRandBytes((uint8_t *)mp,sizeof(*mp)); - free(mp); } CScript musig_sendopret(uint8_t funcid,CPubKey pk) { - CScript opret; uint8_t evalcode = EVAL_MUSIG; - opret << OP_RETURN << E_MARSHAL(ss << evalcode << funcid << pk); + CScript opret; return(opret); } uint8_t musig_sendopretdecode(CPubKey &pk,CScript scriptPubKey) { - std::vector vopret; uint8_t e,f; - GetOpReturnData(scriptPubKey,vopret); - if ( vopret.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> pk) != 0 && e == EVAL_MUSIG && f == 'x' ) - { - return(f); - } return(0); } CScript musig_spendopret(uint8_t funcid,CPubKey pk,std::vector musig64) { - CScript opret; uint8_t evalcode = EVAL_MUSIG; - opret << OP_RETURN << E_MARSHAL(ss << evalcode << funcid << pk << musig64); + CScript opret; return(opret); } uint8_t musig_spendopretdecode(CPubKey &pk,std::vector &musig64,CScript scriptPubKey) { - std::vector vopret; uint8_t e,f; - GetOpReturnData(scriptPubKey,vopret); - if ( vopret.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> pk; ss >> musig64) != 0 && e == EVAL_MUSIG && f == 'y' ) - { - return(f); - } return(0); } int32_t musig_parsepubkey(secp256k1_context *ctx,secp256k1_pubkey &spk,cJSON *item) { - char *hexstr; - if ( (hexstr= jstr(item,0)) != 0 && is_hexstr(hexstr,0) == 66 ) - { - CPubKey pk(ParseHex(hexstr)); - if ( secp256k1_ec_pubkey_parse(ctx,&spk,pk.begin(),33) > 0 ) - return(1); - } else return(-1); + return -1; } int32_t musig_msghash(uint8_t *msg,uint256 prevhash,int32_t prevn,CTxOut vout,CPubKey pk) { - CScript data; uint256 hash; int32_t len = 0; - data << E_MARSHAL(ss << prevhash << prevn << vout << pk); - hash = Hash(data.begin(),data.end()); - memcpy(msg,&hash,sizeof(hash)); return(0); } int32_t musig_prevoutmsg(uint8_t *msg,uint256 sendtxid,CScript scriptPubKey) { - CTransaction vintx; uint256 hashBlock; int32_t numvouts; CTxOut vout; CPubKey pk; - memset(msg,0,32); - if ( myGetTransaction(sendtxid,vintx,hashBlock) != 0 && (numvouts= vintx.vout.size()) > 1 ) - { - if ( musig_sendopretdecode(pk,vintx.vout[numvouts-1].scriptPubKey) == 'x' ) - { - vout.nValue = vintx.vout[MUSIG_PREVN].nValue - MUSIG_TXFEE; - vout.scriptPubKey = scriptPubKey; - return(musig_msghash(msg,sendtxid,MUSIG_PREVN,vout,pk)); - } - } return(-1); } UniValue musig_calcmsg(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) { - UniValue result(UniValue::VOBJ); uint256 sendtxid; int32_t i,zeros=0; uint8_t msg[32]; char *scriptstr,str[65]; int32_t n; - if ( params != 0 && (n= cJSON_GetArraySize(params)) > 0 ) - { - if ( n == 2 ) - { - sendtxid = juint256(jitem(params,0)); - scriptstr = jstr(jitem(params,1),0); - if ( is_hexstr(scriptstr,0) != 0 ) - { - CScript scriptPubKey; - scriptPubKey.resize(strlen(scriptstr)/2); - decode_hex(&scriptPubKey[0],strlen(scriptstr)/2,scriptstr); - musig_prevoutmsg(msg,sendtxid,scriptPubKey); - for (i=0; i<32; i++) - { - sprintf(&str[i<<1],"%02x",msg[i]); - if ( msg[i] == 0 ) - zeros++; - } - str[64] = 0; - if ( zeros != 32 ) - { - result.push_back(Pair("msg",str)); - result.push_back(Pair("result","success")); - return(result); - } else return(cclib_error(result,"null result, make sure params are sendtxid, scriptPubKey")); - } else return(cclib_error(result,"script is not hex")); - } else return(cclib_error(result,"need exactly 2 parameters: sendtxid, scriptPubKey")); - } else return(cclib_error(result,"couldnt parse params")); + UniValue result(UniValue::VOBJ); + return result; } UniValue musig_combine(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) { - static secp256k1_context *ctx; - size_t clen = CPubKey::PUBLIC_KEY_SIZE; - UniValue result(UniValue::VOBJ); CPubKey pk; int32_t i,n; uint8_t pkhash[32]; char *hexstr,str[67]; secp256k1_pubkey combined_pk,spk; std::vector pubkeys; - if ( ctx == 0 ) - ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); - if ( params != 0 && (n= cJSON_GetArraySize(params)) > 0 ) - { - //fprintf(stderr,"n.%d args.(%s)\n",n,jprint(params,0)); - for (i=0; i 0 ) - { - if ( secp256k1_ec_pubkey_serialize(ctx,(uint8_t *)pk.begin(),&clen,&combined_pk,SECP256K1_EC_COMPRESSED) > 0 && clen == 33 ) - { - for (i=0; i<32; i++) - sprintf(&str[i<<1],"%02x",pkhash[i]); - str[64] = 0; - result.push_back(Pair("pkhash",str)); - - for (i=0; i<33; i++) - sprintf(&str[i<<1],"%02x",((uint8_t *)pk.begin())[i]); - str[66] = 0; - result.push_back(Pair("combined_pk",str)); - result.push_back(Pair("result","success")); - return(result); - } else return(cclib_error(result,"error serializeing combined_pk")); - } else return(cclib_error(result,"error combining pukbeys")); - } else return(cclib_error(result,"need pubkeys params")); + UniValue result(UniValue::VOBJ); + return result; } UniValue musig_session(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) { - static secp256k1_context *ctx; - UniValue result(UniValue::VOBJ); int32_t i,n,myind,num,musiglocation; char *pkstr,*pkhashstr,*msgstr; uint8_t session[32],msg[32],pkhash[32],privkey[32],pub33[33]; CPubKey pk; char str[67]; - if ( ctx == 0 ) - ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); - if ( params != 0 && (n= cJSON_GetArraySize(params)) >= 5 ) - { - myind = juint(jitem(params,0),0); - num = juint(jitem(params,1),0); - if ( myind < 0 || myind >= num || num <= 0 ) - return(cclib_error(result,"illegal myindex and numsigners")); - if ( n > 5 ) - musiglocation = juint(jitem(params,5),0); - else if ( n == 5 ) - musiglocation = 0; - //printf("number of params.%i musiglocation.%i\n",n,musiglocation); - if ( MUSIG.size() > musiglocation ) - { - for (int i = 0; i < MUSIG.size()-1; i++) - musig_infofree(MUSIG[i]); - MUSIG.clear(); - } - struct musig_info *temp_musig = musig_infocreate(myind,num); - MUSIG.push_back(temp_musig); - if ( musig_parsepubkey(ctx,MUSIG[musiglocation]->combined_pk,jitem(params,2)) < 0 ) - return(cclib_error(result,"error parsing combined_pubkey")); - else if ( cclib_parsehash(MUSIG[musiglocation]->pkhash,jitem(params,3),32) < 0 ) - return(cclib_error(result,"error parsing pkhash")); - else if ( cclib_parsehash(MUSIG[musiglocation]->msg,jitem(params,4),32) < 0 ) - return(cclib_error(result,"error parsing msg")); - Myprivkey(privkey); - GetRandBytes(session,32); - /** Initializes a signing session for a signer - * - * Returns: 1: session is successfully initialized - * 0: session could not be initialized: secret key or secret nonce overflow - * Args: ctx: pointer to a context object, initialized for signing (cannot - * be NULL) - * Out: session: the session structure to initialize (cannot be NULL) - * signers: an array of signers' data to be initialized. Array length must - * equal to `n_signers` (cannot be NULL) - * nonce_commitment32: filled with a 32-byte commitment to the generated nonce - * (cannot be NULL) - * In: session_id32: a *unique* 32-byte ID to assign to this session (cannot be - * NULL). If a non-unique session_id32 was given then a partial - * signature will LEAK THE SECRET KEY. - * msg32: the 32-byte message to be signed. Shouldn't be NULL unless you - * require sharing public nonces before the message is known - * because it reduces nonce misuse resistance. If NULL, must be - * set with `musig_session_set_msg` before signing and verifying. - * combined_pk: the combined public key of all signers (cannot be NULL) - * pk_hash32: the 32-byte hash of the signers' individual keys (cannot be - * NULL) - * n_signers: length of signers array. Number of signers participating in - * the MuSig. Must be greater than 0 and at most 2^32 - 1. - * my_index: index of this signer in the signers array - * seckey: the signer's 32-byte secret key (cannot be NULL) - */ - //fprintf(stderr, "SESSION: struct_size.%li using struct %i\n",MUSIG.size(), musiglocation); - if ( secp256k1_musig_session_initialize(ctx,&MUSIG[musiglocation]->session,MUSIG[musiglocation]->signer_data, &MUSIG[musiglocation]->nonce_commitments[MUSIG[musiglocation]->myind * 32],session,MUSIG[musiglocation]->msg,&MUSIG[musiglocation]->combined_pk,MUSIG[musiglocation]->pkhash,MUSIG[musiglocation]->num,MUSIG[musiglocation]->myind,privkey) > 0 ) - { - memset(session,0,sizeof(session)); - result.push_back(Pair("myind",(int64_t)myind)); - result.push_back(Pair("numsigners",(int64_t)num)); - for (i=0; i<32; i++) - sprintf(&str[i<<1],"%02x",MUSIG[musiglocation]->nonce_commitments[MUSIG[musiglocation]->myind*32 + i]); - str[64] = 0; - if ( n == 5 ) - MUSIG[musiglocation]->numcommits = 1; - result.push_back(Pair("commitment",str)); - result.push_back(Pair("result","success")); - memset(privkey,0,sizeof(privkey)); - return(result); - } - else - { - memset(privkey,0,sizeof(privkey)); - memset(session,0,sizeof(session)); - return(cclib_error(result,"couldnt initialize session")); - } - } else return(cclib_error(result,"wrong number of params, need 5: myindex, numsigners, combined_pk, pkhash, msg32")); + UniValue result(UniValue::VOBJ); + return result; } UniValue musig_commit(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) { - static secp256k1_context *ctx; - size_t clen = CPubKey::PUBLIC_KEY_SIZE; - UniValue result(UniValue::VOBJ); int32_t i,n,ind,myind; uint8_t pkhash[32]; CPubKey pk; char str[67]; - if ( ctx == 0 ) - ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); - if ( params != 0 && (n= cJSON_GetArraySize(params)) >= 3 ) - { - if ( n > 3 ) - myind = juint(jitem(params,3),0); - else if ( n == 3 ) - myind = 0; - if ( cclib_parsehash(pkhash,jitem(params,0),32) < 0 ) - return(cclib_error(result,"error parsing pkhash")); - else if ( memcmp(MUSIG[myind]->pkhash,pkhash,32) != 0 ) - return(cclib_error(result,"pkhash doesnt match session pkhash")); - else if ( (ind= juint(jitem(params,1),0)) < 0 || ind >= MUSIG[myind]->num ) - return(cclib_error(result,"illegal ind for session")); - else if ( cclib_parsehash(&MUSIG[myind]->nonce_commitments[ind*32],jitem(params,2),32) < 0 ) - return(cclib_error(result,"error parsing commitment")); - /** Gets the signer's public nonce given a list of all signers' data with commitments - * - * Returns: 1: public nonce is written in nonce - * 0: signer data is missing commitments or session isn't initialized - * for signing - * Args: ctx: pointer to a context object (cannot be NULL) - * session: the signing session to get the nonce from (cannot be NULL) - * signers: an array of signers' data initialized with - * `musig_session_initialize`. Array length must equal to - * `n_commitments` (cannot be NULL) - * Out: nonce: the nonce (cannot be NULL) - * In: commitments: array of 32-byte nonce commitments (cannot be NULL) - * n_commitments: the length of commitments and signers array. Must be the total - * number of signers participating in the MuSig. - */ - result.push_back(Pair("added_index",ind)); - //fprintf(stderr, "COMMIT: struct_size.%li using_struct.%i added_index.%i\n",MUSIG.size(), myind, ind); - MUSIG[myind]->numcommits++; - if ( MUSIG[myind]->numcommits >= MUSIG[myind]->num && secp256k1_musig_session_get_public_nonce(ctx,&MUSIG[myind]->session,MUSIG[myind]->signer_data,&MUSIG[myind]->nonces[MUSIG[myind]->myind],MUSIG[myind]->commitment_ptrs,MUSIG[myind]->num) > 0 ) - { - if ( secp256k1_ec_pubkey_serialize(ctx,(uint8_t *)pk.begin(),&clen,&MUSIG[myind]->nonces[MUSIG[myind]->myind],SECP256K1_EC_COMPRESSED) > 0 && clen == 33 ) - { - for (i=0; i<33; i++) - sprintf(&str[i<<1],"%02x",((uint8_t *)pk.begin())[i]); - str[66] = 0; - if ( n == 3 ) - MUSIG[myind]->numnonces = 1; - result.push_back(Pair("myind",MUSIG[myind]->myind)); - result.push_back(Pair("nonce",str)); - result.push_back(Pair("result","success")); - } else return(cclib_error(result,"error serializing nonce (pubkey)")); - } - else - { - result.push_back(Pair("status","not enough commitments")); - result.push_back(Pair("result","success")); - } - return(result); - } else return(cclib_error(result,"wrong number of params, need 3: pkhash, ind, commitment")); + UniValue result(UniValue::VOBJ); + return result; } UniValue musig_nonce(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) { - static secp256k1_context *ctx; - UniValue result(UniValue::VOBJ); int32_t i,n,ind,myind; uint8_t pkhash[32],psig[32]; CPubKey pk; char str[67]; - if ( ctx == 0 ) - ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); - if ( params != 0 && (n= cJSON_GetArraySize(params)) >= 3 ) - { - if ( n > 3 ) - myind = juint(jitem(params,3),0); - else if ( n == 3 ) - myind = 0; - if ( cclib_parsehash(pkhash,jitem(params,0),32) < 0 ) - return(cclib_error(result,"error parsing pkhash")); - else if ( memcmp(MUSIG[myind]->pkhash,pkhash,32) != 0 ) - return(cclib_error(result,"pkhash doesnt match session pkhash")); - else if ( (ind= juint(jitem(params,1),0)) < 0 || ind >= MUSIG[myind]->num ) - return(cclib_error(result,"illegal ind for session")); - else if ( musig_parsepubkey(ctx,MUSIG[myind]->nonces[ind],jitem(params,2)) < 0 ) - return(cclib_error(result,"error parsing nonce")); - result.push_back(Pair("added_index",ind)); - /** Checks a signer's public nonce against a commitment to said nonce, and update - * data structure if they match - * - * Returns: 1: commitment was valid, data structure updated - * 0: commitment was invalid, nothing happened - * Args: ctx: pointer to a context object (cannot be NULL) - * signer: pointer to the signer data to update (cannot be NULL). Must have - * been used with `musig_session_get_public_nonce` or initialized - * with `musig_session_initialize_verifier`. - * In: nonce: signer's alleged public nonce (cannot be NULL) - */ - MUSIG[myind]->numnonces++; - //fprintf(stderr, "NONCE: struct_size.%li using_struct.%i added_index.%i numnounces.%i num.%i\n",MUSIG.size(), myind, ind, MUSIG[myind]->numnonces, MUSIG[myind]->num); - if ( MUSIG[myind]->numnonces < MUSIG[myind]->num ) - { - result.push_back(Pair("status","not enough nonces")); - result.push_back(Pair("result","success")); - return(result); - } - for (i=0; inum; i++) - { - if ( secp256k1_musig_set_nonce(ctx,&MUSIG[myind]->signer_data[i],&MUSIG[myind]->nonces[i]) == 0 ) - return(cclib_error(result,"error setting nonce")); - } - /** Updates a session with the combined public nonce of all signers. The combined - * public nonce is the sum of every signer's public nonce. - * - * Returns: 1: nonces are successfully combined - * 0: a signer's nonce is missing - * Args: ctx: pointer to a context object (cannot be NULL) - * session: session to update with the combined public nonce (cannot be - * NULL) - * signers: an array of signers' data, which must have had public nonces - * set with `musig_set_nonce`. Array length must equal to `n_signers` - * (cannot be NULL) - * n_signers: the length of the signers array. Must be the total number of - * signers participating in the MuSig. - * Out: nonce_is_negated: a pointer to an integer that indicates if the combined - * public nonce had to be negated. - * adaptor: point to add to the combined public nonce. If NULL, nothing is - * added to the combined nonce. - */ - if ( secp256k1_musig_session_combine_nonces(ctx,&MUSIG[myind]->session,MUSIG[myind]->signer_data,MUSIG[myind]->num,NULL,NULL) > 0 ) - { - if ( secp256k1_musig_partial_sign(ctx,&MUSIG[myind]->session,&MUSIG[myind]->partial_sig[MUSIG[myind]->myind]) > 0 ) - { - if ( secp256k1_musig_partial_signature_serialize(ctx,psig,&MUSIG[myind]->partial_sig[MUSIG[myind]->myind]) > 0 ) - { - for (i=0; i<32; i++) - sprintf(&str[i<<1],"%02x",psig[i]); - str[64] = 0; - result.push_back(Pair("myind",MUSIG[myind]->myind)); - result.push_back(Pair("partialsig",str)); - result.push_back(Pair("result","success")); - if ( n == 3 ) - MUSIG[myind]->numpartials = 1; - return(result); - } else return(cclib_error(result,"error serializing partial sig")); - } else return(cclib_error(result,"error making partial sig")); - } else return(cclib_error(result,"error combining nonces")); - } else return(cclib_error(result,"wrong number of params, need 3: pkhash, ind, nonce")); + UniValue result(UniValue::VOBJ); + return result; } UniValue musig_partialsig(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) { - static secp256k1_context *ctx; - UniValue result(UniValue::VOBJ); int32_t i,ind,n,myind; uint8_t pkhash[32],psig[32],out64[64]; char str[129]; secp256k1_schnorrsig sig; - if ( ctx == 0 ) - ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); - if ( params != 0 && (n= cJSON_GetArraySize(params)) >= 3 ) - { - if ( n > 3 ) - myind = juint(jitem(params,3),0); - else if ( n == 3 ) - myind = 0; - if ( cclib_parsehash(pkhash,jitem(params,0),32) < 0 ) - return(cclib_error(result,"error parsing pkhash")); - else if ( memcmp(MUSIG[myind]->pkhash,pkhash,32) != 0 ) - return(cclib_error(result,"pkhash doesnt match session pkhash")); - else if ( (ind= juint(jitem(params,1),0)) < 0 || ind >= MUSIG[myind]->num ) - return(cclib_error(result,"illegal ind for session")); - else if ( cclib_parsehash(psig,jitem(params,2),32) < 0 ) - return(cclib_error(result,"error parsing psig")); - else if ( secp256k1_musig_partial_signature_parse(ctx,&MUSIG[myind]->partial_sig[ind],psig) == 0 ) - return(cclib_error(result,"error parsing partialsig")); - result.push_back(Pair("added_index",ind)); - //fprintf(stderr, "SIG: struct_size.%li using_struct.%i added_index.%i\n",MUSIG.size(), myind, ind); - MUSIG[myind]->numpartials++; - if ( MUSIG[myind]->numpartials >= MUSIG[myind]->num && secp256k1_musig_partial_sig_combine(ctx,&MUSIG[myind]->session,&sig,MUSIG[myind]->partial_sig,MUSIG[myind]->num) > 0 ) - { - if ( secp256k1_schnorrsig_serialize(ctx,out64,&sig) > 0 ) - { - result.push_back(Pair("result","success")); - for (i=0; i<64; i++) - sprintf(&str[i<<1],"%02x",out64[i]); - str[128] = 0; - result.push_back(Pair("combinedsig",str)); - } else return(cclib_error(result,"error serializing combinedsig")); - } - else - { - if ( secp256k1_musig_partial_signature_serialize(ctx,psig,&MUSIG[myind]->partial_sig[MUSIG[myind]->myind]) > 0 ) - { - result.push_back(Pair("myind",ind)); - for (i=0; i<32; i++) - sprintf(&str[i<<1],"%02x",psig[i]); - str[64] = 0; - result.push_back(Pair("partialsig",str)); - result.push_back(Pair("result","success")); - result.push_back(Pair("status","need more partialsigs")); - } else return(cclib_error(result,"error generating my partialsig")); - } - return(result); - } else return(cclib_error(result,"wrong number of params, need 3: pkhash, ind, partialsig")); + UniValue result(UniValue::VOBJ); + return result; } //int testmain(void); UniValue musig_verify(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) { - static secp256k1_context *ctx; - UniValue result(UniValue::VOBJ); int32_t i,n; uint8_t msg[32],musig64[64]; secp256k1_pubkey combined_pk; secp256k1_schnorrsig musig; char str[129]; - //testmain(); - if ( ctx == 0 ) - ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); - if ( params != 0 && (n= cJSON_GetArraySize(params)) == 3 ) - { - if ( cclib_parsehash(msg,jitem(params,0),32) < 0 ) - return(cclib_error(result,"error parsing pkhash")); - else if ( musig_parsepubkey(ctx,combined_pk,jitem(params,1)) < 0 ) - return(cclib_error(result,"error parsing combined_pk")); - else if ( cclib_parsehash(musig64,jitem(params,2),64) < 0 ) - return(cclib_error(result,"error parsing musig64")); - for (i=0; i<32; i++) - sprintf(&str[i*2],"%02x",msg[i]); - str[64] = 0; - result.push_back(Pair("msg",str)); - result.push_back(Pair("combined_pk",jstr(jitem(params,1),0))); - for (i=0; i<64; i++) - sprintf(&str[i*2],"%02x",musig64[i]); - str[128] = 0; - result.push_back(Pair("combinedsig",str)); - if ( secp256k1_schnorrsig_parse(ctx,&musig,&musig64[0]) > 0 ) - { - if ( secp256k1_schnorrsig_verify(ctx,&musig,msg,&combined_pk) > 0 ) - { - result.push_back(Pair("result","success")); - return(result); - } else return(cclib_error(result,"musig didnt verify")); - } else return(cclib_error(result,"couldnt parse musig64")); - } else return(cclib_error(result,"wrong number of params, need 3: msg, combined_pk, combinedsig")); + UniValue result(UniValue::VOBJ); + return result; } -// helpers for rpc calls that generate/validate onchain tx - UniValue musig_rawtxresult(UniValue &result,std::string rawtx) { - CTransaction tx; - if ( rawtx.size() > 0 ) - { - result.push_back(Pair("hex",rawtx)); - if ( DecodeHexTx(tx,rawtx) != 0 ) - { - //if ( broadcastflag != 0 && myAddtomempool(tx) != 0 ) - // RelayTransaction(tx); - result.push_back(Pair("txid",tx.GetHash().ToString())); - result.push_back(Pair("result","success")); - } else result.push_back(Pair("error","decode hex")); - } else result.push_back(Pair("error","couldnt finalize CCtx")); - return(result); + UniValue result(UniValue::VOBJ); + return result; } UniValue musig_send(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) { - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), hush_nextheight()); - UniValue result(UniValue::VOBJ); int32_t n; char *hexstr; std::string rawtx; int64_t amount; CPubKey musigpk,mypk; - if ( txfee == 0 ) - txfee = MUSIG_TXFEE; - mypk = pubkey2pk(Mypubkey()); - musigpk = GetUnspendable(cp,0); - if ( params != 0 && (n= cJSON_GetArraySize(params)) > 0 ) - { - if ( n == 2 && (hexstr= jstr(jitem(params,0),0)) != 0 && is_hexstr(hexstr,0) == 66 ) - { - CPubKey pk(ParseHex(hexstr)); - amount = jdouble(jitem(params,1),0) * COIN + 0.0000000049; - if ( amount >= 3*txfee && AddNormalinputs(mtx,mypk,amount+2*txfee,64) >= amount+2*txfee ) - { - mtx.vout.push_back(MakeCC1vout(cp->evalcode,amount+txfee,musigpk)); - rawtx = FinalizeCCTx(0,cp,mtx,mypk,txfee,musig_sendopret('x',pk)); - return(musig_rawtxresult(result,rawtx)); - } else return(cclib_error(result,"couldnt find funds or less than 0.0003")); - } else return(cclib_error(result,"must have 2 params: pk, amount")); - } else return(cclib_error(result,"not enough parameters")); + UniValue result(UniValue::VOBJ); + return result; } UniValue musig_spend(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) { - static secp256k1_context *ctx; - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), hush_nextheight()); - UniValue result(UniValue::VOBJ); std::string rawtx; CPubKey mypk,pk; secp256k1_pubkey combined_pk; char *scriptstr,*musigstr; uint8_t msg[32]; CTransaction vintx; uint256 prevhash,hashBlock; int32_t i,n,numvouts; char str[129]; CTxOut vout; secp256k1_schnorrsig musig; - if ( ctx == 0 ) - ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); - if ( params != 0 && (n= cJSON_GetArraySize(params)) > 0 ) - { - if ( n == 3 ) - { - prevhash = juint256(jitem(params,0)); - scriptstr = jstr(jitem(params,1),0); - musigstr = jstr(jitem(params,2),0); - if ( is_hexstr(scriptstr,0) != 0 && is_hexstr(musigstr,0) == 128 ) - { - if ( txfee == 0 ) - txfee = MUSIG_TXFEE; - mypk = pubkey2pk(Mypubkey()); - std::vector musig64(ParseHex(musigstr)); - CScript scriptPubKey; - scriptPubKey.resize(strlen(scriptstr)/2); - decode_hex(&scriptPubKey[0],strlen(scriptstr)/2,scriptstr); - if ( myGetTransaction(prevhash,vintx,hashBlock) != 0 && (numvouts= vintx.vout.size()) > 1 ) - { - vout.nValue = vintx.vout[0].nValue - txfee; - vout.scriptPubKey = scriptPubKey; - if ( musig_sendopretdecode(pk,vintx.vout[numvouts-1].scriptPubKey) == 'x' ) - { - if ( secp256k1_schnorrsig_parse((const secp256k1_context *)ctx,&musig,(const uint8_t *)&musig64[0]) > 0 && - secp256k1_ec_pubkey_parse(ctx,&combined_pk,pk.begin(),33) > 0 ) - { - musig_prevoutmsg(msg,prevhash,vout.scriptPubKey); - { - for (i=0; i<32; i++) - sprintf(&str[i*2],"%02x",msg[i]); - str[64] = 0; - result.push_back(Pair("msg",str)); - for (i=0; i<33; i++) - sprintf(&str[i*2],"%02x",((uint8_t *)pk.begin())[i]); - str[66] = 0; - result.push_back(Pair("combined_pk",str)); - for (i=0; i<64; i++) - sprintf(&str[i*2],"%02x",musig64[i]); - str[128] = 0; - result.push_back(Pair("combinedsig",str)); - } - if ( !secp256k1_schnorrsig_verify((const secp256k1_context *)ctx,&musig,(const uint8_t *)msg,(const secp256k1_pubkey *)&combined_pk) ) - { - return(cclib_error(result,"musig didnt validate")); - } - mtx.vin.push_back(CTxIn(prevhash,MUSIG_PREVN)); - mtx.vout.push_back(vout); - rawtx = FinalizeCCTx(0,cp,mtx,mypk,txfee,musig_spendopret('y',pk,musig64)); - return(musig_rawtxresult(result,rawtx)); - } else return(cclib_error(result,"couldnt parse pk or musig")); - } else return(cclib_error(result,"couldnt decode send opret")); - } else return(cclib_error(result,"couldnt find vin0")); - } else return(cclib_error(result,"script or musig is not hex")); - } else return(cclib_error(result,"need to have exactly 3 params sendtxid, scriptPubKey, musig")); - } else return(cclib_error(result,"params parse error")); + UniValue result(UniValue::VOBJ); + return result; } bool musig_validate(struct CCcontract_info *cp,int32_t height,Eval *eval,const CTransaction tx) { - static secp256k1_context *ctx; - secp256k1_pubkey combined_pk; CPubKey pk,checkpk; secp256k1_schnorrsig musig; uint256 hashBlock; CTransaction vintx; int32_t numvouts; std::vector musig64; uint8_t msg[32]; - if ( ctx == 0 ) - ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); - if ( tx.vout.size() != 2 ) - return eval->Invalid("numvouts != 2"); - else if ( tx.vin.size() != 1 ) - return eval->Invalid("numvins != 1"); - else if ( IsCCInput(tx.vin[0].scriptSig) == 0 ) - return eval->Invalid("illegal normal vin0"); - else if ( myGetTransaction(tx.vin[0].prevout.hash,vintx,hashBlock) != 0 && (numvouts= vintx.vout.size()) > 1 ) - { - if ( musig_sendopretdecode(pk,vintx.vout[numvouts-1].scriptPubKey) == 'x' ) - { - if ( musig_spendopretdecode(checkpk,musig64,tx.vout[tx.vout.size()-1].scriptPubKey) == 'y' ) - { - if ( pk == checkpk ) - { - if ( secp256k1_schnorrsig_parse((const secp256k1_context *)ctx,&musig,(const uint8_t *)&musig64[0]) > 0 && - secp256k1_ec_pubkey_parse(ctx,&combined_pk,pk.begin(),33) > 0 ) - { - musig_prevoutmsg(msg,tx.vin[0].prevout.hash,tx.vout[0].scriptPubKey); - if ( !secp256k1_schnorrsig_verify((const secp256k1_context *)ctx,&musig,(const uint8_t *)msg,(const secp256k1_pubkey *)&combined_pk) ) - return eval->Invalid("failed schnorrsig_verify"); - else return(true); - } else return eval->Invalid("couldnt parse pk or musig"); - } else return eval->Invalid("combined_pk didnt match send opret"); - } else return eval->Invalid("failed decode musig spendopret"); - } else return eval->Invalid("couldnt decode send opret"); - } else return eval->Invalid("couldnt find vin0 tx"); + return false; } From a97dcf6022337c0f7fab50321d18c63a17fe9038 Mon Sep 17 00:00:00 2001 From: Duke Date: Wed, 31 Jan 2024 13:50:03 -0500 Subject: [PATCH 13/78] Delete more CCs #381 --- src/cc/CCassets.h | 18 - src/cc/CCassetstx.cpp | 762 ------------------------------------------ 2 files changed, 780 deletions(-) diff --git a/src/cc/CCassets.h b/src/cc/CCassets.h index c0b64f131..3b03570f8 100644 --- a/src/cc/CCassets.h +++ b/src/cc/CCassets.h @@ -46,23 +46,5 @@ int64_t AssetValidateBuyvin(struct CCcontract_info *cp,Eval* eval,int64_t &tmppr int64_t AssetValidateSellvin(struct CCcontract_info *cp,Eval* eval,int64_t &tmpprice,std::vector &tmporigpubkey,char *CCaddr,char *origaddr,const CTransaction &tx,uint256 assetid); bool AssetCalcAmounts(struct CCcontract_info *cpAssets, int64_t &inputs, int64_t &outputs, Eval* eval, const CTransaction &tx, uint256 assetid); -// CCassetstx -//int64_t GetAssetBalance(CPubKey pk,uint256 tokenid); // --> GetTokenBalance() -int64_t AddAssetInputs(struct CCcontract_info *cp, CMutableTransaction &mtx, CPubKey pk, uint256 assetid, int64_t total, int32_t maxinputs); - -UniValue AssetOrders(uint256 tokenid, CPubKey pubkey, uint8_t additionalEvalCode); -//UniValue AssetInfo(uint256 tokenid); -//UniValue AssetList(); -//std::string CreateAsset(int64_t txfee,int64_t assetsupply,std::string name,std::string description); -//std::string AssetTransfer(int64_t txfee,uint256 assetid,std::vector destpubkey,int64_t total); -//std::string AssetConvert(int64_t txfee,uint256 assetid,std::vector destpubkey,int64_t total,int32_t evalcode); - -std::string CreateBuyOffer(int64_t txfee,int64_t bidamount,uint256 assetid,int64_t pricetotal); -std::string CancelBuyOffer(int64_t txfee,uint256 assetid,uint256 bidtxid); -std::string FillBuyOffer(int64_t txfee,uint256 assetid,uint256 bidtxid,int64_t fillamount); -std::string CreateSell(int64_t txfee,int64_t askamount,uint256 assetid,int64_t pricetotal); -std::string CreateSwap(int64_t txfee,int64_t askamount,uint256 assetid,uint256 assetid2,int64_t pricetotal); -std::string CancelSell(int64_t txfee,uint256 assetid,uint256 asktxid); -std::string FillSell(int64_t txfee,uint256 assetid,uint256 assetid2,uint256 asktxid,int64_t fillamount); #endif diff --git a/src/cc/CCassetstx.cpp b/src/cc/CCassetstx.cpp index a0c893937..596f3643b 100644 --- a/src/cc/CCassetstx.cpp +++ b/src/cc/CCassetstx.cpp @@ -19,765 +19,3 @@ #include "CCassets.h" #include "CCtokens.h" - -UniValue AssetOrders(uint256 refassetid, CPubKey pk, uint8_t additionalEvalCode) -{ - UniValue result(UniValue::VARR); - - struct CCcontract_info *cpAssets, assetsC; - struct CCcontract_info *cpTokens, tokensC; - - cpAssets = CCinit(&assetsC, EVAL_ASSETS); - cpTokens = CCinit(&tokensC, EVAL_TOKENS); - - auto addOrders = [&](struct CCcontract_info *cp, std::vector >::const_iterator it) - { - uint256 txid, hashBlock, assetid, assetid2; - int64_t price; - std::vector origpubkey; - CTransaction ordertx; - uint8_t funcid, evalCode; - char numstr[32], funcidstr[16], origaddr[64], origtokenaddr[64]; - - txid = it->first.txhash; - LOGSTREAM("ccassets", CCLOG_DEBUG2, stream << "addOrders() checking txid=" << txid.GetHex() << std::endl); - if ( myGetTransaction(txid, ordertx, hashBlock) != 0 ) - { - // for logging: funcid = DecodeAssetOpRet(vintx.vout[vintx.vout.size() - 1].scriptPubKey, evalCode, assetid, assetid2, price, origpubkey); - if (ordertx.vout.size() > 0 && (funcid = DecodeAssetTokenOpRet(ordertx.vout[ordertx.vout.size()-1].scriptPubKey, evalCode, assetid, assetid2, price, origpubkey)) != 0) - { - LOGSTREAM("ccassets", CCLOG_DEBUG2, stream << "addOrders() checking ordertx.vout.size()=" << ordertx.vout.size() << " funcid=" << (char)(funcid ? funcid : ' ') << " assetid=" << assetid.GetHex() << std::endl); - - if (pk == CPubKey() && (refassetid == zeroid || assetid == refassetid) // tokenorders - || pk != CPubKey() && pk == pubkey2pk(origpubkey) && (funcid == 'S' || funcid == 's')) // mytokenorders, returns only asks (is this correct?) - { - - LOGSTREAM("ccassets", CCLOG_DEBUG2, stream << "addOrders() it->first.index=" << it->first.index << " ordertx.vout[it->first.index].nValue=" << ordertx.vout[it->first.index].nValue << std::endl); - if (ordertx.vout[it->first.index].nValue == 0) { - LOGSTREAM("ccassets", CCLOG_DEBUG2, stream << "addOrders() order with value=0 skipped" << std::endl); - return; - } - - UniValue item(UniValue::VOBJ); - - funcidstr[0] = funcid; - funcidstr[1] = 0; - item.push_back(Pair("funcid", funcidstr)); - item.push_back(Pair("txid", txid.GetHex())); - item.push_back(Pair("vout", (int64_t)it->first.index)); - if (funcid == 'b' || funcid == 'B') - { - sprintf(numstr, "%.8f", (double)ordertx.vout[it->first.index].nValue / COIN); - item.push_back(Pair("amount", numstr)); - sprintf(numstr, "%.8f", (double)ordertx.vout[0].nValue / COIN); - item.push_back(Pair("bidamount", numstr)); - } - else - { - sprintf(numstr, "%llu", (long long)ordertx.vout[it->first.index].nValue); - item.push_back(Pair("amount", numstr)); - sprintf(numstr, "%llu", (long long)ordertx.vout[0].nValue); - item.push_back(Pair("askamount", numstr)); - } - if (origpubkey.size() == CPubKey::COMPRESSED_PUBLIC_KEY_SIZE) - { - GetCCaddress(cp, origaddr, pubkey2pk(origpubkey)); - item.push_back(Pair("origaddress", origaddr)); - GetTokensCCaddress(cpTokens, origtokenaddr, pubkey2pk(origpubkey)); - item.push_back(Pair("origtokenaddress", origtokenaddr)); - } - if (assetid != zeroid) - item.push_back(Pair("tokenid", assetid.GetHex())); - if (assetid2 != zeroid) - item.push_back(Pair("otherid", assetid2.GetHex())); - if (price > 0) - { - if (funcid == 's' || funcid == 'S' || funcid == 'e' || funcid == 'e') - { - sprintf(numstr, "%.8f", (double)price / COIN); - item.push_back(Pair("totalrequired", numstr)); - sprintf(numstr, "%.8f", (double)price / (COIN * ordertx.vout[0].nValue)); - item.push_back(Pair("price", numstr)); - } - else - { - item.push_back(Pair("totalrequired", (int64_t)price)); - sprintf(numstr, "%.8f", (double)ordertx.vout[0].nValue / (price * COIN)); - item.push_back(Pair("price", numstr)); - } - } - result.push_back(item); - LOGSTREAM("ccassets", CCLOG_DEBUG1, stream << "addOrders() added order funcId=" << (char)(funcid ? funcid : ' ') << " it->first.index=" << it->first.index << " ordertx.vout[it->first.index].nValue=" << ordertx.vout[it->first.index].nValue << " tokenid=" << assetid.GetHex() << std::endl); - } - } - } - }; - - std::vector > unspentOutputsTokens, unspentOutputsDualEvalTokens, unspentOutputsCoins; - - char assetsUnspendableAddr[64]; - GetCCaddress(cpAssets, assetsUnspendableAddr, GetUnspendable(cpAssets, NULL)); - SetCCunspents(unspentOutputsCoins, assetsUnspendableAddr,true); - - char assetsTokensUnspendableAddr[64]; - std::vector vopretNonfungible; - if (refassetid != zeroid) { - GetNonfungibleData(refassetid, vopretNonfungible); - if (vopretNonfungible.size() > 0) - cpAssets->additionalTokensEvalcode2 = vopretNonfungible.begin()[0]; - } - GetTokensCCaddress(cpAssets, assetsTokensUnspendableAddr, GetUnspendable(cpAssets, NULL)); - SetCCunspents(unspentOutputsTokens, assetsTokensUnspendableAddr,true); - - // tokenbids: - for (std::vector >::const_iterator itCoins = unspentOutputsCoins.begin(); - itCoins != unspentOutputsCoins.end(); - itCoins++) - addOrders(cpAssets, itCoins); - - // tokenasks: - for (std::vector >::const_iterator itTokens = unspentOutputsTokens.begin(); - itTokens != unspentOutputsTokens.end(); - itTokens++) - addOrders(cpAssets, itTokens); - - if (additionalEvalCode != 0) { //this would be mytokenorders - char assetsDualEvalTokensUnspendableAddr[64]; - - // try also dual eval tokenasks (and we do not need bids): - cpAssets->additionalTokensEvalcode2 = additionalEvalCode; - GetTokensCCaddress(cpAssets, assetsDualEvalTokensUnspendableAddr, GetUnspendable(cpAssets, NULL)); - SetCCunspents(unspentOutputsDualEvalTokens, assetsDualEvalTokensUnspendableAddr,true); - - for (std::vector >::const_iterator itDualEvalTokens = unspentOutputsDualEvalTokens.begin(); - itDualEvalTokens != unspentOutputsDualEvalTokens.end(); - itDualEvalTokens++) - addOrders(cpAssets, itDualEvalTokens); - } - return(result); -} - -// not used (use TokenCreate instead) -/* std::string CreateAsset(int64_t txfee,int64_t assetsupply,std::string name,std::string description) -{ - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), hush_nextheight()); - CPubKey mypk; struct CCcontract_info *cp,C; - if ( assetsupply < 0 ) - { - fprintf(stderr,"negative assetsupply %lld\n",(long long)assetsupply); - return(""); - } - cp = CCinit(&C,EVAL_ASSETS); - if ( name.size() > 32 || description.size() > 4096 ) - { - fprintf(stderr,"name.%d or description.%d is too big\n",(int32_t)name.size(),(int32_t)description.size()); - return(""); - } - if ( txfee == 0 ) - txfee = 10000; - mypk = pubkey2pk(Mypubkey()); - if ( AddNormalinputs(mtx,mypk,assetsupply+2*txfee,64) > 0 ) - { - mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS,assetsupply,mypk)); - mtx.vout.push_back(CTxOut(txfee,CScript() << ParseHex(cp->CChexstr) << OP_CHECKSIG)); - return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeAssetCreateOpRet('c',Mypubkey(),name,description))); - } - return(""); -} */ - -// not used (use TokenTransfer instead) -/* std::string AssetTransfer(int64_t txfee,uint256 assetid,std::vector destpubkey,int64_t total) -{ - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), hush_nextheight()); - CPubKey mypk; uint64_t mask; int64_t CCchange=0,inputs=0; struct CCcontract_info *cp,C; - if ( total < 0 ) - { - fprintf(stderr,"negative total %lld\n",(long long)total); - return(""); - } - cp = CCinit(&C,EVAL_ASSETS); - if ( txfee == 0 ) - txfee = 10000; - mypk = pubkey2pk(Mypubkey()); - if ( AddNormalinputs(mtx,mypk,txfee,3) > 0 ) - { - //n = outputs.size(); - //if ( n == amounts.size() ) - //{ - // for (i=0; i 0 ) - { - - if (inputs < total) { //added dimxy - std::cerr << "AssetTransfer(): insufficient funds" << std::endl; - return (""); - } - if ( inputs > total ) - CCchange = (inputs - total); - //for (i=0; i destpubkey,int64_t total,int32_t evalcode) -{ - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), hush_nextheight()); - CPubKey mypk; int64_t CCchange=0,inputs=0; struct CCcontract_info *cp,C; - if ( total < 0 ) - { - fprintf(stderr,"negative total %lld\n",(long long)total); - return(""); - } - cp = CCinit(&C,EVAL_ASSETS); - if ( txfee == 0 ) - txfee = 10000; - mypk = pubkey2pk(Mypubkey()); - if ( AddNormalinputs(mtx,mypk,txfee,3) > 0 ) - { - if ( (inputs= AddAssetInputs(cp,mtx,mypk,assetid,total,60)) > 0 ) - { - if ( inputs > total ) - CCchange = (inputs - total); - mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS,CCchange,mypk)); - mtx.vout.push_back(MakeCC1vout(evalcode,total,pubkey2pk(destpubkey))); - return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeAssetOpRet('t',assetid,zeroid,0,Mypubkey()))); - } else fprintf(stderr,"not enough CC asset inputs for %.8f\n",(double)total/COIN); - } - return(""); -} */ - -// rpc tokenbid implementation, locks 'bidamount' coins for the 'pricetotal' of tokens -std::string CreateBuyOffer(int64_t txfee, int64_t bidamount, uint256 assetid, int64_t pricetotal) -{ - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), hush_nextheight()); - CPubKey mypk; - struct CCcontract_info *cpAssets, C; - uint256 hashBlock; - CTransaction vintx; - std::vector origpubkey; - std::string name,description; - int64_t inputs; - - std::cerr << "CreateBuyOffer() bidamount=" << bidamount << " numtokens(pricetotal)=" << pricetotal << std::endl; - - if (bidamount < 0 || pricetotal < 0) - { - fprintf(stderr,"negative bidamount %lld, pricetotal %lld\n", (long long)bidamount, (long long)pricetotal); - return(""); - } - if (myGetTransaction(assetid, vintx, hashBlock) == 0) - { - fprintf(stderr,"cant find assetid\n"); - return(""); - } - if (vintx.vout.size() > 0 && DecodeTokenCreateOpRet(vintx.vout[vintx.vout.size()-1].scriptPubKey, origpubkey, name, description) == 0) - { - fprintf(stderr,"assetid isnt assetcreation txid\n"); - return(""); - } - - cpAssets = CCinit(&C,EVAL_ASSETS); // NOTE: assets here! - if (txfee == 0) - txfee = 10000; - - mypk = pubkey2pk(Mypubkey()); - - if ((inputs = AddNormalinputs(mtx, mypk, bidamount+(2*txfee), 64)) > 0) - { - std::cerr << "CreateBuyOffer() inputs=" << inputs << std::endl; - if (inputs < bidamount+txfee) { - std::cerr << "CreateBuyOffer(): insufficient coins to make buy offer" << std::endl; - CCerror = strprintf("insufficient coins to make buy offer"); - return (""); - } - - CPubKey unspendableAssetsPubkey = GetUnspendable(cpAssets, 0); - mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS, bidamount, unspendableAssetsPubkey)); - mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS, txfee, mypk)); - std::vector voutTokenPubkeys; // should be empty - no token vouts - - return FinalizeCCTx(0, cpAssets, mtx, mypk, txfee, - EncodeTokenOpRet(assetid, voutTokenPubkeys, // TODO: actually this tx is not 'tokens', maybe it is better not to have token opret here but only asset opret. - std::make_pair(OPRETID_ASSETSDATA, EncodeAssetOpRet('b', zeroid, pricetotal, Mypubkey())))); // But still such token opret should not make problems because no token eval in these vouts - } - CCerror = strprintf("no coins found to make buy offer"); - return(""); -} - -// rpc tokenask implementation, locks 'askamount' tokens for the 'pricetotal' -std::string CreateSell(int64_t txfee,int64_t askamount,uint256 assetid,int64_t pricetotal) -{ - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), hush_nextheight()); - CPubKey mypk; - uint64_t mask; - int64_t inputs, CCchange; - struct CCcontract_info *cpAssets, assetsC; - struct CCcontract_info *cpTokens, tokensC; - - //std::cerr << "CreateSell() askamount=" << askamount << " pricetotal=" << pricetotal << std::endl; - - if (askamount < 0 || pricetotal < 0) { - fprintf(stderr,"negative askamount %lld, askamount %lld\n",(long long)pricetotal,(long long)askamount); - return(""); - } - - cpAssets = CCinit(&assetsC, EVAL_ASSETS); // NOTE: for signing - - - if (txfee == 0) - txfee = 10000; - - mypk = pubkey2pk(Mypubkey()); - if (AddNormalinputs(mtx, mypk, 2*txfee, 3) > 0) - { - std::vector vopretNonfungible; - mask = ~((1LL << mtx.vin.size()) - 1); - // add single-eval tokens (or non-fungible tokens): - cpTokens = CCinit(&tokensC, EVAL_TOKENS); // NOTE: adding inputs only from EVAL_TOKENS cc - if ((inputs = AddTokenCCInputs(cpTokens, mtx, mypk, assetid, askamount, 60, vopretNonfungible)) > 0) - { - if (inputs < askamount) { - //was: askamount = inputs; - std::cerr << "CreateSell(): insufficient tokens for ask" << std::endl; - CCerror = strprintf("insufficient tokens for ask"); - return (""); - } - - // if this is non-fungible tokens: - if( !vopretNonfungible.empty() ) - // set its evalcode - cpAssets->additionalTokensEvalcode2 = vopretNonfungible.begin()[0]; - - CPubKey unspendableAssetsPubkey = GetUnspendable(cpAssets, NULL); - mtx.vout.push_back(MakeTokensCC1vout(EVAL_ASSETS, cpAssets->additionalTokensEvalcode2, askamount, unspendableAssetsPubkey)); - mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS, txfee, mypk)); //marker (seems, it is not for tokenorders) - if (inputs > askamount) - CCchange = (inputs - askamount); - if (CCchange != 0) - // change to single-eval or non-fungible token vout (although for non-fungible token change currently is not possible) - mtx.vout.push_back(MakeTokensCC1vout((cpAssets->additionalTokensEvalcode2) ? cpAssets->additionalTokensEvalcode2 : EVAL_TOKENS, CCchange, mypk)); - - std::vector voutTokenPubkeys; - voutTokenPubkeys.push_back(unspendableAssetsPubkey); - - return FinalizeCCTx(mask, cpTokens, mtx, mypk, txfee, - EncodeTokenOpRet(assetid, voutTokenPubkeys, - std::make_pair(OPRETID_ASSETSDATA, EncodeAssetOpRet('s', zeroid, pricetotal, Mypubkey())))); - } - else { - fprintf(stderr, "need some tokens to place ask\n"); - } - } - else { // dimxy added 'else', because it was misleading message before - fprintf(stderr, "need some native coins to place ask\n"); - } - return(""); -} - -////////////////////////// NOT IMPLEMENTED YET///////////////////////////////// -std::string CreateSwap(int64_t txfee,int64_t askamount,uint256 assetid,uint256 assetid2,int64_t pricetotal) -{ - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), hush_nextheight()); - CPubKey mypk; uint64_t mask; int64_t inputs,CCchange; CScript opret; struct CCcontract_info *cp,C; - - ////////////////////////// NOT IMPLEMENTED YET///////////////////////////////// - fprintf(stderr,"asset swaps disabled\n"); - return(""); - ////////////////////////// NOT IMPLEMENTED YET///////////////////////////////// - - if ( askamount < 0 || pricetotal < 0 ) - { - fprintf(stderr,"negative askamount %lld, askamount %lld\n",(long long)pricetotal,(long long)askamount); - return(""); - } - cp = CCinit(&C, EVAL_ASSETS); - - if ( txfee == 0 ) - txfee = 10000; - ////////////////////////// NOT IMPLEMENTED YET///////////////////////////////// - mypk = pubkey2pk(Mypubkey()); - - if (AddNormalinputs(mtx, mypk, txfee, 3) > 0) - { - mask = ~((1LL << mtx.vin.size()) - 1); - /*if ((inputs = AddAssetInputs(cp, mtx, mypk, assetid, askamount, 60)) > 0) - { - ////////////////////////// NOT IMPLEMENTED YET///////////////////////////////// - if (inputs < askamount) { - //was: askamount = inputs; - std::cerr << "CreateSwap(): insufficient tokens for ask" << std::endl; - CCerror = strprintf("insufficient tokens for ask"); - return (""); - } - ////////////////////////// NOT IMPLEMENTED YET///////////////////////////////// - CPubKey unspendablePubkey = GetUnspendable(cp, 0); - mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS, askamount, unspendablePubkey)); - - if (inputs > askamount) - CCchange = (inputs - askamount); - if (CCchange != 0) - mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS, CCchange, mypk)); - - ////////////////////////// NOT IMPLEMENTED YET///////////////////////////////// - std::vector voutTokenPubkeys; // should be empty - no token vouts - - if (assetid2 == zeroid) { - opret = EncodeTokenOpRet(assetid, voutTokenPubkeys, - EncodeAssetOpRet('s', zeroid, pricetotal, Mypubkey())); - } - else { - opret = EncodeTokenOpRet(assetid, voutTokenPubkeys, - EncodeAssetOpRet('e', assetid2, pricetotal, Mypubkey())); - } - ////////////////////////// NOT IMPLEMENTED YET///////////////////////////////// - return(FinalizeCCTx(mask,cp,mtx,mypk,txfee,opret)); - } - else { - fprintf(stderr, "need some assets to place ask\n"); - } */ - } - else { // dimxy added 'else', because it was misleading message before - fprintf(stderr,"need some native coins to place ask\n"); - } - - return(""); -} ////////////////////////// NOT IMPLEMENTED YET///////////////////////////////// - -// unlocks coins -std::string CancelBuyOffer(int64_t txfee,uint256 assetid,uint256 bidtxid) -{ - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), hush_nextheight()); - CTransaction vintx; uint64_t mask; - uint256 hashBlock; int64_t bidamount; - CPubKey mypk; struct CCcontract_info *cpAssets, C; - uint8_t funcid,dummyEvalCode; uint256 dummyAssetid, dummyAssetid2; int64_t dummyPrice; std::vector dummyOrigpubkey; - - cpAssets = CCinit(&C, EVAL_ASSETS); - - if (txfee == 0) - txfee = 10000; - - mypk = pubkey2pk(Mypubkey()); - - if (AddNormalinputs(mtx, mypk, txfee, 3) > 0) - { - mask = ~((1LL << mtx.vin.size()) - 1); - if (myGetTransaction(bidtxid, vintx, hashBlock) != 0) - { - std::vector vopretNonfungible; - GetNonfungibleData(assetid, vopretNonfungible); - - bidamount = vintx.vout[0].nValue; - mtx.vin.push_back(CTxIn(bidtxid, 0, CScript())); // coins in Assets - - if((funcid=DecodeAssetTokenOpRet(vintx.vout[vintx.vout.size() - 1].scriptPubKey, dummyEvalCode, dummyAssetid, dummyAssetid2, dummyPrice, dummyOrigpubkey))!=0) - { - if (funcid == 's') mtx.vin.push_back(CTxIn(bidtxid, 1, CScript())); // spend marker if funcid='b' - else if (funcid=='S') mtx.vin.push_back(CTxIn(bidtxid, 3, CScript())); // spend marker if funcid='B' - } - - mtx.vout.push_back(CTxOut(bidamount,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG)); - mtx.vout.push_back(CTxOut(txfee,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG)); - - std::vector voutTokenPubkeys; // should be empty, no token vouts - - return(FinalizeCCTx(mask, cpAssets, mtx, mypk, txfee, - EncodeTokenOpRet(assetid, voutTokenPubkeys, - std::make_pair(OPRETID_ASSETSDATA, EncodeAssetOpRet('o', zeroid, 0, Mypubkey()))))); - } - } - return(""); -} - -//unlocks tokens -std::string CancelSell(int64_t txfee,uint256 assetid,uint256 asktxid) -{ - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), hush_nextheight()); - CTransaction vintx; uint64_t mask; - uint256 hashBlock; int64_t askamount; - CPubKey mypk; - struct CCcontract_info *cpTokens, *cpAssets, tokensC, assetsC; - uint8_t funcid, dummyEvalCode; - uint256 dummyAssetid, dummyAssetid2; - int64_t dummyPrice; - std::vector dummyOrigpubkey; - - cpAssets = CCinit(&assetsC, EVAL_ASSETS); - - if (txfee == 0) - txfee = 10000; - - mypk = pubkey2pk(Mypubkey()); - - if (AddNormalinputs(mtx, mypk, txfee, 3) > 0) - { - mask = ~((1LL << mtx.vin.size()) - 1); - if (myGetTransaction(asktxid, vintx, hashBlock) != 0) - { - std::vector vopretNonfungible; - GetNonfungibleData(assetid, vopretNonfungible); - - askamount = vintx.vout[0].nValue; - mtx.vin.push_back(CTxIn(asktxid, 0, CScript())); - - if ((funcid=DecodeAssetTokenOpRet(vintx.vout[vintx.vout.size() - 1].scriptPubKey, dummyEvalCode, dummyAssetid, dummyAssetid2, dummyPrice, dummyOrigpubkey))!=0) - { - if (funcid == 's') - mtx.vin.push_back(CTxIn(asktxid, 1, CScript())); // marker if funcid='s' - else if (funcid=='S') - mtx.vin.push_back(CTxIn(asktxid, 3, CScript())); // marker if funcid='S' - } - - if (vopretNonfungible.size() > 0) - cpAssets->additionalTokensEvalcode2 = vopretNonfungible.begin()[0]; - - mtx.vout.push_back(MakeTokensCC1vout(cpAssets->additionalTokensEvalcode2 == 0 ? EVAL_TOKENS : cpAssets->additionalTokensEvalcode2, askamount, mypk)); // one-eval token vout - mtx.vout.push_back(CTxOut(txfee,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG)); - - std::vector voutTokenPubkeys; - voutTokenPubkeys.push_back(mypk); - - // this is only for unspendable addresses: - //CCaddr2set(cpTokens, EVAL_ASSETS, mypk, myPrivkey, myCCaddr); //do we need this? Seems FinalizeCCTx can attach to any evalcode cc addr by calling Getscriptaddress - - uint8_t unspendableAssetsPrivkey[32]; - char unspendableAssetsAddr[64]; - // init assets 'unspendable' privkey and pubkey - CPubKey unspendableAssetsPk = GetUnspendable(cpAssets, unspendableAssetsPrivkey); - GetCCaddress(cpAssets, unspendableAssetsAddr, unspendableAssetsPk); - - // add additional eval-tokens unspendable assets privkey: - CCaddr2set(cpAssets, EVAL_TOKENS, unspendableAssetsPk, unspendableAssetsPrivkey, unspendableAssetsAddr); - - return(FinalizeCCTx(mask, cpAssets, mtx, mypk, txfee, - EncodeTokenOpRet(assetid, voutTokenPubkeys, - std::make_pair(OPRETID_ASSETSDATA, EncodeAssetOpRet('x', zeroid, 0, Mypubkey()))))); - } - } - return(""); -} - -//send tokens, receive coins: -std::string FillBuyOffer(int64_t txfee,uint256 assetid,uint256 bidtxid,int64_t fillamount) -{ - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), hush_nextheight()); - CTransaction vintx; - uint256 hashBlock; - CPubKey mypk; - std::vector origpubkey; - int32_t bidvout=0; - uint64_t mask; - int64_t origprice, bidamount, paid_amount, remaining_required, inputs, CCchange=0; - struct CCcontract_info *cpTokens, tokensC; - struct CCcontract_info *cpAssets, assetsC; - - if (fillamount < 0) - { - fprintf(stderr,"negative fillamount %lld\n", (long long)fillamount); - return(""); - } - cpTokens = CCinit(&tokensC, EVAL_TOKENS); - - if (txfee == 0) - txfee = 10000; - - mypk = pubkey2pk(Mypubkey()); - - if (AddNormalinputs(mtx, mypk, 2*txfee, 3) > 0) - { - mask = ~((1LL << mtx.vin.size()) - 1); - if (myGetTransaction(bidtxid, vintx, hashBlock) != 0) - { - bidamount = vintx.vout[bidvout].nValue; - SetAssetOrigpubkey(origpubkey, origprice, vintx); - - mtx.vin.push_back(CTxIn(bidtxid, bidvout, CScript())); // Coins on Assets unspendable - - std::vector vopretNonfungible; - if ((inputs = AddTokenCCInputs(cpTokens, mtx, mypk, assetid, fillamount, 60, vopretNonfungible)) > 0) - { - if (inputs < fillamount) { - std::cerr << "FillBuyOffer(): insufficient tokens to fill buy offer" << std::endl; - CCerror = strprintf("insufficient tokens to fill buy offer"); - return (""); - } - - SetBidFillamounts(paid_amount, remaining_required, bidamount, fillamount, origprice); - - uint8_t additionalTokensEvalcode2 = 0; - if (vopretNonfungible.size() > 0) - additionalTokensEvalcode2 = vopretNonfungible.begin()[0]; - - if (inputs > fillamount) - CCchange = (inputs - fillamount); - - uint8_t unspendableAssetsPrivkey[32]; - cpAssets = CCinit(&assetsC, EVAL_ASSETS); - CPubKey unspendableAssetsPk = GetUnspendable(cpAssets, unspendableAssetsPrivkey); - - mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS, bidamount - paid_amount, unspendableAssetsPk)); // vout0 coins remainder - mtx.vout.push_back(CTxOut(paid_amount,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG)); // vout1 coins to normal - mtx.vout.push_back(MakeTokensCC1vout(additionalTokensEvalcode2 == 0 ? EVAL_TOKENS : additionalTokensEvalcode2, fillamount, pubkey2pk(origpubkey))); // vout2 single-eval tokens sent to the originator - mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS, txfee, origpubkey)); // vout3 marker to origpubkey - - if (CCchange != 0) - mtx.vout.push_back(MakeCC1vout(EVAL_TOKENS, CCchange, mypk)); // vout4 change in single-eval tokens - - fprintf(stderr,"FillBuyOffer() remaining %llu -> origpubkey\n", (long long)remaining_required); - - char unspendableAssetsAddr[64]; - cpAssets = CCinit(&assetsC, EVAL_ASSETS); - GetCCaddress(cpAssets, unspendableAssetsAddr, unspendableAssetsPk); - - // add additional unspendable addr from Assets: - CCaddr2set(cpTokens, EVAL_ASSETS, unspendableAssetsPk, unspendableAssetsPrivkey, unspendableAssetsAddr); - - // token vout verification pubkeys: - std::vector voutTokenPubkeys; - voutTokenPubkeys.push_back(pubkey2pk(origpubkey)); - - return(FinalizeCCTx(mask, cpTokens, mtx, mypk, txfee, - EncodeTokenOpRet(assetid, voutTokenPubkeys, - std::make_pair(OPRETID_ASSETSDATA, EncodeAssetOpRet('B', zeroid, remaining_required, origpubkey))))); - } else return("dont have any assets to fill bid"); - } - } - return("no normal coins left"); -} - - -// send coins, receive tokens -std::string FillSell(int64_t txfee, uint256 assetid, uint256 assetid2, uint256 asktxid, int64_t fillunits) -{ - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), hush_nextheight()); - CTransaction vintx,filltx; - uint256 hashBlock; - CPubKey mypk; - std::vector origpubkey; - double dprice; - uint64_t mask = 0; - int32_t askvout = 0; - int64_t received_assetoshis, total_nValue, orig_assetoshis, paid_nValue, remaining_nValue, inputs, CCchange=0; - //struct CCcontract_info *cpTokens, tokensC; - struct CCcontract_info *cpAssets, assetsC; - - if (fillunits < 0) - { - CCerror = strprintf("negative fillunits %lld\n",(long long)fillunits); - fprintf(stderr,"%s\n",CCerror.c_str()); - return(""); - } - if (assetid2 != zeroid) - { - CCerror = "asset swaps disabled"; - fprintf(stderr,"%s\n",CCerror.c_str()); - return(""); - } - - std::vector vopretNonfungible; - uint8_t additionalTokensEvalcode2 = 0; - GetNonfungibleData(assetid, vopretNonfungible); - if (vopretNonfungible.size() > 0) - additionalTokensEvalcode2 = vopretNonfungible.begin()[0]; - - cpAssets = CCinit(&assetsC, EVAL_ASSETS); - - if (txfee == 0) - txfee = 10000; - - mypk = pubkey2pk(Mypubkey()); - //if (AddNormalinputs(mtx, mypk, 2*txfee, 3) > 0) - //{ - //mask = ~((1LL << mtx.vin.size()) - 1); - if (myGetTransaction(asktxid, vintx, hashBlock) != 0) - { - orig_assetoshis = vintx.vout[askvout].nValue; - SetAssetOrigpubkey(origpubkey, total_nValue, vintx); - dprice = (double)total_nValue / orig_assetoshis; - paid_nValue = dprice * fillunits; - - if (assetid2 != zeroid) { - inputs = 0; // = AddAssetInputs(cpAssets, mtx, mypk, assetid2, paid_nValue, 60); // not implemented yet - } - else - { - inputs = AddNormalinputs(mtx, mypk, 2 * txfee + paid_nValue, 60); // Better to use single AddNormalinputs() to allow payment if user has only single utxo with normal funds - mask = ~((1LL << mtx.vin.size()) - 1); - } - if (inputs > 0) - { - if (inputs < paid_nValue) { - std::cerr << "FillSell(): insufficient coins to fill sell" << std::endl; - CCerror = strprintf("insufficient coins to fill sell"); - return (""); - } - - // cc vin should be after normal vin - mtx.vin.push_back(CTxIn(asktxid, askvout, CScript())); - - if (assetid2 != zeroid) - SetSwapFillamounts(received_assetoshis, remaining_nValue, orig_assetoshis, paid_nValue, total_nValue); //not implemented correctly yet - else - SetAskFillamounts(received_assetoshis, remaining_nValue, orig_assetoshis, paid_nValue, total_nValue); - - if (assetid2 != zeroid && inputs > paid_nValue) - CCchange = (inputs - paid_nValue); - - // vout.0 tokens remainder to unspendable cc addr: - mtx.vout.push_back(MakeTokensCC1vout(EVAL_ASSETS, additionalTokensEvalcode2, orig_assetoshis - received_assetoshis, GetUnspendable(cpAssets, NULL))); - //vout.1 purchased tokens to self token single-eval or dual-eval token+nonfungible cc addr: - mtx.vout.push_back(MakeTokensCC1vout(additionalTokensEvalcode2 == 0 ? EVAL_TOKENS : additionalTokensEvalcode2, received_assetoshis, mypk)); - - if (assetid2 != zeroid) { - std::cerr << "FillSell() WARNING: asset swap not implemented yet! (paid_nValue)" << std::endl; - // TODO: change MakeCC1vout appropriately when implementing: - //mtx.vout.push_back(MakeCC1vout(EVAL_TOKENS, paid_nValue, origpubkey)); //vout.2 tokens... (swap is not implemented yet) - } - else { - //std::cerr << "FillSell() paid_value=" << paid_nValue << " origpubkey=" << HexStr(pubkey2pk(origpubkey)) << std::endl; - mtx.vout.push_back(CTxOut(paid_nValue, CScript() << origpubkey << OP_CHECKSIG)); //vout.2 coins to tokens seller's normal addr - } - mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS,txfee,origpubkey)); //vout.3 marker to origpubkey - - // not implemented - if (CCchange != 0) { - std::cerr << "FillSell() WARNING: asset swap not implemented yet! (CCchange)" << std::endl; - // TODO: change MakeCC1vout appropriately when implementing: - //mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS, CCchange, mypk)); //vout.3 coins in Assets cc addr (swap not implemented) - } - - uint8_t unspendableAssetsPrivkey[32]; - char unspendableAssetsAddr[64]; - // init assets 'unspendable' privkey and pubkey - CPubKey unspendableAssetsPk = GetUnspendable(cpAssets, unspendableAssetsPrivkey); - GetCCaddress(cpAssets, unspendableAssetsAddr, unspendableAssetsPk); - - // add additional eval-tokens unspendable assets privkey: - CCaddr2set(cpAssets, EVAL_TOKENS, unspendableAssetsPk, unspendableAssetsPrivkey, unspendableAssetsAddr); - - // vout verification pubkeys: - std::vector voutTokenPubkeys; - voutTokenPubkeys.push_back(mypk); - - cpAssets->additionalTokensEvalcode2 = additionalTokensEvalcode2; - - return(FinalizeCCTx(mask, cpAssets, mtx, mypk, txfee, - EncodeTokenOpRet(assetid, voutTokenPubkeys, - std::make_pair(OPRETID_ASSETSDATA, EncodeAssetOpRet(assetid2 != zeroid ? 'E' : 'S', assetid2, remaining_nValue, origpubkey))))); - } else { - CCerror = strprintf("filltx not enough utxos"); - fprintf(stderr,"%s\n", CCerror.c_str()); - } - } - //} - return(""); -} From 8811ba4502eebc7d980fdaa4a08f71bb92ed27f9 Mon Sep 17 00:00:00 2001 From: Duke Date: Wed, 31 Jan 2024 20:27:46 -0500 Subject: [PATCH 14/78] Delete more CCs #381 --- src/Makefile.am | 1 - src/cc/CCassetstx.cpp | 21 --------------------- 2 files changed, 22 deletions(-) delete mode 100644 src/cc/CCassetstx.cpp diff --git a/src/Makefile.am b/src/Makefile.am index 97ae53ae1..2685252ec 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -330,7 +330,6 @@ libbitcoin_wallet_a_SOURCES = \ transaction_builder.cpp \ wallet/rpcdump.cpp \ cc/CCassetsCore.cpp \ - cc/CCassetstx.cpp \ cc/CCtx.cpp \ wallet/rpcwallet.cpp \ wallet/rpchushwallet.cpp \ diff --git a/src/cc/CCassetstx.cpp b/src/cc/CCassetstx.cpp deleted file mode 100644 index 596f3643b..000000000 --- a/src/cc/CCassetstx.cpp +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (c) 2016-2023 The Hush developers -// Distributed under the GPLv3 software license, see the accompanying -// file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html -/****************************************************************************** - * Copyright © 2014-2019 The SuperNET Developers. * - * * - * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * - * the top-level directory of this distribution for the individual copyright * - * holder information and the developer policies on copyright and licensing. * - * * - * Unless otherwise agreed in a custom licensing agreement, no part of the * - * SuperNET software, including this file may be copied, modified, propagated * - * or distributed except according to the terms contained in the LICENSE file * - * * - * Removal or modification of this copyright notice is prohibited. * - * * - ******************************************************************************/ - -#include "CCassets.h" -#include "CCtokens.h" - From 1c04972c816e0b45e2793a619d4262533cae7a42 Mon Sep 17 00:00:00 2001 From: Duke Date: Wed, 31 Jan 2024 20:46:37 -0500 Subject: [PATCH 15/78] Delete more CCs #381 --- src/Makefile.am | 2 - src/cc/CCassetsCore.cpp | 653 ---------------------------------------- 2 files changed, 655 deletions(-) delete mode 100644 src/cc/CCassetsCore.cpp diff --git a/src/Makefile.am b/src/Makefile.am index 2685252ec..d3bd209a4 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -272,7 +272,6 @@ libbitcoin_server_a_SOURCES = \ asyncrpcqueue.cpp \ bloom.cpp \ cc/eval.cpp \ - cc/CCassetsCore.cpp \ cc/CCcustom.cpp \ cc/CCtx.cpp \ cc/CCutils.cpp \ @@ -329,7 +328,6 @@ libbitcoin_wallet_a_SOURCES = \ zcash/Note.cpp \ transaction_builder.cpp \ wallet/rpcdump.cpp \ - cc/CCassetsCore.cpp \ cc/CCtx.cpp \ wallet/rpcwallet.cpp \ wallet/rpchushwallet.cpp \ diff --git a/src/cc/CCassetsCore.cpp b/src/cc/CCassetsCore.cpp deleted file mode 100644 index ea716b2b3..000000000 --- a/src/cc/CCassetsCore.cpp +++ /dev/null @@ -1,653 +0,0 @@ -// Copyright (c) 2016-2023 The Hush developers -// Distributed under the GPLv3 software license, see the accompanying -// file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html -/****************************************************************************** - * Copyright © 2014-2018 The SuperNET Developers. * - * * - * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * - * the top-level directory of this distribution for the individual copyright * - * holder information and the developer policies on copyright and licensing. * - * * - * Unless otherwise agreed in a custom licensing agreement, no part of the * - * SuperNET software, including this file may be copied, modified, propagated * - * or distributed except according to the terms contained in the LICENSE file * - * * - * Removal or modification of this copyright notice is prohibited. * - * * - ******************************************************************************/ - -#include "CCassets.h" - -/* - The SetAssetFillamounts() and ValidateAssetRemainder() work in tandem to calculate the vouts for a fill and to validate the vouts, respectively. - - This pair of functions are critical to make sure the trading is correct and is the trickiest part of the assets contract. - - //vin.0: normal input - //vin.1: unspendable.(vout.0 from buyoffer) buyTx.vout[0] - //vin.2+: valid CC output satisfies buyoffer (*tx.vin[2])->nValue - //vout.0: remaining amount of bid to unspendable - //vout.1: vin.1 value to signer of vin.2 - //vout.2: vin.2 assetoshis to original pubkey - //vout.3: CC output for assetoshis change (if any) - //vout.4: normal output for change (if any) - //vout.n-1: opreturn [EVAL_ASSETS] ['B'] [assetid] [remaining asset required] [origpubkey] - ValidateAssetRemainder(remaining_price,tx.vout[0].nValue,nValue,tx.vout[1].nValue,tx.vout[2].nValue,totalunits); - - Yes, this is quite confusing... - - In ValidateAssetRemainder the naming convention is nValue is the coin/asset with the offer on the books and "units" is what it is being paid in. The high level check is to make sure we didnt lose any coins or assets, the harder to validate is the actual price paid as the "orderbook" is in terms of the combined nValue for the combined totalunits. - - We assume that the effective unit cost in the orderbook is valid and that that amount was paid and also that any remainder will be close enough in effective unit cost to not matter. At the edge cases, this will probably be not true and maybe some orders wont be practically fillable when reduced to fractional state. However, the original pubkey that created the offer can always reclaim it. -*/ - -bool ValidateBidRemainder(int64_t remaining_units,int64_t remaining_nValue,int64_t orig_nValue,int64_t received_nValue,int64_t paidunits,int64_t totalunits) -{ - int64_t unitprice,recvunitprice,newunitprice=0; - if ( orig_nValue == 0 || received_nValue == 0 || paidunits == 0 || totalunits == 0 ) - { - fprintf(stderr,"ValidateAssetRemainder() orig_nValue == %llu || received_nValue == %llu || paidunits == %llu || totalunits == %llu\n",(long long)orig_nValue,(long long)received_nValue,(long long)paidunits,(long long)totalunits); - return(false); - } - else if ( totalunits != (remaining_units + paidunits) ) - { - fprintf(stderr,"ValidateAssetRemainder() totalunits %llu != %llu (remaining_units %llu + %llu paidunits)\n",(long long)totalunits,(long long)(remaining_units + paidunits),(long long)remaining_units,(long long)paidunits); - return(false); - } - else if ( orig_nValue != (remaining_nValue + received_nValue) ) - { - fprintf(stderr,"ValidateAssetRemainder() orig_nValue %llu != %llu (remaining_nValue %llu + %llu received_nValue)\n",(long long)orig_nValue,(long long)(remaining_nValue - received_nValue),(long long)remaining_nValue,(long long)received_nValue); - return(false); - } - else - { - //unitprice = (orig_nValue * COIN) / totalunits; - //recvunitprice = (received_nValue * COIN) / paidunits; - //if ( remaining_units != 0 ) - // newunitprice = (remaining_nValue * COIN) / remaining_units; - unitprice = (orig_nValue / totalunits); - recvunitprice = (received_nValue / paidunits); - if ( remaining_units != 0 ) - newunitprice = (remaining_nValue / remaining_units); - if ( recvunitprice < unitprice ) - { - fprintf(stderr,"ValidateAssetRemainder() error recvunitprice %.8f < %.8f unitprice, new unitprice %.8f\n",(double)recvunitprice/(COIN),(double)unitprice/(COIN),(double)newunitprice/(COIN)); - return(false); - } - fprintf(stderr,"ValidateAssetRemainder() orig %llu total %llu, recv %llu paid %llu,recvunitprice %.8f >= %.8f unitprice, new unitprice %.8f\n",(long long)orig_nValue,(long long)totalunits,(long long)received_nValue,(long long)paidunits,(double)recvunitprice/(COIN),(double)unitprice/(COIN),(double)newunitprice/(COIN)); - } - return(true); -} - -bool SetBidFillamounts(int64_t &received_nValue,int64_t &remaining_units,int64_t orig_nValue,int64_t &paidunits,int64_t totalunits) -{ - int64_t remaining_nValue,unitprice; double dprice; - if ( totalunits == 0 ) - { - received_nValue = remaining_units = paidunits = 0; - return(false); - } - if ( paidunits >= totalunits ) - { - paidunits = totalunits; - received_nValue = orig_nValue; - remaining_units = 0; - fprintf(stderr,"SetBidFillamounts() bid order totally filled!\n"); - return(true); - } - remaining_units = (totalunits - paidunits); - //unitprice = (orig_nValue * COIN) / totalunits; - //received_nValue = (paidunits * unitprice) / COIN; - unitprice = (orig_nValue / totalunits); - received_nValue = (paidunits * unitprice); - if ( unitprice > 0 && received_nValue > 0 && received_nValue <= orig_nValue ) - { - remaining_nValue = (orig_nValue - received_nValue); - printf("SetBidFillamounts() total.%llu - paid.%llu, remaining %llu <- %llu (%llu - %llu)\n",(long long)totalunits,(long long)paidunits,(long long)remaining_nValue,(long long)(orig_nValue - received_nValue),(long long)orig_nValue,(long long)received_nValue); - return(ValidateBidRemainder(remaining_units,remaining_nValue,orig_nValue,received_nValue,paidunits,totalunits)); - } else return(false); -} - -bool SetAskFillamounts(int64_t &received_assetoshis,int64_t &remaining_nValue,int64_t orig_assetoshis,int64_t &paid_nValue,int64_t total_nValue) -{ - int64_t remaining_assetoshis; double dunitprice; - if ( total_nValue == 0 ) - { - received_assetoshis = remaining_nValue = paid_nValue = 0; - return(false); - } - if ( paid_nValue >= total_nValue ) - { - paid_nValue = total_nValue; - received_assetoshis = orig_assetoshis; - remaining_nValue = 0; - fprintf(stderr,"SetAskFillamounts() ask order totally filled!\n"); - return(true); - } - remaining_nValue = (total_nValue - paid_nValue); - dunitprice = ((double)total_nValue / orig_assetoshis); - received_assetoshis = (paid_nValue / dunitprice); - fprintf(stderr,"SetAskFillamounts() remaining_nValue %.8f (%.8f - %.8f)\n",(double)remaining_nValue/COIN,(double)total_nValue/COIN,(double)paid_nValue/COIN); - fprintf(stderr,"SetAskFillamounts() unitprice %.8f received_assetoshis %llu orig %llu\n",dunitprice/COIN,(long long)received_assetoshis,(long long)orig_assetoshis); - if ( fabs(dunitprice) > SMALLVAL && received_assetoshis > 0 && received_assetoshis <= orig_assetoshis ) - { - remaining_assetoshis = (orig_assetoshis - received_assetoshis); - return(ValidateAskRemainder(remaining_nValue,remaining_assetoshis,orig_assetoshis,received_assetoshis,paid_nValue,total_nValue)); - } else return(false); -} - -bool ValidateAskRemainder(int64_t remaining_nValue,int64_t remaining_assetoshis,int64_t orig_assetoshis,int64_t received_assetoshis,int64_t paid_nValue,int64_t total_nValue) -{ - int64_t unitprice,recvunitprice,newunitprice=0; - if ( orig_assetoshis == 0 || received_assetoshis == 0 || paid_nValue == 0 || total_nValue == 0 ) - { - fprintf(stderr,"ValidateAssetRemainder() orig_assetoshis == %llu || received_assetoshis == %llu || paid_nValue == %llu || total_nValue == %llu\n",(long long)orig_assetoshis,(long long)received_assetoshis,(long long)paid_nValue,(long long)total_nValue); - return(false); - } - else if ( total_nValue != (remaining_nValue + paid_nValue) ) - { - fprintf(stderr,"ValidateAssetRemainder() total_nValue %llu != %llu (remaining_nValue %llu + %llu paid_nValue)\n",(long long)total_nValue,(long long)(remaining_nValue + paid_nValue),(long long)remaining_nValue,(long long)paid_nValue); - return(false); - } - else if ( orig_assetoshis != (remaining_assetoshis + received_assetoshis) ) - { - fprintf(stderr,"ValidateAssetRemainder() orig_assetoshis %llu != %llu (remaining_nValue %llu + %llu received_nValue)\n",(long long)orig_assetoshis,(long long)(remaining_assetoshis - received_assetoshis),(long long)remaining_assetoshis,(long long)received_assetoshis); - return(false); - } - else - { - unitprice = (total_nValue / orig_assetoshis); - recvunitprice = (paid_nValue / received_assetoshis); - if ( remaining_nValue != 0 ) - newunitprice = (remaining_nValue / remaining_assetoshis); - if ( recvunitprice < unitprice ) - { - fprintf(stderr,"ValidateAskRemainder() error recvunitprice %.8f < %.8f unitprice, new unitprice %.8f\n",(double)recvunitprice/COIN,(double)unitprice/COIN,(double)newunitprice/COIN); - return(false); - } - fprintf(stderr,"ValidateAskRemainder() got recvunitprice %.8f >= %.8f unitprice, new unitprice %.8f\n",(double)recvunitprice/COIN,(double)unitprice/COIN,(double)newunitprice/COIN); - } - return(true); -} - -bool SetSwapFillamounts(int64_t &received_assetoshis,int64_t &remaining_assetoshis2,int64_t orig_assetoshis,int64_t &paid_assetoshis2,int64_t total_assetoshis2) -{ - int64_t remaining_assetoshis; double dunitprice; - if ( total_assetoshis2 == 0 ) - { - fprintf(stderr,"SetSwapFillamounts() total_assetoshis2.0 origsatoshis.%llu paid_assetoshis2.%llu\n",(long long)orig_assetoshis,(long long)paid_assetoshis2); - received_assetoshis = remaining_assetoshis2 = paid_assetoshis2 = 0; - return(false); - } - if ( paid_assetoshis2 >= total_assetoshis2 ) - { - paid_assetoshis2 = total_assetoshis2; - received_assetoshis = orig_assetoshis; - remaining_assetoshis2 = 0; - fprintf(stderr,"SetSwapFillamounts() swap order totally filled!\n"); - return(true); - } - remaining_assetoshis2 = (total_assetoshis2 - paid_assetoshis2); - dunitprice = ((double)total_assetoshis2 / orig_assetoshis); - received_assetoshis = (paid_assetoshis2 / dunitprice); - fprintf(stderr,"SetSwapFillamounts() remaining_assetoshis2 %llu (%llu - %llu)\n",(long long)remaining_assetoshis2/COIN,(long long)total_assetoshis2/COIN,(long long)paid_assetoshis2/COIN); - fprintf(stderr,"SetSwapFillamounts() unitprice %.8f received_assetoshis %llu orig %llu\n",dunitprice/COIN,(long long)received_assetoshis,(long long)orig_assetoshis); - if ( fabs(dunitprice) > SMALLVAL && received_assetoshis > 0 && received_assetoshis <= orig_assetoshis ) - { - remaining_assetoshis = (orig_assetoshis - received_assetoshis); - return(ValidateAskRemainder(remaining_assetoshis2,remaining_assetoshis,orig_assetoshis,received_assetoshis,paid_assetoshis2,total_assetoshis2)); - } else return(false); -} - -bool ValidateSwapRemainder(int64_t remaining_price,int64_t remaining_nValue,int64_t orig_nValue,int64_t received_nValue,int64_t paidunits,int64_t totalunits) -{ - int64_t unitprice,recvunitprice,newunitprice=0; - if ( orig_nValue == 0 || received_nValue == 0 || paidunits == 0 || totalunits == 0 ) - { - fprintf(stderr,"ValidateAssetRemainder() orig_nValue == %llu || received_nValue == %llu || paidunits == %llu || totalunits == %llu\n",(long long)orig_nValue,(long long)received_nValue,(long long)paidunits,(long long)totalunits); - return(false); - } - else if ( totalunits != (remaining_price + paidunits) ) - { - fprintf(stderr,"ValidateAssetRemainder() totalunits %llu != %llu (remaining_price %llu + %llu paidunits)\n",(long long)totalunits,(long long)(remaining_price + paidunits),(long long)remaining_price,(long long)paidunits); - return(false); - } - else if ( orig_nValue != (remaining_nValue + received_nValue) ) - { - fprintf(stderr,"ValidateAssetRemainder() orig_nValue %llu != %llu (remaining_nValue %llu + %llu received_nValue)\n",(long long)orig_nValue,(long long)(remaining_nValue - received_nValue),(long long)remaining_nValue,(long long)received_nValue); - return(false); - } - else - { - unitprice = (orig_nValue * COIN) / totalunits; - recvunitprice = (received_nValue * COIN) / paidunits; - if ( remaining_price != 0 ) - newunitprice = (remaining_nValue * COIN) / remaining_price; - if ( recvunitprice < unitprice ) - { - fprintf(stderr,"ValidateAssetRemainder() error recvunitprice %.8f < %.8f unitprice, new unitprice %.8f\n",(double)recvunitprice/(COIN*COIN),(double)unitprice/(COIN*COIN),(double)newunitprice/(COIN*COIN)); - return(false); - } - fprintf(stderr,"ValidateAssetRemainder() recvunitprice %.8f >= %.8f unitprice, new unitprice %.8f\n",(double)recvunitprice/(COIN*COIN),(double)unitprice/(COIN*COIN),(double)newunitprice/(COIN*COIN)); - } - return(true); -} - -/* use EncodeTokenCreateOpRet instead: -CScript EncodeAssetCreateOpRet(uint8_t funcid,std::vector origpubkey,std::string name,std::string description) -{ - CScript opret; uint8_t evalcode = EVAL_ASSETS; - opret << OP_RETURN << E_MARSHAL(ss << evalcode << funcid << origpubkey << name << description); - return(opret); -} -*/ - -vscript_t EncodeAssetOpRet(uint8_t assetFuncId, uint256 assetid2, int64_t price, std::vector origpubkey) -{ - vscript_t vopret; - uint8_t evalcode = EVAL_ASSETS; - - switch ( assetFuncId ) - { - //case 't': this cannot be here - case 'x': case 'o': - vopret = /*<< OP_RETURN <<*/ E_MARSHAL(ss << evalcode << assetFuncId); - break; - case 's': case 'b': case 'S': case 'B': - vopret = /*<< OP_RETURN <<*/ E_MARSHAL(ss << evalcode << assetFuncId << price << origpubkey); - break; - case 'E': case 'e': - assetid2 = revuint256(assetid2); - vopret = /*<< OP_RETURN <<*/ E_MARSHAL(ss << evalcode << assetFuncId << assetid2 << price << origpubkey); - break; - default: - fprintf(stderr,"EncodeAssetOpRet: illegal funcid.%02x\n", assetFuncId); - //opret << OP_RETURN; - break; - } - return(vopret); -} - -/* it is for compatibility, do not use this for new contracts (use DecodeTokenCreateOpRet) -bool DecodeAssetCreateOpRet(const CScript &scriptPubKey, std::vector &origpubkey, std::string &name, std::string &description) -{ - std::vector vopret; uint8_t evalcode,funcid,*script; - GetOpReturnData(scriptPubKey, vopret); - script = (uint8_t *)vopret.data(); - if ( script != 0 && vopret.size() > 2 && script[0] == EVAL_ASSETS && script[1] == 'c' ) - { - if ( E_UNMARSHAL(vopret,ss >> evalcode; ss >> funcid; ss >> origpubkey; ss >> name; ss >> description) != 0 ) - return(true); - } - return(0); -} */ - -uint8_t DecodeAssetTokenOpRet(const CScript &scriptPubKey, uint8_t &assetsEvalCode, uint256 &tokenid, uint256 &assetid2, int64_t &price, std::vector &origpubkey) -{ - vscript_t vopretAssets; //, vopretAssetsStripped; - uint8_t *script, funcId = 0, assetsFuncId = 0, dummyEvalCode, dummyAssetFuncId; - uint256 dummyTokenid; - std::vector voutPubkeysDummy; - std::vector> oprets; - - tokenid = zeroid; - assetid2 = zeroid; - price = 0; - assetsEvalCode = 0; - assetsFuncId = 0; - - // First - decode token opret: - funcId = DecodeTokenOpRet(scriptPubKey, dummyEvalCode, tokenid, voutPubkeysDummy, oprets); - GetOpretBlob(oprets, OPRETID_ASSETSDATA, vopretAssets); - - LOGSTREAM((char *)"ccassets", CCLOG_DEBUG2, stream << "DecodeAssetTokenOpRet() from DecodeTokenOpRet returned funcId=" << (int)funcId << std::endl); - - if (funcId == 0 || vopretAssets.size() < 2) { - LOGSTREAM((char *)"ccassets", CCLOG_INFO, stream << "DecodeAssetTokenOpRet() incorrect opret or no asset's payload" << " funcId=" << (int)funcId << " vopretAssets.size()=" << vopretAssets.size() << std::endl); - return (uint8_t)0; - } - - //if (!E_UNMARSHAL(vopretAssets, { ss >> vopretAssetsStripped; })) { //strip string size - // std::cerr << "DecodeAssetTokenOpRet() could not unmarshal vopretAssetsStripped" << std::endl; - // return (uint8_t)0; - //} - - // additional check to prevent crash - if (vopretAssets.size() >= 2) { - - assetsEvalCode = vopretAssets.begin()[0]; - assetsFuncId = vopretAssets.begin()[1]; - - LOGSTREAM((char *)"ccassets", CCLOG_DEBUG2, stream << "DecodeAssetTokenOpRet() assetsEvalCode=" << (int)assetsEvalCode << " funcId=" << (char)(funcId ? funcId : ' ') << " assetsFuncId=" << (char)(assetsFuncId ? assetsFuncId : ' ') << std::endl); - - if (assetsEvalCode == EVAL_ASSETS) - { - //fprintf(stderr,"DecodeAssetTokenOpRet() decode.[%c] assetFuncId.[%c]\n", funcId, assetFuncId); - switch (assetsFuncId) - { - case 'x': case 'o': - if (vopretAssets.size() == 2) // no data after 'evalcode assetFuncId' allowed - { - return(assetsFuncId); - } - break; - case 's': case 'b': case 'S': case 'B': - if (E_UNMARSHAL(vopretAssets, ss >> dummyEvalCode; ss >> dummyAssetFuncId; ss >> price; ss >> origpubkey) != 0) - { - //fprintf(stderr,"DecodeAssetTokenOpRet() got price %llu\n",(long long)price); - return(assetsFuncId); - } - break; - case 'E': case 'e': - if (E_UNMARSHAL(vopretAssets, ss >> dummyEvalCode; ss >> dummyAssetFuncId; ss >> assetid2; ss >> price; ss >> origpubkey) != 0) - { - //fprintf(stderr,"DecodeAssetTokenOpRet() got price %llu\n",(long long)price); - assetid2 = revuint256(assetid2); - return(assetsFuncId); - } - break; - default: - break; - } - } - } - - LOGSTREAM((char *)"ccassets", CCLOG_INFO, stream << "DecodeAssetTokenOpRet() no asset's payload or incorrect assets funcId or evalcode" << " funcId=" << (int)funcId << " vopretAssets.size()=" << vopretAssets.size() << " assetsEvalCode=" << assetsEvalCode << " assetsFuncId=" << assetsFuncId << std::endl); - return (uint8_t)0; -} - -// extract sell/buy owner's pubkey from the opret -bool SetAssetOrigpubkey(std::vector &origpubkey,int64_t &price,const CTransaction &tx) -{ - uint256 assetid,assetid2; - uint8_t evalCode; - - if ( tx.vout.size() > 0 && DecodeAssetTokenOpRet(tx.vout[tx.vout.size()-1].scriptPubKey, evalCode, assetid, assetid2, price, origpubkey) != 0 ) - return(true); - else - return(false); -} - -// Calculate seller/buyer's dest cc address from ask/bid tx funcid -bool GetAssetorigaddrs(struct CCcontract_info *cp, char *origCCaddr, char *origNormalAddr, const CTransaction& vintx) -{ - uint256 assetid, assetid2; - int64_t price,nValue=0; - int32_t n; - uint8_t vintxFuncId; - std::vector origpubkey; - CScript script; - uint8_t evalCode; - - n = vintx.vout.size(); - if( n == 0 || (vintxFuncId = DecodeAssetTokenOpRet(vintx.vout[n-1].scriptPubKey, evalCode, assetid, assetid2, price, origpubkey)) == 0 ) - return(false); - - bool bGetCCaddr = false; - struct CCcontract_info *cpTokens, tokensC; - cpTokens = CCinit(&tokensC, EVAL_TOKENS); - - if (vintxFuncId == 's' || vintxFuncId == 'S') { - // bGetCCaddr = GetCCaddress(cpTokens, origCCaddr, pubkey2pk(origpubkey)); - cpTokens->additionalTokensEvalcode2 = cp->additionalTokensEvalcode2; // add non-fungible if present - bGetCCaddr = GetTokensCCaddress(cpTokens, origCCaddr, pubkey2pk(origpubkey)); // tokens to single-eval token or token+nonfungible - } - else if (vintxFuncId == 'b' || vintxFuncId == 'B') { - cpTokens->additionalTokensEvalcode2 = cp->additionalTokensEvalcode2; // add non-fungible if present - bGetCCaddr = GetTokensCCaddress(cpTokens, origCCaddr, pubkey2pk(origpubkey)); // tokens to single-eval token or token+nonfungible - } - else { - std::cerr << "GetAssetorigaddrs incorrect vintx funcid=" << (char)(vintxFuncId?vintxFuncId:' ') << std::endl; - return false; - } - if( bGetCCaddr && Getscriptaddress(origNormalAddr, CScript() << origpubkey << OP_CHECKSIG)) - return(true); - else - return(false); -} - - -int64_t AssetValidateCCvin(struct CCcontract_info *cp,Eval* eval,char *origCCaddr,char *origaddr,const CTransaction &tx,int32_t vini,CTransaction &vinTx) -{ - uint256 hashBlock; - uint256 assetid, assetid2; - int64_t tmpprice; - std::vector tmporigpubkey; - uint8_t evalCode; - - char destaddr[64], unspendableAddr[64]; - - origaddr[0] = destaddr[0] = origCCaddr[0] = 0; - - uint8_t funcid = 0; - if (tx.vout.size() > 0) { - uint256 assetid, assetid2; - int64_t tmpprice; - std::vector tmporigpubkey; - uint8_t evalCode; - - funcid = DecodeAssetTokenOpRet(tx.vout[tx.vout.size() - 1].scriptPubKey, evalCode, assetid, assetid2, tmpprice, tmporigpubkey); - } - - if( tx.vin.size() < 2 ) - return eval->Invalid("not enough for CC vins"); - else if( tx.vin[vini].prevout.n != 0 ) - return eval->Invalid("vin1 needs to be buyvin.vout[0]"); - else if( eval->GetTxUnconfirmed(tx.vin[vini].prevout.hash, vinTx,hashBlock) == 0 ) - { - std::cerr << "AssetValidateCCvin() cannot load vintx for vin=" << vini << " vintx id=" << tx.vin[vini].prevout.hash.GetHex() << std::endl; - return eval->Invalid("always should find CCvin, but didnt"); - } - // check source cc unspendable cc address: - // if fillSell or cancelSell --> should spend tokens from dual-eval token-assets unspendable addr - else if( (funcid == 'S' || funcid == 'x') && - (Getscriptaddress(destaddr, vinTx.vout[tx.vin[vini].prevout.n].scriptPubKey) == 0 || - !GetTokensCCaddress(cp, unspendableAddr, GetUnspendable(cp, NULL)) || - strcmp(destaddr, unspendableAddr) != 0)) - { - fprintf(stderr,"AssetValidateCCvin() cc addr %s is not dual token-evalcode=0x%02x asset unspendable addr %s\n", destaddr, (int)cp->evalcode, unspendableAddr); - return eval->Invalid("invalid vin assets CCaddr"); - } - // if fillBuy or cancelBuy --> should spend coins from asset unspendable addr - else if ((funcid == 'B' || funcid == 'o') && - (Getscriptaddress(destaddr, vinTx.vout[tx.vin[vini].prevout.n].scriptPubKey) == 0 || - !GetCCaddress(cp, unspendableAddr, GetUnspendable(cp, NULL)) || - strcmp(destaddr, unspendableAddr) != 0)) - { - fprintf(stderr, "AssetValidateCCvin() cc addr %s is not evalcode=0x%02x asset unspendable addr %s\n", destaddr, (int)cp->evalcode, unspendableAddr); - return eval->Invalid("invalid vin assets CCaddr"); - } - // end of check source unspendable cc address - //else if ( vinTx.vout[0].nValue < 10000 ) - // return eval->Invalid("invalid dust for buyvin"); - // get user dest cc and normal addresses: - else if( GetAssetorigaddrs(cp, origCCaddr, origaddr, vinTx) == 0 ) - return eval->Invalid("couldnt get origaddr for buyvin"); - - //fprintf(stderr,"AssetValidateCCvin() got %.8f to origaddr.(%s)\n", (double)vinTx.vout[tx.vin[vini].prevout.n].nValue/COIN,origaddr); - - if ( vinTx.vout[0].nValue == 0 ) - return eval->Invalid("null value CCvin"); - - return(vinTx.vout[0].nValue); -} - -int64_t AssetValidateBuyvin(struct CCcontract_info *cp,Eval* eval,int64_t &tmpprice,std::vector &tmporigpubkey,char *CCaddr,char *origaddr,const CTransaction &tx,uint256 refassetid) -{ - CTransaction vinTx; int64_t nValue; uint256 assetid,assetid2; uint8_t funcid, evalCode; - - CCaddr[0] = origaddr[0] = 0; - - // validate locked coins on Assets vin[1] - if ( (nValue= AssetValidateCCvin(cp, eval, CCaddr, origaddr, tx, 1, vinTx)) == 0 ) - return(0); - else if ( vinTx.vout[0].scriptPubKey.IsPayToCryptoCondition() == 0 ) - return eval->Invalid("invalid normal vout0 for buyvin"); - else if ((funcid = DecodeAssetTokenOpRet(vinTx.vout[vinTx.vout.size() - 1].scriptPubKey, evalCode, assetid, assetid2, tmpprice, tmporigpubkey)) == 'b' && - vinTx.vout[1].scriptPubKey.IsPayToCryptoCondition() == 0 ) // marker is only in 'b'? - return eval->Invalid("invalid normal vout1 for buyvin"); - else - { - //fprintf(stderr,"have %.8f checking assetid origaddr.(%s)\n",(double)nValue/COIN,origaddr); - if ( vinTx.vout.size() > 0 && funcid != 'b' && funcid != 'B' ) - return eval->Invalid("invalid opreturn for buyvin"); - else if ( refassetid != assetid ) - return eval->Invalid("invalid assetid for buyvin"); - //int32_t i; for (i=31; i>=0; i--) - // fprintf(stderr,"%02x",((uint8_t *)&assetid)[i]); - //fprintf(stderr," AssetValidateBuyvin assetid for %s\n",origaddr); - } - return(nValue); -} - -int64_t AssetValidateSellvin(struct CCcontract_info *cp,Eval* eval,int64_t &tmpprice,std::vector &tmporigpubkey,char *CCaddr,char *origaddr,const CTransaction &tx,uint256 assetid) -{ - CTransaction vinTx; int64_t nValue,assetoshis; - //fprintf(stderr,"AssetValidateSellvin()\n"); - if ( (nValue = AssetValidateCCvin(cp, eval, CCaddr, origaddr, tx, 1, vinTx)) == 0 ) - return(0); - if ( (assetoshis= IsAssetvout(cp, tmpprice, tmporigpubkey, vinTx, 0, assetid)) == 0 ) - return eval->Invalid("invalid missing CC vout0 for sellvin"); - else - return(assetoshis); -} - - -// validates opret for asset tx: -bool ValidateAssetOpret(CTransaction tx, int32_t v, uint256 assetid, int64_t &price, std::vector &origpubkey) { - - uint256 assetidOpret, assetidOpret2; - uint8_t funcid, evalCode; - - // this is just for log messages indentation fur debugging recursive calls: - int32_t n = tx.vout.size(); - - if ((funcid = DecodeAssetTokenOpRet(tx.vout[n - 1].scriptPubKey, evalCode, assetidOpret, assetidOpret2, price, origpubkey)) == 0) - { - std::cerr << "ValidateAssetOpret() DecodeAssetTokenOpRet returned funcId=0 for opret from txid=" << tx.GetHash().GetHex() << std::endl; - return(false); - } -/* it is now on token level: - else if (funcid == 'c') - { - if (assetid != zeroid && assetid == tx.GetHash() && v == 0) { - //std::cerr << "ValidateAssetOpret() this is the tokenbase 'c' tx, txid=" << tx.GetHash().GetHex() << " vout=" << v << " returning true" << std::endl; - return(true); - } - } - else if (funcid == 't') // TODO: check if this new block does not influence IsAssetVout - { - //std::cerr << "ValidateAssetOpret() assetid=" << assetid.GetHex() << " assetIdOpret=" << assetidOpret.GetHex() << " txid=" << tx.GetHash().GetHex() << std::endl; - if (assetid != zeroid && assetid == assetidOpret) { - //std::cerr << "ValidateAssetOpret() this is a transfer 't' tx, txid=" << tx.GetHash().GetHex() << " vout=" << v << " returning true" << std::endl; - return(true); - } - } */ - //else if ((funcid == 'b' || funcid == 'B') && v == 0) // critical! 'b'/'B' vout0 is NOT asset - // return(false); - else if (funcid != 'E') - { - if (assetid != zeroid && assetidOpret == assetid) - { - //std::cerr << "ValidateAssetOpret() returns true for not 'E', funcid=" << (char)funcid << std::endl; - return(true); - } - } - else if (funcid == 'E') // NOTE: not implemented yet! - { - if (v < 2 && assetid != zeroid && assetidOpret == assetid) - return(true); - else if (v == 2 && assetid != zeroid && assetidOpret2 == assetid) - return(true); - } - - //std::cerr << "ValidateAssetOpret() return false funcid=" << (char)funcid << " assetid=" << assetid.GetHex() << " assetIdOpret=" << assetidOpret.GetHex() << " txid=" << tx.GetHash().GetHex() << std::endl; - return false; -} - -// Checks if the vout is a really Asset CC vout -int64_t IsAssetvout(struct CCcontract_info *cp, int64_t &price, std::vector &origpubkey, const CTransaction& tx, int32_t v, uint256 refassetid) -{ - - //std::cerr << "IsAssetvout() entered for txid=" << tx.GetHash().GetHex() << " v=" << v << " for assetid=" << refassetid.GetHex() << std::endl; - - int32_t n = tx.vout.size(); - // just check boundaries: - if (v >= n - 1) { // just moved this up (dimxy) - std::cerr << "isAssetVout() internal err: (v >= n - 1), returning 0" << std::endl; - return(0); - } - - if (tx.vout[v].scriptPubKey.IsPayToCryptoCondition() != 0) // maybe check address too? dimxy: possibly no, because there are too many cases with different addresses here - { - // moved opret checking to this new reusable func (dimxy): - const bool valOpret = ValidateAssetOpret(tx, v, refassetid, price, origpubkey); - //std::cerr << "IsAssetvout() ValidateAssetOpret returned=" << std::boolalpha << valOpret << " for txid=" << tx.GetHash().GetHex() << " for assetid=" << refassetid.GetHex() << std::endl; - if (valOpret) { - //std::cerr << "IsAssetvout() ValidateAssetOpret returned true, returning nValue=" << tx.vout[v].nValue << " for txid=" << tx.GetHash().GetHex() << " for assetid=" << refassetid.GetHex() << std::endl; - return tx.vout[v].nValue; - } - - //fprintf(stderr,"IsAssetvout() CC vout v.%d of n=%d amount=%.8f txid=%s\n",v,n,(double)0/COIN, tx.GetHash().GetHex().c_str()); - } - //fprintf(stderr,"IsAssetvout() normal output v.%d %.8f\n",v,(double)tx.vout[v].nValue/COIN); - return(0); -} - -// sets cc inputs vs cc outputs and ensures they are equal: -bool AssetCalcAmounts(struct CCcontract_info *cpAssets, int64_t &inputs, int64_t &outputs, Eval* eval, const CTransaction &tx, uint256 assetid) -{ - CTransaction vinTx; uint256 hashBlock, id, id2; int32_t flag; int64_t assetoshis; std::vector tmporigpubkey; int64_t tmpprice; - int32_t numvins = tx.vin.size(); - int32_t numvouts = tx.vout.size(); - inputs = outputs = 0; - - struct CCcontract_info *cpTokens, C; - - cpTokens = CCinit(&C, EVAL_TOKENS); - - for (int32_t i = 0; iismyvin)(tx.vin[i].scriptSig)*/ (*cpTokens->ismyvin)(tx.vin[i].scriptSig) ) // || IsVinAllowed(tx.vin[i].scriptSig) != 0) - { - //std::cerr << indentStr << "AssetExactAmounts() eval is true=" << (eval != NULL) << " ismyvin=ok for_i=" << i << std::endl; - // we are not inside the validation code -- dimxy - if ((eval && eval->GetTxUnconfirmed(tx.vin[i].prevout.hash, vinTx, hashBlock) == 0) || (!eval && !myGetTransaction(tx.vin[i].prevout.hash, vinTx, hashBlock))) - { - std::cerr << "AssetCalcAmounts() cannot read vintx for i." << i << " numvins." << numvins << std::endl; - return (!eval) ? false : eval->Invalid("always should find vin tx, but didnt"); - } - else { - // validate vouts of vintx - //std::cerr << indentStr << "AssetExactAmounts() check vin i=" << i << " nValue=" << vinTx.vout[tx.vin[i].prevout.n].nValue << std::endl; - //assetoshis = IsAssetvout(cpAssets, tmpprice, tmporigpubkey, vinTx, tx.vin[i].prevout.n, assetid); - std::vector vopretExtra; - std::vector vinPubkeysEmpty; - - // TODO: maybe we do not need call to IsTokensVout here, cause we've already selected token vins - assetoshis = IsTokensvout(false, false, cpTokens, NULL, vinTx, tx.vin[i].prevout.n, assetid); - if (assetoshis != 0) - { - //std::cerr << "AssetCalcAmounts() vin i=" << i << " assetoshis=" << assetoshis << std::endl; - inputs += assetoshis; - } - } - } - } - - for (int32_t i = 0; i < numvouts-1; i++) - { - assetoshis = IsAssetvout(cpAssets, tmpprice, tmporigpubkey, tx, i, assetid); - if (assetoshis != 0) - { - //std::cerr << "AssetCalcAmounts() vout i=" << i << " assetoshis=" << assetoshis << std::endl; - outputs += assetoshis; - } - } - - //std::cerr << "AssetCalcAmounts() inputs=" << inputs << " outputs=" << outputs << " for txid=" << tx.GetHash().GetHex() << std::endl; - - /* we do not verify inputs == outputs here, - it's now done in Tokens */ - return(true); -} From 43cdfb08a268a84be55fbddf2eb35ea1a2865424 Mon Sep 17 00:00:00 2001 From: Duke Date: Sat, 10 Feb 2024 12:07:52 -0500 Subject: [PATCH 16/78] Delete more CCs #381 --- src/cc/cclib.cpp | 6 - src/cc/dilithium.c | 3732 -------------------------------------------- 2 files changed, 3738 deletions(-) delete mode 100644 src/cc/dilithium.c diff --git a/src/cc/cclib.cpp b/src/cc/cclib.cpp index c1051b3b7..48b69c7e5 100644 --- a/src/cc/cclib.cpp +++ b/src/cc/cclib.cpp @@ -641,10 +641,4 @@ int32_t cclib_parsehash(uint8_t *hash32,cJSON *item,int32_t len) #if BUILD_CUSTOMCC #include "customcc.cpp" - -#else -#include "musig.cpp" -#include "dilithium.c" -//#include "../secp256k1/src/modules/musig/example.c" #endif - diff --git a/src/cc/dilithium.c b/src/cc/dilithium.c deleted file mode 100644 index 7b531002d..000000000 --- a/src/cc/dilithium.c +++ /dev/null @@ -1,3732 +0,0 @@ -// Copyright (c) 2016-2023 The Hush developers -// Distributed under the GPLv3 software license, see the accompanying -// file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html - -/* Based on the public domain implementation in - * crypto_hash/keccakc512/simple/ from http://bench.cr.yp.to/supercop.html - * by Ronny Van Keer - * and the public domain "TweetFips202" implementation - * from https://twitter.com/tweetfips202 - * by Gilles Van Assche, Daniel J. Bernstein, and Peter Schwabe */ - -#include - -#define DBENCH_START() -#define DBENCH_STOP(arg) - -#include "dilithium.h" -#define NROUNDS 24 -#define ROL(a, offset) ((a << offset) ^ (a >> (64-offset))) - -/************************************************* -* Name: load64 -* -* Description: Load 8 bytes into uint64_t in little-endian order -* -* Arguments: - const uint8_t *x: pointer to input byte array -* -* Returns the loaded 64-bit unsigned integer -**************************************************/ -static uint64_t load64(const uint8_t *x) { - uint32_t i; - uint64_t r = 0; - - for (i = 0; i < 8; ++i) - r |= (uint64_t)x[i] << 8*i; - - return r; -} - -/************************************************* -* Name: store64 -* -* Description: Store a 64-bit integer to array of 8 bytes in little-endian order -* -* Arguments: - uint8_t *x: pointer to the output byte array (allocated) -* - uint64_t u: input 64-bit unsigned integer -**************************************************/ -static void store64(uint8_t *x, uint64_t u) { - uint32_t i; - - for(i = 0; i < 8; ++i) - x[i] = u >> 8*i; -} - -/* Keccak round constants */ -static const uint64_t KeccakF_RoundConstants[NROUNDS] = { - (uint64_t)0x0000000000000001ULL, - (uint64_t)0x0000000000008082ULL, - (uint64_t)0x800000000000808aULL, - (uint64_t)0x8000000080008000ULL, - (uint64_t)0x000000000000808bULL, - (uint64_t)0x0000000080000001ULL, - (uint64_t)0x8000000080008081ULL, - (uint64_t)0x8000000000008009ULL, - (uint64_t)0x000000000000008aULL, - (uint64_t)0x0000000000000088ULL, - (uint64_t)0x0000000080008009ULL, - (uint64_t)0x000000008000000aULL, - (uint64_t)0x000000008000808bULL, - (uint64_t)0x800000000000008bULL, - (uint64_t)0x8000000000008089ULL, - (uint64_t)0x8000000000008003ULL, - (uint64_t)0x8000000000008002ULL, - (uint64_t)0x8000000000000080ULL, - (uint64_t)0x000000000000800aULL, - (uint64_t)0x800000008000000aULL, - (uint64_t)0x8000000080008081ULL, - (uint64_t)0x8000000000008080ULL, - (uint64_t)0x0000000080000001ULL, - (uint64_t)0x8000000080008008ULL -}; - -/************************************************* -* Name: KeccakF1600_StatePermute -* -* Description: The Keccak F1600 Permutation -* -* Arguments: - uint64_t *state: pointer to input/output Keccak state -**************************************************/ -static void KeccakF1600_StatePermute(uint64_t *state) -{ - int round; - - uint64_t Aba, Abe, Abi, Abo, Abu; - uint64_t Aga, Age, Agi, Ago, Agu; - uint64_t Aka, Ake, Aki, Ako, Aku; - uint64_t Ama, Ame, Ami, Amo, Amu; - uint64_t Asa, Ase, Asi, Aso, Asu; - uint64_t BCa, BCe, BCi, BCo, BCu; - uint64_t Da, De, Di, Do, Du; - uint64_t Eba, Ebe, Ebi, Ebo, Ebu; - uint64_t Ega, Ege, Egi, Ego, Egu; - uint64_t Eka, Eke, Eki, Eko, Eku; - uint64_t Ema, Eme, Emi, Emo, Emu; - uint64_t Esa, Ese, Esi, Eso, Esu; - - //copyFromState(A, state) - Aba = state[ 0]; - Abe = state[ 1]; - Abi = state[ 2]; - Abo = state[ 3]; - Abu = state[ 4]; - Aga = state[ 5]; - Age = state[ 6]; - Agi = state[ 7]; - Ago = state[ 8]; - Agu = state[ 9]; - Aka = state[10]; - Ake = state[11]; - Aki = state[12]; - Ako = state[13]; - Aku = state[14]; - Ama = state[15]; - Ame = state[16]; - Ami = state[17]; - Amo = state[18]; - Amu = state[19]; - Asa = state[20]; - Ase = state[21]; - Asi = state[22]; - Aso = state[23]; - Asu = state[24]; - - for( round = 0; round < NROUNDS; round += 2 ) - { - // prepareTheta - BCa = Aba^Aga^Aka^Ama^Asa; - BCe = Abe^Age^Ake^Ame^Ase; - BCi = Abi^Agi^Aki^Ami^Asi; - BCo = Abo^Ago^Ako^Amo^Aso; - BCu = Abu^Agu^Aku^Amu^Asu; - - //thetaRhoPiChiIotaPrepareTheta(round , A, E) - Da = BCu^ROL(BCe, 1); - De = BCa^ROL(BCi, 1); - Di = BCe^ROL(BCo, 1); - Do = BCi^ROL(BCu, 1); - Du = BCo^ROL(BCa, 1); - - Aba ^= Da; - BCa = Aba; - Age ^= De; - BCe = ROL(Age, 44); - Aki ^= Di; - BCi = ROL(Aki, 43); - Amo ^= Do; - BCo = ROL(Amo, 21); - Asu ^= Du; - BCu = ROL(Asu, 14); - Eba = BCa ^((~BCe)& BCi ); - Eba ^= (uint64_t)KeccakF_RoundConstants[round]; - Ebe = BCe ^((~BCi)& BCo ); - Ebi = BCi ^((~BCo)& BCu ); - Ebo = BCo ^((~BCu)& BCa ); - Ebu = BCu ^((~BCa)& BCe ); - - Abo ^= Do; - BCa = ROL(Abo, 28); - Agu ^= Du; - BCe = ROL(Agu, 20); - Aka ^= Da; - BCi = ROL(Aka, 3); - Ame ^= De; - BCo = ROL(Ame, 45); - Asi ^= Di; - BCu = ROL(Asi, 61); - Ega = BCa ^((~BCe)& BCi ); - Ege = BCe ^((~BCi)& BCo ); - Egi = BCi ^((~BCo)& BCu ); - Ego = BCo ^((~BCu)& BCa ); - Egu = BCu ^((~BCa)& BCe ); - - Abe ^= De; - BCa = ROL(Abe, 1); - Agi ^= Di; - BCe = ROL(Agi, 6); - Ako ^= Do; - BCi = ROL(Ako, 25); - Amu ^= Du; - BCo = ROL(Amu, 8); - Asa ^= Da; - BCu = ROL(Asa, 18); - Eka = BCa ^((~BCe)& BCi ); - Eke = BCe ^((~BCi)& BCo ); - Eki = BCi ^((~BCo)& BCu ); - Eko = BCo ^((~BCu)& BCa ); - Eku = BCu ^((~BCa)& BCe ); - - Abu ^= Du; - BCa = ROL(Abu, 27); - Aga ^= Da; - BCe = ROL(Aga, 36); - Ake ^= De; - BCi = ROL(Ake, 10); - Ami ^= Di; - BCo = ROL(Ami, 15); - Aso ^= Do; - BCu = ROL(Aso, 56); - Ema = BCa ^((~BCe)& BCi ); - Eme = BCe ^((~BCi)& BCo ); - Emi = BCi ^((~BCo)& BCu ); - Emo = BCo ^((~BCu)& BCa ); - Emu = BCu ^((~BCa)& BCe ); - - Abi ^= Di; - BCa = ROL(Abi, 62); - Ago ^= Do; - BCe = ROL(Ago, 55); - Aku ^= Du; - BCi = ROL(Aku, 39); - Ama ^= Da; - BCo = ROL(Ama, 41); - Ase ^= De; - BCu = ROL(Ase, 2); - Esa = BCa ^((~BCe)& BCi ); - Ese = BCe ^((~BCi)& BCo ); - Esi = BCi ^((~BCo)& BCu ); - Eso = BCo ^((~BCu)& BCa ); - Esu = BCu ^((~BCa)& BCe ); - - // prepareTheta - BCa = Eba^Ega^Eka^Ema^Esa; - BCe = Ebe^Ege^Eke^Eme^Ese; - BCi = Ebi^Egi^Eki^Emi^Esi; - BCo = Ebo^Ego^Eko^Emo^Eso; - BCu = Ebu^Egu^Eku^Emu^Esu; - - //thetaRhoPiChiIotaPrepareTheta(round+1, E, A) - Da = BCu^ROL(BCe, 1); - De = BCa^ROL(BCi, 1); - Di = BCe^ROL(BCo, 1); - Do = BCi^ROL(BCu, 1); - Du = BCo^ROL(BCa, 1); - - Eba ^= Da; - BCa = Eba; - Ege ^= De; - BCe = ROL(Ege, 44); - Eki ^= Di; - BCi = ROL(Eki, 43); - Emo ^= Do; - BCo = ROL(Emo, 21); - Esu ^= Du; - BCu = ROL(Esu, 14); - Aba = BCa ^((~BCe)& BCi ); - Aba ^= (uint64_t)KeccakF_RoundConstants[round+1]; - Abe = BCe ^((~BCi)& BCo ); - Abi = BCi ^((~BCo)& BCu ); - Abo = BCo ^((~BCu)& BCa ); - Abu = BCu ^((~BCa)& BCe ); - - Ebo ^= Do; - BCa = ROL(Ebo, 28); - Egu ^= Du; - BCe = ROL(Egu, 20); - Eka ^= Da; - BCi = ROL(Eka, 3); - Eme ^= De; - BCo = ROL(Eme, 45); - Esi ^= Di; - BCu = ROL(Esi, 61); - Aga = BCa ^((~BCe)& BCi ); - Age = BCe ^((~BCi)& BCo ); - Agi = BCi ^((~BCo)& BCu ); - Ago = BCo ^((~BCu)& BCa ); - Agu = BCu ^((~BCa)& BCe ); - - Ebe ^= De; - BCa = ROL(Ebe, 1); - Egi ^= Di; - BCe = ROL(Egi, 6); - Eko ^= Do; - BCi = ROL(Eko, 25); - Emu ^= Du; - BCo = ROL(Emu, 8); - Esa ^= Da; - BCu = ROL(Esa, 18); - Aka = BCa ^((~BCe)& BCi ); - Ake = BCe ^((~BCi)& BCo ); - Aki = BCi ^((~BCo)& BCu ); - Ako = BCo ^((~BCu)& BCa ); - Aku = BCu ^((~BCa)& BCe ); - - Ebu ^= Du; - BCa = ROL(Ebu, 27); - Ega ^= Da; - BCe = ROL(Ega, 36); - Eke ^= De; - BCi = ROL(Eke, 10); - Emi ^= Di; - BCo = ROL(Emi, 15); - Eso ^= Do; - BCu = ROL(Eso, 56); - Ama = BCa ^((~BCe)& BCi ); - Ame = BCe ^((~BCi)& BCo ); - Ami = BCi ^((~BCo)& BCu ); - Amo = BCo ^((~BCu)& BCa ); - Amu = BCu ^((~BCa)& BCe ); - - Ebi ^= Di; - BCa = ROL(Ebi, 62); - Ego ^= Do; - BCe = ROL(Ego, 55); - Eku ^= Du; - BCi = ROL(Eku, 39); - Ema ^= Da; - BCo = ROL(Ema, 41); - Ese ^= De; - BCu = ROL(Ese, 2); - Asa = BCa ^((~BCe)& BCi ); - Ase = BCe ^((~BCi)& BCo ); - Asi = BCi ^((~BCo)& BCu ); - Aso = BCo ^((~BCu)& BCa ); - Asu = BCu ^((~BCa)& BCe ); - } - - //copyToState(state, A) - state[ 0] = Aba; - state[ 1] = Abe; - state[ 2] = Abi; - state[ 3] = Abo; - state[ 4] = Abu; - state[ 5] = Aga; - state[ 6] = Age; - state[ 7] = Agi; - state[ 8] = Ago; - state[ 9] = Agu; - state[10] = Aka; - state[11] = Ake; - state[12] = Aki; - state[13] = Ako; - state[14] = Aku; - state[15] = Ama; - state[16] = Ame; - state[17] = Ami; - state[18] = Amo; - state[19] = Amu; - state[20] = Asa; - state[21] = Ase; - state[22] = Asi; - state[23] = Aso; - state[24] = Asu; -} - -/************************************************* -* Name: keccak_absorb -* -* Description: Absorb step of Keccak; -* non-incremental, starts by zeroeing the state. -* -* Arguments: - uint64_t *s: pointer to (uninitialized) output Keccak state -* - unsigned int r: rate in bytes (e.g., 168 for SHAKE128) -* - const uint8_t *m: pointer to input to be absorbed into s -* - int32_t mlen: length of input in bytes -* - uint8_t p: domain-separation byte for different -* Keccak-derived functions -**************************************************/ -static void keccak_absorb(uint64_t *s, - uint32_t r, - const uint8_t *m, - int32_t mlen, - uint8_t p) -{ - uint32_t i; - uint8_t t[200]; - DBENCH_START(); - - /* Zero state */ - for(i = 0; i < 25; ++i) - s[i] = 0; - - while(mlen >= r) { - for(i = 0; i < r/8; ++i) - s[i] ^= load64(m + 8*i); - - KeccakF1600_StatePermute(s); - mlen -= r; - m += r; - } - - for(i = 0; i < r; ++i) - t[i] = 0; - for(i = 0; i < mlen; ++i) - t[i] = m[i]; - t[i] = p; - t[r-1] |= 128; - for(i = 0; i < r/8; ++i) - s[i] ^= load64(t + 8*i); - - DBENCH_STOP(*tshake); -} - -/************************************************* -* Name: keccak_squeezeblocks -* -* Description: Squeeze step of Keccak. Squeezes full blocks of r bytes each. -* Modifies the state. Can be called multiple times to keep -* squeezing, i.e., is incremental. -* -* Arguments: - uint8_t *h: pointer to output blocks -* - int32_t int nblocks: number of blocks to be -* squeezed (written to h) -* - uint64_t *s: pointer to input/output Keccak state -* - uint32_t r: rate in bytes (e.g., 168 for SHAKE128) -**************************************************/ -static void keccak_squeezeblocks(uint8_t *h, - int32_t nblocks, - uint64_t *s, - uint32_t r) -{ - uint32_t i; - DBENCH_START(); - - while(nblocks > 0) { - KeccakF1600_StatePermute(s); - for(i=0; i < (r >> 3); i++) { - store64(h + 8*i, s[i]); - } - h += r; - --nblocks; - } - - DBENCH_STOP(*tshake); -} - -/************************************************* -* Name: shake128_absorb -* -* Description: Absorb step of the SHAKE128 XOF. -* non-incremental, starts by zeroeing the state. -* -* Arguments: - uint64_t *s: pointer to (uninitialized) output Keccak state -* - const uint8_t *input: pointer to input to be absorbed -* into s -* - int32_t inlen: length of input in bytes -**************************************************/ -void shake128_absorb(uint64_t *s, - const uint8_t *input, - int32_t inlen) -{ - keccak_absorb(s, SHAKE128_RATE, input, inlen, 0x1F); -} - -/************************************************* -* Name: shake128_squeezeblocks -* -* Description: Squeeze step of SHAKE128 XOF. Squeezes full blocks of -* SHAKE128_RATE bytes each. Modifies the state. Can be called -* multiple times to keep squeezing, i.e., is incremental. -* -* Arguments: - uint8_t *output: pointer to output blocks -* - int32_t nblocks: number of blocks to be squeezed -* (written to output) -* - uint64_t *s: pointer to input/output Keccak state -**************************************************/ -void shake128_squeezeblocks(uint8_t *output, - int32_t nblocks, - uint64_t *s) -{ - keccak_squeezeblocks(output, nblocks, s, SHAKE128_RATE); -} - -/************************************************* -* Name: shake256_absorb -* -* Description: Absorb step of the SHAKE256 XOF. -* non-incremental, starts by zeroeing the state. -* -* Arguments: - uint64_t *s: pointer to (uninitialized) output Keccak state -* - const uint8_t *input: pointer to input to be absorbed -* into s -* - int32_t inlen: length of input in bytes -**************************************************/ -void shake256_absorb(uint64_t *s, - const uint8_t *input, - int32_t inlen) -{ - keccak_absorb(s, SHAKE256_RATE, input, inlen, 0x1F); -} - -/************************************************* -* Name: shake256_squeezeblocks -* -* Description: Squeeze step of SHAKE256 XOF. Squeezes full blocks of -* SHAKE256_RATE bytes each. Modifies the state. Can be called -* multiple times to keep squeezing, i.e., is incremental. -* -* Arguments: - uint8_t *output: pointer to output blocks -* - int32_t nblocks: number of blocks to be squeezed -* (written to output) -* - uint64_t *s: pointer to input/output Keccak state -**************************************************/ -void shake256_squeezeblocks(uint8_t *output, - int32_t nblocks, - uint64_t *s) -{ - keccak_squeezeblocks(output, nblocks, s, SHAKE256_RATE); -} - -/************************************************* -* Name: shake128 -* -* Description: SHAKE128 XOF with non-incremental API -* -* Arguments: - uint8_t *output: pointer to output -* - int32_t outlen: requested output length in bytes -* - const uint8_t *input: pointer to input -* - int32_t inlen: length of input in bytes -**************************************************/ -void shake128(uint8_t *output, - int32_t outlen, - const uint8_t *input, - int32_t inlen) -{ - uint32_t i,nblocks = outlen/SHAKE128_RATE; - uint8_t t[SHAKE128_RATE]; - uint64_t s[25]; - - shake128_absorb(s, input, inlen); - shake128_squeezeblocks(output, nblocks, s); - - output += nblocks*SHAKE128_RATE; - outlen -= nblocks*SHAKE128_RATE; - - if(outlen) { - shake128_squeezeblocks(t, 1, s); - for(i = 0; i < outlen; ++i) - output[i] = t[i]; - } -} - -/************************************************* -* Name: shake256 -* -* Description: SHAKE256 XOF with non-incremental API -* -* Arguments: - uint8_t *output: pointer to output -* - int32_t outlen: requested output length in bytes -* - const uint8_t *input: pointer to input -* - int32_t inlen: length of input in bytes -**************************************************/ -void shake256(uint8_t *output, - int32_t outlen, - const uint8_t *input, - int32_t inlen) -{ - uint32_t i,nblocks = outlen/SHAKE256_RATE; - uint8_t t[SHAKE256_RATE]; - uint64_t s[25]; - - shake256_absorb(s, input, inlen); - shake256_squeezeblocks(output, nblocks, s); - - output += nblocks*SHAKE256_RATE; - outlen -= nblocks*SHAKE256_RATE; - - if(outlen) { - shake256_squeezeblocks(t, 1, s); - for(i = 0; i < outlen; ++i) - output[i] = t[i]; - } -} -//#include "params.h" -//#include "reduce.h" -//#include "ntt.h" -//#include "poly.h" - -/* Roots of unity in order needed by forward ntt */ -static const uint32_t zetas[N] = {0, 25847, 5771523, 7861508, 237124, 7602457, 7504169, 466468, 1826347, 2353451, 8021166, 6288512, 3119733, 5495562, 3111497, 2680103, 2725464, 1024112, 7300517, 3585928, 7830929, 7260833, 2619752, 6271868, 6262231, 4520680, 6980856, 5102745, 1757237, 8360995, 4010497, 280005, 2706023, 95776, 3077325, 3530437, 6718724, 4788269, 5842901, 3915439, 4519302, 5336701, 3574422, 5512770, 3539968, 8079950, 2348700, 7841118, 6681150, 6736599, 3505694, 4558682, 3507263, 6239768, 6779997, 3699596, 811944, 531354, 954230, 3881043, 3900724, 5823537, 2071892, 5582638, 4450022, 6851714, 4702672, 5339162, 6927966, 3475950, 2176455, 6795196, 7122806, 1939314, 4296819, 7380215, 5190273, 5223087, 4747489, 126922, 3412210, 7396998, 2147896, 2715295, 5412772, 4686924, 7969390, 5903370, 7709315, 7151892, 8357436, 7072248, 7998430, 1349076, 1852771, 6949987, 5037034, 264944, 508951, 3097992, 44288, 7280319, 904516, 3958618, 4656075, 8371839, 1653064, 5130689, 2389356, 8169440, 759969, 7063561, 189548, 4827145, 3159746, 6529015, 5971092, 8202977, 1315589, 1341330, 1285669, 6795489, 7567685, 6940675, 5361315, 4499357, 4751448, 3839961, 2091667, 3407706, 2316500, 3817976, 5037939, 2244091, 5933984, 4817955, 266997, 2434439, 7144689, 3513181, 4860065, 4621053, 7183191, 5187039, 900702, 1859098, 909542, 819034, 495491, 6767243, 8337157, 7857917, 7725090, 5257975, 2031748, 3207046, 4823422, 7855319, 7611795, 4784579, 342297, 286988, 5942594, 4108315, 3437287, 5038140, 1735879, 203044, 2842341, 2691481, 5790267, 1265009, 4055324, 1247620, 2486353, 1595974, 4613401, 1250494, 2635921, 4832145, 5386378, 1869119, 1903435, 7329447, 7047359, 1237275, 5062207, 6950192, 7929317, 1312455, 3306115, 6417775, 7100756, 1917081, 5834105, 7005614, 1500165, 777191, 2235880, 3406031, 7838005, 5548557, 6709241, 6533464, 5796124, 4656147, 594136, 4603424, 6366809, 2432395, 2454455, 8215696, 1957272, 3369112, 185531, 7173032, 5196991, 162844, 1616392, 3014001, 810149, 1652634, 4686184, 6581310, 5341501, 3523897, 3866901, 269760, 2213111, 7404533, 1717735, 472078, 7953734, 1723600, 6577327, 1910376, 6712985, 7276084, 8119771, 4546524, 5441381, 6144432, 7959518, 6094090, 183443, 7403526, 1612842, 4834730, 7826001, 3919660, 8332111, 7018208, 3937738, 1400424, 7534263, 1976782}; - -/* Roots of unity in order needed by inverse ntt */ -static const uint32_t zetas_inv[N] = {6403635, 846154, 6979993, 4442679, 1362209, 48306, 4460757, 554416, 3545687, 6767575, 976891, 8196974, 2286327, 420899, 2235985, 2939036, 3833893, 260646, 1104333, 1667432, 6470041, 1803090, 6656817, 426683, 7908339, 6662682, 975884, 6167306, 8110657, 4513516, 4856520, 3038916, 1799107, 3694233, 6727783, 7570268, 5366416, 6764025, 8217573, 3183426, 1207385, 8194886, 5011305, 6423145, 164721, 5925962, 5948022, 2013608, 3776993, 7786281, 3724270, 2584293, 1846953, 1671176, 2831860, 542412, 4974386, 6144537, 7603226, 6880252, 1374803, 2546312, 6463336, 1279661, 1962642, 5074302, 7067962, 451100, 1430225, 3318210, 7143142, 1333058, 1050970, 6476982, 6511298, 2994039, 3548272, 5744496, 7129923, 3767016, 6784443, 5894064, 7132797, 4325093, 7115408, 2590150, 5688936, 5538076, 8177373, 6644538, 3342277, 4943130, 4272102, 2437823, 8093429, 8038120, 3595838, 768622, 525098, 3556995, 5173371, 6348669, 3122442, 655327, 522500, 43260, 1613174, 7884926, 7561383, 7470875, 6521319, 7479715, 3193378, 1197226, 3759364, 3520352, 4867236, 1235728, 5945978, 8113420, 3562462, 2446433, 6136326, 3342478, 4562441, 6063917, 4972711, 6288750, 4540456, 3628969, 3881060, 3019102, 1439742, 812732, 1584928, 7094748, 7039087, 7064828, 177440, 2409325, 1851402, 5220671, 3553272, 8190869, 1316856, 7620448, 210977, 5991061, 3249728, 6727353, 8578, 3724342, 4421799, 7475901, 1100098, 8336129, 5282425, 7871466, 8115473, 3343383, 1430430, 6527646, 7031341, 381987, 1308169, 22981, 1228525, 671102, 2477047, 411027, 3693493, 2967645, 5665122, 6232521, 983419, 4968207, 8253495, 3632928, 3157330, 3190144, 1000202, 4083598, 6441103, 1257611, 1585221, 6203962, 4904467, 1452451, 3041255, 3677745, 1528703, 3930395, 2797779, 6308525, 2556880, 4479693, 4499374, 7426187, 7849063, 7568473, 4680821, 1600420, 2140649, 4873154, 3821735, 4874723, 1643818, 1699267, 539299, 6031717, 300467, 4840449, 2867647, 4805995, 3043716, 3861115, 4464978, 2537516, 3592148, 1661693, 4849980, 5303092, 8284641, 5674394, 8100412, 4369920, 19422, 6623180, 3277672, 1399561, 3859737, 2118186, 2108549, 5760665, 1119584, 549488, 4794489, 1079900, 7356305, 5654953, 5700314, 5268920, 2884855, 5260684, 2091905, 359251, 6026966, 6554070, 7913949, 876248, 777960, 8143293, 518909, 2608894, 8354570}; - -/************************************************* -* Name: ntt -* -* Description: Forward NTT, in-place. No modular reduction is performed after -* additions or subtractions. Hence output coefficients can be up -* to 16*Q larger than the coefficients of the input polynomial. -* Output vector is in bitreversed order. -* -* Arguments: - uint32_t p[N]: input/output coefficient array -**************************************************/ -void ntt(uint32_t p[N]) { - uint32_t len, start, j, k; - uint32_t zeta, t; - - k = 1; - for(len = 128; len > 0; len >>= 1) { - for(start = 0; start < N; start = j + len) { - zeta = zetas[k++]; - for(j = start; j < start + len; ++j) { - t = montgomery_reduce((uint64_t)zeta * p[j + len]); - p[j + len] = p[j] + 2*Q - t; - p[j] = p[j] + t; - } - } - } -} - -/************************************************* -* Name: invntt_frominvmont -* -* Description: Inverse NTT and multiplication by Montgomery factor 2^32. -* In-place. No modular reductions after additions or -* subtractions. Input coefficient need to be smaller than 2*Q. -* Output coefficient are smaller than 2*Q. -* -* Arguments: - uint32_t p[N]: input/output coefficient array -**************************************************/ -void invntt_frominvmont(uint32_t p[N]) { - uint32_t start, len, j, k; - uint32_t t, zeta; - const uint32_t f = (((uint64_t)MONT*MONT % Q) * (Q-1) % Q) * ((Q-1) >> 8) % Q; - - k = 0; - for(len = 1; len < N; len <<= 1) { - for(start = 0; start < N; start = j + len) { - zeta = zetas_inv[k++]; - for(j = start; j < start + len; ++j) { - t = p[j]; - p[j] = t + p[j + len]; - p[j + len] = t + 256*Q - p[j + len]; - p[j + len] = montgomery_reduce((uint64_t)zeta * p[j + len]); - } - } - } - - for(j = 0; j < N; ++j) { - p[j] = montgomery_reduce((uint64_t)f * p[j]); - } -} -//#include "params.h" -//#include "poly.h" -//#include "polyvec.h" -//#include "packing.h" - -/************************************************* -* Name: pack_pk -* -* Description: Bit-pack public key pk = (rho, t1). -* -* Arguments: - uint8_t pk[]: output byte array -* - const uint8_t rho[]: byte array containing rho -* - const polyveck *t1: pointer to vector t1 -**************************************************/ -void pack_pk(uint8_t pk[CRYPTO_PUBLICKEYBYTES], - const uint8_t rho[SEEDBYTES], - const polyveck *t1) -{ - uint32_t i; - - for(i = 0; i < SEEDBYTES; ++i) - pk[i] = rho[i]; - pk += SEEDBYTES; - - for(i = 0; i < K; ++i) - polyt1_pack(pk + i*POLT1_SIZE_PACKED, t1->vec+i); -} - -/************************************************* -* Name: unpack_pk -* -* Description: Unpack public key pk = (rho, t1). -* -* Arguments: - const uint8_t rho[]: output byte array for rho -* - const polyveck *t1: pointer to output vector t1 -* - uint8_t pk[]: byte array containing bit-packed pk -**************************************************/ -void unpack_pk(uint8_t rho[SEEDBYTES], - polyveck *t1, - const uint8_t pk[CRYPTO_PUBLICKEYBYTES]) -{ - uint32_t i; - - for(i = 0; i < SEEDBYTES; ++i) - rho[i] = pk[i]; - pk += SEEDBYTES; - - for(i = 0; i < K; ++i) - polyt1_unpack(t1->vec+i, pk + i*POLT1_SIZE_PACKED); -} - -/************************************************* -* Name: pack_sk -* -* Description: Bit-pack secret key sk = (rho, key, tr, s1, s2, t0). -* -* Arguments: - uint8_t sk[]: output byte array -* - const uint8_t rho[]: byte array containing rho -* - const uint8_t key[]: byte array containing key -* - const uint8_t tr[]: byte array containing tr -* - const polyvecl *s1: pointer to vector s1 -* - const polyveck *s2: pointer to vector s2 -* - const polyveck *t0: pointer to vector t0 -**************************************************/ -void pack_sk(uint8_t sk[CRYPTO_SECRETKEYBYTES], - const uint8_t rho[SEEDBYTES], - const uint8_t key[SEEDBYTES], - const uint8_t tr[CRHBYTES], - const polyvecl *s1, - const polyveck *s2, - const polyveck *t0) -{ - uint32_t i; - - for(i = 0; i < SEEDBYTES; ++i) - sk[i] = rho[i]; - sk += SEEDBYTES; - - for(i = 0; i < SEEDBYTES; ++i) - sk[i] = key[i]; - sk += SEEDBYTES; - - for(i = 0; i < CRHBYTES; ++i) - sk[i] = tr[i]; - sk += CRHBYTES; - - for(i = 0; i < L; ++i) - polyeta_pack(sk + i*POLETA_SIZE_PACKED, s1->vec+i); - sk += L*POLETA_SIZE_PACKED; - - for(i = 0; i < K; ++i) - polyeta_pack(sk + i*POLETA_SIZE_PACKED, s2->vec+i); - sk += K*POLETA_SIZE_PACKED; - - for(i = 0; i < K; ++i) - polyt0_pack(sk + i*POLT0_SIZE_PACKED, t0->vec+i); -} - -/************************************************* -* Name: unpack_sk -* -* Description: Unpack secret key sk = (rho, key, tr, s1, s2, t0). -* -* Arguments: - const uint8_t rho[]: output byte array for rho -* - const uint8_t key[]: output byte array for key -* - const uint8_t tr[]: output byte array for tr -* - const polyvecl *s1: pointer to output vector s1 -* - const polyveck *s2: pointer to output vector s2 -* - const polyveck *r0: pointer to output vector t0 -* - uint8_t sk[]: byte array containing bit-packed sk -**************************************************/ -void unpack_sk(uint8_t rho[SEEDBYTES], - uint8_t key[SEEDBYTES], - uint8_t tr[CRHBYTES], - polyvecl *s1, - polyveck *s2, - polyveck *t0, - const uint8_t sk[CRYPTO_SECRETKEYBYTES]) -{ - uint32_t i; - - for(i = 0; i < SEEDBYTES; ++i) - rho[i] = sk[i]; - sk += SEEDBYTES; - - for(i = 0; i < SEEDBYTES; ++i) - key[i] = sk[i]; - sk += SEEDBYTES; - - for(i = 0; i < CRHBYTES; ++i) - tr[i] = sk[i]; - sk += CRHBYTES; - - for(i=0; i < L; ++i) - polyeta_unpack(s1->vec+i, sk + i*POLETA_SIZE_PACKED); - sk += L*POLETA_SIZE_PACKED; - - for(i=0; i < K; ++i) - polyeta_unpack(s2->vec+i, sk + i*POLETA_SIZE_PACKED); - sk += K*POLETA_SIZE_PACKED; - - for(i=0; i < K; ++i) - polyt0_unpack(t0->vec+i, sk + i*POLT0_SIZE_PACKED); -} - -/************************************************* -* Name: pack_sig -* -* Description: Bit-pack signature sig = (z, h, c). -* -* Arguments: - uint8_t sig[]: output byte array -* - const polyvecl *z: pointer to vector z -* - const polyveck *h: pointer to hint vector h -* - const poly *c: pointer to challenge polynomial -**************************************************/ -void pack_sig(uint8_t sig[CRYPTO_BYTES], - const polyvecl *z, - const polyveck *h, - const poly *c) -{ - uint32_t i, j, k; - uint64_t signs, mask; - - for(i = 0; i < L; ++i) - polyz_pack(sig + i*POLZ_SIZE_PACKED, z->vec+i); - sig += L*POLZ_SIZE_PACKED; - - /* Encode h */ - k = 0; - for(i = 0; i < K; ++i) { - for(j = 0; j < N; ++j) - if(h->vec[i].coeffs[j] != 0) - sig[k++] = j; - - sig[OMEGA + i] = k; - } - while(k < OMEGA) sig[k++] = 0; - sig += OMEGA + K; - - /* Encode c */ - signs = 0; - mask = 1; - for(i = 0; i < N/8; ++i) { - sig[i] = 0; - for(j = 0; j < 8; ++j) { - if(c->coeffs[8*i+j] != 0) { - sig[i] |= (1U << j); - if(c->coeffs[8*i+j] == (Q - 1)) signs |= mask; - mask <<= 1; - } - } - } - sig += N/8; - for(i = 0; i < 8; ++i) - sig[i] = signs >> 8*i; -} - -/************************************************* -* Name: unpack_sig -* -* Description: Unpack signature sig = (z, h, c). -* -* Arguments: - polyvecl *z: pointer to output vector z -* - polyveck *h: pointer to output hint vector h -* - poly *c: pointer to output challenge polynomial -* - const uint8_t sig[]: byte array containing -* bit-packed signature -* -* Returns 1 in case of malformed signature; otherwise 0. -**************************************************/ -int unpack_sig(polyvecl *z, - polyveck *h, - poly *c, - const uint8_t sig[CRYPTO_BYTES]) -{ - uint32_t i, j, k; - uint64_t signs, mask; - - for(i = 0; i < L; ++i) - polyz_unpack(z->vec+i, sig + i*POLZ_SIZE_PACKED); - sig += L*POLZ_SIZE_PACKED; - - /* Decode h */ - k = 0; - for(i = 0; i < K; ++i) { - for(j = 0; j < N; ++j) - h->vec[i].coeffs[j] = 0; - - if(sig[OMEGA + i] < k || sig[OMEGA + i] > OMEGA) - return 1; - - for(j = k; j < sig[OMEGA + i]; ++j) { - /* Coefficients are ordered for strong unforgeability */ - if(j > k && sig[j] <= sig[j-1]) return 1; - h->vec[i].coeffs[sig[j]] = 1; - } - - k = sig[OMEGA + i]; - } - - /* Extra indices are zero for strong unforgeability */ - for(j = k; j < OMEGA; ++j) - if(sig[j]) - return 1; - - sig += OMEGA + K; - - /* Decode c */ - for(i = 0; i < N; ++i) - c->coeffs[i] = 0; - - signs = 0; - for(i = 0; i < 8; ++i) - signs |= (uint64_t)sig[N/8+i] << 8*i; - - /* Extra sign bits are zero for strong unforgeability */ - if(signs >> 60) - return 1; - - mask = 1; - for(i = 0; i < N/8; ++i) { - for(j = 0; j < 8; ++j) { - if((sig[i] >> j) & 0x01) { - c->coeffs[8*i+j] = (signs & mask) ? Q - 1 : 1; - mask <<= 1; - } - } - } - - return 0; -} -//#include -//#include "test/cpucycles.h" -//#include "fips202.h" -//#include "params.h" -//#include "reduce.h" -//#include "rounding.h" -//#include "ntt.h" -//#include "poly.h" - -#ifdef DBENCH -extern const uint64_t timing_overhead; -extern uint64_t *tred, *tadd, *tmul, *tround, *tsample, *tpack; -#endif - -/************************************************* -* Name: poly_reduce -* -* Description: Reduce all coefficients of input polynomial to representative -* in [0,2*Q[. -* -* Arguments: - poly *a: pointer to input/output polynomial -**************************************************/ -void poly_reduce(poly *a) { - uint32_t i; - DBENCH_START(); - - for(i = 0; i < N; ++i) - a->coeffs[i] = reduce32(a->coeffs[i]); - - DBENCH_STOP(*tred); -} - -/************************************************* -* Name: poly_csubq -* -* Description: For all coefficients of input polynomial subtract Q if -* coefficient is bigger than Q. -* -* Arguments: - poly *a: pointer to input/output polynomial -**************************************************/ -void poly_csubq(poly *a) { - uint32_t i; - DBENCH_START(); - - for(i = 0; i < N; ++i) - a->coeffs[i] = csubq(a->coeffs[i]); - - DBENCH_STOP(*tred); -} - -/************************************************* -* Name: poly_freeze -* -* Description: Reduce all coefficients of the polynomial to standard -* representatives. -* -* Arguments: - poly *a: pointer to input/output polynomial -**************************************************/ -void poly_freeze(poly *a) { - uint32_t i; - DBENCH_START(); - - for(i = 0; i < N; ++i) - a->coeffs[i] = freeze(a->coeffs[i]); - - DBENCH_STOP(*tred); -} - -/************************************************* -* Name: poly_add -* -* Description: Add polynomials. No modular reduction is performed. -* -* Arguments: - poly *c: pointer to output polynomial -* - const poly *a: pointer to first summand -* - const poly *b: pointer to second summand -**************************************************/ -void poly_add(poly *c, const poly *a, const poly *b) { - uint32_t i; - DBENCH_START(); - - for(i = 0; i < N; ++i) - c->coeffs[i] = a->coeffs[i] + b->coeffs[i]; - - DBENCH_STOP(*tadd); -} - -/************************************************* -* Name: poly_sub -* -* Description: Subtract polynomials. Assumes coefficients of second input -* polynomial to be less than 2*Q. No modular reduction is -* performed. -* -* Arguments: - poly *c: pointer to output polynomial -* - const poly *a: pointer to first input polynomial -* - const poly *b: pointer to second input polynomial to be -* subtraced from first input polynomial -**************************************************/ -void poly_sub(poly *c, const poly *a, const poly *b) { - uint32_t i; - DBENCH_START(); - - for(i = 0; i < N; ++i) - c->coeffs[i] = a->coeffs[i] + 2*Q - b->coeffs[i]; - - DBENCH_STOP(*tadd); -} - -/************************************************* -* Name: poly_neg -* -* Description: Negate polynomial. Assumes input coefficients to be standard -* representatives. -* -* Arguments: - poly *a: pointer to input/output polynomial -**************************************************/ -void poly_neg(poly *a) { - uint32_t i; - DBENCH_START(); - - for(i = 0; i < N; ++i) - a->coeffs[i] = Q - a->coeffs[i]; - - DBENCH_STOP(*tadd); -} - -/************************************************* -* Name: poly_shiftl -* -* Description: Multiply polynomial by 2^k without modular reduction. Assumes -* input coefficients to be less than 2^{32-k}. -* -* Arguments: - poly *a: pointer to input/output polynomial -* - uint32_t k: exponent -**************************************************/ -void poly_shiftl(poly *a, uint32_t k) { - uint32_t i; - DBENCH_START(); - - for(i = 0; i < N; ++i) - a->coeffs[i] <<= k; - - DBENCH_STOP(*tmul); -} - -/************************************************* -* Name: poly_ntt -* -* Description: Forward NTT. Output coefficients can be up to 16*Q larger than -* input coefficients. -* -* Arguments: - poly *a: pointer to input/output polynomial -**************************************************/ -void poly_ntt(poly *a) { - DBENCH_START(); - - ntt(a->coeffs); - - DBENCH_STOP(*tmul); -} - -/************************************************* -* Name: poly_invntt_montgomery -* -* Description: Inverse NTT and multiplication with 2^{32}. Input coefficients -* need to be less than 2*Q. Output coefficients are less than 2*Q. -* -* Arguments: - poly *a: pointer to input/output polynomial -**************************************************/ -void poly_invntt_montgomery(poly *a) { - DBENCH_START(); - - invntt_frominvmont(a->coeffs); - - DBENCH_STOP(*tmul); -} - -/************************************************* -* Name: poly_pointwise_invmontgomery -* -* Description: Pointwise multiplication of polynomials in NTT domain -* representation and multiplication of resulting polynomial -* with 2^{-32}. Output coefficients are less than 2*Q if input -* coefficient are less than 22*Q. -* -* Arguments: - poly *c: pointer to output polynomial -* - const poly *a: pointer to first input polynomial -* - const poly *b: pointer to second input polynomial -**************************************************/ -void poly_pointwise_invmontgomery(poly *c, const poly *a, const poly *b) { - uint32_t i; - DBENCH_START(); - - for(i = 0; i < N; ++i) - c->coeffs[i] = montgomery_reduce((uint64_t)a->coeffs[i] * b->coeffs[i]); - - DBENCH_STOP(*tmul); -} - -/************************************************* -* Name: poly_power2round -* -* Description: For all coefficients c of the input polynomial, -* compute c0, c1 such that c mod Q = c1*2^D + c0 -* with -2^{D-1} < c0 <= 2^{D-1}. Assumes coefficients to be -* standard representatives. -* -* Arguments: - poly *a1: pointer to output polynomial with coefficients c1 -* - poly *a0: pointer to output polynomial with coefficients Q + a0 -* - const poly *v: pointer to input polynomial -**************************************************/ -void poly_power2round(poly *a1, poly *a0, const poly *a) { - uint32_t i; - DBENCH_START(); - - for(i = 0; i < N; ++i) - a1->coeffs[i] = power2round(a->coeffs[i], a0->coeffs+i); - - DBENCH_STOP(*tround); -} - -/************************************************* -* Name: poly_decompose -* -* Description: For all coefficients c of the input polynomial, -* compute high and low bits c0, c1 such c mod Q = c1*ALPHA + c0 -* with -ALPHA/2 < c0 <= ALPHA/2 except c1 = (Q-1)/ALPHA where we -* set c1 = 0 and -ALPHA/2 <= c0 = c mod Q - Q < 0. -* Assumes coefficients to be standard representatives. -* -* Arguments: - poly *a1: pointer to output polynomial with coefficients c1 -* - poly *a0: pointer to output polynomial with coefficients Q + a0 -* - const poly *c: pointer to input polynomial -**************************************************/ -void poly_decompose(poly *a1, poly *a0, const poly *a) { - uint32_t i; - DBENCH_START(); - - for(i = 0; i < N; ++i) - a1->coeffs[i] = decompose(a->coeffs[i], a0->coeffs+i); - - DBENCH_STOP(*tround); -} - -/************************************************* -* Name: poly_make_hint -* -* Description: Compute hint polynomial. The coefficients of which indicate -* whether the high bits of the corresponding coefficients -* of the first input polynomial and of the sum of the input -* polynomials differ. -* -* Arguments: - poly *h: pointer to output hint polynomial -* - const poly *a: pointer to first input polynomial -* - const poly *b: pointer to second input polynomial -* -* Returns number of 1 bits. -**************************************************/ -uint32_t poly_make_hint(poly *h, const poly *a, const poly *b) { - uint32_t i, s = 0; - DBENCH_START(); - - for(i = 0; i < N; ++i) { - h->coeffs[i] = make_hint(a->coeffs[i], b->coeffs[i]); - s += h->coeffs[i]; - } - - DBENCH_STOP(*tround); - return s; -} - -/************************************************* -* Name: poly_use_hint -* -* Description: Use hint polynomial to correct the high bits of a polynomial. -* -* Arguments: - poly *a: pointer to output polynomial with corrected high bits -* - const poly *b: pointer to input polynomial -* - const poly *h: pointer to input hint polynomial -**************************************************/ -void poly_use_hint(poly *a, const poly *b, const poly *h) { - uint32_t i; - DBENCH_START(); - - for(i = 0; i < N; ++i) - a->coeffs[i] = use_hint(b->coeffs[i], h->coeffs[i]); - - DBENCH_STOP(*tround); -} - -/************************************************* -* Name: poly_chknorm -* -* Description: Check infinity norm of polynomial against given bound. -* Assumes input coefficients to be standard representatives. -* -* Arguments: - const poly *a: pointer to polynomial -* - uint32_t B: norm bound -* -* Returns 0 if norm is strictly smaller than B and 1 otherwise. -**************************************************/ -int poly_chknorm(const poly *a, uint32_t B) { - uint32_t i; - int32_t t; - DBENCH_START(); - - /* It is ok to leak which coefficient violates the bound since - the probability for each coefficient is independent of secret - data but we must not leak the sign of the centralized representative. */ - for(i = 0; i < N; ++i) { - /* Absolute value of centralized representative */ - t = (Q-1)/2 - a->coeffs[i]; - t ^= (t >> 31); - t = (Q-1)/2 - t; - - if((uint32_t)t >= B) { - DBENCH_STOP(*tsample); - return 1; - } - } - - DBENCH_STOP(*tsample); - return 0; -} - -/************************************************* -* Name: poly_uniform -* -* Description: Sample uniformly random polynomial using stream of random bytes. -* Assumes that enough random bytes are given (e.g. -* 5*SHAKE128_RATE bytes). -* -* Arguments: - poly *a: pointer to output polynomial -* - const uint8_t *buf: array of random bytes -**************************************************/ -void poly_uniform(poly *a, const uint8_t *buf) { - uint32_t ctr, pos; - uint32_t t; - DBENCH_START(); - - ctr = pos = 0; - while(ctr < N) { - t = buf[pos++]; - t |= (uint32_t)buf[pos++] << 8; - t |= (uint32_t)buf[pos++] << 16; - t &= 0x7FFFFF; - - if(t < Q) - a->coeffs[ctr++] = t; - } - - DBENCH_STOP(*tsample); -} - -/************************************************* -* Name: rej_eta -* -* Description: Sample uniformly random coefficients in [-ETA, ETA] by -* performing rejection sampling using array of random bytes. -* -* Arguments: - uint32_t *a: pointer to output array (allocated) -* - uint32_t len: number of coefficients to be sampled -* - const uint8_t *buf: array of random bytes -* - uint32_t buflen: length of array of random bytes -* -* Returns number of sampled coefficients. Can be smaller than len if not enough -* random bytes were given. -**************************************************/ -static uint32_t rej_eta(uint32_t *a, - uint32_t len, - const uint8_t *buf, - uint32_t buflen) -{ -#if ETA > 7 -#error "rej_eta() assumes ETA <= 7" -#endif - uint32_t ctr, pos; - uint8_t t0, t1; - DBENCH_START(); - - ctr = pos = 0; - while(ctr < len && pos < buflen) { -#if ETA <= 3 - t0 = buf[pos] & 0x07; - t1 = buf[pos++] >> 5; -#else - t0 = buf[pos] & 0x0F; - t1 = buf[pos++] >> 4; -#endif - - if(t0 <= 2*ETA) - a[ctr++] = Q + ETA - t0; - if(t1 <= 2*ETA && ctr < len) - a[ctr++] = Q + ETA - t1; - } - - DBENCH_STOP(*tsample); - return ctr; -} - -/************************************************* -* Name: poly_uniform_eta -* -* Description: Sample polynomial with uniformly random coefficients -* in [-ETA,ETA] by performing rejection sampling using the -* output stream from SHAKE256(seed|nonce). -* -* Arguments: - poly *a: pointer to output polynomial -* - const uint8_t seed[]: byte array with seed of length -* SEEDBYTES -* - uint8_t nonce: nonce byte -**************************************************/ -void poly_uniform_eta(poly *a, - const uint8_t seed[SEEDBYTES], - uint8_t nonce) -{ - uint32_t i, ctr; - uint8_t inbuf[SEEDBYTES + 1]; - /* Probability that we need more than 2 blocks: < 2^{-84} - Probability that we need more than 3 blocks: < 2^{-352} */ - uint8_t outbuf[2*SHAKE256_RATE]; - uint64_t state[25]; - - for(i= 0; i < SEEDBYTES; ++i) - inbuf[i] = seed[i]; - inbuf[SEEDBYTES] = nonce; - - shake256_absorb(state, inbuf, SEEDBYTES + 1); - shake256_squeezeblocks(outbuf, 2, state); - - ctr = rej_eta(a->coeffs, N, outbuf, 2*SHAKE256_RATE); - if(ctr < N) { - shake256_squeezeblocks(outbuf, 1, state); - rej_eta(a->coeffs + ctr, N - ctr, outbuf, SHAKE256_RATE); - } -} - -/************************************************* -* Name: rej_gamma1m1 -* -* Description: Sample uniformly random coefficients -* in [-(GAMMA1 - 1), GAMMA1 - 1] by performing rejection sampling -* using array of random bytes. -* -* Arguments: - uint32_t *a: pointer to output array (allocated) -* - uint32_t len: number of coefficients to be sampled -* - const uint8_t *buf: array of random bytes -* - uint32_t buflen: length of array of random bytes -* -* Returns number of sampled coefficients. Can be smaller than len if not enough -* random bytes were given. -**************************************************/ -static uint32_t rej_gamma1m1(uint32_t *a, - uint32_t len, - const uint8_t *buf, - uint32_t buflen) -{ -#if GAMMA1 > (1 << 19) -#error "rej_gamma1m1() assumes GAMMA1 - 1 fits in 19 bits" -#endif - uint32_t ctr, pos; - uint32_t t0, t1; - DBENCH_START(); - - ctr = pos = 0; - while(ctr < len && pos + 5 <= buflen) { - t0 = buf[pos]; - t0 |= (uint32_t)buf[pos + 1] << 8; - t0 |= (uint32_t)buf[pos + 2] << 16; - t0 &= 0xFFFFF; - - t1 = buf[pos + 2] >> 4; - t1 |= (uint32_t)buf[pos + 3] << 4; - t1 |= (uint32_t)buf[pos + 4] << 12; - - pos += 5; - - if(t0 <= 2*GAMMA1 - 2) - a[ctr++] = Q + GAMMA1 - 1 - t0; - if(t1 <= 2*GAMMA1 - 2 && ctr < len) - a[ctr++] = Q + GAMMA1 - 1 - t1; - } - - DBENCH_STOP(*tsample); - return ctr; -} - -/************************************************* -* Name: poly_uniform_gamma1m1 -* -* Description: Sample polynomial with uniformly random coefficients -* in [-(GAMMA1 - 1), GAMMA1 - 1] by performing rejection -* sampling on output stream of SHAKE256(seed|nonce). -* -* Arguments: - poly *a: pointer to output polynomial -* - const uint8_t seed[]: byte array with seed of length -* SEEDBYTES + CRHBYTES -* - uint16_t nonce: 16-bit nonce -**************************************************/ -void poly_uniform_gamma1m1(poly *a, - const uint8_t seed[SEEDBYTES + CRHBYTES], - uint16_t nonce) -{ - uint32_t i, ctr; - uint8_t inbuf[SEEDBYTES + CRHBYTES + 2]; - /* Probability that we need more than 5 blocks: < 2^{-81} - Probability that we need more than 6 blocks: < 2^{-467} */ - uint8_t outbuf[5*SHAKE256_RATE]; - uint64_t state[25]; - - for(i = 0; i < SEEDBYTES + CRHBYTES; ++i) - inbuf[i] = seed[i]; - inbuf[SEEDBYTES + CRHBYTES] = nonce & 0xFF; - inbuf[SEEDBYTES + CRHBYTES + 1] = nonce >> 8; - - shake256_absorb(state, inbuf, SEEDBYTES + CRHBYTES + 2); - shake256_squeezeblocks(outbuf, 5, state); - - ctr = rej_gamma1m1(a->coeffs, N, outbuf, 5*SHAKE256_RATE); - if(ctr < N) { - /* There are no bytes left in outbuf - since 5*SHAKE256_RATE is divisible by 5 */ - shake256_squeezeblocks(outbuf, 1, state); - rej_gamma1m1(a->coeffs + ctr, N - ctr, outbuf, SHAKE256_RATE); - } -} - -/************************************************* -* Name: polyeta_pack -* -* Description: Bit-pack polynomial with coefficients in [-ETA,ETA]. -* Input coefficients are assumed to lie in [Q-ETA,Q+ETA]. -* -* Arguments: - uint8_t *r: pointer to output byte array with at least -* POLETA_SIZE_PACKED bytes -* - const poly *a: pointer to input polynomial -**************************************************/ -void polyeta_pack(uint8_t *r, const poly *a) { -#if ETA > 7 -#error "polyeta_pack() assumes ETA <= 7" -#endif - uint32_t i; - uint8_t t[8]; - DBENCH_START(); - -#if ETA <= 3 - for(i = 0; i < N/8; ++i) { - t[0] = Q + ETA - a->coeffs[8*i+0]; - t[1] = Q + ETA - a->coeffs[8*i+1]; - t[2] = Q + ETA - a->coeffs[8*i+2]; - t[3] = Q + ETA - a->coeffs[8*i+3]; - t[4] = Q + ETA - a->coeffs[8*i+4]; - t[5] = Q + ETA - a->coeffs[8*i+5]; - t[6] = Q + ETA - a->coeffs[8*i+6]; - t[7] = Q + ETA - a->coeffs[8*i+7]; - - r[3*i+0] = t[0]; - r[3*i+0] |= t[1] << 3; - r[3*i+0] |= t[2] << 6; - r[3*i+1] = t[2] >> 2; - r[3*i+1] |= t[3] << 1; - r[3*i+1] |= t[4] << 4; - r[3*i+1] |= t[5] << 7; - r[3*i+2] = t[5] >> 1; - r[3*i+2] |= t[6] << 2; - r[3*i+2] |= t[7] << 5; - } -#else - for(i = 0; i < N/2; ++i) { - t[0] = Q + ETA - a->coeffs[2*i+0]; - t[1] = Q + ETA - a->coeffs[2*i+1]; - r[i] = t[0] | (t[1] << 4); - } -#endif - - DBENCH_STOP(*tpack); -} - -/************************************************* -* Name: polyeta_unpack -* -* Description: Unpack polynomial with coefficients in [-ETA,ETA]. -* Output coefficients lie in [Q-ETA,Q+ETA]. -* -* Arguments: - poly *r: pointer to output polynomial -* - const uint8_t *a: byte array with bit-packed polynomial -**************************************************/ -void polyeta_unpack(poly *r, const uint8_t *a) { - uint32_t i; - DBENCH_START(); - -#if ETA <= 3 - for(i = 0; i < N/8; ++i) { - r->coeffs[8*i+0] = a[3*i+0] & 0x07; - r->coeffs[8*i+1] = (a[3*i+0] >> 3) & 0x07; - r->coeffs[8*i+2] = (a[3*i+0] >> 6) | ((a[3*i+1] & 0x01) << 2); - r->coeffs[8*i+3] = (a[3*i+1] >> 1) & 0x07; - r->coeffs[8*i+4] = (a[3*i+1] >> 4) & 0x07; - r->coeffs[8*i+5] = (a[3*i+1] >> 7) | ((a[3*i+2] & 0x03) << 1); - r->coeffs[8*i+6] = (a[3*i+2] >> 2) & 0x07; - r->coeffs[8*i+7] = (a[3*i+2] >> 5); - - r->coeffs[8*i+0] = Q + ETA - r->coeffs[8*i+0]; - r->coeffs[8*i+1] = Q + ETA - r->coeffs[8*i+1]; - r->coeffs[8*i+2] = Q + ETA - r->coeffs[8*i+2]; - r->coeffs[8*i+3] = Q + ETA - r->coeffs[8*i+3]; - r->coeffs[8*i+4] = Q + ETA - r->coeffs[8*i+4]; - r->coeffs[8*i+5] = Q + ETA - r->coeffs[8*i+5]; - r->coeffs[8*i+6] = Q + ETA - r->coeffs[8*i+6]; - r->coeffs[8*i+7] = Q + ETA - r->coeffs[8*i+7]; - } -#else - for(i = 0; i < N/2; ++i) { - r->coeffs[2*i+0] = a[i] & 0x0F; - r->coeffs[2*i+1] = a[i] >> 4; - r->coeffs[2*i+0] = Q + ETA - r->coeffs[2*i+0]; - r->coeffs[2*i+1] = Q + ETA - r->coeffs[2*i+1]; - } -#endif - - DBENCH_STOP(*tpack); -} - -/************************************************* -* Name: polyt1_pack -* -* Description: Bit-pack polynomial t1 with coefficients fitting in 9 bits. -* Input coefficients are assumed to be standard representatives. -* -* Arguments: - uint8_t *r: pointer to output byte array with at least -* POLT1_SIZE_PACKED bytes -* - const poly *a: pointer to input polynomial -**************************************************/ -void polyt1_pack(uint8_t *r, const poly *a) { -#if D != 14 -#error "polyt1_pack() assumes D == 14" -#endif - uint32_t i; - DBENCH_START(); - - for(i = 0; i < N/8; ++i) { - r[9*i+0] = a->coeffs[8*i+0] & 0xFF; - r[9*i+1] = (a->coeffs[8*i+0] >> 8) | ((a->coeffs[8*i+1] & 0x7F) << 1); - r[9*i+2] = (a->coeffs[8*i+1] >> 7) | ((a->coeffs[8*i+2] & 0x3F) << 2); - r[9*i+3] = (a->coeffs[8*i+2] >> 6) | ((a->coeffs[8*i+3] & 0x1F) << 3); - r[9*i+4] = (a->coeffs[8*i+3] >> 5) | ((a->coeffs[8*i+4] & 0x0F) << 4); - r[9*i+5] = (a->coeffs[8*i+4] >> 4) | ((a->coeffs[8*i+5] & 0x07) << 5); - r[9*i+6] = (a->coeffs[8*i+5] >> 3) | ((a->coeffs[8*i+6] & 0x03) << 6); - r[9*i+7] = (a->coeffs[8*i+6] >> 2) | ((a->coeffs[8*i+7] & 0x01) << 7); - r[9*i+8] = a->coeffs[8*i+7] >> 1; - } - - DBENCH_STOP(*tpack); -} - -/************************************************* -* Name: polyt1_unpack -* -* Description: Unpack polynomial t1 with 9-bit coefficients. -* Output coefficients are standard representatives. -* -* Arguments: - poly *r: pointer to output polynomial -* - const uint8_t *a: byte array with bit-packed polynomial -**************************************************/ -void polyt1_unpack(poly *r, const uint8_t *a) { - uint32_t i; - DBENCH_START(); - - for(i = 0; i < N/8; ++i) { - r->coeffs[8*i+0] = a[9*i+0] | ((uint32_t)(a[9*i+1] & 0x01) << 8); - r->coeffs[8*i+1] = (a[9*i+1] >> 1) | ((uint32_t)(a[9*i+2] & 0x03) << 7); - r->coeffs[8*i+2] = (a[9*i+2] >> 2) | ((uint32_t)(a[9*i+3] & 0x07) << 6); - r->coeffs[8*i+3] = (a[9*i+3] >> 3) | ((uint32_t)(a[9*i+4] & 0x0F) << 5); - r->coeffs[8*i+4] = (a[9*i+4] >> 4) | ((uint32_t)(a[9*i+5] & 0x1F) << 4); - r->coeffs[8*i+5] = (a[9*i+5] >> 5) | ((uint32_t)(a[9*i+6] & 0x3F) << 3); - r->coeffs[8*i+6] = (a[9*i+6] >> 6) | ((uint32_t)(a[9*i+7] & 0x7F) << 2); - r->coeffs[8*i+7] = (a[9*i+7] >> 7) | ((uint32_t)(a[9*i+8] & 0xFF) << 1); - } - - DBENCH_STOP(*tpack); -} - -/************************************************* -* Name: polyt0_pack -* -* Description: Bit-pack polynomial t0 with coefficients in ]-2^{D-1}, 2^{D-1}]. -* Input coefficients are assumed to lie in ]Q-2^{D-1}, Q+2^{D-1}]. -* -* Arguments: - uint8_t *r: pointer to output byte array with at least -* POLT0_SIZE_PACKED bytes -* - const poly *a: pointer to input polynomial -**************************************************/ -void polyt0_pack(uint8_t *r, const poly *a) { - uint32_t i; - uint32_t t[4]; - DBENCH_START(); - - for(i = 0; i < N/4; ++i) { - t[0] = Q + (1 << (D-1)) - a->coeffs[4*i+0]; - t[1] = Q + (1 << (D-1)) - a->coeffs[4*i+1]; - t[2] = Q + (1 << (D-1)) - a->coeffs[4*i+2]; - t[3] = Q + (1 << (D-1)) - a->coeffs[4*i+3]; - - r[7*i+0] = t[0]; - r[7*i+1] = t[0] >> 8; - r[7*i+1] |= t[1] << 6; - r[7*i+2] = t[1] >> 2; - r[7*i+3] = t[1] >> 10; - r[7*i+3] |= t[2] << 4; - r[7*i+4] = t[2] >> 4; - r[7*i+5] = t[2] >> 12; - r[7*i+5] |= t[3] << 2; - r[7*i+6] = t[3] >> 6; - } - - DBENCH_STOP(*tpack); -} - -/************************************************* -* Name: polyt0_unpack -* -* Description: Unpack polynomial t0 with coefficients in ]-2^{D-1}, 2^{D-1}]. -* Output coefficients lie in ]Q-2^{D-1},Q+2^{D-1}]. -* -* Arguments: - poly *r: pointer to output polynomial -* - const uint8_t *a: byte array with bit-packed polynomial -**************************************************/ -void polyt0_unpack(poly *r, const uint8_t *a) { - uint32_t i; - DBENCH_START(); - - for(i = 0; i < N/4; ++i) { - r->coeffs[4*i+0] = a[7*i+0]; - r->coeffs[4*i+0] |= (uint32_t)(a[7*i+1] & 0x3F) << 8; - - r->coeffs[4*i+1] = a[7*i+1] >> 6; - r->coeffs[4*i+1] |= (uint32_t)a[7*i+2] << 2; - r->coeffs[4*i+1] |= (uint32_t)(a[7*i+3] & 0x0F) << 10; - - r->coeffs[4*i+2] = a[7*i+3] >> 4; - r->coeffs[4*i+2] |= (uint32_t)a[7*i+4] << 4; - r->coeffs[4*i+2] |= (uint32_t)(a[7*i+5] & 0x03) << 12; - - r->coeffs[4*i+3] = a[7*i+5] >> 2; - r->coeffs[4*i+3] |= (uint32_t)a[7*i+6] << 6; - - r->coeffs[4*i+0] = Q + (1 << (D-1)) - r->coeffs[4*i+0]; - r->coeffs[4*i+1] = Q + (1 << (D-1)) - r->coeffs[4*i+1]; - r->coeffs[4*i+2] = Q + (1 << (D-1)) - r->coeffs[4*i+2]; - r->coeffs[4*i+3] = Q + (1 << (D-1)) - r->coeffs[4*i+3]; - } - - DBENCH_STOP(*tpack); -} - -/************************************************* -* Name: polyz_pack -* -* Description: Bit-pack polynomial z with coefficients -* in [-(GAMMA1 - 1), GAMMA1 - 1]. -* Input coefficients are assumed to be standard representatives. -* -* Arguments: - uint8_t *r: pointer to output byte array with at least -* POLZ_SIZE_PACKED bytes -* - const poly *a: pointer to input polynomial -**************************************************/ -void polyz_pack(uint8_t *r, const poly *a) { -#if GAMMA1 > (1 << 19) -#error "polyz_pack() assumes GAMMA1 <= 2^{19}" -#endif - uint32_t i; - uint32_t t[2]; - DBENCH_START(); - - for(i = 0; i < N/2; ++i) { - /* Map to {0,...,2*GAMMA1 - 2} */ - t[0] = GAMMA1 - 1 - a->coeffs[2*i+0]; - t[0] += ((int32_t)t[0] >> 31) & Q; - t[1] = GAMMA1 - 1 - a->coeffs[2*i+1]; - t[1] += ((int32_t)t[1] >> 31) & Q; - - r[5*i+0] = t[0]; - r[5*i+1] = t[0] >> 8; - r[5*i+2] = t[0] >> 16; - r[5*i+2] |= t[1] << 4; - r[5*i+3] = t[1] >> 4; - r[5*i+4] = t[1] >> 12; - } - - DBENCH_STOP(*tpack); -} - -/************************************************* -* Name: polyz_unpack -* -* Description: Unpack polynomial z with coefficients -* in [-(GAMMA1 - 1), GAMMA1 - 1]. -* Output coefficients are standard representatives. -* -* Arguments: - poly *r: pointer to output polynomial -* - const uint8_t *a: byte array with bit-packed polynomial -**************************************************/ -void polyz_unpack(poly *r, const uint8_t *a) { - uint32_t i; - DBENCH_START(); - - for(i = 0; i < N/2; ++i) { - r->coeffs[2*i+0] = a[5*i+0]; - r->coeffs[2*i+0] |= (uint32_t)a[5*i+1] << 8; - r->coeffs[2*i+0] |= (uint32_t)(a[5*i+2] & 0x0F) << 16; - - r->coeffs[2*i+1] = a[5*i+2] >> 4; - r->coeffs[2*i+1] |= (uint32_t)a[5*i+3] << 4; - r->coeffs[2*i+1] |= (uint32_t)a[5*i+4] << 12; - - r->coeffs[2*i+0] = GAMMA1 - 1 - r->coeffs[2*i+0]; - r->coeffs[2*i+0] += ((int32_t)r->coeffs[2*i+0] >> 31) & Q; - r->coeffs[2*i+1] = GAMMA1 - 1 - r->coeffs[2*i+1]; - r->coeffs[2*i+1] += ((int32_t)r->coeffs[2*i+1] >> 31) & Q; - } - - DBENCH_STOP(*tpack); -} - -/************************************************* -* Name: polyw1_pack -* -* Description: Bit-pack polynomial w1 with coefficients in [0, 15]. -* Input coefficients are assumed to be standard representatives. -* -* Arguments: - uint8_t *r: pointer to output byte array with at least -* POLW1_SIZE_PACKED bytes -* - const poly *a: pointer to input polynomial -**************************************************/ -void polyw1_pack(uint8_t *r, const poly *a) { - uint32_t i; - DBENCH_START(); - - for(i = 0; i < N/2; ++i) - r[i] = a->coeffs[2*i+0] | (a->coeffs[2*i+1] << 4); - - DBENCH_STOP(*tpack); -} -//#include -//#include "params.h" -//#include "poly.h" -//#include "polyvec.h" - -/**************************************************************/ -/************ Vectors of polynomials of length L **************/ -/**************************************************************/ - -/************************************************* -* Name: polyvecl_freeze -* -* Description: Reduce coefficients of polynomials in vector of length L -* to standard representatives. -* -* Arguments: - polyvecl *v: pointer to input/output vector -**************************************************/ -void polyvecl_freeze(polyvecl *v) { - uint32_t i; - - for(i = 0; i < L; ++i) - poly_freeze(v->vec+i); -} - -/************************************************* -* Name: polyvecl_add -* -* Description: Add vectors of polynomials of length L. -* No modular reduction is performed. -* -* Arguments: - polyvecl *w: pointer to output vector -* - const polyvecl *u: pointer to first summand -* - const polyvecl *v: pointer to second summand -**************************************************/ -void polyvecl_add(polyvecl *w, const polyvecl *u, const polyvecl *v) { - uint32_t i; - - for(i = 0; i < L; ++i) - poly_add(w->vec+i, u->vec+i, v->vec+i); -} - -/************************************************* -* Name: polyvecl_ntt -* -* Description: Forward NTT of all polynomials in vector of length L. Output -* coefficients can be up to 16*Q larger than input coefficients. -* -* Arguments: - polyvecl *v: pointer to input/output vector -**************************************************/ -void polyvecl_ntt(polyvecl *v) { - uint32_t i; - - for(i = 0; i < L; ++i) - poly_ntt(v->vec+i); -} - -/************************************************* -* Name: polyvecl_pointwise_acc_invmontgomery -* -* Description: Pointwise multiply vectors of polynomials of length L, multiply -* resulting vector by 2^{-32} and add (accumulate) polynomials -* in it. Input/output vectors are in NTT domain representation. -* Input coefficients are assumed to be less than 22*Q. Output -* coeffcient are less than 2*L*Q. -* -* Arguments: - poly *w: output polynomial -* - const polyvecl *u: pointer to first input vector -* - const polyvecl *v: pointer to second input vector -**************************************************/ -void polyvecl_pointwise_acc_invmontgomery(poly *w, - const polyvecl *u, - const polyvecl *v) -{ - uint32_t i; - poly t; - - poly_pointwise_invmontgomery(w, u->vec+0, v->vec+0); - - for(i = 1; i < L; ++i) { - poly_pointwise_invmontgomery(&t, u->vec+i, v->vec+i); - poly_add(w, w, &t); - } -} - -/************************************************* -* Name: polyvecl_chknorm -* -* Description: Check infinity norm of polynomials in vector of length L. -* Assumes input coefficients to be standard representatives. -* -* Arguments: - const polyvecl *v: pointer to vector -* - uint32_t B: norm bound -* -* Returns 0 if norm of all polynomials is strictly smaller than B and 1 -* otherwise. -**************************************************/ -int polyvecl_chknorm(const polyvecl *v, uint32_t bound) { - uint32_t i; - int ret = 0; - - for(i = 0; i < L; ++i) - ret |= poly_chknorm(v->vec+i, bound); - - return ret; -} - -/**************************************************************/ -/************ Vectors of polynomials of length K **************/ -/**************************************************************/ - - -/************************************************* -* Name: polyveck_reduce -* -* Description: Reduce coefficients of polynomials in vector of length K -* to representatives in [0,2*Q[. -* -* Arguments: - polyveck *v: pointer to input/output vector -**************************************************/ -void polyveck_reduce(polyveck *v) { - uint32_t i; - - for(i = 0; i < K; ++i) - poly_reduce(v->vec+i); -} - -/************************************************* -* Name: polyveck_csubq -* -* Description: For all coefficients of polynomials in vector of length K -* subtract Q if coefficient is bigger than Q. -* -* Arguments: - polyveck *v: pointer to input/output vector -**************************************************/ -void polyveck_csubq(polyveck *v) { - uint32_t i; - - for(i = 0; i < K; ++i) - poly_csubq(v->vec+i); -} - -/************************************************* -* Name: polyveck_freeze -* -* Description: Reduce coefficients of polynomials in vector of length K -* to standard representatives. -* -* Arguments: - polyveck *v: pointer to input/output vector -**************************************************/ -void polyveck_freeze(polyveck *v) { - uint32_t i; - - for(i = 0; i < K; ++i) - poly_freeze(v->vec+i); -} - -/************************************************* -* Name: polyveck_add -* -* Description: Add vectors of polynomials of length K. -* No modular reduction is performed. -* -* Arguments: - polyveck *w: pointer to output vector -* - const polyveck *u: pointer to first summand -* - const polyveck *v: pointer to second summand -**************************************************/ -void polyveck_add(polyveck *w, const polyveck *u, const polyveck *v) { - uint32_t i; - - for(i = 0; i < K; ++i) - poly_add(w->vec+i, u->vec+i, v->vec+i); -} - -/************************************************* -* Name: polyveck_sub -* -* Description: Subtract vectors of polynomials of length K. -* Assumes coefficients of polynomials in second input vector -* to be less than 2*Q. No modular reduction is performed. -* -* Arguments: - polyveck *w: pointer to output vector -* - const polyveck *u: pointer to first input vector -* - const polyveck *v: pointer to second input vector to be -* subtracted from first input vector -**************************************************/ -void polyveck_sub(polyveck *w, const polyveck *u, const polyveck *v) { - uint32_t i; - - for(i = 0; i < K; ++i) - poly_sub(w->vec+i, u->vec+i, v->vec+i); -} - -/************************************************* -* Name: polyveck_shiftl -* -* Description: Multiply vector of polynomials of Length K by 2^k without modular -* reduction. Assumes input coefficients to be less than 2^{32-k}. -* -* Arguments: - polyveck *v: pointer to input/output vector -* - uint32_t k: exponent -**************************************************/ -void polyveck_shiftl(polyveck *v, uint32_t k) { - uint32_t i; - - for(i = 0; i < K; ++i) - poly_shiftl(v->vec+i, k); -} - -/************************************************* -* Name: polyveck_ntt -* -* Description: Forward NTT of all polynomials in vector of length K. Output -* coefficients can be up to 16*Q larger than input coefficients. -* -* Arguments: - polyveck *v: pointer to input/output vector -**************************************************/ -void polyveck_ntt(polyveck *v) { - uint32_t i; - - for(i = 0; i < K; ++i) - poly_ntt(v->vec+i); -} - -/************************************************* -* Name: polyveck_invntt_montgomery -* -* Description: Inverse NTT and multiplication by 2^{32} of polynomials -* in vector of length K. Input coefficients need to be less -* than 2*Q. -* -* Arguments: - polyveck *v: pointer to input/output vector -**************************************************/ -void polyveck_invntt_montgomery(polyveck *v) { - uint32_t i; - - for(i = 0; i < K; ++i) - poly_invntt_montgomery(v->vec+i); -} - -/************************************************* -* Name: polyveck_chknorm -* -* Description: Check infinity norm of polynomials in vector of length K. -* Assumes input coefficients to be standard representatives. -* -* Arguments: - const polyveck *v: pointer to vector -* - uint32_t B: norm bound -* -* Returns 0 if norm of all polynomials are strictly smaller than B and 1 -* otherwise. -**************************************************/ -int polyveck_chknorm(const polyveck *v, uint32_t bound) { - uint32_t i; - int ret = 0; - - for(i = 0; i < K; ++i) - ret |= poly_chknorm(v->vec+i, bound); - - return ret; -} - -/************************************************* -* Name: polyveck_power2round -* -* Description: For all coefficients a of polynomials in vector of length K, -* compute a0, a1 such that a mod Q = a1*2^D + a0 -* with -2^{D-1} < a0 <= 2^{D-1}. Assumes coefficients to be -* standard representatives. -* -* Arguments: - polyveck *v1: pointer to output vector of polynomials with -* coefficients a1 -* - polyveck *v0: pointer to output vector of polynomials with -* coefficients Q + a0 -* - const polyveck *v: pointer to input vector -**************************************************/ -void polyveck_power2round(polyveck *v1, polyveck *v0, const polyveck *v) { - uint32_t i; - - for(i = 0; i < K; ++i) - poly_power2round(v1->vec+i, v0->vec+i, v->vec+i); -} - -/************************************************* -* Name: polyveck_decompose -* -* Description: For all coefficients a of polynomials in vector of length K, -* compute high and low bits a0, a1 such a mod Q = a1*ALPHA + a0 -* with -ALPHA/2 < a0 <= ALPHA/2 except a1 = (Q-1)/ALPHA where we -* set a1 = 0 and -ALPHA/2 <= a0 = a mod Q - Q < 0. -* Assumes coefficients to be standard representatives. -* -* Arguments: - polyveck *v1: pointer to output vector of polynomials with -* coefficients a1 -* - polyveck *v0: pointer to output vector of polynomials with -* coefficients Q + a0 -* - const polyveck *v: pointer to input vector -**************************************************/ -void polyveck_decompose(polyveck *v1, polyveck *v0, const polyveck *v) { - uint32_t i; - - for(i = 0; i < K; ++i) - poly_decompose(v1->vec+i, v0->vec+i, v->vec+i); -} - -/************************************************* -* Name: polyveck_make_hint -* -* Description: Compute hint vector. -* -* Arguments: - polyveck *h: pointer to output vector -* - const polyveck *u: pointer to first input vector -* - const polyveck *u: pointer to second input vector -* -* Returns number of 1 bits. -**************************************************/ -uint32_t polyveck_make_hint(polyveck *h, - const polyveck *u, - const polyveck *v) -{ - uint32_t i, s = 0; - - for(i = 0; i < K; ++i) - s += poly_make_hint(h->vec+i, u->vec+i, v->vec+i); - - return s; -} - -/************************************************* -* Name: polyveck_use_hint -* -* Description: Use hint vector to correct the high bits of input vector. -* -* Arguments: - polyveck *w: pointer to output vector of polynomials with -* corrected high bits -* - const polyveck *u: pointer to input vector -* - const polyveck *h: pointer to input hint vector -**************************************************/ -void polyveck_use_hint(polyveck *w, const polyveck *u, const polyveck *h) { - uint32_t i; - - for(i = 0; i < K; ++i) - poly_use_hint(w->vec+i, u->vec+i, h->vec+i); -} -//#include -//#include "params.h" -//#include "reduce.h" - -/************************************************* -* Name: montgomery_reduce -* -* Description: For finite field element a with 0 <= a <= Q*2^32, -* compute r \equiv a*2^{-32} (mod Q) such that 0 <= r < 2*Q. -* -* Arguments: - uint64_t: finite field element a -* -* Returns r. -**************************************************/ -uint32_t montgomery_reduce(uint64_t a) { - uint64_t t; - - t = a * QINV; - t &= (1ULL << 32) - 1; - t *= Q; - t = a + t; - t >>= 32; - return t; -} - -/************************************************* -* Name: reduce32 -* -* Description: For finite field element a, compute r \equiv a (mod Q) -* such that 0 <= r < 2*Q. -* -* Arguments: - uint32_t: finite field element a -* -* Returns r. -**************************************************/ -uint32_t reduce32(uint32_t a) { - uint32_t t; - - t = a & 0x7FFFFF; - a >>= 23; - t += (a << 13) - a; - return t; -} - -/************************************************* -* Name: csubq -* -* Description: Subtract Q if input coefficient is bigger than Q. -* -* Arguments: - uint32_t: finite field element a -* -* Returns r. -**************************************************/ -uint32_t csubq(uint32_t a) { - a -= Q; - a += ((int32_t)a >> 31) & Q; - return a; -} - -/************************************************* -* Name: freeze -* -* Description: For finite field element a, compute standard -* representative r = a mod Q. -* -* Arguments: - uint32_t: finite field element a -* -* Returns r. -**************************************************/ -uint32_t freeze(uint32_t a) { - a = reduce32(a); - a = csubq(a); - return a; -} -//#include -//#include "params.h" - -/************************************************* -* Name: power2round -* -* Description: For finite field element a, compute a0, a1 such that -* a mod Q = a1*2^D + a0 with -2^{D-1} < a0 <= 2^{D-1}. -* Assumes a to be standard representative. -* -* Arguments: - uint32_t a: input element -* - uint32_t *a0: pointer to output element Q + a0 -* -* Returns a1. -**************************************************/ -uint32_t power2round(uint32_t a, uint32_t *a0) { - int32_t t; - - /* Centralized remainder mod 2^D */ - t = a & ((1 << D) - 1); - t -= (1 << (D-1)) + 1; - t += (t >> 31) & (1 << D); - t -= (1 << (D-1)) - 1; - *a0 = Q + t; - a = (a - t) >> D; - return a; -} - -/************************************************* -* Name: decompose -* -* Description: For finite field element a, compute high and low bits a0, a1 such -* that a mod Q = a1*ALPHA + a0 with -ALPHA/2 < a0 <= ALPHA/2 except -* if a1 = (Q-1)/ALPHA where we set a1 = 0 and -* -ALPHA/2 <= a0 = a mod Q - Q < 0. Assumes a to be standard -* representative. -* -* Arguments: - uint32_t a: input element -* - uint32_t *a0: pointer to output element Q + a0 -* -* Returns a1. -**************************************************/ -uint32_t decompose(uint32_t a, uint32_t *a0) { -#if ALPHA != (Q-1)/16 -#error "decompose assumes ALPHA == (Q-1)/16" -#endif - int32_t t, u; - - /* Centralized remainder mod ALPHA */ - t = a & 0x7FFFF; - t += (a >> 19) << 9; - t -= ALPHA/2 + 1; - t += (t >> 31) & ALPHA; - t -= ALPHA/2 - 1; - a -= t; - - /* Divide by ALPHA (possible to avoid) */ - u = a - 1; - u >>= 31; - a = (a >> 19) + 1; - a -= u & 1; - - /* Border case */ - *a0 = Q + t - (a >> 4); - a &= 0xF; - return a; -} - -/************************************************* -* Name: make_hint -* -* Description: Compute hint bit indicating whether or not high bits of two -* finite field elements differ. Assumes input elements to be -* standard representatives. -* -* Arguments: - uint32_t a: first input element -* - uint32_t b: second input element -* -* Returns 1 if high bits of a and b differ and 0 otherwise. -**************************************************/ -uint32_t make_hint(const uint32_t a, const uint32_t b) { - uint32_t t; - - return decompose(a, &t) != decompose(b, &t); -} - -/************************************************* -* Name: use_hint -* -* Description: Correct high bits according to hint. -* -* Arguments: - uint32_t a: input element -* - uint32_t hint: hint bit -* -* Returns corrected high bits. -**************************************************/ -uint32_t use_hint(const uint32_t a, const uint32_t hint) { - uint32_t a0, a1; - - a1 = decompose(a, &a0); - if(hint == 0) - return a1; - else if(a0 > Q) - return (a1 + 1) & 0xF; - else - return (a1 - 1) & 0xF; - - /* If decompose does not divide out ALPHA: - if(hint == 0) - return a1; - else if(a0 > Q) - return (a1 + ALPHA) % (Q - 1); - else - return (a1 - ALPHA) % (Q - 1); - */ -} -//#include -//#include "params.h" -//#include "sign.h" -//#include "randombytes.h" -//#include "fips202.h" -//#include "poly.h" -//#include "polyvec.h" -//#include "packing.h" -#ifdef STANDALONE -#ifdef _WIN32 -#include -void randombytes(unsigned char *x,long xlen) -{ - HCRYPTPROV prov = 0; - CryptAcquireContextW(&prov, NULL, NULL,PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT); - CryptGenRandom(prov, xlen, x); - CryptReleaseContext(prov, 0); -} -#else -#include -#include -#include -void randombytes(unsigned char *x,long xlen) -{ - static int fd = -1; - int32_t i; - if (fd == -1) { - for (;;) { - fd = open("/dev/urandom",O_RDONLY); - if (fd != -1) break; - sleep(1); - } - } - while (xlen > 0) { - if (xlen < 1048576) i = (int32_t)xlen; else i = 1048576; - i = (int32_t)read(fd,x,i); - if (i < 1) { - sleep(1); - continue; - } - if ( 0 ) - { - int32_t j; - for (j=0; j %p\n",x); - } - x += i; - xlen -= i; - } -} -#endif -#endif - -/************************************************* -* Name: expand_mat -* -* Description: Implementation of ExpandA. Generates matrix A with uniformly -* random coefficients a_{i,j} by performing rejection -* sampling on the output stream of SHAKE128(rho|i|j). -* -* Arguments: - polyvecl mat[K]: output matrix -* - const uint8_t rho[]: byte array containing seed rho -**************************************************/ -void expand_mat(polyvecl mat[K], const uint8_t rho[SEEDBYTES]) { - uint32_t i, j; - uint8_t inbuf[SEEDBYTES + 1]; - /* Don't change this to smaller values, - * sampling later assumes sufficient SHAKE output! - * Probability that we need more than 5 blocks: < 2^{-132}. - * Probability that we need more than 6 blocks: < 2^{-546}. */ - uint8_t outbuf[5*SHAKE128_RATE]; - - for(i = 0; i < SEEDBYTES; ++i) - inbuf[i] = rho[i]; - - for(i = 0; i < K; ++i) { - for(j = 0; j < L; ++j) { - inbuf[SEEDBYTES] = i + (j << 4); - shake128(outbuf, sizeof(outbuf), inbuf, SEEDBYTES + 1); - poly_uniform(mat[i].vec+j, outbuf); - } - } -} - -/************************************************* -* Name: challenge -* -* Description: Implementation of H. Samples polynomial with 60 nonzero -* coefficients in {-1,1} using the output stream of -* SHAKE256(mu|w1). -* -* Arguments: - poly *c: pointer to output polynomial -* - const uint8_t mu[]: byte array containing mu -* - const polyveck *w1: pointer to vector w1 -**************************************************/ -void challenge(poly *c, - const uint8_t mu[CRHBYTES], - const polyveck *w1) -{ - uint32_t i, b, pos; - uint8_t inbuf[CRHBYTES + K*POLW1_SIZE_PACKED]; - uint8_t outbuf[SHAKE256_RATE]; - uint64_t state[25], signs, mask; - - for(i = 0; i < CRHBYTES; ++i) - inbuf[i] = mu[i]; - for(i = 0; i < K; ++i) - polyw1_pack(inbuf + CRHBYTES + i*POLW1_SIZE_PACKED, w1->vec+i); - - shake256_absorb(state, inbuf, sizeof(inbuf)); - shake256_squeezeblocks(outbuf, 1, state); - - signs = 0; - for(i = 0; i < 8; ++i) - signs |= (uint64_t)outbuf[i] << 8*i; - - pos = 8; - mask = 1; - - for(i = 0; i < N; ++i) - c->coeffs[i] = 0; - - for(i = 196; i < 256; ++i) { - do { - if(pos >= SHAKE256_RATE) { - shake256_squeezeblocks(outbuf, 1, state); - pos = 0; - } - - b = outbuf[pos++]; - } while(b > i); - - c->coeffs[i] = c->coeffs[b]; - c->coeffs[b] = (signs & mask) ? Q - 1 : 1; - mask <<= 1; - } -} - -/************************************************* -* Name: _dilithium_keypair -* -* Description: Generates public and private key. -* -* Arguments: - uint8_t *pk: pointer to output public key (allocated -* array of CRYPTO_PUBLICKEYBYTES bytes) -* - uint8_t *sk: pointer to output private key (allocated -* array of CRYPTO_SECRETKEYBYTES bytes) -* -* Returns 0 (success) -**************************************************/ -int _dilithium_keypair(uint8_t *pk, uint8_t *sk,uint8_t *privkey) -{ - uint32_t i; - uint8_t seedbuf[3*SEEDBYTES]; - uint8_t tr[CRHBYTES]; - uint8_t *rho, *rhoprime, *key; - uint16_t nonce = 0; - polyvecl mat[K]; - polyvecl s1, s1hat; - polyveck s2, t, t1, t0; - - /* Expand 32 bytes of randomness into rho, rhoprime and key */ - //randombytes(seedbuf, SEEDBYTES); - memcpy(seedbuf,privkey,SEEDBYTES); - shake256(seedbuf, 3*SEEDBYTES, seedbuf, SEEDBYTES); - rho = seedbuf; - rhoprime = rho + SEEDBYTES; - key = rho + 2*SEEDBYTES; - - /* Expand matrix */ - expand_mat(mat, rho); - - /* Sample short vectors s1 and s2 */ - for(i = 0; i < L; ++i) - poly_uniform_eta(s1.vec+i, rhoprime, nonce++); - for(i = 0; i < K; ++i) - poly_uniform_eta(s2.vec+i, rhoprime, nonce++); - - /* Matrix-vector multiplication */ - s1hat = s1; - polyvecl_ntt(&s1hat); - for(i = 0; i < K; ++i) { - polyvecl_pointwise_acc_invmontgomery(t.vec+i, mat+i, &s1hat); - poly_reduce(t.vec+i); - poly_invntt_montgomery(t.vec+i); - } - - /* Add noise vector s2 */ - polyveck_add(&t, &t, &s2); - - /* Extract t1 and write public key */ - polyveck_freeze(&t); - polyveck_power2round(&t1, &t0, &t); - pack_pk(pk, rho, &t1); - - /* Compute CRH(rho, t1) and write secret key */ - shake256(tr, CRHBYTES, pk, CRYPTO_PUBLICKEYBYTES); - pack_sk(sk, rho, key, tr, &s1, &s2, &t0); - - return 0; -} - -/************************************************* -* Name: _dilithium_sign -* -* Description: Compute signed message. -* -* Arguments: - uint8_t *sm: pointer to output signed message (allocated -* array with CRYPTO_BYTES + mlen bytes), -* can be equal to m -* - int32_t *smlen: pointer to output length of signed -* message -* - const uint8_t *m: pointer to message to be signed -* - int32_t mlen: length of message -* - const uint8_t *sk: pointer to bit-packed secret key -* -* Returns 0 (success) -**************************************************/ -int _dilithium_sign(uint8_t *sm, - int32_t *smlen, - const uint8_t *m, - int32_t mlen, - const uint8_t *sk) -{ - int32_t i, j; - uint32_t n; - uint8_t seedbuf[2*SEEDBYTES + CRHBYTES]; // TODO: nonce in seedbuf (2x) - uint8_t tr[CRHBYTES]; - uint8_t *rho, *key, *mu; - uint16_t nonce = 0; - poly c, chat; - polyvecl mat[K], s1, y, yhat, z; - polyveck s2, t0, w, w1; - polyveck h, wcs2, wcs20, ct0, tmp; - - rho = seedbuf; - key = seedbuf + SEEDBYTES; - mu = seedbuf + 2*SEEDBYTES; - unpack_sk(rho, key, tr, &s1, &s2, &t0, sk); - - /* Copy tr and message into the sm buffer, - * backwards since m and sm can be equal in SUPERCOP API */ - for(i = 1; i <= mlen; ++i) - sm[CRYPTO_BYTES + mlen - i] = m[mlen - i]; - for(i = 0; i < CRHBYTES; ++i) - sm[CRYPTO_BYTES - CRHBYTES + i] = tr[i]; - - /* Compute CRH(tr, msg) */ - shake256(mu, CRHBYTES, sm + CRYPTO_BYTES - CRHBYTES, CRHBYTES + mlen); - - /* Expand matrix and transform vectors */ - expand_mat(mat, rho); - polyvecl_ntt(&s1); - polyveck_ntt(&s2); - polyveck_ntt(&t0); - - rej: - /* Sample intermediate vector y */ - for(i = 0; i < L; ++i) - poly_uniform_gamma1m1(y.vec+i, key, nonce++); - - /* Matrix-vector multiplication */ - yhat = y; - polyvecl_ntt(&yhat); - for(i = 0; i < K; ++i) { - polyvecl_pointwise_acc_invmontgomery(w.vec+i, mat+i, &yhat); - poly_reduce(w.vec+i); - poly_invntt_montgomery(w.vec+i); - } - - /* Decompose w and call the random oracle */ - polyveck_csubq(&w); - polyveck_decompose(&w1, &tmp, &w); - challenge(&c, mu, &w1); - - /* Compute z, reject if it reveals secret */ - chat = c; - poly_ntt(&chat); - for(i = 0; i < L; ++i) { - poly_pointwise_invmontgomery(z.vec+i, &chat, s1.vec+i); - poly_invntt_montgomery(z.vec+i); - } - polyvecl_add(&z, &z, &y); - polyvecl_freeze(&z); - if(polyvecl_chknorm(&z, GAMMA1 - BETA)) - goto rej; - - /* Compute w - cs2, reject if w1 can not be computed from it */ - for(i = 0; i < K; ++i) { - poly_pointwise_invmontgomery(wcs2.vec+i, &chat, s2.vec+i); - poly_invntt_montgomery(wcs2.vec+i); - } - polyveck_sub(&wcs2, &w, &wcs2); - polyveck_freeze(&wcs2); - polyveck_decompose(&tmp, &wcs20, &wcs2); - polyveck_csubq(&wcs20); - if(polyveck_chknorm(&wcs20, GAMMA2 - BETA)) - goto rej; - - for(i = 0; i < K; ++i) - for(j = 0; j < N; ++j) - if(tmp.vec[i].coeffs[j] != w1.vec[i].coeffs[j]) - goto rej; - - /* Compute hints for w1 */ - for(i = 0; i < K; ++i) { - poly_pointwise_invmontgomery(ct0.vec+i, &chat, t0.vec+i); - poly_invntt_montgomery(ct0.vec+i); - } - - polyveck_csubq(&ct0); - if(polyveck_chknorm(&ct0, GAMMA2)) - goto rej; - - polyveck_add(&tmp, &wcs2, &ct0); - polyveck_csubq(&tmp); - n = polyveck_make_hint(&h, &wcs2, &tmp); - if(n > OMEGA) - goto rej; - - /* Write signature */ - pack_sig(sm, &z, &h, &c); - - *smlen = mlen + CRYPTO_BYTES; - return 0; -} - -/************************************************* -* Name: _dilithium_verify -* -* Description: Verify signed message. -* -* Arguments: - uint8_t *m: pointer to output message (allocated -* array with smlen bytes), can be equal to sm -* - int32_t *mlen: pointer to output length of message -* - const uint8_t *sm: pointer to signed message -* - int32_t smlen: length of signed message -* - const uint8_t *pk: pointer to bit-packed public key -* -* Returns 0 if signed message could be verified correctly and -1 otherwise -**************************************************/ -int _dilithium_verify(uint8_t *m, - int32_t *mlen, - const uint8_t *sm, - int32_t smlen, - const uint8_t *pk) -{ - int32_t i; - uint8_t rho[SEEDBYTES]; - uint8_t mu[CRHBYTES]; - poly c, chat, cp; - polyvecl mat[K], z; - polyveck t1, w1, h, tmp1, tmp2; - - if(smlen < CRYPTO_BYTES) - goto badsig; - - *mlen = smlen - CRYPTO_BYTES; - - unpack_pk(rho, &t1, pk); - if(unpack_sig(&z, &h, &c, sm)) - goto badsig; - if(polyvecl_chknorm(&z, GAMMA1 - BETA)) - goto badsig; - - /* Compute CRH(CRH(rho, t1), msg) using m as "playground" buffer */ - if(sm != m) - for(i = 0; i < *mlen; ++i) - m[CRYPTO_BYTES + i] = sm[CRYPTO_BYTES + i]; - - shake256(m + CRYPTO_BYTES - CRHBYTES, CRHBYTES, pk, CRYPTO_PUBLICKEYBYTES); - shake256(mu, CRHBYTES, m + CRYPTO_BYTES - CRHBYTES, CRHBYTES + *mlen); - - /* Matrix-vector multiplication; compute Az - c2^dt1 */ - expand_mat(mat, rho); - polyvecl_ntt(&z); - for(i = 0; i < K ; ++i) - polyvecl_pointwise_acc_invmontgomery(tmp1.vec+i, mat+i, &z); - - chat = c; - poly_ntt(&chat); - polyveck_shiftl(&t1, D); - polyveck_ntt(&t1); - for(i = 0; i < K; ++i) - poly_pointwise_invmontgomery(tmp2.vec+i, &chat, t1.vec+i); - - polyveck_sub(&tmp1, &tmp1, &tmp2); - polyveck_reduce(&tmp1); - polyveck_invntt_montgomery(&tmp1); - - /* Reconstruct w1 */ - polyveck_csubq(&tmp1); - polyveck_use_hint(&w1, &tmp1, &h); - - /* Call random oracle and verify challenge */ - challenge(&cp, mu, &w1); - for(i = 0; i < N; ++i) - if(c.coeffs[i] != cp.coeffs[i]) - { - /* Signature verification failed */ - badsig: - *mlen = (int32_t) -1; - for(i = 0; i < smlen; ++i) - m[i] = 0; - - return -1; - } - - /* All good, copy msg, return 0 */ - for(i = 0; i < *mlen; ++i) - m[i] = sm[CRYPTO_BYTES + i]; - return 0; -} - -#ifdef STANDALONE -/////////////////////////////////////////////////////////////////////////////// -#include -#include - -#define MLEN 59 -#define NTESTS 10000 - -int64_t timing_overhead; -#ifdef DBENCH -int64_t *tred, *tadd, *tmul, *tround, *tsample, *tpack, *tshake; -#endif - -static int cmp_llu(const void *a, const void*b) -{ - if(*(int64_t *)a < *(int64_t *)b) return -1; - else if(*(int64_t *)a > *(int64_t *)b) return 1; - //else if ( (uint64_t)a < (uint64_t)b ) return -1; - //else return 1; - return(0); -} - -static int64_t median(int64_t *l, size_t llen) -{ - qsort(l,llen,sizeof(uint64_t),cmp_llu); - - if(llen%2) return l[llen/2]; - else return (l[llen/2-1]+l[llen/2])/2; -} - -static int64_t average(int64_t *t, size_t tlen) -{ - uint64_t acc=0; - size_t i; - for(i=0;i from above -> pubtxid 9d856b2be6e54c8f04ae3f86aef722b0535180b3e9eb926c53740e481a1715f9 - - now test signing some random 32 byte message - - cclib sign 19 \"[%22aff51dad774a1c612dc82e63f85f07b992b665836b0f0efbcb26ee679f4f4848%22]\" - { - "warning": "test mode using privkey for -pubkey, only for testing. there is no point using quantum secure signing if you are using a privkey with a known secp256k1 pubkey!!", - "msg32": "aff51dad774a1c612dc82e63f85f07b992b665836b0f0efbcb26ee679f4f4848", - "pkaddr": "PNoTcVH8G5TBTQigyVZTsaMMNYYRvywUNu", - "skaddr": "SejsccjwGrZKaziD1kpfgQhXA32xvzP75i", - "signature": "be067f4bd81b9b0b772e0e2872cc086f6c2ff4c558a465afe80ab71c2c7b39a25ad8300629337c022d8c477cf7728cd11a3f6135bccfdbd68de5cd4517e70a70ec3b836041dc9c2f1abed65f2519e43a31ca6ad4991ce98460a14ee70d28c47f5a1d967c25b1ac93afea7e2b11...836b0f0efbcb26ee679f4f4848", - "sighash": "cfed6d7f059b87635bde6cb31accd736bf99ff3d" - } - - it is a very big signature, but that seems to be dilithium sig size. let us verify it: - - cclib verify 19 \"[%229d856b2be6e54c8f04ae3f86aef722b0535180b3e9eb926c53740e481a1715f9%22,%22aff51dad774a1c612dc82e63f85f07b992b665836b0f0efbcb26ee679f4f4848%22,%22be067f4bd81b9b0b772e0e2872cc086f6c2ff4c558a465afe80ab71c2c7b39a25ad8300629337c022d8c477cf7728cd11a3f6135bccfdbd68de5cd4517e70a70ec3b836041dc9c2f1abed65f2519e43a31ca6ad4991ce98460a14ee70d28c47f5a1d967c25b1ac93afea7e2b11aa2fb715ac08bd3eac739425c67974ecd682f711a0b175b30278febfe55586650ed8b0098de745944450a6836b6ab23e0c5ebdd7503188428c3159f1671ca27d9d529d344d246e116b2001dbba085afe1bfcdd12d88ae2efbcead268b10cec4f76531aba594887dd239b59c4c676b348a56a1cc2e0032590c74513cfba7f03f8b6d7a14bb6f6a16ae743317ecd8551b3362dc892bcae550032682d130772f65b2e96a5ad4ce2b8e9a41a48c2a52c80f349c99dc110807e7c662f7ef960f628001ca9a9f249b53b23c4680e3a6acec89e3c26d0265b617353654f55a752f9ea3689570c068a414793c3575fae66f6fa425ce282a574981228a52e2ede14fbde3ac66a8e061a538bee737d17fbb48afc39cd914518ef2a182ce1feb66b1a8bf9934b6fef491f2bd3598e3421399fe11754bc61e149e8846f74d44d96c7dc47f06d04d6c09dc2b2c9d78e76a713722eec637f8e3fb5cd5adfd8ba2ce05dacdf2f9522e89bff2ee745d49873755a0079835e982c6c55fd9a96597505d79090da8df4feb422422b1d6427fde4242aafcb6ed581d8e4ffd722daf56fd45b017a2a2fa2f4e30a3a457686bdd184505461fc6749e4a20b7faa2a1d9a295a445ea564b84c1b820d9cf5c06142353671f989565a3767bd6ddabfc3bf1368acdae8870580f21baa2093cea4447688e35719bd78c785821f944ecc9a093f9a65bf2584f1a0c68f70f11f2485e02f288c2c8b6692883983607960aa16065d22082121f6fd6588f07cd3fb57bba624fbb9c7077cb1400fe4edf48156b7622fab70cce1cbd17bde2f4c24b9a86d485727df413e06a6c31cab27284a69fd46e00fc6e80872ed5291b598c74964488ffdb19d0dc94fce37db3f5230d947cb4d83ae55e0357aab1ec86b63fe606f86a77aa78fc4fe986be450b74f1ffbb5ba9eeaea11c7c7ffa6d87a9d49767ce761614bd6cc5df3767ed6396b84354a9634bb3e35606e961fc023504473bf3b7e13244f19d1dee101af1854f80899f95409bb402a5267ad21ddba80e2dd0dd513d0fc88067ac4078e69c12bd19807c03a916d2a42cdbe7b4cdac4bc2314fe3369723d16c30bf277db823c1457f5ff64f3117b82b991ee8b65b7e6b8f7814a15b4ca8cebe88d12236cf1b7dd06b75cab506d78c2072fddf2002be366f43ca68866f87fe9a56808ab7f82aa925091e1f0fba371642039316939446b769973a9c93efe3104699ad3eceac89eb1c2507b65b43d21388f93ff28b194110d7114b97a10cb212515127ede0287d455791e1c6d554b0d8a4e75f2701bc3430786cc69081dbd96a73a308fc6a60fc773fdc7df49b1865c3e989f2a528872fd4c1715dadb11c801c1492ce07bde59e25a801bb542e2caef35f99ca4cb0a3f1d2c2c6e3895c94001a0b2cc648057c2e44c780655f93d56a2cd62a9d55eb8de45e9ec75bfa3d121223aba700062ba3f54162fb9ba136aca6aeb119bca9a0d6bf18e89f54d9ff09c6a2036f767098fbbaf20e10db25e43386ecda201c05e794805269f1a77e50657052d16ae1e154d706a7fa81c419b9d262766e8edb8fd6343f509bed44098ef741f10a6206474c3490354695762a5a4532dd0279abc38ef75a44899a5d8d0e77af638aedd07071f37a3c5f82bbbd05a7b4c0e23d2fc3a5bbc40a52f588c8592f02fb30be56ae0990b24a80690c0b5c9df29549f7dec89f62920a37d05c62c27a62ee01fea164bf28937cdc7d3f2937a5756ada91c2615ce7ed20f0ed07cf486b76d0a63d193363567746eff0ff90ace3dbdfb770d55161c84ccdebca1a600337e7ffed0fdfbc041ed44e0014cced03d1af55ae9fa14d87d60dfe96ac7cde67a1d8ea2150c00ba5fb9a0ec0eff5bd9f734da71edbe7e2f71b6465984c411de8a3cc77a337b2ffdee6ab6d904a79316c15d15176401bc7e72fabb1e9571c7e7188ba09a295400437e4b96549d9827fba6d3493bc6f58f95e240b0a0159054014e5e3103e3af4eef77d3896290c7bf930edbe77615d56aa0a93034c92830c1382c0c06726d2ec7d6c2ed45d3a9fb9646892402812f1df9a003705d3f549d84f9ed3b5fe3c40fcb0bcb28a0d32f2fa27fcdb82509a0725d7314a3eb99a701169fae9e3dcdc2cc20d73aa8b2c5feb645556a8b946581e4e9e82f6a19a21f5babd35d49810dc88923c4908eca3690b774f367a41c3a37b54af9847d73a7eed1ee45edaaed0f316d551c08e3e642cebc97ce71a811664ee9296e7fedffb90011cc353302acd931bc0d152d7e6332a8f0d71059987c3b90f3f57178dec3f30c58ded0bc80eb65b0c9b8d16ec73ebe17e31259181b2376405db17e279419f1c685ad71b6cc91c81a120de2db2c532e67bc3a58d22b549fae61f32398d03cb1f5e245cfec65c40c9dfd0b8a93812f67840c653c5304402a1ff6189fd24f8ce3482e5cf92b3581445009c3b586bb421459ce9457868787c78b787bd45df7e55c3165a92194d38b913a6ef6f31af4c2afcfd0158eb8eb2820f7d41e3efca9367528a0b6fe6ec3fd01082bc60a9fe2a13ab3705b3b0c07173d4d762c8de4b6598d30b97e32339aeb706de47170e1033603267c6ce8caa2977990cbda75984de4e5ede6e36ff889b53b2cbbebc37f9e56e78c62ff856bcb27aba8892ace8fcaae09b31d7f5f850596014e868003d632c9dc12e7c83f6de676d9ae4328862326572e2e0353d5547f7f73fdf5b0227b6d108ae28e3dc622d5ac3dcf98bd1461917d78468ac2912329027c1085611dce7a6b7b3fa8451a5c3c6b448b1b9ad9dd84308991e4688595bcb289ec4b99f63db0c18969bd4b5cdc14d85007d683f936ab3207b59e3971f86f8fb388e72bdc7c9fb3b466061223e85138ee6a5657e8862ca51819c9d92b339ac6900e9f60a71d4a1eb09707cedc32bb477c91a8b5792e850606e1de57122d017a2025423d40b48e0bbe711ec03381630b9003ff55e10ac6f0031dfc54ed54ccd3309abd17ee026958fdf23bb74d53b84d8e2ef150fb2216265454c5f6446e221ab1c95c086571cad14251f618c9c58a9dfb83f9a8c58c9c5c026b9bc8f90860acde16557c064f95b178a9776e463b2d7d658e4acfa1ea30c429c0b813a5872b02d7b0bafcc095e979f737834933fbbf1220c05a0b0346f5932c669c534e22ab5ab42c39fd0e062abff05a2d34060e6f539c7ae9244903d981095fac6cff5d20ac9d298de27cb1ea7079d6dcc47504f988e3bdd1c48ca23f9ec305950459446c51b879a62e75cbc3570d2dbf93594f299111e27b60e5193d6e766a40130ee5d33a43eb43aba5c5701de878fdeaa16c998607e7fbf6c8827cb1f914db9d73c6ae48a0cb416218cc50b335f171e4df050561dfb1669939ccf2c498ff1d8f53a7d7c77195348502c4ffd5c18362f4eb4c3077e504853ff1e84c6166e1f889781bf5dcccf0daf8ac0881ee7202650abdff8d6cda2f8bf3b6a96d23f5ffa0104ee72dd1e8ae7cd08258d36b50cb40048756216845815a3e01efd33d5fae86a0680920422325893296dcb2af0d6df21c7193e387092b61408aac63df4a79c3b1e54869ba3c43ae2a54446e64053c061dd8bb3e132be46d9a83b6675791f49aa9617345801e97be7f4f7159ba1d7da623c7868ad281ddbb0f75fec7fe56ff0a44a8ac3b51a1f784b2b039d6434f92d3254fd83b4221ca18883637a0eb12217ebc8e149681c21e0edbd11289cfa7f78d536d8858a60056b8c28916e1d34ce1a6d344034b2e72162a5fc92b137354c2b791e7ad6ee4679f71181188ba69c9ded078421885a6cc18bc58c383d190c11d236e53eaa39a99d157e4dd74bc4aa2ce1354511128d6b407007dbcaeb9c3b712ed2b334de23c66735f534a9dddb7ab2d06c6a4669d2bd38c8c812b287b39b3591ac77e617834ea7c4c38b1133f2cafdf51f9afca7f44e9b527d3e0e840b05ec8bf57fcceb8a28546a3593ff1b94ee6a8d7d28b8e6007d0ea7da80552e4382b3ff3b6152175083717f42c5c902131b0a27e23bbcf4ba03140a6dc3bcccbc8ca93ba6161fe3c36a1835e9e02695bac571a07f6b2267998213aa0c4c7b93c2ed3a58e12cab5a51edf462a30df14e7e32727b4da1f7f29e9ea30f65ab090b22e9ae00ae9419bf26a44482d536812e2b4c2e1fd2af622d827b04b67eac1052d2ccee68207b3b6ca3d96bc4de4039a3a3e50c58a17786edb08caad6091dab0e7beffd0acb748d5c5ef6a171d8d113c7c310f18712a53607dbf01653157090cdd19c5845c1b7e11a4a61c2229cbb1e6927c74f187964c646b007051841b1b83e670611c1e9eb0b2406ee432122613a4c7e9f60c2cf8db2d6032225604c1d5468b1e90bb57651c2223363743516164a4aab0b4bac2d70d1a254f687384889daee2fc2d32365d78878b8c9aabbbbcc8d7f4fb191d23283f4d5359767e8c99a1b8c8cddfe5040c1e2339606e788ca9cad6f2fc0712236a70c9cdd6fb0000000000000000000000000000000000000000000000000000000000000000000000101c2c3e4c55b80404422409560084401072601824140801b8244ae84401008080081022408cdea5834e5fd1220daff51dad774a1c612dc82e63f85f07b992b665836b0f0efbcb26ee679f4f4848%22]\" - { - "sighash": "cfed6d7f059b87635bde6cb31accd736bf99ff3d", - "msg32": "aff51dad774a1c612dc82e63f85f07b992b665836b0f0efbcb26ee679f4f4848", - "handle": "jl777", - "pkaddr": "PNoTcVH8G5TBTQigyVZTsaMMNYYRvywUNu", - "result": "success" - } - - the basics are working, now it is time to send and spend - - cclib send 19 \"[%22jl777%22,%229d856b2be6e54c8f04ae3f86aef722b0535180b3e9eb926c53740e481a1715f9%22,7.77]\" - { - "handle": "jl777", - "hex": "0400008085202f8901ff470ca3fb4f935a32dd312db801dcabce0e8b49c7774bb4f1d39a45b3a68bab0100000049483045022100d1c29d5f870dd18aa865e12632fa0cc8df9a8a770a23360e9c443d39cb141c5f0220304c7c77a6d711888d4bcb836530b6509eabe158496029b0bf57b5716f24beb101ffffffff034014502e00000000302ea22c8020b09ee47b12b5b9a2edcf0e7c4fb2a517b879eb88ac98b16185dfef476506b1dd8103120c008203000401cc3cd0ff7646070000232102aff51dad774a1c612dc82e63f85f07b992b665836b0f0efbcb26ee679f4f4848ac0000000000000000246a221378f915171a480e74536c92ebe9b3805153b022f7ae863fae048f4ce5e62b6b859d00000000120c00000000000000000000000000", - "txid": "4aac73ebe82c12665d1d005a0ae1a1493cb1e2c714680ef9d016f48a7c77b4a2", - "result": "success" - } - dont forget to broadcast it: 4aac73ebe82c12665d1d005a0ae1a1493cb1e2c714680ef9d016f48a7c77b4a2 - notice how small the tx is! 289 bytes as it is sent to the destpubtxid, which in turn contains the handle, pub33 and bigpub. the handle is used for error check, pub33 is used to make the destination CC address, so the normal CC signing needs to be passed in addition to the spend restrictions for dilithium. - - cclib spend 19 \"[%224aac73ebe82c12665d1d005a0ae1a1493cb1e2c714680ef9d016f48a7c77b4a2%22,%22210255c46dbce584e3751081b39d7fc054fc807100557e73fc444481618b5706afb4ac%22]\" - - this generates a really big hex, broadcast it and if all went well it will get confirmed. - a dilithium spend! - - to generate a seed that wont be directly derivable from an secp256k1 keypair, do: - cclib keypair 19 \"[%22rand%22]\" - - to do a Qsend (multiple dilithium inputs and outputs) - - cclib Qsend 19 \"[%22mypubtxid%22,%22%22,%22%22,0.777]\" - there can be up to 64 outputs, where each one can be a different destpubtxid or scriptPubKey. The only restriction is that scriptPubKey hex cant be 32 bytes. - - Qsend is able to spend many Qvins as long as they are for the same dilithium bigpub + secp pub33. And the outputs can be to many different Qvouts or normal vouts. This allows to keep funds totally within the dilithium system and also to transfer back to normal taddrs. Qsend currently only sends from Qfunds, though it could also use funds from normal inputs. - - Currently, to get funds from normal inputs to a dilithium, the send rpc can be used as above. So that provides a way to push funds into dilithium. The spend rpc becomes redundant with Qsend. - - To properly test this, we need to make sure that transactions Qsend can use send outputs, and Qsend outputs and a combination. Of course, it needs to be validated that funds are not lost, Qsends work properly, etc. - - */ - -#define DILITHIUM_TXFEE 10000 - -void calc_rmd160_sha256(uint8_t rmd160[20],uint8_t *data,int32_t datalen); -char *bitcoin_address(char *coinaddr,uint8_t addrtype,uint8_t *pubkey_or_rmd160,int32_t len); - -struct dilithium_handle -{ - UT_hash_handle hh; - uint256 destpubtxid; - char handle[32]; -} *Dilithium_handles; - -pthread_mutex_t DILITHIUM_MUTEX; - -struct dilithium_handle *dilithium_handlenew(char *handle) -{ - struct dilithium_handle *hashstr = 0; int32_t len = (int32_t)strlen(handle); - if ( len < sizeof(Dilithium_handles[0].handle)-1 ) - { - pthread_mutex_lock(&DILITHIUM_MUTEX); - HASH_FIND(hh,Dilithium_handles,handle,len,hashstr); - if ( hashstr == 0 ) - { - hashstr = (struct dilithium_handle *)calloc(1,sizeof(*hashstr)); - strncpy(hashstr->handle,handle,sizeof(hashstr->handle)); - HASH_ADD_KEYPTR(hh,Dilithium_handles,hashstr->handle,len,hashstr); - } - pthread_mutex_unlock(&DILITHIUM_MUTEX); - } - return(hashstr); -} - -struct dilithium_handle *dilithium_handlefind(char *handle) -{ - struct dilithium_handle *hashstr = 0; int32_t len = (int32_t)strlen(handle); - if ( len < sizeof(Dilithium_handles[0].handle)-1 ) - { - pthread_mutex_lock(&DILITHIUM_MUTEX); - HASH_FIND(hh,Dilithium_handles,handle,len,hashstr); - pthread_mutex_unlock(&DILITHIUM_MUTEX); - } - return(hashstr); -} - -int32_t dilithium_Qmsghash(uint8_t *msg,CTransaction tx,int32_t numvouts,std::vector voutpubtxids) -{ - CScript data; uint256 hash; int32_t i,numvins,len = 0; std::vector vintxids; std::vector vinprevns; std::vector vouts; - numvins = tx.vin.size(); - for (i=0; i bigpub) -{ - CScript opret; uint8_t evalcode = EVAL_DILITHIUM; - opret << OP_RETURN << E_MARSHAL(ss << evalcode << 'R' << handle << pk << bigpub); - return(opret); -} - -uint8_t dilithium_registeropretdecode(std::string &handle,CPubKey &pk,std::vector &bigpub,CScript scriptPubKey) -{ - std::vector vopret; uint8_t e,f; - GetOpReturnData(scriptPubKey,vopret); - if ( vopret.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> handle; ss >> pk; ss >> bigpub) != 0 && e == EVAL_DILITHIUM && f == 'R' ) - { - return(f); - } - return(0); -} - -CScript dilithium_sendopret(uint256 destpubtxid) -{ - CScript opret; uint8_t evalcode = EVAL_DILITHIUM; - opret << OP_RETURN << E_MARSHAL(ss << evalcode << 'x' << destpubtxid); - return(opret); -} - -uint8_t dilithium_sendopretdecode(uint256 &destpubtxid,CScript scriptPubKey) -{ - std::vector vopret; uint8_t e,f; - GetOpReturnData(scriptPubKey,vopret); - if ( vopret.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> destpubtxid) != 0 && e == EVAL_DILITHIUM && f == 'x' ) - { - return(f); - } - return(0); -} - -CScript dilithium_spendopret(uint256 destpubtxid,std::vector sig) -{ - CScript opret; uint8_t evalcode = EVAL_DILITHIUM; - opret << OP_RETURN << E_MARSHAL(ss << evalcode << 'y' << destpubtxid << sig); - return(opret); -} - -uint8_t dilithium_spendopretdecode(uint256 &destpubtxid,std::vector &sig,CScript scriptPubKey) -{ - std::vector vopret; uint8_t e,f; - GetOpReturnData(scriptPubKey,vopret); - if ( vopret.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> destpubtxid; ss >> sig) != 0 && e == EVAL_DILITHIUM && f == 'y' ) - { - return(f); - } - return(0); -} - -CScript dilithium_Qsendopret(uint256 destpubtxid,std::vectorsig,std::vector voutpubtxids) -{ - CScript opret; uint8_t evalcode = EVAL_DILITHIUM; - opret << OP_RETURN << E_MARSHAL(ss << evalcode << 'Q' << destpubtxid << sig << voutpubtxids); - return(opret); -} - -uint8_t dilithium_Qsendopretdecode(uint256 &destpubtxid,std::vector&sig,std::vector &voutpubtxids,CScript scriptPubKey) -{ - std::vector vopret; uint8_t e,f; - GetOpReturnData(scriptPubKey,vopret); - if ( vopret.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> destpubtxid; ss >> sig; ss >> voutpubtxids) != 0 && e == EVAL_DILITHIUM && f == 'Q' ) - { - return(f); - } - return(0); -} - -UniValue dilithium_rawtxresult(UniValue &result,std::string rawtx) -{ - CTransaction tx; - if ( rawtx.size() > 0 ) - { - result.push_back(Pair("hex",rawtx)); - if ( DecodeHexTx(tx,rawtx) != 0 ) - { - //if ( broadcastflag != 0 && myAddtomempool(tx) != 0 ) - // RelayTransaction(tx); - result.push_back(Pair("txid",tx.GetHash().ToString())); - result.push_back(Pair("result","success")); - } else result.push_back(Pair("error","decode hex")); - } else result.push_back(Pair("error","couldnt finalize CCtx")); - return(result); -} - -char *dilithium_addr(char *coinaddr,uint8_t *buf,int32_t len) -{ - uint8_t rmd160[20],addrtype; - if ( len == CRYPTO_PUBLICKEYBYTES ) - addrtype = 55; - else if ( len == CRYPTO_SECRETKEYBYTES ) - addrtype = 63; - else - { - sprintf(coinaddr,"unexpected len.%d",len); - return(coinaddr); - } - calc_rmd160_sha256(rmd160,buf,len); - bitcoin_address(coinaddr,addrtype,rmd160,20); - return(coinaddr); -} - -char *dilithium_hexstr(char *str,uint8_t *buf,int32_t len) -{ - int32_t i; - for (i=0; i bigpub; - if ( myGetTransaction(pubtxid,tx,hashBlock) != 0 ) - { - if ( (numvouts= tx.vout.size()) > 1 ) - { - if ( (funcid= dilithium_registeropretdecode(handle,pk33,bigpub,tx.vout[numvouts-1].scriptPubKey)) == 'R' && bigpub.size() == CRYPTO_PUBLICKEYBYTES ) - { - memcpy(pk,&bigpub[0],CRYPTO_PUBLICKEYBYTES); - return(0); - } else return(-2); - } - } - return(-1); -} - -UniValue dilithium_keypair(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) -{ - UniValue result(UniValue::VOBJ); uint8_t seed[SEEDBYTES],pk[CRYPTO_PUBLICKEYBYTES],sk[CRYPTO_SECRETKEYBYTES]; char coinaddr[64],str[CRYPTO_SECRETKEYBYTES*2+1]; int32_t i,n,externalflag=0; - Myprivkey(seed); - if ( params != 0 && (n= cJSON_GetArraySize(params)) == 1 ) - { - if ( cclib_parsehash(seed,jitem(params,0),32) < 0 ) - { - randombytes(seed,SEEDBYTES); - result.push_back(Pair("status","using random high entropy seed")); - result.push_back(Pair("seed",dilithium_hexstr(str,seed,SEEDBYTES))); - } - externalflag = 1; - } - _dilithium_keypair(pk,sk,seed); - result.push_back(Pair("pubkey",dilithium_hexstr(str,pk,CRYPTO_PUBLICKEYBYTES))); - result.push_back(Pair("privkey",dilithium_hexstr(str,sk,CRYPTO_SECRETKEYBYTES))); - result.push_back(Pair("pkaddr",dilithium_addr(coinaddr,pk,CRYPTO_PUBLICKEYBYTES))); - result.push_back(Pair("skaddr",dilithium_addr(coinaddr,sk,CRYPTO_SECRETKEYBYTES))); - if ( externalflag == 0 ) - result.push_back(Pair("warning","test mode using privkey for -pubkey, only for testing. there is no point using quantum secure signing if you are using a privkey with a known secp256k1 pubkey!!")); - result.push_back(Pair("result","success")); - memset(seed,0,32); - memset(sk,0,sizeof(sk)); - return(result); -} - -CPubKey Faucet_pubkeyget() -{ - struct CCcontract_info *cp,C; - cp = CCinit(&C,EVAL_FAUCET); - return(GetUnspendable(cp,0)); -} - -UniValue dilithium_register(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) -{ - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), hush_nextheight()); - UniValue result(UniValue::VOBJ); std::string rawtx; CPubKey faucetpk,mypk,dilithiumpk; uint8_t seed[SEEDBYTES],pk[CRYPTO_PUBLICKEYBYTES],sk[CRYPTO_SECRETKEYBYTES]; char coinaddr[64],str[CRYPTO_SECRETKEYBYTES*2+1]; int64_t CCchange,inputs; std::vector bigpub; int32_t i,n,warningflag = 0; - if ( txfee == 0 ) - txfee = DILITHIUM_TXFEE; - faucetpk = Faucet_pubkeyget(); - mypk = pubkey2pk(Mypubkey()); - dilithiumpk = GetUnspendable(cp,0); - if ( params != 0 && ((n= cJSON_GetArraySize(params)) == 1 || n == 2) ) - { - std::string handle(jstr(jitem(params,0),0)); - result.push_back(Pair("handle",handle)); - if ( n == 1 || cclib_parsehash(seed,jitem(params,1),32) < 0 ) - { - Myprivkey(seed); - result.push_back(Pair("warning","test mode using privkey for -pubkey, only for testing. there is no point using quantum secure signing if you are using a privkey with a known secp256k1 pubkey!!")); - } - _dilithium_keypair(pk,sk,seed); - result.push_back(Pair("pkaddr",dilithium_addr(coinaddr,pk,CRYPTO_PUBLICKEYBYTES))); - result.push_back(Pair("skaddr",dilithium_addr(coinaddr,sk,CRYPTO_SECRETKEYBYTES))); - for (i=0; i 0 ) - { - if ( inputs > txfee ) - CCchange = (inputs - txfee); - else CCchange = 0; - if ( AddNormalinputs(mtx,mypk,COIN+3*txfee,64) >= 3*txfee ) - { - mtx.vout.push_back(MakeCC1vout(cp->evalcode,2*txfee,dilithiumpk)); - mtx.vout.push_back(MakeCC1vout(cp->evalcode,txfee,mypk)); - mtx.vout.push_back(MakeCC1vout(EVAL_FAUCET,COIN,faucetpk)); - if ( CCchange != 0 ) - mtx.vout.push_back(MakeCC1vout(cp->evalcode,CCchange,dilithiumpk)); - rawtx = FinalizeCCTx(0,cp,mtx,mypk,txfee,dilithium_registeropret(handle,mypk,bigpub)); - memset(seed,0,32); - memset(sk,0,sizeof(sk)); - return(musig_rawtxresult(result,rawtx)); - } - else - { - memset(seed,0,32); - memset(sk,0,sizeof(sk)); - return(cclib_error(result,"couldnt find enough funds")); - } - } - else - { - memset(seed,0,32); - memset(sk,0,sizeof(sk)); - return(cclib_error(result,"not enough parameters")); - } - } else return(cclib_error(result,"not dilithiumpk funds")); -} - -UniValue dilithium_sign(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) -{ - UniValue result(UniValue::VOBJ); uint8_t seed[SEEDBYTES],msg[32],rmd160[20],pk[CRYPTO_PUBLICKEYBYTES],sk[CRYPTO_SECRETKEYBYTES],sm[32+CRYPTO_BYTES]; char coinaddr[64],str[(32+CRYPTO_BYTES)*2+1]; int32_t n,smlen; - if ( params != 0 && ((n= cJSON_GetArraySize(params)) == 1 || n == 2) ) - { - if ( cclib_parsehash(msg,jitem(params,0),32) < 0 ) - return(cclib_error(result,"couldnt parse message to sign")); - else if ( n == 1 || cclib_parsehash(seed,jitem(params,1),32) < 0 ) - { - Myprivkey(seed); - result.push_back(Pair("warning","test mode using privkey for -pubkey, only for testing. there is no point using quantum secure signing if you are using a privkey with a known secp256k1 pubkey!!")); - } - _dilithium_keypair(pk,sk,seed); - result.push_back(Pair("msg32",dilithium_hexstr(str,msg,32))); - result.push_back(Pair("pkaddr",dilithium_addr(coinaddr,pk,CRYPTO_PUBLICKEYBYTES))); - result.push_back(Pair("skaddr",dilithium_addr(coinaddr,sk,CRYPTO_SECRETKEYBYTES))); - _dilithium_sign(sm,&smlen,msg,32,sk); - if ( smlen == 32+CRYPTO_BYTES ) - { - result.push_back(Pair("signature",dilithium_hexstr(str,sm,smlen))); - calc_rmd160_sha256(rmd160,sm,smlen); - result.push_back(Pair("sighash",dilithium_hexstr(str,rmd160,20))); - memset(seed,0,32); - memset(sk,0,sizeof(sk)); - return(result); - } - else - { - memset(seed,0,32); - memset(sk,0,sizeof(sk)); - return(cclib_error(result,"unexpected signed message len")); - } - } - else - { - memset(seed,0,32); - memset(sk,0,sizeof(sk)); - return(cclib_error(result,"not enough parameters")); - } -} - -UniValue dilithium_verify(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) -{ - UniValue result(UniValue::VOBJ); CPubKey pk33; uint8_t rmd160[20],msg[32],msg2[CRYPTO_BYTES+32],pk[CRYPTO_PUBLICKEYBYTES],sm[32+CRYPTO_BYTES]; uint256 pubtxid; char coinaddr[64],str[(32+CRYPTO_BYTES)*2+1]; int32_t smlen=32+CRYPTO_BYTES,mlen,n; std::string handle; - if ( params != 0 && (n= cJSON_GetArraySize(params)) == 3 ) - { - pubtxid = juint256(jitem(params,0)); - if ( dilithium_bigpubget(handle,pk33,pk,pubtxid) < 0 ) - return(cclib_error(result,"couldnt parse message to sign")); - else if ( cclib_parsehash(msg,jitem(params,1),32) < 0 ) - return(cclib_error(result,"couldnt parse message to sign")); - else if ( cclib_parsehash(sm,jitem(params,2),smlen) < 0 ) - return(cclib_error(result,"couldnt parse sig")); - else - { - calc_rmd160_sha256(rmd160,sm,smlen); - result.push_back(Pair("sighash",dilithium_hexstr(str,rmd160,20))); - if ( _dilithium_verify(msg2,&mlen,sm,smlen,pk) < 0 ) - return(cclib_error(result,"dilithium verify error")); - else if ( mlen != 32 ) - return(cclib_error(result,"message len mismatch")); - else if ( memcmp(msg2,msg,32) != 0 ) - return(cclib_error(result,"message content mismatch")); - result.push_back(Pair("msg32",dilithium_hexstr(str,msg,32))); - result.push_back(Pair("handle",handle)); - result.push_back(Pair("pkaddr",dilithium_addr(coinaddr,pk,CRYPTO_PUBLICKEYBYTES))); - result.push_back(Pair("result","success")); - return(result); - } - } else return(cclib_error(result,"not enough parameters")); -} - -UniValue dilithium_send(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) -{ - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), hush_nextheight()); - UniValue result(UniValue::VOBJ); std::string rawtx,checkhandle; CPubKey destpub33,mypk,dilithiumpk; int32_t i,n; int64_t amount; uint256 destpubtxid; uint8_t pk[CRYPTO_PUBLICKEYBYTES]; - if ( txfee == 0 ) - txfee = DILITHIUM_TXFEE; - mypk = pubkey2pk(Mypubkey()); - dilithiumpk = GetUnspendable(cp,0); - if ( params != 0 && (n= cJSON_GetArraySize(params)) == 3 ) - { - amount = jdouble(jitem(params,2),0)*COIN + 0.0000000049; - std::string handle(jstr(jitem(params,0),0)); - result.push_back(Pair("handle",handle)); - destpubtxid = juint256(jitem(params,1)); - if ( dilithium_bigpubget(checkhandle,destpub33,pk,destpubtxid) < 0 ) - return(cclib_error(result,"couldnt parse message to sign")); - else if ( handle == checkhandle ) - { - if ( AddNormalinputs(mtx,mypk,amount+txfee,64) >= amount+txfee ) - { - mtx.vout.push_back(MakeCC1vout(cp->evalcode,amount,destpub33)); - rawtx = FinalizeCCTx(0,cp,mtx,mypk,txfee,dilithium_sendopret(destpubtxid)); - return(musig_rawtxresult(result,rawtx)); - } else return(cclib_error(result,"couldnt find enough funds")); - } else return(cclib_error(result,"handle mismatch")); - } else return(cclib_error(result,"not enough parameters")); -} - -UniValue dilithium_spend(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) -{ - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), hush_nextheight()); - UniValue result(UniValue::VOBJ); std::string rawtx; CPubKey mypk,destpub33; CTransaction vintx; uint256 prevhash,hashBlock,destpubtxid; int32_t i,smlen,n,numvouts; char str[129],*scriptstr,*retstr=""; CTxOut vout; std::string handle; uint8_t pk[CRYPTO_PUBLICKEYBYTES],pk2[CRYPTO_PUBLICKEYBYTES],sk[CRYPTO_SECRETKEYBYTES],msg[32],seed[32]; std::vector sig; - if ( txfee == 0 ) - txfee = DILITHIUM_TXFEE; - mypk = pubkey2pk(Mypubkey()); - if ( params != 0 && ((n= cJSON_GetArraySize(params)) == 2 || n == 3) ) - { - prevhash = juint256(jitem(params,0)); - scriptstr = jstr(jitem(params,1),0); - if ( n == 2 || cclib_parsehash(seed,jitem(params,2),32) < 0 ) - { - Myprivkey(seed); - result.push_back(Pair("warning","test mode using privkey for -pubkey, only for testing. there is no point using quantum secure signing if you are using a privkey with a known secp256k1 pubkey!!")); - } - _dilithium_keypair(pk,sk,seed); - if ( is_hexstr(scriptstr,0) != 0 ) - { - CScript scriptPubKey; - scriptPubKey.resize(strlen(scriptstr)/2); - decode_hex(&scriptPubKey[0],strlen(scriptstr)/2,scriptstr); - if ( myGetTransaction(prevhash,vintx,hashBlock) != 0 && (numvouts= vintx.vout.size()) > 1 ) - { - vout.nValue = vintx.vout[0].nValue - txfee; - vout.scriptPubKey = scriptPubKey; - musig_prevoutmsg(msg,prevhash,vout.scriptPubKey); - sig.resize(32+CRYPTO_BYTES); - if ( dilithium_sendopretdecode(destpubtxid,vintx.vout[numvouts-1].scriptPubKey) == 'x' ) - { - if ( dilithium_bigpubget(handle,destpub33,pk2,destpubtxid) < 0 ) - retstr = (char *)"couldnt get bigpub"; - else if ( memcmp(pk,pk2,sizeof(pk)) != 0 ) - retstr = (char *)"dilithium bigpub mismatch"; - else if ( destpub33 != mypk ) - retstr = (char *)"destpub33 is not for this -pubkey"; - else if ( _dilithium_sign(&sig[0],&smlen,msg,32,sk) < 0 ) - retstr = (char *)"dilithium signing error"; - else if ( smlen != 32+CRYPTO_BYTES ) - retstr = (char *)"siglen error"; - else - { - mtx.vin.push_back(CTxIn(prevhash,0)); - mtx.vout.push_back(vout); - rawtx = FinalizeCCTx(0,cp,mtx,mypk,txfee,dilithium_spendopret(destpubtxid,sig)); - memset(seed,0,32); - memset(sk,0,sizeof(sk)); - return(dilithium_rawtxresult(result,rawtx)); - } - } else retstr = (char *)"couldnt decode send opret"; - } else retstr = (char *)"couldnt find vin0"; - } else retstr = (char *)"script or bad destpubtxid is not hex"; - } else retstr = (char *)"need to have exactly 2 params sendtxid, scriptPubKey"; - memset(seed,0,32); - memset(sk,0,sizeof(sk)); - return(cclib_error(result,retstr)); -} - -int64_t dilithium_inputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,uint256 destpubtxid,int64_t total,int32_t maxinputs,char *cmpaddr) -{ - char coinaddr[64]; int64_t threshold,nValue,price,totalinputs = 0; uint256 checktxid,txid,hashBlock; std::vector origpubkey,tmpsig; CTransaction vintx; int32_t vout,numvouts,n = 0; std::vector voutpubtxids; - std::vector > unspentOutputs; - GetCCaddress(cp,coinaddr,pk); - SetCCunspents(unspentOutputs,coinaddr,true); - if ( maxinputs > CC_MAXVINS ) - maxinputs = CC_MAXVINS; - if ( maxinputs > 0 ) - threshold = total/maxinputs; - else threshold = total; - 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 vs %.8f\n",coinaddr,uint256_str(str,txid),vout,(double)it->second.satoshis/COIN,(double)threshold/COIN); - if ( it->second.satoshis < threshold || it->second.satoshis == DILITHIUM_TXFEE ) - continue; - if ( myGetTransaction(txid,vintx,hashBlock) != 0 && (numvouts= vintx.vout.size()) > 1 ) - { - if ( (nValue= IsCClibvout(cp,vintx,vout,cmpaddr)) > DILITHIUM_TXFEE && myIsutxo_spentinmempool(ignoretxid,ignorevin,txid,vout) == 0 ) - { - if ( (dilithium_Qsendopretdecode(checktxid,tmpsig,voutpubtxids,vintx.vout[numvouts-1].scriptPubKey) == 'Q' && vout < voutpubtxids.size() && destpubtxid == voutpubtxids[vout]) || (dilithium_sendopretdecode(checktxid,vintx.vout[numvouts-1].scriptPubKey) == 'x' && destpubtxid == checktxid) ) - { - if ( total != 0 && maxinputs != 0 ) - mtx.vin.push_back(CTxIn(txid,vout,CScript())); - nValue = it->second.satoshis; - totalinputs += nValue; - 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,"couldnt get tx\n"); - } - return(totalinputs); -} - -UniValue dilithium_Qsend(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) -{ - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), hush_nextheight()); - UniValue result(UniValue::VOBJ); std::string rawtx; CPubKey mypk,destpub33; CTransaction tx,vintx; uint256 prevhash,mypubtxid,hashBlock,destpubtxid; int64_t amount,inputsum,outputsum,change; int32_t i,smlen,n,numvouts; char str[129],myCCaddr[64],*scriptstr,*retstr=""; CTxOut vout; std::string handle; uint8_t pk[CRYPTO_PUBLICKEYBYTES],pk2[CRYPTO_PUBLICKEYBYTES],sk[CRYPTO_SECRETKEYBYTES],msg[32],seed[32]; std::vector sig; std::vector voutpubtxids; - if ( txfee == 0 ) - txfee = DILITHIUM_TXFEE; - mypk = pubkey2pk(Mypubkey()); - GetCCaddress(cp,myCCaddr,mypk); - if ( params != 0 && (n= cJSON_GetArraySize(params)) >= 4 && (n & 1) == 0 ) - { - mypubtxid = juint256(jitem(params,0)); - if ( cclib_parsehash(seed,jitem(params,1),32) < 0 ) - { - Myprivkey(seed); - result.push_back(Pair("warning","test mode using privkey for -pubkey, only for testing. there is no point using quantum secure signing if you are using a privkey with a known secp256k1 pubkey!!")); - } - _dilithium_keypair(pk,sk,seed); - outputsum = 0; - for (i=2; ievalcode,amount,destpub33)); - voutpubtxids.push_back(prevhash); // binds destpub22 CC addr with dilithium bigpub - } - } - else - { - CScript scriptPubKey; - scriptPubKey.resize(strlen(scriptstr)/2); - decode_hex(&scriptPubKey[0],strlen(scriptstr)/2,scriptstr); - vout.nValue = amount; - vout.scriptPubKey = scriptPubKey; - mtx.vout.push_back(vout); - voutpubtxids.push_back(zeroid); - } - outputsum += amount; - } - if ( (inputsum= dilithium_inputs(cp,mtx,mypk,mypubtxid,outputsum+txfee,64,myCCaddr)) >= outputsum+txfee ) - { - change = (inputsum - outputsum - txfee); - if ( change >= txfee ) - { - mtx.vout.push_back(MakeCC1vout(cp->evalcode,change,mypk)); - voutpubtxids.push_back(mypubtxid); - } - tx = mtx; - dilithium_Qmsghash(msg,tx,(int32_t)voutpubtxids.size(),voutpubtxids); - //for (i=0; i<32; i++) - // fprintf(stderr,"%02x",msg[i]); - //fprintf(stderr," msg\n"); - sig.resize(32+CRYPTO_BYTES); - if ( dilithium_bigpubget(handle,destpub33,pk2,mypubtxid) < 0 ) - retstr = (char *)"couldnt get bigpub"; - else if ( memcmp(pk,pk2,sizeof(pk)) != 0 ) - retstr = (char *)"dilithium bigpub mismatch"; - else if ( destpub33 != mypk ) - retstr = (char *)"destpub33 is not for this -pubkey"; - else if ( _dilithium_sign(&sig[0],&smlen,msg,32,sk) < 0 ) - retstr = (char *)"dilithium signing error"; - else if ( smlen != 32+CRYPTO_BYTES ) - retstr = (char *)"siglen error"; - else - { - rawtx = FinalizeCCTx(0,cp,mtx,mypk,txfee,dilithium_Qsendopret(mypubtxid,sig,voutpubtxids)); - memset(seed,0,32); - memset(sk,0,sizeof(sk)); - return(dilithium_rawtxresult(result,rawtx)); - } - } else retstr = (char *)"Q couldnt find enough Q or x inputs"; - } else retstr = (char *)"need to have exactly 2 params sendtxid, scriptPubKey"; - memset(seed,0,32); - memset(sk,0,sizeof(sk)); - return(cclib_error(result,retstr)); -} - -bool dilithium_Qvalidate(struct CCcontract_info *cp,int32_t height,Eval *eval,const CTransaction tx) -{ - int32_t i,numvins,numvouts,mlen,smlen=CRYPTO_BYTES+32; CPubKey destpub33; std::string handle; uint256 tmptxid,hashBlock,destpubtxid,signerpubtxid; CTransaction vintx; std::vector tmpsig,sig,vopret; uint8_t msg[32],msg2[CRYPTO_BYTES+32],pk[CRYPTO_PUBLICKEYBYTES],*script; std::vector voutpubtxids; - numvins = tx.vin.size(); - signerpubtxid = zeroid; - for (i=0; i 1 ) - { - GetOpReturnData(vintx.vout[numvouts-1].scriptPubKey,vopret); - script = (uint8_t *)vopret.data(); - if ( script[1] == 'Q' ) - { - if ( dilithium_Qsendopretdecode(tmptxid,tmpsig,voutpubtxids,vintx.vout[numvouts-1].scriptPubKey) != 'Q' ) - return eval->Invalid("couldnt decode destpubtxid from Qsend"); - else if ( tx.vin[i].prevout.n > voutpubtxids.size() ) - return eval->Invalid("no destpubtxid for prevout.n"); - destpubtxid = voutpubtxids[tx.vin[i].prevout.n]; - } - else - { - if ( dilithium_sendopretdecode(destpubtxid,vintx.vout[numvouts-1].scriptPubKey) != 'x' ) - return eval->Invalid("couldnt decode destpubtxid from send"); - } - if ( signerpubtxid == zeroid ) - signerpubtxid = destpubtxid; - else if ( destpubtxid != signerpubtxid ) - return eval->Invalid("destpubtxid of vini doesnt match first one"); - } - } - } - if ( signerpubtxid != zeroid ) - { - numvouts = tx.vout.size(); - if ( dilithium_Qsendopretdecode(destpubtxid,sig,voutpubtxids,tx.vout[numvouts-1].scriptPubKey) == 'Q' && destpubtxid == signerpubtxid && sig.size() == smlen ) - { - if ( dilithium_Qmsghash(msg,tx,numvouts-1,voutpubtxids) < 0 ) - return eval->Invalid("couldnt get Qmsghash"); - else if ( dilithium_bigpubget(handle,destpub33,pk,signerpubtxid) < 0 ) - return eval->Invalid("couldnt get bigpub"); - else - { - if ( _dilithium_verify(msg2,&mlen,&sig[0],smlen,pk) < 0 ) - return eval->Invalid("failed dilithium verify"); - else if ( mlen != 32 || memcmp(msg,msg2,32) != 0 ) - { - for (i=0; i<32; i++) - fprintf(stderr,"%02x",msg[i]); - fprintf(stderr," vs "); - for (i=0; iInvalid("failed dilithium msg verify"); - } - else return true; - } - } else return eval->Invalid("failed decode Qsend"); - } else return eval->Invalid("unexpected zero signerpubtxid"); -} - -int32_t dilithium_registrationpub33(char *pkaddr,CPubKey &pub33,uint256 txid) -{ - std::string handle; std::vector bigpub; CTransaction tx; uint256 hashBlock; int32_t numvouts; - pkaddr[0] = 0; - if ( myGetTransaction(txid,tx,hashBlock) != 0 && (numvouts= tx.vout.size()) > 1 ) - { - if ( dilithium_registeropretdecode(handle,pub33,bigpub,tx.vout[numvouts-1].scriptPubKey) == 'R' ) - { - dilithium_addr(pkaddr,&bigpub[0],CRYPTO_PUBLICKEYBYTES); - return(0); - } - } - return(-1); -} - -void dilithium_handleinit(struct CCcontract_info *cp) -{ - static int32_t didinit; - std::vector txids; struct dilithium_handle *hashstr; CPubKey dilithiumpk,pub33; uint256 txid,hashBlock; CTransaction txi; int32_t numvouts; std::vector bigpub; std::string handle; char CCaddr[64]; - if ( didinit != 0 ) - return; - pthread_mutex_init(&DILITHIUM_MUTEX,NULL); - dilithiumpk = GetUnspendable(cp,0); - GetCCaddress(cp,CCaddr,dilithiumpk); - SetCCtxids(txids,CCaddr,true,cp->evalcode,zeroid,'R'); - for (std::vector::const_iterator it=txids.begin(); it!=txids.end(); it++) - { - txid = *it; - if ( myGetTransaction(txid,txi,hashBlock) != 0 && (numvouts= txi.vout.size()) > 1 ) - { - if ( dilithium_registeropretdecode(handle,pub33,bigpub,txi.vout[numvouts-1].scriptPubKey) == 'R' ) - { - if ( (hashstr= dilithium_handlenew((char *)handle.c_str())) != 0 ) - { - if ( hashstr->destpubtxid != txid ) - { - if ( hashstr->destpubtxid != zeroid ) - fprintf(stderr,"overwriting %s %s with %s\n",handle.c_str(),hashstr->destpubtxid.GetHex().c_str(),txid.GetHex().c_str()); - fprintf(stderr,"%s <- %s\n",handle.c_str(),txid.GetHex().c_str()); - hashstr->destpubtxid = txid; - } - } - } - } - } - didinit = 1; -} - -UniValue dilithium_handleinfo(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) -{ - UniValue result(UniValue::VOBJ); CPubKey pub33; int32_t i,n; char *handlestr,pkaddr[64],str[67]; struct dilithium_handle *hashstr; - if ( params != 0 && (n= cJSON_GetArraySize(params)) == 1 ) - { - dilithium_handleinit(cp); - if ( (handlestr= jstr(jitem(params,0),0)) != 0 ) - { - result.push_back(Pair("result","success")); - result.push_back(Pair("handle",handlestr)); - if ( (hashstr= dilithium_handlefind(handlestr)) != 0 ) - { - result.push_back(Pair("destpubtxid",hashstr->destpubtxid.GetHex().c_str())); - if ( dilithium_registrationpub33(pkaddr,pub33,hashstr->destpubtxid) == 0 ) - { - for (i=0; i<33; i++) - sprintf(&str[i<<1],"%02x",((uint8_t *)pub33.begin())[i]); - str[i<<1] = 0; - result.push_back(Pair("pkaddr",pkaddr)); - } - result.push_back(Pair("pubkey",str)); - } else result.push_back(Pair("status","available")); - return(result); - } - } - result.push_back(Pair("result","error")); - return(result); -} - -bool dilithium_Rvalidate(struct CCcontract_info *cp,int32_t height,Eval *eval,const CTransaction tx) -{ - static int32_t didinit; - uint256 txid; int32_t numvouts; struct dilithium_handle *hashstr; std::string handle; std::vector bigpub; CPubKey oldpub33,pub33,dilithiumpk; CTxOut vout,vout0; char pkaddr[64]; - if ( height < 14500 ) - return(true); - dilithium_handleinit(cp); - dilithiumpk = GetUnspendable(cp,0); - if ( (numvouts= tx.vout.size()) <= 1 ) - return eval->Invalid("not enough vouts for registration tx"); - else if ( dilithium_registeropretdecode(handle,pub33,bigpub,tx.vout[numvouts-1].scriptPubKey) == 'R' ) - { - // relies on all current block tx to be put into mempool - txid = tx.GetHash(); - vout0 = MakeCC1vout(cp->evalcode,2*DILITHIUM_TXFEE,dilithiumpk); - vout = MakeCC1vout(EVAL_FAUCET,COIN,Faucet_pubkeyget()); - if ( tx.vout[0] != vout0 ) - return eval->Invalid("mismatched vout0 for register"); - else if ( tx.vout[1].nValue != DILITHIUM_TXFEE ) - return eval->Invalid("vout1 for register not txfee"); - else if ( tx.vout[2] != vout ) - return eval->Invalid("register not sending to faucet"); - else if ( (hashstr= dilithium_handlenew((char *)handle.c_str())) == 0 ) - return eval->Invalid("error creating dilithium handle"); - else if ( hashstr->destpubtxid == zeroid ) - { - hashstr->destpubtxid = txid; - return(true); - } - else - { - if ( hashstr->destpubtxid == txid ) - return(true); - else if ( dilithium_registrationpub33(pkaddr,oldpub33,hashstr->destpubtxid) == 0 ) - { - if ( oldpub33 == pub33 ) - { - hashstr->destpubtxid = txid; - fprintf(stderr,"ht.%d %s <- %s\n",height,handle.c_str(),txid.GetHex().c_str()); - return(true); - } - } - return eval->Invalid("duplicate dilithium handle rejected"); - } - } else return eval->Invalid("couldnt decode register opret"); -} - -bool dilithium_validate(struct CCcontract_info *cp,int32_t height,Eval *eval,const CTransaction tx) -{ - CPubKey destpub33; std::string handle; uint256 hashBlock,destpubtxid,checktxid; CTransaction vintx; int32_t numvouts,mlen,smlen=CRYPTO_BYTES+32; std::vector sig,vopret; uint8_t msg[32],msg2[CRYPTO_BYTES+32],pk[CRYPTO_PUBLICKEYBYTES],*script; - // if all dilithium tx -> do multispend/send, else: - numvouts = tx.vout.size(); - GetOpReturnData(tx.vout[numvouts-1].scriptPubKey,vopret); - script = (uint8_t *)vopret.data(); - if ( script[1] == 'R' ) - return(dilithium_Rvalidate(cp,height,eval,tx)); - else if ( script[1] == 'Q' ) - return(dilithium_Qvalidate(cp,height,eval,tx)); - else if ( tx.vout.size() != 2 ) - return eval->Invalid("numvouts != 2"); - else if ( tx.vin.size() != 1 ) - return eval->Invalid("numvins != 1"); - else if ( IsCCInput(tx.vin[0].scriptSig) == 0 ) - return eval->Invalid("illegal normal vin0"); - else if ( myGetTransaction(tx.vin[0].prevout.hash,vintx,hashBlock) != 0 && (numvouts= vintx.vout.size()) > 1 ) - { - if ( dilithium_sendopretdecode(destpubtxid,vintx.vout[numvouts-1].scriptPubKey) == 'x' ) - { - if ( dilithium_spendopretdecode(checktxid,sig,tx.vout[tx.vout.size()-1].scriptPubKey) == 'y' ) - { - if ( destpubtxid == checktxid && sig.size() == smlen ) - { - musig_prevoutmsg(msg,tx.vin[0].prevout.hash,tx.vout[0].scriptPubKey); - if ( dilithium_bigpubget(handle,destpub33,pk,destpubtxid) < 0 ) - return eval->Invalid("couldnt get bigpub"); - else - { - if ( _dilithium_verify(msg2,&mlen,&sig[0],smlen,pk) < 0 ) - return eval->Invalid("failed dilithium verify"); - else if ( mlen != 32 || memcmp(msg,msg2,32) != 0 ) - return eval->Invalid("failed dilithium msg verify"); - else return(true); - } - } else return eval->Invalid("destpubtxid or sig size didnt match send opret"); - } else return eval->Invalid("failed decode dilithium spendopret"); - } else return eval->Invalid("couldnt decode send opret"); - } else return eval->Invalid("couldnt find vin0 tx"); -} - From ff1d30cbad7f2580080d7e38b2e39c5e2363414f Mon Sep 17 00:00:00 2001 From: Duke Date: Sat, 10 Feb 2024 12:16:47 -0500 Subject: [PATCH 17/78] Delete more CCs #381 --- src/cc/cclib.cpp | 419 +---------------------------------------------- src/cc/musig.cpp | 341 -------------------------------------- 2 files changed, 8 insertions(+), 752 deletions(-) delete mode 100644 src/cc/musig.cpp diff --git a/src/cc/cclib.cpp b/src/cc/cclib.cpp index 48b69c7e5..0fa2ae68a 100644 --- a/src/cc/cclib.cpp +++ b/src/cc/cclib.cpp @@ -61,93 +61,13 @@ CClib_methods[] = { { (char *)"faucet2", (char *)"fund", (char *)"amount", 1, 1, 'F', EVAL_FAUCET2 }, { (char *)"faucet2", (char *)"get", (char *)"", 0, 0, 'G', EVAL_FAUCET2 }, -#ifdef BUILD_ROGUE - { (char *)"rogue", (char *)"newgame", (char *)"maxplayers buyin", 0, 2, 'G', EVAL_ROGUE }, - { (char *)"rogue", (char *)"gameinfo", (char *)"gametxid", 1, 1, 'T', EVAL_ROGUE }, - { (char *)"rogue", (char *)"pending", (char *)"", 0, 0, 'P', EVAL_ROGUE }, - { (char *)"rogue", (char *)"register", (char *)"gametxid [playertxid]", 1, 2, 'R', EVAL_ROGUE }, - { (char *)"rogue", (char *)"keystrokes", (char *)"gametxid keystrokes", 2, 2, 'K', EVAL_ROGUE }, - { (char *)"rogue", (char *)"bailout", (char *)"gametxid", 1, 1, 'Q', EVAL_ROGUE }, - { (char *)"rogue", (char *)"highlander", (char *)"gametxid", 1, 1, 'H', EVAL_ROGUE }, - { (char *)"rogue", (char *)"playerinfo", (char *)"playertxid", 1, 1, 'I', EVAL_ROGUE }, - { (char *)"rogue", (char *)"players", (char *)"", 0, 0, 'D', EVAL_ROGUE }, - { (char *)"rogue", (char *)"games", (char *)"", 0, 0, 'F', EVAL_ROGUE }, - { (char *)"rogue", (char *)"setname", (char *)"pname", 1, 1, 'N', EVAL_ROGUE }, - { (char *)"rogue", (char *)"extract", (char *)"gametxid [pubkey]", 1, 2, 'X', EVAL_ROGUE }, -#elif BUILD_CUSTOMCC +#ifdef BUILD_CUSTOMCC RPC_FUNCS -#elif BUILD_GAMESCC - RPC_FUNCS -#else - { (char *)"musig", (char *)"calcmsg", (char *)"sendtxid scriptPubKey", 2, 2, 'C', EVAL_MUSIG }, - { (char *)"musig", (char *)"combine", (char *)"pubkeys ...", 2, 999999999, 'P', EVAL_MUSIG }, - { (char *)"musig", (char *)"session", (char *)"myindex,numsigners,combined_pk,pkhash,msg32", 5, 5, 'R', EVAL_MUSIG }, - { (char *)"musig", (char *)"commit", (char *)"pkhash,ind,commitment", 3, 3, 'H', EVAL_MUSIG }, - { (char *)"musig", (char *)"nonce", (char *)"pkhash,ind,nonce", 3, 3, 'N', EVAL_MUSIG }, - { (char *)"musig", (char *)"partialsig", (char *)"pkhash,ind,partialsig", 3, 3, 'S', EVAL_MUSIG }, - { (char *)"musig", (char *)"verify", (char *)"msg sig pubkey", 3, 3, 'V', EVAL_MUSIG }, - { (char *)"musig", (char *)"send", (char *)"combined_pk amount", 2, 2, 'x', EVAL_MUSIG }, - { (char *)"musig", (char *)"spend", (char *)"sendtxid sig scriptPubKey", 3, 3, 'y', EVAL_MUSIG }, - { (char *)"dilithium", (char *)"keypair", (char *)"[hexseed]", 0, 1, 'K', EVAL_DILITHIUM }, - { (char *)"dilithium", (char *)"register", (char *)"handle, [hexseed]", 1, 2, 'R', EVAL_DILITHIUM }, - { (char *)"dilithium", (char *)"handleinfo", (char *)"handle", 1, 1, 'I', EVAL_DILITHIUM }, - { (char *)"dilithium", (char *)"sign", (char *)"msg [hexseed]", 1, 2, 'S', EVAL_DILITHIUM }, - { (char *)"dilithium", (char *)"verify", (char *)"pubtxid msg sig", 3, 3, 'V', EVAL_DILITHIUM }, - { (char *)"dilithium", (char *)"send", (char *)"handle pubtxid amount", 3, 3, 'x', EVAL_DILITHIUM }, - { (char *)"dilithium", (char *)"spend", (char *)"sendtxid scriptPubKey [hexseed]", 2, 3, 'y', EVAL_DILITHIUM }, - { (char *)"dilithium", (char *)"Qsend", (char *)"mypubtxid hexseed/'mypriv' destpubtxid,amount, ...", 4, 66, 'Q', EVAL_DILITHIUM }, #endif }; std::string CClib_rawtxgen(struct CCcontract_info *cp,uint8_t funcid,cJSON *params); -#ifdef BUILD_ROGUE -int32_t rogue_replay(uint64_t seed,int32_t sleepmillis); -bool rogue_validate(struct CCcontract_info *cp,int32_t height,Eval *eval,const CTransaction tx); - -UniValue rogue_newgame(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); -UniValue rogue_pending(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); -UniValue rogue_gameinfo(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); -UniValue rogue_register(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); -UniValue rogue_keystrokes(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); -UniValue rogue_bailout(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); -UniValue rogue_highlander(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); -UniValue rogue_playerinfo(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); -UniValue rogue_players(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); -UniValue rogue_games(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); -UniValue rogue_setname(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); -UniValue rogue_extract(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); - -#else -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); -UniValue sudoku_pending(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); - -bool musig_validate(struct CCcontract_info *cp,int32_t height,Eval *eval,const CTransaction tx); -UniValue musig_calcmsg(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); -UniValue musig_combine(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); -UniValue musig_session(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); -UniValue musig_commit(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); -UniValue musig_nonce(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); -UniValue musig_partialsig(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); -UniValue musig_verify(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); -UniValue musig_send(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); -UniValue musig_spend(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); - -bool dilithium_validate(struct CCcontract_info *cp,int32_t height,Eval *eval,const CTransaction tx); -UniValue dilithium_register(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); -UniValue dilithium_handleinfo(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); -UniValue dilithium_send(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); -UniValue dilithium_spend(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); -UniValue dilithium_keypair(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); -UniValue dilithium_sign(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); -UniValue dilithium_verify(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); -UniValue dilithium_Qsend(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); - -#endif - cJSON *cclib_reparse(int32_t *nump,char *jsonstr) // assumes origparams will be freed by caller { cJSON *params; char *newstr; int32_t i,j; @@ -184,367 +104,44 @@ cJSON *cclib_reparse(int32_t *nump,char *jsonstr) // assumes origparams will be UniValue CClib_method(struct CCcontract_info *cp,char *method,char *jsonstr) { - UniValue result(UniValue::VOBJ); uint64_t txfee = 10000; int32_t m; cJSON *params = cclib_reparse(&m,jsonstr); - fprintf(stderr,"method.(%s) -> (%s)\n",jsonstr!=0?jsonstr:"",params!=0?jprint(params,0):""); -#ifdef BUILD_ROGUE - if ( cp->evalcode == EVAL_ROGUE ) - { - if ( strcmp(method,"newgame") == 0 ) - return(rogue_newgame(txfee,cp,params)); - else if ( strcmp(method,"pending") == 0 ) - return(rogue_pending(txfee,cp,params)); - else if ( strcmp(method,"gameinfo") == 0 ) - return(rogue_gameinfo(txfee,cp,params)); - else if ( strcmp(method,"register") == 0 ) - return(rogue_register(txfee,cp,params)); - else if ( strcmp(method,"keystrokes") == 0 ) - return(rogue_keystrokes(txfee,cp,params)); - else if ( strcmp(method,"bailout") == 0 ) - return(rogue_bailout(txfee,cp,params)); - else if ( strcmp(method,"highlander") == 0 ) - return(rogue_highlander(txfee,cp,params)); - else if ( strcmp(method,"extract") == 0 ) - return(rogue_extract(txfee,cp,params)); - else if ( strcmp(method,"playerinfo") == 0 ) - return(rogue_playerinfo(txfee,cp,params)); - else if ( strcmp(method,"players") == 0 ) - return(rogue_players(txfee,cp,params)); - else if ( strcmp(method,"games") == 0 ) - return(rogue_games(txfee,cp,params)); - else if ( strcmp(method,"setname") == 0 ) - return(rogue_setname(txfee,cp,params)); - else - { - result.push_back(Pair("result","error")); - result.push_back(Pair("error","invalid rogue method")); - result.push_back(Pair("method",method)); - return(result); - } - } -#elif BUILD_CUSTOMCC - CUSTOM_DISPATCH -#elif BUILD_GAMESCC - CUSTOM_DISPATCH -#else - 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 ) - return(sudoku_generate(txfee,cp,params)); - else if ( strcmp(method,"solution") == 0 ) - return(sudoku_solution(txfee,cp,params)); - else if ( strcmp(method,"pending") == 0 ) - return(sudoku_pending(txfee,cp,params)); - else - { - result.push_back(Pair("result","error")); - result.push_back(Pair("error","invalid sudoku method")); - result.push_back(Pair("method",method)); - return(result); - } - } - else if ( cp->evalcode == EVAL_MUSIG ) - { - //printf("CClib_method params.%p\n",params); - if ( strcmp(method,"combine") == 0 ) - return(musig_combine(txfee,cp,params)); - else if ( strcmp(method,"calcmsg") == 0 ) - return(musig_calcmsg(txfee,cp,params)); - else if ( strcmp(method,"session") == 0 ) - return(musig_session(txfee,cp,params)); - else if ( strcmp(method,"commit") == 0 ) - return(musig_commit(txfee,cp,params)); - else if ( strcmp(method,"nonce") == 0 ) // returns combined nonce if ready - return(musig_nonce(txfee,cp,params)); - else if ( strcmp(method,"partialsig") == 0 ) - return(musig_partialsig(txfee,cp,params)); - else if ( strcmp(method,"verify") == 0 ) - return(musig_verify(txfee,cp,params)); - else if ( strcmp(method,"send") == 0 ) - return(musig_send(txfee,cp,params)); - else if ( strcmp(method,"spend") == 0 ) - return(musig_spend(txfee,cp,params)); - else - { - result.push_back(Pair("result","error")); - result.push_back(Pair("error","invalid musig method")); - result.push_back(Pair("method",method)); - return(result); - } - } - else if ( cp->evalcode == EVAL_DILITHIUM ) - { - if ( strcmp(method,"Qsend") == 0 ) - return(dilithium_Qsend(txfee,cp,params)); - else if ( strcmp(method,"send") == 0 ) - return(dilithium_send(txfee,cp,params)); - else if ( strcmp(method,"spend") == 0 ) - return(dilithium_spend(txfee,cp,params)); - else if ( strcmp(method,"keypair") == 0 ) - return(dilithium_keypair(txfee,cp,params)); - else if ( strcmp(method,"register") == 0 ) - return(dilithium_register(txfee,cp,params)); - else if ( strcmp(method,"handleinfo") == 0 ) - return(dilithium_handleinfo(txfee,cp,params)); - else if ( strcmp(method,"sign") == 0 ) - return(dilithium_sign(txfee,cp,params)); - else if ( strcmp(method,"verify") == 0 ) - return(dilithium_verify(txfee,cp,params)); - else - { - result.push_back(Pair("result","error")); - result.push_back(Pair("error","invalid dilithium method")); - result.push_back(Pair("method",method)); - return(result); - } - } -#endif - else - { - result.push_back(Pair("result","error")); - result.push_back(Pair("error","only sudoku supported for now")); - result.push_back(Pair("evalcode",(int)cp->evalcode)); - return(result); - } + UniValue result(UniValue::VOBJ); + return(result); } UniValue CClib_info(struct CCcontract_info *cp) { - UniValue result(UniValue::VOBJ),a(UniValue::VARR); int32_t i; char str[2]; - result.push_back(Pair("result","success")); - result.push_back(Pair("CClib",CClib_name())); - for (i=0; i= 128 ) - obj.push_back(Pair("funcid",CClib_methods[i].funcid)); - else - { - str[0] = CClib_methods[i].funcid; - str[1] = 0; - obj.push_back(Pair("funcid",str)); - } - obj.push_back(Pair("name",CClib_methods[i].CCname)); - obj.push_back(Pair("method",CClib_methods[i].method)); - obj.push_back(Pair("help",CClib_methods[i].help)); - obj.push_back(Pair("params_required",CClib_methods[i].numrequiredargs)); - obj.push_back(Pair("params_max",CClib_methods[i].maxargs)); - a.push_back(obj); - } - result.push_back(Pair("methods",a)); + UniValue result(UniValue::VOBJ); return(result); } UniValue CClib(struct CCcontract_info *cp,char *method,char *jsonstr) { - UniValue result(UniValue::VOBJ); int32_t i; std::string rawtx; cJSON *params; -//printf("CClib params.(%s)\n",jsonstr!=0?jsonstr:""); - for (i=0; ievalcode == CClib_methods[i].evalcode && strcmp(method,CClib_methods[i].method) == 0 ) - { - if ( cp->evalcode == EVAL_FAUCET2 ) - { - result.push_back(Pair("result","success")); - result.push_back(Pair("method",CClib_methods[i].method)); - params = cJSON_Parse(jsonstr); - rawtx = CClib_rawtxgen(cp,CClib_methods[i].funcid,params); - free_json(params); - result.push_back(Pair("rawtx",rawtx)); - return(result); - } else return(CClib_method(cp,method,jsonstr)); - } - } - result.push_back(Pair("result","error")); - result.push_back(Pair("method",method)); - result.push_back(Pair("error","method not found")); + UniValue result(UniValue::VOBJ); return(result); } 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,cmpaddr) == 0 ) - return(tx.vout[v].nValue); - } return(0); } bool CClibExactAmounts(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx,int32_t minage,uint64_t txfee) { - static uint256 zerohash; - CTransaction vinTx; uint256 hashBlock,activehash; int32_t i,numvins,numvouts; int64_t inputs=0,outputs=0,assetoshis; - numvins = tx.vin.size(); - numvouts = tx.vout.size(); - for (i=0; iismyvin)(tx.vin[i].scriptSig) != 0 ) - { - //fprintf(stderr,"vini.%d check mempool\n",i); - if ( eval->GetTxUnconfirmed(tx.vin[i].prevout.hash,vinTx,hashBlock) == 0 ) - return eval->Invalid("cant find vinTx"); - else - { - //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,cp->unspendableCCaddr)) != 0 ) - inputs += assetoshis; - } - } - } - for (i=0; iunspendableCCaddr)) != 0 ) - outputs += assetoshis; - } - if ( inputs != outputs+FAUCET2SIZE+txfee ) - { - fprintf(stderr,"inputs %llu vs outputs %llu\n",(long long)inputs,(long long)outputs); - return eval->Invalid("mismatched inputs != outputs + FAUCET2SIZE + txfee"); - } - else return(true); + return false; } bool CClib_validate(struct CCcontract_info *cp,int32_t height,Eval *eval,const CTransaction tx,unsigned int nIn) { - 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 ) - { -#ifdef BUILD_ROGUE - return(rogue_validate(cp,height,eval,tx)); -#elif BUILD_CUSTOMCC - return(custom_validate(cp,height,eval,tx)); -#elif BUILD_GAMESCC - return(games_validate(cp,height,eval,tx)); -#else - if ( cp->evalcode == EVAL_SUDOKU ) - return(sudoku_validate(cp,height,eval,tx)); - else if ( cp->evalcode == EVAL_MUSIG ) - return(musig_validate(cp,height,eval,tx)); - else if ( cp->evalcode == EVAL_DILITHIUM ) - return(dilithium_validate(cp,height,eval,tx)); - else return eval->Invalid("invalid evalcode"); -#endif - } - numvins = tx.vin.size(); - numvouts = tx.vout.size(); - preventCCvins = preventCCvouts = -1; - if ( numvouts < 1 ) { - return eval->Invalid("no vouts"); - } else { - for (i=0; iInvalid("illegal normal vini"); - } - } - //fprintf(stderr,"check amounts\n"); - if ( CClibExactAmounts(cp,eval,tx,1,10000) == false ) { - fprintf(stderr,"faucetget invalid amount\n"); - return false; - } else { - preventCCvouts = 1; - if ( IsCClibvout(cp,tx,0,cp->unspendableCCaddr) != 0 ) - { - preventCCvouts++; - i = 1; - } else i = 0; - txid = tx.GetHash(); - memcpy(hash,&txid,sizeof(hash)); - fprintf(stderr,"check faucetget txid %s %02x/%02x\n",uint256_str(str,txid),hash[0],hash[31]); - if ( tx.vout[i].nValue != FAUCET2SIZE ) - return eval->Invalid("invalid faucet output"); - else if ( (hash[0] & 0xff) != 0 || (hash[31] & 0xff) != 0 ) - return eval->Invalid("invalid faucetget txid"); - Getscriptaddress(destaddr,tx.vout[i].scriptPubKey); - SetCCtxids(txids,destaddr,tx.vout[i].scriptPubKey.IsPayToCryptoCondition()); - for (std::vector >::const_iterator it=txids.begin(); it!=txids.end(); it++) - { - //int height = it->first.blockHeight; - if ( CCduration(numblocks,it->first.txhash) > 0 && numblocks > 3 ) - { - //fprintf(stderr,"would return error %s numblocks.%d ago\n",uint256_str(str,it->first.txhash),numblocks); - return eval->Invalid("faucet2 is only for brand new addresses"); - } - } - retval = PreventCC(eval,tx,preventCCvins,numvins,preventCCvouts,numvouts); - if ( retval != 0 ) - fprintf(stderr,"faucet2get validated\n"); - else fprintf(stderr,"faucet2get invalid\n"); - return(retval); - } - } + return false; } int64_t AddCClibInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,int64_t total,int32_t maxinputs,char *cmpaddr,int32_t CCflag) { - char coinaddr[64]; int64_t threshold,nValue,price,totalinputs = 0,txfee = 10000; uint256 txid,hashBlock; std::vector origpubkey; CTransaction vintx; int32_t vout,n = 0; - std::vector > unspentOutputs; - GetCCaddress(cp,coinaddr,pk); - SetCCunspents(unspentOutputs,coinaddr,CCflag!=0?true:false); - if ( maxinputs > CC_MAXVINS ) - maxinputs = CC_MAXVINS; - if ( maxinputs != 0 ) - threshold = total/maxinputs; - else threshold = total; - 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 vs %.8f\n",coinaddr,uint256_str(str,txid),vout,(double)it->second.satoshis/COIN,(double)threshold/COIN); - if ( it->second.satoshis < threshold || it->second.satoshis == txfee ) - continue; - // no need to prevent dup - if ( myGetTransaction(txid,vintx,hashBlock) != 0 ) - { - if ( (nValue= IsCClibvout(cp,vintx,vout,cmpaddr)) >= 1000000 && myIsutxo_spentinmempool(ignoretxid,ignorevin,txid,vout) == 0 ) - { - if ( total != 0 && maxinputs != 0 ) - mtx.vin.push_back(CTxIn(txid,vout,CScript())); - nValue = it->second.satoshis; - totalinputs += nValue; - 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,"couldnt get tx\n"); - } - return(totalinputs); + return 0; } int64_t AddCClibtxfee(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk) { - char coinaddr[64]; int64_t nValue,txfee = 10000; uint256 txid,hashBlock; CTransaction vintx; int32_t vout; - std::vector > unspentOutputs; - GetCCaddress(cp,coinaddr,pk); - SetCCunspents(unspentOutputs,coinaddr,true); - 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 vs %.8f\n",coinaddr,uint256_str(str,txid),vout,(double)it->second.satoshis/COIN,(double)threshold/COIN); - if ( it->second.satoshis < txfee ) - continue; - if ( myGetTransaction(txid,vintx,hashBlock) != 0 ) - { - if ( (nValue= IsCClibvout(cp,vintx,vout,coinaddr)) != 0 && myIsutxo_spentinmempool(ignoretxid,ignorevin,txid,vout) == 0 ) - { - mtx.vin.push_back(CTxIn(txid,vout,CScript())); - return(it->second.satoshis); - } //else fprintf(stderr,"nValue %.8f too small or already spent in mempool\n",(double)nValue/COIN); - } else fprintf(stderr,"couldnt get tx\n"); - } return(0); } diff --git a/src/cc/musig.cpp b/src/cc/musig.cpp deleted file mode 100644 index 6aafe5fd5..000000000 --- a/src/cc/musig.cpp +++ /dev/null @@ -1,341 +0,0 @@ -// Copyright (c) 2016-2023 The Hush developers -// Distributed under the GPLv3 software license, see the accompanying -// file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html -/****************************************************************************** - * Copyright © 2014-2019 The SuperNET Developers. * - * * - * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * - * the top-level directory of this distribution for the individual copyright * - * holder information and the developer policies on copyright and licensing. * - * * - * Unless otherwise agreed in a custom licensing agreement, no part of the * - * SuperNET software, including this file may be copied, modified, propagated * - * or distributed except according to the terms contained in the LICENSE file * - * * - * Removal or modification of this copyright notice is prohibited. * - * * - ******************************************************************************/ - -/* first make a combined pk: - -./hush-cli -ac_name=MUSIG cclib combine 18 '["02fb6aa0b96cad24d46b5da93eba3864c45ce07a73bba12da530ae841e140fcf28","0255c46dbce584e3751081b39d7fc054fc807100557e73fc444481618b5706afb4"]' -{ - "pkhash": "5cb5a225064ca6ffc1438cb2a6ac2ac65fe2d5055dc7f6c7ebffb9a231f8912b", - "combined_pk": "03f016c348437c7422eed92d865aa9789614f75327cada463eefc566126b54785b", - "result": "success" -} - - the combined_pk and pkhash will be needed for various other rpc calls - - second, send 1 coin to the combined_pk - ./hush-cli -ac_name=MUSIG cclib send 18 '["03f016c348437c7422eed92d865aa9789614f75327cada463eefc566126b54785b",1]' - { - "hex": "0400008085202f8901a980664dffc810725a79ffb89ac48be4c7b6bade9b789732fcf871acf8e81a2e010000006a47304402207e52763661ecd2c34a65d6623950be11794825db71576dc11894c606ddc317800220028fef46dc20630d0fdf22647b5d4ff0f1c47cf75f48702d0a91d5589eff99d001210255c46dbce584e3751081b39d7fc054fc807100557e73fc444481618b5706afb4ffffffff031008f60500000000302ea22c8020c71ddb3aac7f9b9e4bdacf032aaa8b8e4433c4ff9f8a43cebb9c1f5da96928a48103120c008203000401cce09aa4350000000023210255c46dbce584e3751081b39d7fc054fc807100557e73fc444481618b5706afb4ac0000000000000000266a2412782103f016c348437c7422eed92d865aa9789614f75327cada463eefc566126b54785b00000000920500000000000000000000000000", - "txid": "5ce74037a153ee210413b48d4e88638b99825a2de1a1f1aa0d36ebf93019824c", - "result": "success" - } - - sendrawtransaction of the above hex. - ./hush-cli -ac_name=MUSIG getrawtransaction 5ce74037a153ee210413b48d4e88638b99825a2de1a1f1aa0d36ebf93019824c 1 - "vout": [ - { - "value": 1.00010000, - "valueSat": 100010000, - "n": 0, - "scriptPubKey": { - "asm": "a22c8020c71ddb3aac7f9b9e4bdacf032aaa8b8e4433c4ff9f8a43cebb9c1f5da96928a48103120c008203000401 OP_CHECKCRYPTOCONDITION", - "hex": "2ea22c8020c71ddb3aac7f9b9e4bdacf032aaa8b8e4433c4ff9f8a43cebb9c1f5da96928a48103120c008203000401cc", - "reqSigs": 1, - "type": "cryptocondition", - "addresses": [ - "RKWS7jxyjPX9iaJttk8iMKf1AumanKypez" - ] - } - }, - { - "value": 8.99980000, - "valueSat": 899980000, - "n": 1, - "scriptPubKey": { - "asm": "0255c46dbce584e3751081b39d7fc054fc807100557e73fc444481618b5706afb4 OP_CHECKSIG", - "hex": "210255c46dbce584e3751081b39d7fc054fc807100557e73fc444481618b5706afb4ac", - "reqSigs": 1, - "type": "pubkey", - "addresses": [ - "RVQjvGdRbYLJ49bfH4SAFseipvwE3UdoDw" - ] - } - - script: 210255c46dbce584e3751081b39d7fc054fc807100557e73fc444481618b5706afb4ac - - sendtxid: 5ce74037a153ee210413b48d4e88638b99825a2de1a1f1aa0d36ebf93019824c - - get the msg we need to sign: - - ./hush-cli -ac_name=MUSIG cclib calcmsg 18 '["5ce74037a153ee210413b48d4e88638b99825a2de1a1f1aa0d36ebf93019824c","210255c46dbce584e3751081b39d7fc054fc807100557e73fc444481618b5706afb4ac"]' - - { - "msg": "f7fb85d1412814e3c2f98b990802af6ee33dad368c6ba05c2050e9e5506fcd75", - "result": "success" - } - -the "msg" is what needs to be signed to create a valid spend - - now on each signing node, a session needs to be created: - 5 args: ind, numsigners, combined_pk, pkhash, message to be signed - - on node with pubkey: 02fb6aa0b96cad24d46b5da93eba3864c45ce07a73bba12da530ae841e140fcf28 - ./hush-cli -ac_name=MUSIG cclib session 18 '[0,2,"03f016c348437c7422eed92d865aa9789614f75327cada463eefc566126b54785b","5cb5a225064ca6ffc1438cb2a6ac2ac65fe2d5055dc7f6c7ebffb9a231f8912b","f7fb85d1412814e3c2f98b990802af6ee33dad368c6ba05c2050e9e5506fcd75"]' - { - "myind": 0, - "numsigners": 2, - "commitment": "bbea1f2562eca01b9a1393c5dc188bdd44551aebf684f4459930f59dde01f7ae", - "result": "success" - } - - on node with pubkey: 0255c46dbce584e3751081b39d7fc054fc807100557e73fc444481618b5706afb4 - ./hush-cli -ac_name=MUSIG cclib session 18 '[1,2,"03f016c348437c7422eed92d865aa9789614f75327cada463eefc566126b54785b","5cb5a225064ca6ffc1438cb2a6ac2ac65fe2d5055dc7f6c7ebffb9a231f8912b","f7fb85d1412814e3c2f98b990802af6ee33dad368c6ba05c2050e9e5506fcd75"]' - { - "myind": 1, - "numsigners": 2, - "commitment": "c2291acb747a75b1a40014d8eb0cc90a1360f74d413f65f78e20a7de45eda851", - "result": "success" - } - - now we need to get the commitment from each node to the other one. the session already put the commitment for each node into the global struct. Keep in mind there is a single global struct with session unique to each cclib session call. that means no restarting any deamon in the middle of the process on any of the nodes and only call cclib session a single time. this is an artificial restriction just to simplify the initial implementation of musig - ./hush-cli -ac_name=MUSIG cclib commit 18 '["5cb5a225064ca6ffc1438cb2a6ac2ac65fe2d5055dc7f6c7ebffb9a231f8912b","1","c2291acb747a75b1a40014d8eb0cc90a1360f74d413f65f78e20a7de45eda851"]' - { - "added_index": 1, - "myind": 0, - "nonce": "02fec7a9310c959a0a97b86bc3f8c30d392d1fb51793915898c568f73f1f70476b", - "result": "success" - } - - ./hush-cli -ac_name=MUSIG cclib commit 18 '["5cb5a225064ca6ffc1438cb2a6ac2ac65fe2d5055dc7f6c7ebffb9a231f8912b",0,"d242cff13fa8c9b83248e4219fda459ada146b885f2171481f1b0f66c66d94ad"]' - { - "added_index": 0, - "myind": 1, - "nonce": "039365deaaaea089d509ba4c9f846de2baf4aa04cf6b26fa2c1cd818553e47f80c", - "result": "success" - } - - Now exchange the revealed nonces to each node: - ./hush-cli -ac_name=MUSIG cclib nonce 18 '["5cb5a225064ca6ffc1438cb2a6ac2ac65fe2d5055dc7f6c7ebffb9a231f8912b","1","039365deaaaea089d509ba4c9f846de2baf4aa04cf6b26fa2c1cd818553e47f80c"]' -{ - "added_index": 1, - "myind": 0, - "partialsig": "1d65c09cd9bffe4f0604227e66cd7cd221480bbb08262fe885563a9df7cf8f5b", - "result": "success" -} - -./hush-cli -ac_name=MUSIG cclib nonce 18 '["5cb5a225064ca6ffc1438cb2a6ac2ac65fe2d5055dc7f6c7ebffb9a231f8912b",0,"02fec7a9310c959a0a97b86bc3f8c30d392d1fb51793915898c568f73f1f70476b"]' -{ - "added_index": 0, - "myind": 1, - "partialsig": "4a3795e6801b355102c617390cf5a462061e082e35dc2ed8f8b1fab54cc0769e", - "result": "success" -} - - Almost there! final step is to exchange the partial sigs between signers - ./hush-cli -ac_name=MUSIG cclib partialsig 18 '["5cb5a225064ca6ffc1438cb2a6ac2ac65fe2d5055dc7f6c7ebffb9a231f8912b","1","4a3795e6801b355102c617390cf5a462061e082e35dc2ed8f8b1fab54cc0769e"]' - { - "added_index": 1, - "result": "success", - "combinedsig": "a76f2790747ed2436a281f2660bdbee21bad9ee130b9cab6e542fa618fba1512679d568359db33a008ca39b773c32134276613e93e025ec17e083553449005f9" - } - - ./hush-cli -ac_name=MUSIG cclib partialsig 18 '["5cb5a225064ca6ffc1438cb2a6ac2ac65fe2d5055dc7f6c7ebffb9a231f8912b",0,"1d65c09cd9bffe4f0604227e66cd7cd221480bbb08262fe885563a9df7cf8f5b"]' - { - "added_index": 0, - "result": "success", - "combinedsig": "a76f2790747ed2436a281f2660bdbee21bad9ee130b9cab6e542fa618fba1512679d568359db33a008ca39b773c32134276613e93e025ec17e083553449005f9" - } - - Notice both nodes generated the same combined signature! - - Now for a sanity test, we can use the verify call to make sure this sig will work with the msg needed for the spend: - - ./hush-cli -ac_name=MUSIG cclib verify 18 '["f7fb85d1412814e3c2f98b990802af6ee33dad368c6ba05c2050e9e5506fcd75","03f016c348437c7422eed92d865aa9789614f75327cada463eefc566126b54785b","a76f2790747ed2436a281f2660bdbee21bad9ee130b9cab6e542fa618fba1512679d568359db33a008ca39b773c32134276613e93e025ec17e083553449005f9"]' - { - "msg": "f7fb85d1412814e3c2f98b990802af6ee33dad368c6ba05c2050e9e5506fcd75", - "combined_pk": "03f016c348437c7422eed92d865aa9789614f75327cada463eefc566126b54785b", - "combinedsig": "a76f2790747ed2436a281f2660bdbee21bad9ee130b9cab6e542fa618fba1512679d568359db33a008ca39b773c32134276613e93e025ec17e083553449005f9", - "result": "success" - } - - and finally the spend: sendtxid, scriptPubKey, musig - - ./hush-cli -ac_name=MUSIG cclib spend 18 '["5ce74037a153ee210413b48d4e88638b99825a2de1a1f1aa0d36ebf93019824c","210255c46dbce584e3751081b39d7fc054fc807100557e73fc444481618b5706afb4ac","a76f2790747ed2436a281f2660bdbee21bad9ee130b9cab6e542fa618fba1512679d568359db33a008ca39b773c32134276613e93e025ec17e083553449005f9"]' -{ - "scriptpubkey": "210255c46dbce584e3751081b39d7fc054fc807100557e73fc444481618b5706afb4ac", - "msg": "f7fb85d1412814e3c2f98b990802af6ee33dad368c6ba05c2050e9e5506fcd75", - "combined_pk": "03f016c348437c7422eed92d865aa9789614f75327cada463eefc566126b54785b", - "combinedsig": "a76f2790747ed2436a281f2660bdbee21bad9ee130b9cab6e542fa618fba1512679d568359db33a008ca39b773c32134276613e93e025ec17e083553449005f9", - "hex": "0400008085202f89014c821930f9eb360daaf1a1e12d5a82998b63884e8db4130421ee53a13740e75c000000007b4c79a276a072a26ba067a5658021032d29d6545a2aafad795d9cf50912ecade549137 -163934dfb2895ebc0e211ce8a81409671a60db89b3bc58966f3acc80194479b1a43d868e95a11ebc5609646d18710341a8ff92a7817571980307f5d660cc00a2735ac6333e0a7191243f1263f1959a100af03800112 -a10001ffffffff0200e1f5050000000023210255c46dbce584e3751081b39d7fc054fc807100557e73fc444481618b5706afb4ac0000000000000000686a4c6512792103f016c348437c7422eed92d865aa9789614f -75327cada463eefc566126b54785b40a76f2790747ed2436a281f2660bdbee21bad9ee130b9cab6e542fa618fba1512679d568359db33a008ca39b773c32134276613e93e025ec17e083553449005f900000000a805 -00000000000000000000000000", - "txid": "910635bf69a047fc90567a83ff12e47b753f470658b6d0855ec96e07e7349a8a", - "result": "success" -} -*/ - - -#define USE_BASIC_CONFIG -#define ENABLE_MODULE_MUSIG -#include "../secp256k1/src/basic-config.h" -#include "../secp256k1/include/secp256k1.h" -#include "../secp256k1/src/ecmult.h" -#include "../secp256k1/src/ecmult_gen.h" - -typedef struct { unsigned char data[64]; } secp256k1_schnorrsig; -struct secp256k1_context_struct { - secp256k1_ecmult_context ecmult_ctx; - secp256k1_ecmult_gen_context ecmult_gen_ctx; - secp256k1_callback illegal_callback; - secp256k1_callback error_callback; -}; - - -//#include "../secp256k1/include/secp256k1.h" -//#include "../secp256k1/include/secp256k1_schnorrsig.h" -#include "../secp256k1/include/secp256k1_musig.h" - -#define MUSIG_PREVN 0 // for now, just use vout0 for the musig output -#define MUSIG_TXFEE 10000 - -struct musig_info -{ - secp256k1_musig_session session; - secp256k1_pubkey combined_pk; - uint8_t *nonce_commitments,**commitment_ptrs; // 32*N_SIGNERS - secp256k1_musig_session_signer_data *signer_data; //[N_SIGNERS]; - secp256k1_pubkey *nonces; //[N_SIGNERS]; - secp256k1_musig_partial_signature *partial_sig; //[N_SIGNERS]; - int32_t myind,num,numcommits,numnonces,numpartials; - uint8_t msg[32],pkhash[32],combpk[33]; -}; - -std::vector MUSIG; - -struct musig_info *musig_infocreate(int32_t myind,int32_t num) -{ - int32_t i; struct musig_info *mp = (struct musig_info *)calloc(1,sizeof(*mp)); - mp->myind = myind, mp->num = num; - mp->nonce_commitments = (uint8_t *)calloc(num,32); - mp->commitment_ptrs = (uint8_t **)calloc(num,sizeof(*mp->commitment_ptrs)); - for (i=0; icommitment_ptrs[i] = &mp->nonce_commitments[i*32]; - mp->signer_data = (secp256k1_musig_session_signer_data *)calloc(num,sizeof(*mp->signer_data)); - mp->nonces = (secp256k1_pubkey *)calloc(num,sizeof(*mp->nonces)); - mp->partial_sig = (secp256k1_musig_partial_signature *)calloc(num,sizeof(*mp->partial_sig)); - return(mp); -} - -void musig_infofree(struct musig_info *mp) -{ -} - -CScript musig_sendopret(uint8_t funcid,CPubKey pk) -{ - CScript opret; - return(opret); -} - -uint8_t musig_sendopretdecode(CPubKey &pk,CScript scriptPubKey) -{ - return(0); -} - -CScript musig_spendopret(uint8_t funcid,CPubKey pk,std::vector musig64) -{ - CScript opret; - return(opret); -} - -uint8_t musig_spendopretdecode(CPubKey &pk,std::vector &musig64,CScript scriptPubKey) -{ - return(0); -} - -int32_t musig_parsepubkey(secp256k1_context *ctx,secp256k1_pubkey &spk,cJSON *item) -{ - return -1; -} - -int32_t musig_msghash(uint8_t *msg,uint256 prevhash,int32_t prevn,CTxOut vout,CPubKey pk) -{ - return(0); -} - -int32_t musig_prevoutmsg(uint8_t *msg,uint256 sendtxid,CScript scriptPubKey) -{ - return(-1); -} - -UniValue musig_calcmsg(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) -{ - UniValue result(UniValue::VOBJ); - return result; -} - -UniValue musig_combine(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) -{ - UniValue result(UniValue::VOBJ); - return result; -} - -UniValue musig_session(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) -{ - UniValue result(UniValue::VOBJ); - return result; -} - -UniValue musig_commit(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) -{ - UniValue result(UniValue::VOBJ); - return result; -} - -UniValue musig_nonce(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) -{ - UniValue result(UniValue::VOBJ); - return result; -} - -UniValue musig_partialsig(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) -{ - UniValue result(UniValue::VOBJ); - return result; -} - -//int testmain(void); -UniValue musig_verify(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) -{ - UniValue result(UniValue::VOBJ); - return result; -} - -UniValue musig_rawtxresult(UniValue &result,std::string rawtx) -{ - UniValue result(UniValue::VOBJ); - return result; -} - -UniValue musig_send(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) -{ - UniValue result(UniValue::VOBJ); - return result; -} - -UniValue musig_spend(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) -{ - UniValue result(UniValue::VOBJ); - return result; -} - -bool musig_validate(struct CCcontract_info *cp,int32_t height,Eval *eval,const CTransaction tx) -{ - return false; -} From cb0a9800832f25aae8a9921a7ecc4619b178b651 Mon Sep 17 00:00:00 2001 From: Duke Date: Sat, 10 Feb 2024 12:36:28 -0500 Subject: [PATCH 18/78] Delete more CCs #381 --- src/cc/cclib.cpp | 76 +---- src/cc/heir_validate.h | 679 ----------------------------------------- 2 files changed, 2 insertions(+), 753 deletions(-) delete mode 100644 src/cc/heir_validate.h diff --git a/src/cc/cclib.cpp b/src/cc/cclib.cpp index 0fa2ae68a..35dae0adb 100644 --- a/src/cc/cclib.cpp +++ b/src/cc/cclib.cpp @@ -28,18 +28,9 @@ #include "core_io.h" #define FAUCET2SIZE COIN #define EVAL_FAUCET2 EVAL_FIRSTUSER -#ifdef BUILD_ROGUE -#define EVAL_ROGUE 17 -std::string MYCCLIBNAME = (char *)"rogue"; -#elif BUILD_CUSTOMCC +#ifdef BUILD_CUSTOMCC #include "customcc.h" - -#else -#define EVAL_SUDOKU 17 -#define EVAL_MUSIG 18 -#define EVAL_DILITHIUM 19 -std::string MYCCLIBNAME = (char *)"sudoku"; #endif #ifndef BUILD_GAMESCC @@ -147,74 +138,16 @@ int64_t AddCClibtxfee(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKe std::string Faucet2Fund(struct CCcontract_info *cp,uint64_t txfee,int64_t funds) { - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), hush_nextheight()); - CPubKey mypk,cclibpk; CScript opret; - if ( txfee == 0 ) - txfee = 10000; - mypk = pubkey2pk(Mypubkey()); - cclibpk = GetUnspendable(cp,0); - if ( AddNormalinputs2(mtx,funds+txfee,64) > 0 ) - { - mtx.vout.push_back(MakeCC1vout(cp->evalcode,funds,cclibpk)); - return(FinalizeCCTx(0,cp,mtx,mypk,txfee,opret)); - } return(""); } std::string CClib_rawtxgen(struct CCcontract_info *cp,uint8_t funcid,cJSON *params) { - CMutableTransaction tmpmtx,mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), hush_nextheight()); - CPubKey mypk,cclibpk; int64_t funds,txfee=0,inputs,CCchange=0,nValue=FAUCET2SIZE; std::string rawhex; uint32_t j; int32_t i,len; uint8_t buf[32768]; bits256 hash; - if ( txfee == 0 ) - txfee = 10000; - if ( funcid == 'F' ) - { - if ( cJSON_GetArraySize(params) > 0 ) - { - funds = (int64_t)jdouble(jitem(params,0),0)*COIN + 0.0000000049; - return(Faucet2Fund(cp,0,funds)); - } else return(""); - } - else if ( funcid != 'G' ) - return(""); - cclibpk = GetUnspendable(cp,0); - mypk = pubkey2pk(Mypubkey()); - if ( (inputs= AddCClibInputs(cp,mtx,cclibpk,nValue+txfee,60,cp->unspendableCCaddr,1)) > 0 ) - { - if ( inputs > nValue ) - CCchange = (inputs - nValue - txfee); - if ( CCchange != 0 ) - mtx.vout.push_back(MakeCC1vout(EVAL_FAUCET2,CCchange,cclibpk)); - mtx.vout.push_back(CTxOut(nValue,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG)); - fprintf(stderr,"start at %u\n",(uint32_t)time(NULL)); - j = rand() & 0xfffffff; - for (i=0; i<1000000; i++,j++) - { - tmpmtx = mtx; - rawhex = FinalizeCCTx(-1LL,cp,tmpmtx,mypk,txfee,CScript() << OP_RETURN << E_MARSHAL(ss << (uint8_t)EVAL_FAUCET2 << (uint8_t)'G' << j)); - if ( (len= (int32_t)rawhex.size()) > 0 && len < 65536 ) - { - len >>= 1; - decode_hex(buf,len,(char *)rawhex.c_str()); - hash = bits256_doublesha256(0,buf,len); - if ( (hash.bytes[0] & 0xff) == 0 && (hash.bytes[31] & 0xff) == 0 ) - { - fprintf(stderr,"found valid txid after %d iterations %u\n",i,(uint32_t)time(NULL)); - return(rawhex); - } - //fprintf(stderr,"%02x%02x ",hash.bytes[0],hash.bytes[31]); - } - } - fprintf(stderr,"couldnt generate valid txid %u\n",(uint32_t)time(NULL)); - return(""); - } else fprintf(stderr,"cant find faucet inputs\n"); return(""); } UniValue cclib_error(UniValue &result,const char *errorstr) { - result.push_back(Pair("status","error")); - result.push_back(Pair("error",errorstr)); return(result); } @@ -227,12 +160,7 @@ uint256 juint256(cJSON *obj) int32_t cclib_parsehash(uint8_t *hash32,cJSON *item,int32_t len) { - char *hexstr; - if ( (hexstr= jstr(item,0)) != 0 && is_hexstr(hexstr,0) == len*2 ) - { - decode_hex(hash32,len,hexstr); - return(0); - } else return(-1); + return(0); } diff --git a/src/cc/heir_validate.h b/src/cc/heir_validate.h deleted file mode 100644 index 4e0a24668..000000000 --- a/src/cc/heir_validate.h +++ /dev/null @@ -1,679 +0,0 @@ -// Copyright (c) 2016-2023 The Hush developers -// Distributed under the GPLv3 software license, see the accompanying -// file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html -#ifndef HEIR_VALIDATE_H -#define HEIR_VALIDATE_H - -#include "CCinclude.h" -#include "CCHeir.h" - -#define IS_CHARINSTR(c, str) (std::string(str).find((char)(c)) != std::string::npos) - -// makes coin initial tx opret -vscript_t EncodeHeirCreateOpRet(uint8_t funcid, CPubKey ownerPubkey, CPubKey heirPubkey, int64_t inactivityTimeSec, std::string heirName, std::string memo); -vscript_t EncodeHeirOpRet(uint8_t funcid, uint256 fundingtxid, uint8_t isHeirSpendingBegan); - -uint256 FindLatestFundingTx(uint256 fundingtxid, uint256 &tokenid, CScript& opRetScript, uint8_t &isHeirSpendingBegan); -//uint8_t DecodeHeirOpRet(CScript scriptPubKey, uint256& fundingtxid, uint8_t &isHeirSpendingBegan, bool noLogging = false); -//uint8_t DecodeHeirOpRet(CScript scriptPubKey, CPubKey& ownerPubkey, CPubKey& heirPubkey, int64_t& inactivityTime, std::string& heirName, bool noLogging = false); -uint8_t DecodeHeirEitherOpRet(CScript scriptPubKey, uint256 &tokenid, CPubKey& ownerPubkey, CPubKey& heirPubkey, int64_t& inactivityTime, std::string& heirName, std::string& memo, bool noLogging = false); -uint8_t DecodeHeirEitherOpRet(CScript scriptPubKey, uint256 &tokenid, uint256 &fundingTxidInOpret, uint8_t &hasHeirSpendingBegun, bool noLogging = false); - -inline static bool isMyFuncId(uint8_t funcid) { return IS_CHARINSTR(funcid, "FAC"); } -inline static bool isSpendingTx(uint8_t funcid) { return (funcid == 'C'); } - -// helper class to allow polymorphic behaviour for HeirXXX() functions in case of coins -class CoinHelper { -public: - - static uint8_t getMyEval() { return EVAL_HEIR; } - static int64_t addOwnerInputs(uint256 dummyid, CMutableTransaction& mtx, CPubKey ownerPubkey, int64_t total, int32_t maxinputs) { - return AddNormalinputs(mtx, ownerPubkey, total, maxinputs); - } - - static CScript makeCreateOpRet(uint256 dummyid, std::vector dummyPubkeys, CPubKey ownerPubkey, CPubKey heirPubkey, int64_t inactivityTimeSec, std::string heirName, std::string memo) { - return CScript() << OP_RETURN << EncodeHeirCreateOpRet((uint8_t)'F', ownerPubkey, heirPubkey, inactivityTimeSec, heirName, memo); - } - static CScript makeAddOpRet(uint256 dummyid, std::vector dummyPubkeys, uint256 fundingtxid, uint8_t isHeirSpendingBegan) { - return CScript() << OP_RETURN << EncodeHeirOpRet((uint8_t)'A', fundingtxid, isHeirSpendingBegan); - } - static CScript makeClaimOpRet(uint256 dummyid, std::vector dummyPubkeys, uint256 fundingtxid, uint8_t isHeirSpendingBegan) { - return CScript() << OP_RETURN << EncodeHeirOpRet((uint8_t)'C', fundingtxid, isHeirSpendingBegan); - } - static CTxOut make1of2Vout(int64_t amount, CPubKey ownerPubkey, CPubKey heirPubkey) { - return MakeCC1of2vout(EVAL_HEIR, amount, ownerPubkey, heirPubkey); - } - static CTxOut makeUserVout(int64_t amount, CPubKey myPubkey) { - return CTxOut(amount, CScript() << ParseHex(HexStr(myPubkey)) << OP_CHECKSIG); - } - /* static CTxOut makeClaimerVout(int64_t amount, CPubKey myPubkey) { - return CTxOut(amount, CScript() << ParseHex(HexStr(myPubkey)) << OP_CHECKSIG); - } */ - static bool GetCoinsOrTokensCCaddress1of2(char *coinaddr, CPubKey ownerPubkey, CPubKey heirPubkey) { - struct CCcontract_info *cpHeir, heirC; - cpHeir = CCinit(&heirC, EVAL_HEIR); - return GetCCaddress1of2(cpHeir, coinaddr, ownerPubkey, heirPubkey); - } - static void CCaddrCoinsOrTokens1of2set(struct CCcontract_info *cp, CPubKey ownerPubkey, CPubKey heirPubkey, char *coinaddr) - { - uint8_t mypriv[32]; - Myprivkey(mypriv); - CCaddr1of2set(cp, ownerPubkey, heirPubkey,mypriv, coinaddr); - memset(mypriv,0,sizeof(mypriv)); - } -}; - -// helper class to allow polymorphic behaviour for HeirXXX() functions in case of tokens -class TokenHelper { -public: - static uint8_t getMyEval() { return EVAL_TOKENS; } - static int64_t addOwnerInputs(uint256 tokenid, CMutableTransaction& mtx, CPubKey ownerPubkey, int64_t total, int32_t maxinputs) { - /* - struct CCcontract_info *cpHeir, heirC; - cpHeir = CCinit(&heirC, EVAL_TOKENS); - return AddTokenCCInputs(cpHeir, mtx, ownerPubkey, tokenid, total, maxinputs); - */ - return 0; - } - - static CScript makeCreateOpRet(uint256 tokenid, std::vector voutTokenPubkeys, CPubKey ownerPubkey, CPubKey heirPubkey, int64_t inactivityTimeSec, std::string heirName, std::string memo) { - return EncodeTokenOpRet(tokenid, voutTokenPubkeys, - std::make_pair(OPRETID_HEIRDATA, EncodeHeirCreateOpRet((uint8_t)'F', ownerPubkey, heirPubkey, inactivityTimeSec, heirName, memo))); - } - static CScript makeAddOpRet(uint256 tokenid, std::vector voutTokenPubkeys, uint256 fundingtxid, uint8_t isHeirSpendingBegan) { - return EncodeTokenOpRet(tokenid, voutTokenPubkeys, - std::make_pair(OPRETID_HEIRDATA, EncodeHeirOpRet((uint8_t)'A', fundingtxid, isHeirSpendingBegan))); - } - static CScript makeClaimOpRet(uint256 tokenid, std::vector voutTokenPubkeys, uint256 fundingtxid, uint8_t isHeirSpendingBegan) { - return EncodeTokenOpRet(tokenid, voutTokenPubkeys, - std::make_pair(OPRETID_HEIRDATA, EncodeHeirOpRet((uint8_t)'C', fundingtxid, isHeirSpendingBegan))); - } - - static CTxOut make1of2Vout(int64_t amount, CPubKey ownerPubkey, CPubKey heirPubkey) { - return MakeTokensCC1of2vout(EVAL_HEIR, amount, ownerPubkey, heirPubkey); - } - static CTxOut makeUserVout(int64_t amount, CPubKey myPubkey) { - return MakeCC1vout(EVAL_TOKENS, amount, myPubkey); // yes EVAL_TOKENS - } - /* static CTxOut makeClaimerVout(int64_t amount, CPubKey myPubkey) { - return MakeCC1vout(EVAL_TOKENS, amount, myPubkey); // yes EVAL_TOKENS - } */ - static bool GetCoinsOrTokensCCaddress1of2(char *coinaddr, CPubKey ownerPubkey, CPubKey heirPubkey) { - struct CCcontract_info *cpHeir, heirC; - cpHeir = CCinit(&heirC, EVAL_HEIR); - return GetTokensCCaddress1of2(cpHeir, coinaddr, ownerPubkey, heirPubkey); - } - - static void CCaddrCoinsOrTokens1of2set(struct CCcontract_info *cp, CPubKey ownerPubkey, CPubKey heirPubkey, char *coinaddr) { - uint8_t mypriv[32]; - Myprivkey(mypriv); - CCaddrTokens1of2set(cp, ownerPubkey, heirPubkey, mypriv, coinaddr); - memset(mypriv,0,sizeof(mypriv)); - } -}; - - -/** - * Small framework for vins and vouts validation implementing a variation of 'chain of responsibility' pattern: - * It consists of two classes CInputValidationPlan and COutputValidationPlan which both are configured with an array of vectors of validators - * (These validators are derived from the class CValidatorBase). - * - * A example of a validator may verify for a vout if its public key corresponds to the public key which is stored in opreturn. - * Or, vin validator may check if this vin depicts correctly to the CC contract's address. - * - * For validating vins CInputValidator additionally is provided with an instance of a class derived from the CInputIdentifierBase class. - * this identifier class allows to select identical vins (for example, normal vins or cc input vins) and apply validators from the corresponding vector to it. - * Note: CInputValidator treats that at least one identified vin should be present, otherwise it returns eval->invalid() and false. - * - * For validating vouts COutputValidator is configured for each vector of validators with the vout index to which these validators are applied - * (see constructors of both CInputValidator and COutputValidator) - */ - -/** - * base class for all validators - */ -class CValidatorBase -{ -public: - CValidatorBase(CCcontract_info* cp) : m_cp(cp) {} - virtual bool isVinValidator() const = 0; - virtual bool validateVin(CTxIn vin, std::vector prevVout, int32_t prevN, std::string& message) const = 0; - virtual bool validateVout(CTxOut vout, int32_t vout_n, std::string& message) const = 0; - -protected: - CCcontract_info * m_cp; -}; - -/** - * Base class for classes which identify vins as normal or cc inputs - */ -class CInputIdentifierBase -{ -public: - CInputIdentifierBase(CCcontract_info* cp) : m_cp(cp) {} - virtual std::string inputName() const = 0; - virtual bool identifyInput(CTxIn vin) const = 0; -protected: - CCcontract_info * m_cp; -}; - -/** - * Encapsulates an array containing rows of validators - * Each row is a vector of validators (zero is possible) for validating vins or prev tx's vouts - * this validation plan is used for validating tx inputs - */ -template -class CInputValidationPlan -{ - using ValidatorsRow = std::vector; - -public: - - // Pushes a row of validators for validating a vin or vout - // @param CInputIdentifierBase* pointer to class-identifier which determines several identical adjacent vins (like in schema "vin.0+: normal inputs") - // @param pargs parameter pack of zero or more pointer to validator objects - // Why pointers? because we store the base class in validators' row and then call its virtual functions - template - void pushValidators(CInputIdentifierBase *identifier, ARGS*... pargs) // validators row passed as variadic arguments CValidatorX *val1, CValidatorY *val2 ... - { - ValidatorsRow vValidators({ (TValidatorBase*)pargs... }); - m_arrayValidators.push_back(std::make_pair(identifier, vValidators)); - } - - // validate tx inputs and corresponding prev tx vouts - bool validate(const CTransaction& tx, Eval* eval) - { - std::string message = ""; - //std::cerr << "CInputValidationPlan::validate() starting vins validation..." << std::endl; - - int32_t ival = 0; - int32_t iv = 0; - int32_t numv = tx.vin.size(); - int32_t numValidators = m_arrayValidators.size(); - - // run over vins: - while (iv < numv && ival < numValidators) { - - int32_t identifiedCount = 0; - CInputIdentifierBase *identifier = m_arrayValidators[ival].first; - // check if this is 'our' input: - while (iv < numv && identifier->identifyInput(tx.vin[iv])) { - - // get prev tx: - CTransaction prevTx, *pPrevTxOrNull = NULL; - uint256 hashBlock; - - if (!eval->GetTxUnconfirmed(tx.vin[iv].prevout.hash, prevTx, hashBlock)) { - std::ostringstream stream; - stream << "can't find vinTx for vin=" << iv << "."; - return eval->Invalid(stream.str().c_str()); - } - pPrevTxOrNull = &prevTx; // TODO: get prev tx only if it required (i.e. if vout validators are present) - - // exec 'validators' from validator row of ival index, for tx.vin[iv] - if (!execValidatorsInRow(&tx, pPrevTxOrNull, iv, ival, message)) { - std::ostringstream stream; - stream << "invalid tx vin[" << iv << "]:" << message; - return eval->Invalid(stream.str().c_str()); // ... if not, return 'invalid' - } - - identifiedCount++; // how many vins we identified - iv++; // advance to the next vin - } - - // CInputValidationPlan treats that there must be at least one identified vin for configured validators' row - // like in 'vin.0: normal input' - if (identifiedCount == 0) { - std::ostringstream stream; - stream << "can't find required vins for " << identifier->inputName() << "."; - return eval->Invalid(stream.str().c_str()); - } - - ival++; // advance to the next validator row - // and it will try the same vin with the new CInputIdentifierBase and validators row - } - - // validation is successful if all validators have been used (i.e. ival = numValidators) - if (ival < numValidators) { - std::cerr << "CInputValidationPlan::validate() incorrect tx" << " ival=" << ival << " numValidators=" << numValidators << std::endl; - return eval->Invalid("incorrect tx structure: not all required vins are present."); - } - - //std::cerr << "CInputValidationPlan::validate() returns with true" << std::endl; - return true; - } - -private: - // Executes validators from the requested row of validators (selected by iValidators) for selected vin or vout (selected by iv) - bool execValidatorsInRow(const CTransaction* pTx, const CTransaction* pPrevTx, int32_t iv, int32_t ival, std::string& refMessage) const - { - // check boundaries: - if (ival < 0 || ival >= m_arrayValidators.size()) { - std::cerr << "CInputValidationPlan::execValidatorsInRow() internal error: incorrect param ival=" << ival << " size=" << m_arrayValidators.size(); - refMessage = "internal error: incorrect param ival index"; - return false; - } - - if (iv < 0 || iv >= pTx->vin.size()) { - std::cerr << "CInputValidationPlan::execValidatorsInRow() internal error: incorrect param iv=" << iv << " size=" << m_arrayValidators.size(); - refMessage = "internal error: incorrect param iv index"; - return false; - } - - // get requested row of validators: - ValidatorsRow vValidators = m_arrayValidators[ival].second; - - //std::cerr << "CInputValidationPlan::execValidatorsInRow() calling validators" << " for vin iv=" << iv << " ival=" << ival << std::endl; - - for (auto v : vValidators) { - bool result; - - if (v->isVinValidator()) - // validate this vin and previous vout: - result = v->validateVin(pTx->vin[iv], pPrevTx->vout, pTx->vin[iv].prevout.n, refMessage); - else - // if it is vout validator pass the previous tx vout: - result = v->validateVout( pPrevTx->vout[pTx->vin[iv].prevout.n], pTx->vin[iv].prevout.n, refMessage); - if (!result) { - return result; - } - } - return true; // validation OK - } - - -private: - //std::map m_arrayValidators; - std::vector< std::pair > m_arrayValidators; - -}; - - -/** - * Encapsulates an array containing rows of validators - * Each row is a vector of validators (zero is possible) for validating vouts - * this validation plan is used for validating tx outputs - */ -template -class COutputValidationPlan -{ - using ValidatorsRow = std::vector; - -public: - // Pushes a row of validators for validating a vout - // @param ivout index to vout to validate - // @param pargs parameter pack of zero or more pointer to validator objects - // Why pointers? because we store base class and call its virtual functions - - template - void pushValidators(int32_t ivout, ARGS*... pargs) // validators row passed as variadic arguments CValidatorX *val1, CValidatorY *val2 ... - { - ValidatorsRow vValidators({ (TValidatorBase*)pargs... }); - m_arrayValidators.push_back(std::make_pair(ivout, vValidators)); - } - - // validate tx outputs - bool validate(const CTransaction& tx, Eval* eval) - { - std::string message = ""; - //std::cerr << "COutputValidationPlan::validateOutputs() starting vouts validation..." << std::endl; - - int32_t ival = 0; - int32_t numVouts = tx.vout.size(); - int32_t numValidators = m_arrayValidators.size(); - - // run over vouts: - while (ival < numValidators) { - - int32_t ivout = m_arrayValidators[ival].first; - if (ivout >= numVouts) { - std::cerr << "COutputValidationPlan::validate() incorrect tx" << "for ival=" << ival << " in tx.vout no such ivout=" << ivout << std::endl; - return eval->Invalid("incorrect tx structure: not all required vouts are present."); - } - else - { - // exec 'validators' from validator row of ival index, for tx.vout[ivout] - if (!execValidatorsInRow(&tx, ivout, ival, message)) { - std::ostringstream stream; - stream << "invalid tx vout[" << ivout << "]:" << message; - return eval->Invalid(stream.str().c_str()); // ... if not, return 'invalid' - } - } - ival++; // advance to the next vout - } - //std::cerr << "COutputValidationPlan::validate() returns with true" << std::endl; - return true; - } - -private: - // Executes validators from the requested row of validators (selected by iValidators) for selected vin or vout (selected by iv) - bool execValidatorsInRow(const CTransaction* pTx, int32_t iv, int32_t ival, std::string& refMessage) const - { - // check boundaries: - if (ival < 0 || ival >= m_arrayValidators.size()) { - std::cerr << "COutputValidationPlan::execValidatorsInRow() internal error: incorrect param ival=" << ival << " size=" << m_arrayValidators.size(); - refMessage = "internal error: incorrect param ival index"; - return false; - } - - if (iv < 0 || iv >= pTx->vout.size()) { - std::cerr << "COutputValidationPlan::execValidatorsInRow() internal error: incorrect param iv=" << iv << " size=" << m_arrayValidators.size(); - refMessage = "internal error: incorrect param iv index"; - return false; - } - - // get requested row of validators: - ValidatorsRow vValidators = m_arrayValidators[ival].second; - - //std::cerr << "COutputValidationPlan::execRow() calling validators" << " for vout iv=" << iv << " ival=" << ival << std::endl; - - for (auto v : vValidators) { - - if (!v->isVinValidator()) { - // if this is a 'in' validation plan then pass the previous tx vout: - bool result = v->validateVout(pTx->vout[iv], iv, refMessage); - if (!result) - return result; - } - } - return true; // validation OK - } - -private: - //std::map m_mapValidators; - std::vector< std::pair > m_arrayValidators; - -}; - -class CNormalInputIdentifier : CInputIdentifierBase { -public: - CNormalInputIdentifier(CCcontract_info* cp) : CInputIdentifierBase(cp) {} - virtual std::string inputName() const { return std::string("normal input"); } - virtual bool identifyInput(CTxIn vin) const { - return !IsCCInput(vin.scriptSig); - } -}; - -class CCCInputIdentifier : CInputIdentifierBase { -public: - CCCInputIdentifier(CCcontract_info* cp) : CInputIdentifierBase(cp) {} - virtual std::string inputName() const { return std::string("CC input"); } - virtual bool identifyInput(CTxIn vin) const { - return IsCCInput(vin.scriptSig); - } -}; - - -/** - * Validates 1of2address for vout (may be used for either this or prev tx) - */ -template class CCC1of2AddressValidator : CValidatorBase -{ -public: - CCC1of2AddressValidator(CCcontract_info* cp, CScript opRetScript, std::string customMessage = "") : - m_fundingOpretScript(opRetScript), m_customMessage(customMessage), CValidatorBase(cp) {} - - virtual bool isVinValidator() const { return false; } - virtual bool validateVout(CTxOut vout, int32_t vout_n, std::string& message) const - { - //std::cerr << "CCC1of2AddressValidator::validateVout() entered" << std::endl; - CPubKey ownerPubkey, heirPubkey; - int64_t inactivityTime; - std::string heirName, memo; - uint256 tokenid; - - uint8_t funcId = DecodeHeirEitherOpRet(m_fundingOpretScript, tokenid, ownerPubkey, heirPubkey, inactivityTime, heirName, memo, true); - if (funcId == 0) { - message = m_customMessage + std::string(" invalid opreturn format"); - std::cerr << "CCC1of2AddressValidator::validateVout() exits with false: " << message << std::endl; - return false; - } - - char shouldBeAddr[65], ccAddr[65]; - - //GetCCaddress1of2(m_cp, shouldBeAddr, ownerPubkey, heirPubkey); - Helper::GetCoinsOrTokensCCaddress1of2(shouldBeAddr, ownerPubkey, heirPubkey); - - if (vout.scriptPubKey.IsPayToCryptoCondition()) { - if (Getscriptaddress(ccAddr, vout.scriptPubKey) && strcmp(shouldBeAddr, ccAddr) == 0) { - //std::cerr << "CCC1of2AddressValidator::validateVout() exits with true" << std::endl; - return true; - } - else { - message = m_customMessage + std::string(" incorrect heir funding address: incorrect pubkey(s)"); - } - } - else { - message = m_customMessage + std::string(" incorrect heir funding address: not a 1of2addr"); - } - - std::cerr << "CCC1of2AddressValidator::validateVout() exits with false: " << message << std::endl; - return false; - } - virtual bool validateVin(CTxIn vin, std::vector prevVout, int32_t prevN, std::string& message) const { return false; } - -private: - CScript m_fundingOpretScript; - std::string m_customMessage; -}; - - -/** - * Validates if this is vout to owner or heir from opret (funding or change) - */ -template class CMyPubkeyVoutValidator : CValidatorBase -{ -public: - CMyPubkeyVoutValidator(CCcontract_info* cp, CScript opRetScript, bool checkNormals) - : m_fundingOpretScript(opRetScript), m_checkNormals(checkNormals), CValidatorBase(cp) { } - - virtual bool isVinValidator() const { return false; } - virtual bool validateVout(CTxOut vout, int32_t vout_n, std::string& message) const - { - //std::cerr << "CMyPubkeyVoutValidator::validateVout() entered" << std::endl; - - CPubKey ownerPubkey, heirPubkey; - int64_t inactivityTime; - std::string heirName, memo; - uint256 tokenid; - - ///std::cerr << "CMyPubkeyVoutValidator::validateVout() m_opRetScript=" << m_opRetScript.ToString() << std::endl; - - // get both pubkeys: - uint8_t funcId = DecodeHeirEitherOpRet(m_fundingOpretScript, tokenid, ownerPubkey, heirPubkey, inactivityTime, heirName, memo, true); - if (funcId == 0) { - message = std::string("invalid opreturn format"); - return false; - } - - CScript ownerScript; - CScript heirScript; - if (m_checkNormals) { //not used, incorrect check, too strict - ownerScript = CoinHelper::makeUserVout(vout.nValue, ownerPubkey).scriptPubKey; - heirScript = CoinHelper::makeUserVout(vout.nValue, heirPubkey).scriptPubKey; - std::cerr << "CMyPubkeyVoutValidator::validateVout() vout.scriptPubKey=" << vout.scriptPubKey.ToString() << " makeUserVout(coin,owner)=" << CoinHelper::makeUserVout(vout.nValue, ownerPubkey).scriptPubKey.ToString() << " makeUserVout(coin,heir)=" << CoinHelper::makeUserVout(vout.nValue, heirPubkey).scriptPubKey.ToString() << std::endl; - } - else { - ownerScript = Helper::makeUserVout(vout.nValue, ownerPubkey).scriptPubKey; - heirScript = Helper::makeUserVout(vout.nValue, heirPubkey).scriptPubKey; - std::cerr << "CMyPubkeyVoutValidator::validateVout() vout.scriptPubKey=" << vout.scriptPubKey.ToString() << " makeUserVout(owner)=" << Helper::makeUserVout(vout.nValue, ownerPubkey).scriptPubKey.ToString() << " makeUserVout(heir)=" << Helper::makeUserVout(vout.nValue, heirPubkey).scriptPubKey.ToString() << std::endl; - } - - // recreate scriptPubKey for owner and heir and compare it with that of the vout to check: - if (vout.scriptPubKey == ownerScript || vout.scriptPubKey == heirScript) { - // this is vout to owner or heir addr: - //std::cerr << "CMyPubkeyVoutValidator::validateVout() exits with true" << std::endl; - return true; - } - - std::cerr << "CMyPubkeyVoutValidator::validateVout() exits with false (not the owner's or heir's addresses)" << std::endl; - message = std::string("invalid pubkey"); - return false; - } - virtual bool validateVin(CTxIn vin, std::vector prevVout, int32_t prevN, std::string& message) const { return true; } - -private: - CScript m_fundingOpretScript; - //uint256 m_lasttxid; - bool m_checkNormals; -}; - -/** - * Check if the user is the heir and the heir is allowed to spend (duration > inactivityTime) - */ -template class CHeirSpendValidator : CValidatorBase -{ -public: - CHeirSpendValidator(CCcontract_info* cp, CScript opRetScript, uint256 latesttxid, uint8_t isHeirSpendingBegan) - : m_fundingOpretScript(opRetScript), m_latesttxid(latesttxid), m_isHeirSpendingBegan(isHeirSpendingBegan), CValidatorBase(cp) {} - - virtual bool isVinValidator() const { return false; } - virtual bool validateVout(CTxOut vout, int32_t vout_n, std::string& message) const - { - //std::cerr << "CHeirSpendValidator::validateVout() entered" << std::endl; - - CPubKey ownerPubkey, heirPubkey; - int64_t inactivityTime; - std::string heirName, memo; - uint256 tokenid; - - // get heir pubkey: - uint8_t funcId = DecodeHeirEitherOpRet(m_fundingOpretScript, tokenid, ownerPubkey, heirPubkey, inactivityTime, heirName, memo, true); - if (funcId == 0) { - message = std::string("invalid opreturn format"); - return false; - } - - int32_t numblocks; - int64_t durationSec = CCduration(numblocks, m_latesttxid); - - // recreate scriptPubKey for heir and compare it with that of the vout: - if (vout.scriptPubKey == Helper::makeUserVout(vout.nValue, heirPubkey).scriptPubKey) { - // this is the heir is trying to spend - if (!m_isHeirSpendingBegan && durationSec <= inactivityTime) { - message = "heir is not allowed yet to spend funds"; - std::cerr << "CHeirSpendValidator::validateVout() heir is not allowed yet to spend funds" << std::endl; - return false; - } - else { - // heir is allowed to spend - return true; - } - } - - //std::cerr << "CHeirSpendValidator::validateVout() exits with true" << std::endl; - - // this is not heir: - return true; - } - virtual bool validateVin(CTxIn vin, std::vector prevVout, int32_t prevN, std::string& message) const { return true; } - -private: - CScript m_fundingOpretScript; - uint256 m_latesttxid; - uint8_t m_isHeirSpendingBegan; -}; - -/** - * Validates this opreturn and compares it with the opreturn from the previous tx - */ -template class COpRetValidator : CValidatorBase -{ -public: - COpRetValidator(CCcontract_info* cp, CScript opret) - : m_fundingOpretScript(opret), CValidatorBase(cp) {} - - virtual bool isVinValidator() const { return false; } - virtual bool validateVout(CTxOut vout, int32_t vout_n, std::string& message) const - { - //std::cerr << "COpRetValidator::validateVout() entered" << std::endl; - - uint256 fundingTxidInOpret = zeroid, dummyTxid, tokenid = zeroid, initialTokenid = zeroid; - uint8_t dummyIsHeirSpendingBegan; - - uint8_t funcId = DecodeHeirEitherOpRet(vout.scriptPubKey, tokenid, fundingTxidInOpret, dummyIsHeirSpendingBegan, true); - if (funcId == 0) { - message = std::string("invalid opreturn format"); - return false; - } - - uint8_t initialFuncId = DecodeHeirEitherOpRet(m_fundingOpretScript, initialTokenid, dummyTxid, dummyIsHeirSpendingBegan, true); - if (initialFuncId == 0) { - message = std::string("invalid initial tx opreturn format"); - return false; - } - - // validation rules: - if (!isMyFuncId(funcId)) { - message = std::string("invalid funcid in opret"); - return false; - } - - if (typeid(Helper) == typeid(TokenHelper)) { - if (tokenid != initialTokenid) { - message = std::string("invalid tokenid in opret"); - return false; - } - } - - //std::cerr << "COpRetValidator::validateVout() exits with true" << std::endl; - return true; - } - virtual bool validateVin(CTxIn vin, std::vector prevVout, int32_t prevN, std::string& message) const { return true; } - -private: - CScript m_fundingOpretScript; -}; - - -/** - * marker spending prevention validator, - * returns false if for tx with funcid=F vout.1 is being tried to spend - */ -template class CMarkerValidator : CValidatorBase -{ -public: - CMarkerValidator(CCcontract_info* cp) - : CValidatorBase(cp) { } - - virtual bool isVinValidator() const { return true; } // this is vin validator - virtual bool validateVout(CTxOut vout, int32_t vout_n, std::string& message) const { return true; } - virtual bool validateVin(CTxIn vin, std::vector prevVout, int32_t prevN, std::string& message) const { - - uint256 fundingTxidInOpret = zeroid, dummyTxid, tokenid = zeroid, initialTokenid = zeroid; - uint8_t dummyIsHeirSpendingBegan; - - //std::cerr << "CMarkerValidator::validateVin() prevVout.size()=" << prevVout.size() << " prevN=" << prevN << std::endl; - if (prevVout.size() > 0) { - - // get funcId for prev tx: - uint8_t funcId = DecodeHeirEitherOpRet(prevVout[prevVout.size()-1].scriptPubKey, tokenid, fundingTxidInOpret, dummyIsHeirSpendingBegan, true); - - //std::cerr << "CMarkerValidator::validateVin() funcId=" << (funcId?funcId:' ') << std::endl; - - if (funcId == 'F' && prevN == 1) { // do not allow to spend 'F' marker's vout - message = std::string("spending marker not allowed"); - return false; - } - } - //std::cerr << "CMarkerValidator::validateVin() exits with true" << std::endl; - return true; - } -}; - -/** - * empty validator always returns true - */ -template class CNullValidator : CValidatorBase -{ -public: - CNullValidator(CCcontract_info* cp) - : CValidatorBase(cp) { } - - virtual bool isVinValidator() const { return false; } - virtual bool validateVout(CTxOut vout, int32_t vout_n, std::string& message) const { return true; } - virtual bool validateVin(CTxIn vin, std::vector prevVout, int32_t prevN, std::string& message) const { return true; } -}; - - -#endif From 5b9906539d7100ab8a27ab8e323b81fdd06139f2 Mon Sep 17 00:00:00 2001 From: Duke Date: Sat, 10 Feb 2024 12:44:47 -0500 Subject: [PATCH 19/78] Delete more CCs #381 --- src/cc/eval.cpp | 99 +++--------------------------------------------- src/cc/makegames | 7 ---- src/cc/makerogue | 39 ------------------- 3 files changed, 5 insertions(+), 140 deletions(-) delete mode 100755 src/cc/makegames delete mode 100755 src/cc/makerogue diff --git a/src/cc/eval.cpp b/src/cc/eval.cpp index c4b3cde79..9c8aeb22b 100644 --- a/src/cc/eval.cpp +++ b/src/cc/eval.cpp @@ -37,32 +37,6 @@ extern pthread_mutex_t HUSH_CC_mutex; bool RunCCEval(const CC *cond, const CTransaction &tx, unsigned int nIn) { - EvalRef eval; - pthread_mutex_lock(&HUSH_CC_mutex); - bool out = eval->Dispatch(cond, tx, nIn); - pthread_mutex_unlock(&HUSH_CC_mutex); - if ( eval->state.IsValid() != out) - fprintf(stderr,"out %d vs %d isValid\n",(int32_t)out,(int32_t)eval->state.IsValid()); - //assert(eval->state.IsValid() == out); - - if (eval->state.IsValid()) return true; - - std::string lvl = eval->state.IsInvalid() ? "Invalid" : "Error!"; - fprintf(stderr, "CC Eval %s %s: %s spending tx %s\n", - EvalToStr(cond->code[0]).data(), - lvl.data(), - eval->state.GetRejectReason().data(), - tx.vin[nIn].prevout.hash.GetHex().data()); - if (eval->state.IsError()) fprintf(stderr, "Culprit: %s\n", EncodeHexTx(tx).data()); - CTransaction tmp; - if (mempool.lookup(tx.GetHash(), tmp)) - { - // This is to remove a payments airdrop if it gets stuck in the mempool. - // Miner will mine 1 invalid block, but doesnt stop them mining until a restart. - // This would almost never happen in normal use. - std::list dummy; - mempool.remove(tx,dummy,true); - } return false; } @@ -72,51 +46,7 @@ bool RunCCEval(const CC *cond, const CTransaction &tx, unsigned int nIn) */ bool Eval::Dispatch(const CC *cond, const CTransaction &txTo, unsigned int nIn) { - struct CCcontract_info *cp; - if (cond->codeLength == 0) - return Invalid("empty-eval"); - - uint8_t ecode = cond->code[0]; - if ( ASSETCHAINS_CCDISABLES[ecode] != 0 ) - { - // check if a height activation has been set. - if ( mapHeightEvalActivate[ecode] == 0 || this->GetCurrentHeight() == 0 || mapHeightEvalActivate[ecode] > this->GetCurrentHeight() ) - { - fprintf(stderr,"%s evalcode.%d %02x\n",txTo.GetHash().GetHex().c_str(),ecode,ecode); - fprintf(stderr, "ac_ccactivateht: evalcode.%i activates at height.%i vs current height.%i\n", ecode, mapHeightEvalActivate[ecode], this->GetCurrentHeight()); - return Invalid("disabled-code, -ac_ccenables didnt include this ecode"); - } - } - std::vector vparams(cond->code+1, cond->code+cond->codeLength); - if ( ecode >= EVAL_FIRSTUSER && ecode <= EVAL_LASTUSER ) - { - if ( ASSETCHAINS_CCLIB.size() > 0 && ASSETCHAINS_CCLIB == CClib_name() ) - return CClib_Dispatch(cond,this,vparams,txTo,nIn); - else return Invalid("mismatched -ac_cclib vs CClib_name"); - } - cp = &CCinfos[(int32_t)ecode]; - if ( cp->didinit == 0 ) - { - CCinit(cp,ecode); - cp->didinit = 1; - } - - switch ( ecode ) - { - /* - case EVAL_IMPORTPAYOUT: - return ImportPayout(vparams, txTo, nIn); - break; - - case EVAL_IMPORTCOIN: - return ImportCoin(vparams, txTo, nIn); - break; - */ - default: - return(ProcessCC(cp,this, vparams, txTo, nIn)); - break; - } - return Invalid("invalid-code, dont forget to add EVAL_NEWCC to Eval::Dispatch"); + return false; } @@ -129,21 +59,13 @@ bool Eval::GetSpendsConfirmed(uint256 hash, std::vector &spends) c bool Eval::GetTxUnconfirmed(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock) const { - return(myGetTransaction(hash, txOut,hashBlock)); - /*if (!myGetTransaction(hash, txOut,hashBlock)) { - return(myGetTransaction(hash, txOut,hashBlock)); - } else return(true);*/ + return false; } bool Eval::GetTxConfirmed(const uint256 &hash, CTransaction &txOut, CBlockIndex &block) const { - uint256 hashBlock; - if (!GetTxUnconfirmed(hash, txOut, hashBlock)) - return false; - if (hashBlock.IsNull() || !GetBlock(hashBlock, block)) - return false; - return true; + return false; } unsigned int Eval::GetCurrentHeight() const @@ -153,12 +75,6 @@ unsigned int Eval::GetCurrentHeight() const bool Eval::GetBlock(uint256 hash, CBlockIndex& blockIdx) const { - auto r = mapBlockIndex.find(hash); - if (r != mapBlockIndex.end()) { - blockIdx = *r->second; - return true; - } - fprintf(stderr, "CC Eval Error: Can't get block from index\n"); return false; } @@ -172,13 +88,7 @@ int32_t Eval::GetNotaries(uint8_t pubkeys[64][33], int32_t height, uint32_t time bool Eval::CheckNotaryInputs(const CTransaction &tx, uint32_t height, uint32_t timestamp) const { - if (tx.vin.size() < 11) return false; - - CrosschainAuthority auth; - auth.requiredSigs = 11; - auth.size = GetNotaries(auth.notaries, height, timestamp); - - return CheckTxAuthority(tx, auth); + return false; } // Get MoM from a notarization tx hash (on HUSH) @@ -208,6 +118,7 @@ std::string Eval::GetAssetchainsSymbol() const /* * Notarization data, ie, OP_RETURN payload in notarization transactions */ +// This is used by notarizationdb.cpp bool ParseNotarizationOpReturn(const CTransaction &tx, NotarizationData &data) { if (tx.vout.size() < 2) return false; diff --git a/src/cc/makegames b/src/cc/makegames deleted file mode 100755 index b4b8cb803..000000000 --- a/src/cc/makegames +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/sh -gcc -O3 -DBUILD_GAMESCC -std=c++11 -I../secp256k1/include -I../univalue/include -I../cryptoconditions/include -I../cryptoconditions/src -I../cryptoconditions/src/asn -I.. -I. -fPIC -shared -c -o gamescc.so cclib.cpp -cp gamescc.so ../libcc.so -cd .. -make -cd cc - diff --git a/src/cc/makerogue b/src/cc/makerogue deleted file mode 100755 index 99b4f889f..000000000 --- a/src/cc/makerogue +++ /dev/null @@ -1,39 +0,0 @@ -#!/bin/sh -# Copyright 2016-2023 The Hush developers -cd rogue; -make clean; - -if [ "$HOST" = "x86_64-w64-mingw32" ]; then - echo "Not supported" - exit 1 - ./configure --host=x86_64-w64-mingw32 - echo $PWD - # wget ... - tar xvfz x86_64-w64-mingw32.tar.gz && rm x86_64-w64-mingw32.tar.gz - echo lib archive cleaned - echo $PWD - if make -f Makefile_win "$@"; then - echo rogue.exe build SUCCESSFUL - cd .. - else - echo rogue.exe build FAILED - exit 1 - fi -else - echo building rogue... - ./configure - if make "$@"; then - echo rogue build SUCCESSFUL - cd .. - else - echo rogue build FAILED - exit 1 - fi -fi - -if make -f Makefile_rogue "$@"; then - echo ROGUE BUILD SUCCESSFUL -else - echo ROGUE BUILD FAILED - exit 1 -fi From 7bd7a716df6e750daa1bef2689e6cbbe3e0db840 Mon Sep 17 00:00:00 2001 From: Duke Date: Sat, 10 Feb 2024 12:59:10 -0500 Subject: [PATCH 20/78] Delete more CCs #381 --- src/cc/CCtx.cpp | 492 +----------------------------------------------- 1 file changed, 8 insertions(+), 484 deletions(-) diff --git a/src/cc/CCtx.cpp b/src/cc/CCtx.cpp index bc358dcbe..e2b477330 100644 --- a/src/cc/CCtx.cpp +++ b/src/cc/CCtx.cpp @@ -46,350 +46,14 @@ By using -addressindex=1, it allows tracking of all the CC addresses */ std::string FinalizeCCTx(uint64_t CCmask, struct CCcontract_info *cp, CMutableTransaction &mtx, CPubKey mypk, uint64_t txfee, CScript opret, std::vector pubkeys) { - UniValue sigData = FinalizeCCTxExt(false, CCmask, cp, mtx, mypk, txfee, opret, pubkeys); - return sigData[JSON_HEXTX].getValStr(); + return std::string(""); } // extended version that supports signInfo object with conds to vins map for remote cc calls UniValue FinalizeCCTxExt(bool remote, uint64_t CCmask, struct CCcontract_info *cp, CMutableTransaction &mtx, CPubKey mypk, uint64_t txfee, CScript opret, std::vector pubkeys) { - auto consensusBranchId = CurrentEpochBranchId(chainActive.Height() + 1, Params().GetConsensus()); - CTransaction vintx; std::string hex; CPubKey globalpk; uint256 hashBlock; uint64_t mask=0,nmask=0,vinimask=0; - int64_t utxovalues[CC_MAXVINS],change,normalinputs=0,totaloutputs=0,normaloutputs=0,totalinputs=0,normalvins=0,ccvins=0; - int32_t i,flag,mgret,utxovout,n,err = 0; - char myaddr[64], destaddr[64], unspendable[64], mytokensaddr[64], mysingletokensaddr[64], unspendabletokensaddr[64],CC1of2CCaddr[64]; - uint8_t *privkey = NULL, myprivkey[32] = { '\0' }, unspendablepriv[32] = { '\0' }, /*tokensunspendablepriv[32],*/ *msg32 = 0; - CC *mycond=0, *othercond=0, *othercond2=0,*othercond4=0, *othercond3=0, *othercond1of2=NULL, *othercond1of2tokens = NULL, *cond=0, *condCC2=0,*mytokenscond = NULL, *mysingletokenscond = NULL, *othertokenscond = NULL; - CPubKey unspendablepk /*, tokensunspendablepk*/; - struct CCcontract_info *cpTokens, tokensC; - UniValue sigData(UniValue::VARR),result(UniValue::VOBJ); - const UniValue sigDataNull = NullUniValue; - - globalpk = GetUnspendable(cp,0); - n = mtx.vout.size(); - for (i=0; i CC_MAXVINS ) - { - fprintf(stderr,"FinalizeCCTx: %d is too many vins\n",n); - result.push_back(Pair(JSON_HEXTX, "0")); - return result; - } - - //Myprivkey(myprivkey); // for NSPV mode we need to add myprivkey for the explicitly defined mypk param -#ifdef ENABLE_WALLET - // get privkey for mypk - CKeyID keyID = mypk.GetID(); - CKey vchSecret; - if (pwalletMain->GetKey(keyID, vchSecret)) - memcpy(myprivkey, vchSecret.begin(), sizeof(myprivkey)); -#endif - - GetCCaddress(cp,myaddr,mypk); - mycond = MakeCCcond1(cp->evalcode,mypk); - - // to spend from single-eval evalcode 'unspendable' cc addr - unspendablepk = GetUnspendable(cp, unspendablepriv); - GetCCaddress(cp, unspendable, unspendablepk); - othercond = MakeCCcond1(cp->evalcode, unspendablepk); - GetCCaddress1of2(cp,CC1of2CCaddr,unspendablepk,unspendablepk); - - //fprintf(stderr,"evalcode.%d (%s)\n",cp->evalcode,unspendable); - - // tokens support: - // to spend from dual/three-eval mypk vout - GetTokensCCaddress(cp, mytokensaddr, mypk); - // NOTE: if additionalEvalcode2 is not set it is a dual-eval (not three-eval) cc cond: - mytokenscond = MakeTokensCCcond1(cp->evalcode, cp->additionalTokensEvalcode2, mypk); - - // to spend from single-eval EVAL_TOKENS mypk - cpTokens = CCinit(&tokensC, EVAL_TOKENS); - GetCCaddress(cpTokens, mysingletokensaddr, mypk); - mysingletokenscond = MakeCCcond1(EVAL_TOKENS, mypk); - - // to spend from dual/three-eval EVAL_TOKEN+evalcode 'unspendable' pk: - GetTokensCCaddress(cp, unspendabletokensaddr, unspendablepk); // it may be a three-eval cc, if cp->additionalEvalcode2 is set - othertokenscond = MakeTokensCCcond1(cp->evalcode, cp->additionalTokensEvalcode2, unspendablepk); - - //Reorder vins so that for multiple normal vins all other except vin0 goes to the end - //This is a must to avoid hardfork change of validation in every CC, because there could be maximum one normal vin at the begining with current validation. - for (i=0; i1 && ccvins) - { - for(i=1;i= totaloutputs+2*txfee ) - { - change = totalinputs - (totaloutputs+txfee); - mtx.vout.push_back(CTxOut(change,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG)); - } - if ( opret.size() > 0 ) - mtx.vout.push_back(CTxOut(0,opret)); - PrecomputedTransactionData txdata(mtx); - n = mtx.vin.size(); - for (i=0; i %s\n",utxovout,dstr(vintx.vout[utxovout].nValue),addr); - } - if ( NSPV_SignTx(mtx,i,vintx.vout[utxovout].nValue,vintx.vout[utxovout].scriptPubKey,0) == 0 ) - fprintf(stderr,"NSPV signing error for vini.%d of %llx\n",i,(long long)vinimask); - } - } - else - { - Getscriptaddress(destaddr,vintx.vout[utxovout].scriptPubKey); - //fprintf(stderr,"FinalizeCCTx() vin.%d is CC %.8f -> (%s) vs %s\n",i,(double)utxovalues[i]/COIN,destaddr,mysingletokensaddr); - //std::cerr << "FinalizeCCtx() searching destaddr=" << destaddr << " for vin[" << i << "] satoshis=" << utxovalues[i] << std::endl; - if( strcmp(destaddr, myaddr) == 0 ) - { -//fprintf(stderr, "FinalizeCCTx() matched cc myaddr (%s)\n", myaddr); - privkey = myprivkey; - cond = mycond; - } - else if (strcmp(destaddr, mytokensaddr) == 0) // if this is TokensCC1vout - { - privkey = myprivkey; - cond = mytokenscond; -//fprintf(stderr,"FinalizeCCTx() matched dual-eval TokensCC1vout my token addr.(%s)\n",mytokensaddr); - } - else if (strcmp(destaddr, mysingletokensaddr) == 0) // if this is TokensCC1vout - { - privkey = myprivkey; - cond = mysingletokenscond; -//fprintf(stderr, "FinalizeCCTx() matched single-eval token CC1vout my token addr.(%s)\n", mytokensaddr); - } - else if ( strcmp(destaddr,unspendable) == 0 ) - { - privkey = unspendablepriv; - cond = othercond; -//fprintf(stderr,"FinalizeCCTx evalcode(%d) matched unspendable CC addr.(%s)\n",cp->evalcode,unspendable); - } - else if (strcmp(destaddr, unspendabletokensaddr) == 0) - { - privkey = unspendablepriv; - cond = othertokenscond; -//fprintf(stderr,"FinalizeCCTx() matched unspendabletokensaddr dual/three-eval CC addr.(%s)\n",unspendabletokensaddr); - } - // check if this is the 2nd additional evalcode + 'unspendable' cc addr: - else if ( strcmp(destaddr, cp->unspendableaddr2) == 0) - { -//fprintf(stderr,"FinalizeCCTx() matched %s unspendable2!\n",cp->unspendableaddr2); - privkey = cp->unspendablepriv2; - if( othercond2 == 0 ) - othercond2 = MakeCCcond1(cp->unspendableEvalcode2, cp->unspendablepk2); - cond = othercond2; - } - // check if this is 3rd additional evalcode + 'unspendable' cc addr: - else if ( strcmp(destaddr,cp->unspendableaddr3) == 0 ) - { -//fprintf(stderr,"FinalizeCCTx() matched %s unspendable3!\n",cp->unspendableaddr3); - privkey = cp->unspendablepriv3; - if( othercond3 == 0 ) - othercond3 = MakeCCcond1(cp->unspendableEvalcode3, cp->unspendablepk3); - cond = othercond3; - } - // check if this is spending from 1of2 cc coins addr: - else if (strcmp(cp->coins1of2addr, destaddr) == 0) - { -//fprintf(stderr,"FinalizeCCTx() matched %s unspendable1of2!\n",cp->coins1of2addr); - privkey = cp->coins1of2priv;//myprivkey; - if (othercond1of2 == 0) - othercond1of2 = MakeCCcond1of2(cp->evalcode, cp->coins1of2pk[0], cp->coins1of2pk[1]); - cond = othercond1of2; - } - else if ( strcmp(CC1of2CCaddr,destaddr) == 0 ) - { -//fprintf(stderr,"FinalizeCCTx() matched %s CC1of2CCaddr!\n",CC1of2CCaddr); - privkey = unspendablepriv; - if (condCC2 == 0) - condCC2 = MakeCCcond1of2(cp->evalcode,unspendablepk,unspendablepk); - cond = condCC2; - } - // check if this is spending from 1of2 cc tokens addr: - else if (strcmp(cp->tokens1of2addr, destaddr) == 0) - { -//fprintf(stderr,"FinalizeCCTx() matched %s cp->tokens1of2addr!\n", cp->tokens1of2addr); - privkey = cp->tokens1of2priv;//myprivkey; - if (othercond1of2tokens == 0) - // NOTE: if additionalEvalcode2 is not set then it is dual-eval cc else three-eval cc - // TODO: verify evalcodes order if additionalEvalcode2 is not 0 - othercond1of2tokens = MakeTokensCCcond1of2(cp->evalcode, cp->additionalTokensEvalcode2, cp->tokens1of2pk[0], cp->tokens1of2pk[1]); - cond = othercond1of2tokens; - } - else - { - flag = 0; - if ( pubkeys != NULL_pubkeys ) - { - char coinaddr[64]; - GetCCaddress1of2(cp,coinaddr,globalpk,pubkeys[i]); - //fprintf(stderr,"%s + %s -> %s vs %s\n",HexStr(globalpk).c_str(),HexStr(pubkeys[i]).c_str(),coinaddr,destaddr); - if ( strcmp(destaddr,coinaddr) == 0 ) - { - privkey = cp->CCpriv; - if ( othercond4 != 0 ) - cc_free(othercond4); - othercond4 = MakeCCcond1of2(cp->evalcode,globalpk,pubkeys[i]); - cond = othercond4; - flag = 1; - } - } //else privkey = myprivkey; - - if ( flag == 0 ) - { - fprintf(stderr,"CC signing error: vini.%d has unknown CC address.(%s)\n",i,destaddr); - memset(myprivkey,0,32); - return sigDataNull; - } - } - uint256 sighash = SignatureHash(CCPubKey(cond), mtx, i, SIGHASH_ALL,utxovalues[i],consensusBranchId, &txdata); - if ( 0 ) - { - int32_t z; - for (z=0; z<32; z++) - fprintf(stderr,"%02x",privkey[z]); - fprintf(stderr," privkey, "); - for (z=0; z<32; z++) - fprintf(stderr,"%02x",((uint8_t *)sighash.begin())[z]); - fprintf(stderr," sighash [%d] %.8f %x\n",i,(double)utxovalues[i]/COIN,consensusBranchId); - } - - if (!remote) // we have privkey in the wallet - { - if (cc_signTreeSecp256k1Msg32(cond, privkey, sighash.begin()) != 0) - { - mtx.vin[i].scriptSig = CCSig(cond); - } - else - { - fprintf(stderr, "vini.%d has CC signing error address.(%s) %s\n", i, destaddr, EncodeHexTx(mtx).c_str()); - memset(myprivkey, 0, sizeof(myprivkey)); - return sigDataNull; - } - } - else // no privkey locally - remote call - { - // serialize cc: - UniValue ccjson; - ccjson.read(cc_conditionToJSONString(cond)); - if (ccjson.empty()) - { - fprintf(stderr, "vini.%d can't serialize CC.(%s) %s\n", i, destaddr, EncodeHexTx(mtx).c_str()); - memset(myprivkey, 0, sizeof(myprivkey)); - return sigDataNull; - } - - AddSigData2UniValue(sigData, i, ccjson, std::string(), vintx.vout[utxovout].nValue); // store vin i with scriptPubKey - } - } - } else fprintf(stderr,"FinalizeCCTx2 couldnt find %s mgret.%d\n",mtx.vin[i].prevout.hash.ToString().c_str(),mgret); - } - if ( mycond != 0 ) - cc_free(mycond); - if ( condCC2 != 0 ) - cc_free(condCC2); - if ( othercond != 0 ) - cc_free(othercond); - if ( othercond2 != 0 ) - cc_free(othercond2); - if ( othercond3 != 0 ) - cc_free(othercond3); - if ( othercond4 != 0 ) - cc_free(othercond4); - if ( othercond1of2 != 0 ) - cc_free(othercond1of2); - if ( othercond1of2tokens != 0 ) - cc_free(othercond1of2tokens); - if ( mytokenscond != 0 ) - cc_free(mytokenscond); - if ( mysingletokenscond != 0 ) - cc_free(mysingletokenscond); - if ( othertokenscond != 0 ) - cc_free(othertokenscond); - memset(myprivkey,0,sizeof(myprivkey)); - std::string strHex = EncodeHexTx(mtx); - if ( strHex.size() > 0 ) - result.push_back(Pair(JSON_HEXTX, strHex)); - else { - result.push_back(Pair(JSON_HEXTX, "0")); - } - if (sigData.size() > 0) result.push_back(Pair(JSON_SIGDATA,sigData)); + UniValue result(UniValue::VOBJ); return result; } @@ -399,187 +63,47 @@ void NSPV_CCtxids(std::vector &txids,char *coinaddr,bool ccflag, uint8_ void SetCCunspents(std::vector > &unspentOutputs,char *coinaddr,bool ccflag) { - int32_t type=0,i,n; char *ptr; std::string addrstr; uint160 hashBytes; std::vector > addresses; - if ( HUSH_NSPV_SUPERLITE ) - { - NSPV_CCunspents(unspentOutputs,coinaddr,ccflag); - return; - } - n = (int32_t)strlen(coinaddr); - addrstr.resize(n+1); - ptr = (char *)addrstr.data(); - for (i=0; i<=n; i++) - ptr[i] = coinaddr[i]; - CBitcoinAddress address(addrstr); - if ( address.GetIndexKey(hashBytes, type, ccflag) == 0 ) - return; - addresses.push_back(std::make_pair(hashBytes,type)); - for (std::vector >::iterator it = addresses.begin(); it != addresses.end(); it++) - { - if ( GetAddressUnspent((*it).first, (*it).second, unspentOutputs) == 0 ) - return; - } + return; } void SetCCtxids(std::vector > &addressIndex,char *coinaddr,bool ccflag) { - int32_t type=0,i,n; char *ptr; std::string addrstr; uint160 hashBytes; std::vector > addresses; - if ( HUSH_NSPV_SUPERLITE ) - { - NSPV_CCtxids(addressIndex,coinaddr,ccflag); - return; - } - n = (int32_t)strlen(coinaddr); - addrstr.resize(n+1); - ptr = (char *)addrstr.data(); - for (i=0; i<=n; i++) - ptr[i] = coinaddr[i]; - CBitcoinAddress address(addrstr); - if ( address.GetIndexKey(hashBytes, type, ccflag) == 0 ) - return; - addresses.push_back(std::make_pair(hashBytes,type)); - for (std::vector >::iterator it = addresses.begin(); it != addresses.end(); it++) - { - if ( GetAddressIndex((*it).first, (*it).second, addressIndex) == 0 ) - return; - } + return; } void SetCCtxids(std::vector &txids,char *coinaddr,bool ccflag, uint8_t evalcode, uint256 filtertxid, uint8_t func) { - int32_t type=0,i,n; char *ptr; std::string addrstr; uint160 hashBytes; std::vector > addresses; - std::vector > addressIndex; - if ( HUSH_NSPV_SUPERLITE ) - { - NSPV_CCtxids(txids,coinaddr,ccflag,evalcode,filtertxid,func); - return; - } - n = (int32_t)strlen(coinaddr); - addrstr.resize(n+1); - ptr = (char *)addrstr.data(); - for (i=0; i<=n; i++) - ptr[i] = coinaddr[i]; - CBitcoinAddress address(addrstr); - if ( address.GetIndexKey(hashBytes, type, ccflag) == 0 ) - return; - addresses.push_back(std::make_pair(hashBytes,type)); - for (std::vector >::iterator it = addresses.begin(); it != addresses.end(); it++) - { - if ( GetAddressIndex((*it).first, (*it).second, addressIndex) == 0 ) - return; - for (std::vector >::const_iterator it1=addressIndex.begin(); it1!=addressIndex.end(); it1++) - { - if (it1->second>=0) txids.push_back(it1->first.txhash); - } - } + return; } int64_t CCutxovalue(char *coinaddr,uint256 utxotxid,int32_t utxovout,int32_t CCflag) { - uint256 txid; std::vector > unspentOutputs; - SetCCunspents(unspentOutputs,coinaddr,CCflag!=0?true:false); - for (std::vector >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++) - { - txid = it->first.txhash; - if ( txid == utxotxid && utxovout == it->first.index ) - return(it->second.satoshis); - } return(0); } int64_t CCgettxout(uint256 txid,int32_t vout,int32_t mempoolflag,int32_t lockflag) { - CCoins coins; - //fprintf(stderr,"CCgettxoud %s/v%d\n",txid.GetHex().c_str(),vout); - if ( mempoolflag != 0 ) - { - if ( lockflag != 0 ) - { - LOCK(mempool.cs); - CCoinsViewMemPool view(pcoinsTip, mempool); - if (!view.GetCoins(txid, coins)) - return(-1); - else if ( myIsutxo_spentinmempool(ignoretxid,ignorevin,txid,vout) != 0 ) - return(-1); - } - else - { - CCoinsViewMemPool view(pcoinsTip, mempool); - if (!view.GetCoins(txid, coins)) - return(-1); - else if ( myIsutxo_spentinmempool(ignoretxid,ignorevin,txid,vout) != 0 ) - return(-1); - } - } - else - { - if (!pcoinsTip->GetCoins(txid, coins)) - return(-1); - } - if ( vout < coins.vout.size() ) - return(coins.vout[vout].nValue); - else return(-1); + return(-1); } int32_t CCgetspenttxid(uint256 &spenttxid,int32_t &vini,int32_t &height,uint256 txid,int32_t vout) { - CSpentIndexKey key(txid, vout); - CSpentIndexValue value; - if ( !GetSpentIndex(key, value) ) - return(-1); - spenttxid = value.txid; - vini = (int32_t)value.inputIndex; - height = value.blockHeight; return(0); } int64_t CCaddress_balance(char *coinaddr,int32_t CCflag) { - int64_t sum = 0; std::vector > unspentOutputs; - SetCCunspents(unspentOutputs,coinaddr,CCflag!=0?true:false); - for (std::vector >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++) - { - sum += it->second.satoshis; - } - return(sum); + return 0; } int64_t CCfullsupply(uint256 tokenid) { - uint256 hashBlock; int32_t numvouts; CTransaction tx; std::vector origpubkey; std::string name,description; - if ( myGetTransaction(tokenid,tx,hashBlock) != 0 && (numvouts= tx.vout.size()) > 0 ) - { - if (DecodeTokenCreateOpRet(tx.vout[numvouts-1].scriptPubKey,origpubkey,name,description)) - { - return(tx.vout[1].nValue); - } - } return(0); } int64_t CCtoken_balance(char *coinaddr,uint256 reftokenid) { - int64_t price,sum = 0; int32_t numvouts; CTransaction tx; uint256 tokenid,txid,hashBlock; - std::vector vopretExtra; - std::vector > unspentOutputs; - uint8_t evalCode; - - SetCCunspents(unspentOutputs,coinaddr,true); - for (std::vector >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++) - { - txid = it->first.txhash; - if ( myGetTransaction(txid,tx,hashBlock) != 0 && (numvouts=tx.vout.size()) > 0 ) - { - char str[65]; - std::vector voutTokenPubkeys; - std::vector> oprets; - if ( reftokenid==txid || (DecodeTokenOpRet(tx.vout[numvouts-1].scriptPubKey, evalCode, tokenid, voutTokenPubkeys, oprets) != 0 && reftokenid == tokenid)) - { - sum += it->second.satoshis; - } - } - } - return(sum); + return 0; } int32_t CC_vinselect(int32_t *aboveip,int64_t *abovep,int32_t *belowip,int64_t *belowp,struct CC_utxo utxos[],int32_t numunspents,int64_t value) From d81e8c0a3f90c93ea10102822116256d60c9481b Mon Sep 17 00:00:00 2001 From: Duke Date: Sat, 10 Feb 2024 18:56:37 -0500 Subject: [PATCH 21/78] Delete more CCs #381 --- src/cc/CCcustom.cpp | 389 -------------------------------------------- src/cc/CCcustom.inc | 17 -- 2 files changed, 406 deletions(-) delete mode 100644 src/cc/CCcustom.inc diff --git a/src/cc/CCcustom.cpp b/src/cc/CCcustom.cpp index 1e9653609..f526cd2fe 100644 --- a/src/cc/CCcustom.cpp +++ b/src/cc/CCcustom.cpp @@ -28,402 +28,13 @@ #include "CCPegs.h" #include "CCtokens.h" -/* - CCcustom has most of the functions that need to be extended to create a new CC contract. - - A CC scriptPubKey can only be spent if it is properly signed and validated. By constraining the vins and vouts, it is possible to implement a variety of functionality. CC vouts have an otherwise non-standard form, but it is properly supported by the enhanced bitcoin protocol code as a "cryptoconditions" output and the same pubkey will create a different address. - - This allows creation of a special address(es) for each contract type, which has the privkey public. That allows anybody to properly sign and spend it, but with the constraints on what is allowed in the validation code, the contract functionality can be implemented. - - what needs to be done to add a new contract: - 1. add EVAL_CODE to eval.h - 2. initialize the variables in the CCinit function below - 3. write a Validate function to reject any unsanctioned usage of vin/vout - 4. make helper functions to create rawtx for RPC functions - 5. add rpc calls to rpcserver.cpp and rpcserver.h and in one of the rpc.cpp files - 6. add the new .cpp files to src/Makefile.am - - IMPORTANT: make sure that all CC inputs and CC outputs are properly accounted for and reconcile to the satoshi. The built in utxo management will enforce overall vin/vout constraints but it wont know anything about the CC constraints. That is what your Validate function needs to do. - - Generally speaking, there will be normal coins that change into CC outputs, CC outputs that go back to being normal coins, CC outputs that are spent to new CC outputs. - - Make sure both the CC coins and normal coins are preserved and follow the rules that make sense. It is a good idea to define specific roles for specific vins and vouts to reduce the complexity of validation. - */ - -// to create a new CCaddr, add to rpcwallet the CCaddress and start with -pubkey= with the pubkey of the new address, with its wif already imported. set normaladdr and CChexstr. run CCaddress and it will print the privkey along with autocorrect the CCaddress. which should then update the CCaddr here - -// Assets, aka Tokens -#define FUNCNAME IsAssetsInput -#define EVALCODE EVAL_ASSETS -const char *AssetsCCaddr = "RGKRjeTBw4LYFotSDLT6RWzMHbhXri6BG6"; -const char *AssetsNormaladdr = "RFYE2yL3KknWdHK6uNhvWacYsCUtwzjY3u"; -char AssetsCChexstr[67] = { "02adf84e0e075cf90868bd4e3d34a03420e034719649c41f371fc70d8e33aa2702" }; -uint8_t AssetsCCpriv[32] = { 0x9b, 0x17, 0x66, 0xe5, 0x82, 0x66, 0xac, 0xb6, 0xba, 0x43, 0x83, 0x74, 0xf7, 0x63, 0x11, 0x3b, 0xf0, 0xf3, 0x50, 0x6f, 0xd9, 0x6b, 0x67, 0x85, 0xf9, 0x7a, 0xf0, 0x54, 0x4d, 0xb1, 0x30, 0x77 }; -#include "CCcustom.inc" -#undef FUNCNAME -#undef EVALCODE - -// Faucet -#define FUNCNAME IsFaucetInput -#define EVALCODE EVAL_FAUCET -const char *FaucetCCaddr = "R9zHrofhRbub7ER77B7NrVch3A63R39GuC"; -const char *FaucetNormaladdr = "RKQV4oYs4rvxAWx1J43VnT73rSTVtUeckk"; -char FaucetCChexstr[67] = { "03682b255c40d0cde8faee381a1a50bbb89980ff24539cb8518e294d3a63cefe12" }; -uint8_t FaucetCCpriv[32] = { 0xd4, 0x4f, 0xf2, 0x31, 0x71, 0x7d, 0x28, 0x02, 0x4b, 0xc7, 0xdd, 0x71, 0xa0, 0x39, 0xc4, 0xbe, 0x1a, 0xfe, 0xeb, 0xc2, 0x46, 0xda, 0x76, 0xf8, 0x07, 0x53, 0x3d, 0x96, 0xb4, 0xca, 0xa0, 0xe9 }; -#include "CCcustom.inc" -#undef FUNCNAME -#undef EVALCODE - -// Rewards -#define FUNCNAME IsRewardsInput -#define EVALCODE EVAL_REWARDS -const char *RewardsCCaddr = "RTsRBYL1HSvMoE3qtBJkyiswdVaWkm8YTK"; -const char *RewardsNormaladdr = "RMgye9jeczNjQx9Uzq8no8pTLiCSwuHwkz"; -char RewardsCChexstr[67] = { "03da60379d924c2c30ac290d2a86c2ead128cb7bd571f69211cb95356e2dcc5eb9" }; -uint8_t RewardsCCpriv[32] = { 0x82, 0xf5, 0xd2, 0xe7, 0xd6, 0x99, 0x33, 0x77, 0xfb, 0x80, 0x00, 0x97, 0x23, 0x3d, 0x1e, 0x6f, 0x61, 0xa9, 0xb5, 0x2e, 0x5e, 0xb4, 0x96, 0x6f, 0xbc, 0xed, 0x6b, 0xe2, 0xbb, 0x7b, 0x4b, 0xb3 }; -#include "CCcustom.inc" -#undef FUNCNAME -#undef EVALCODE - -// Dice -#define FUNCNAME IsDiceInput -#define EVALCODE EVAL_DICE -const char *DiceCCaddr = "REabWB7KjFN5C3LFMZ5odExHPenYzHLtVw"; -const char *DiceNormaladdr = "RLEe8f7Eg3TDuXii9BmNiiiaVGraHUt25c"; -char DiceCChexstr[67] = { "039d966927cfdadab3ee6c56da63c21f17ea753dde4b3dfd41487103e24b27e94e" }; -uint8_t DiceCCpriv[32] = { 0x0e, 0xe8, 0xf5, 0xb4, 0x3d, 0x25, 0xcc, 0x35, 0xd1, 0xf1, 0x2f, 0x04, 0x5f, 0x01, 0x26, 0xb8, 0xd1, 0xac, 0x3a, 0x5a, 0xea, 0xe0, 0x25, 0xa2, 0x8f, 0x2a, 0x8e, 0x0e, 0xf9, 0x34, 0xfa, 0x77 }; -#include "CCcustom.inc" -#undef FUNCNAME -#undef EVALCODE - -// Lotto -#define FUNCNAME IsLottoInput -#define EVALCODE EVAL_LOTTO -const char *LottoCCaddr = "RNXZxgyWSAE6XS3qGnTaf5dVNCxnYzhPrg"; -const char *LottoNormaladdr = "RLW6hhRqBZZMBndnyPv29Yg3krh6iBYCyg"; -char LottoCChexstr[67] = { "03f72d2c4db440df1e706502b09ca5fec73ffe954ea1883e4049e98da68690d98f" }; -uint8_t LottoCCpriv[32] = { 0xb4, 0xac, 0xc2, 0xd9, 0x67, 0x34, 0xd7, 0x58, 0x80, 0x4e, 0x25, 0x55, 0xc0, 0x50, 0x66, 0x84, 0xbb, 0xa2, 0xe7, 0xc0, 0x39, 0x17, 0xb4, 0xc5, 0x07, 0xb7, 0x3f, 0xca, 0x07, 0xb0, 0x9a, 0xeb }; -#include "CCcustom.inc" -#undef FUNCNAME -#undef EVALCODE - -// Finite State Machine -#define FUNCNAME IsFSMInput -#define EVALCODE EVAL_FSM -const char *FSMCCaddr = "RUKTbLBeKgHkm3Ss4hKZP3ikuLW1xx7B2x"; -const char *FSMNormaladdr = "RWSHRbxnJYLvDjpcQ2i8MekgP6h2ctTKaj"; -char FSMCChexstr[67] = { "039b52d294b413b07f3643c1a28c5467901a76562d8b39a785910ae0a0f3043810" }; -uint8_t FSMCCpriv[32] = { 0x11, 0xe1, 0xea, 0x3e, 0xdb, 0x36, 0xf0, 0xa8, 0xc6, 0x34, 0xe1, 0x21, 0xb8, 0x02, 0xb9, 0x4b, 0x12, 0x37, 0x8f, 0xa0, 0x86, 0x23, 0x50, 0xb2, 0x5f, 0xe4, 0xe7, 0x36, 0x0f, 0xda, 0xae, 0xfc }; -#include "CCcustom.inc" -#undef FUNCNAME -#undef EVALCODE - -// Auction -#define FUNCNAME IsAuctionInput -#define EVALCODE EVAL_AUCTION -const char *AuctionCCaddr = "RL4YPX7JYG3FnvoPqWF2pn3nQknH5NWEwx"; -const char *AuctionNormaladdr = "RFtVDNmdTZBTNZdmFRbfBgJ6LitgTghikL"; -char AuctionCChexstr[67] = { "037eefe050c14cb60ae65d5b2f69eaa1c9006826d729bc0957bdc3024e3ca1dbe6" }; -uint8_t AuctionCCpriv[32] = { 0x8c, 0x1b, 0xb7, 0x8c, 0x02, 0xa3, 0x9d, 0x21, 0x28, 0x59, 0xf5, 0xea, 0xda, 0xec, 0x0d, 0x11, 0xcd, 0x38, 0x47, 0xac, 0x0b, 0x6f, 0x19, 0xc0, 0x24, 0x36, 0xbf, 0x1c, 0x0a, 0x06, 0x31, 0xfb }; -#include "CCcustom.inc" -#undef FUNCNAME -#undef EVALCODE - -// Heir -#define FUNCNAME IsHeirInput -#define EVALCODE EVAL_HEIR -const char *HeirCCaddr = "RDVHcSekmXgeYBqRupNTmqo3Rn8QRXNduy"; -const char *HeirNormaladdr = "RTPwUjKYECcGn6Y4KYChLhgaht1RSU4jwf"; -char HeirCChexstr[67] = { "03c91bef3d7cc59c3a89286833a3446b29e52a5e773f738a1ad2b09785e5f4179e" }; -uint8_t HeirCCpriv[32] = { 0x9d, 0xa1, 0xf8, 0xf7, 0xba, 0x0a, 0x91, 0x36, 0x89, 0x9a, 0x86, 0x30, 0x63, 0x20, 0xd7, 0xdf, 0xaa, 0x35, 0xe3, 0x99, 0x32, 0x2b, 0x63, 0xc0, 0x66, 0x9c, 0x93, 0xc4, 0x5e, 0x9d, 0xb9, 0xce }; -#include "CCcustom.inc" -#undef FUNCNAME -#undef EVALCODE - -// Channels -#define FUNCNAME IsChannelsInput -#define EVALCODE EVAL_CHANNELS -const char *ChannelsCCaddr = "RQy3rwX8sP9oDm3c39vGKA6H315cgtPLfr"; -const char *ChannelsNormaladdr = "RQUuT8zmkvDfXqECH4m3VD3SsHZAfnoh1v"; -char ChannelsCChexstr[67] = { "035debdb19b1c98c615259339500511d6216a3ffbeb28ff5655a7ef5790a12ab0b" }; -uint8_t ChannelsCCpriv[32] = { 0xec, 0x91, 0x36, 0x15, 0x2d, 0xd4, 0x48, 0x73, 0x22, 0x36, 0x4f, 0x6a, 0x34, 0x5c, 0x61, 0x0f, 0x01, 0xb4, 0x79, 0xe8, 0x1c, 0x2f, 0xa1, 0x1d, 0x4a, 0x0a, 0x21, 0x16, 0xea, 0x82, 0x84, 0x60 }; -#include "CCcustom.inc" -#undef FUNCNAME -#undef EVALCODE - -// Oracles -#define FUNCNAME IsOraclesInput -#define EVALCODE EVAL_ORACLES -const char *OraclesCCaddr = "REt2C4ZMnX8YYX1DRpffNA4hECZTFm39e3"; -const char *OraclesNormaladdr = "RHkFKzn1csxA3fWzAsxsLWohoCgBbirXb5"; -char OraclesCChexstr[67] = { "038c1d42db6a45a57eccb8981b078fb7857b9b496293fe299d2b8d120ac5b5691a" }; -uint8_t OraclesCCpriv[32] = { 0xf7, 0x4b, 0x5b, 0xa2, 0x7a, 0x5e, 0x9c, 0xda, 0x89, 0xb1, 0xcb, 0xb9, 0xe6, 0x9c, 0x2c, 0x70, 0x85, 0x37, 0xdd, 0x00, 0x7a, 0x67, 0xff, 0x7c, 0x62, 0x1b, 0xe2, 0xfb, 0x04, 0x8f, 0x85, 0xbf }; -#include "CCcustom.inc" -#undef FUNCNAME -#undef EVALCODE - -// Prices -#define FUNCNAME IsPricesInput -#define EVALCODE EVAL_PRICES -const char *PricesCCaddr = "RAL5Vh8NXmFqEKJRKrk1KjKaUckK7mM1iS"; -const char *PricesNormaladdr = "RBunXCsMHk5NPd6q8SQfmpgre3x133rSwZ"; -char PricesCChexstr[67] = { "039894cb054c0032e99e65e715b03799607aa91212a16648d391b6fa2cc52ed0cf" }; -uint8_t PricesCCpriv[32] = { 0x0a, 0x3b, 0xe7, 0x5d, 0xce, 0x06, 0xed, 0xb7, 0xc0, 0xb1, 0xbe, 0xe8, 0x7b, 0x5a, 0xd4, 0x99, 0xb8, 0x8d, 0xde, 0xac, 0xb2, 0x7e, 0x7a, 0x52, 0x96, 0x15, 0xd2, 0xa0, 0xc6, 0xb9, 0x89, 0x61 }; -#include "CCcustom.inc" -#undef FUNCNAME -#undef EVALCODE - -// Pegs -#define FUNCNAME IsPegsInput -#define EVALCODE EVAL_PEGS -const char *PegsCCaddr = "RHnkVb7vHuHnjEjhkCF1bS6xxLLNZPv5fd"; -const char *PegsNormaladdr = "RMcCZtX6dHf1fz3gpLQhUEMQ8cVZ6Rzaro"; -char PegsCChexstr[67] = { "03c75c1de29a35e41606363b430c08be1c2dd93cf7a468229a082cc79c7b77eece" }; -uint8_t PegsCCpriv[32] = { 0x52, 0x56, 0x4c, 0x78, 0x87, 0xf7, 0xa2, 0x39, 0xb0, 0x90, 0xb7, 0xb8, 0x62, 0x80, 0x0f, 0x83, 0x18, 0x9d, 0xf4, 0xf4, 0xbd, 0x28, 0x09, 0xa9, 0x9b, 0x85, 0x54, 0x16, 0x0f, 0x3f, 0xfb, 0x65 }; -#include "CCcustom.inc" -#undef FUNCNAME -#undef EVALCODE - -// Payments -#define FUNCNAME IsPaymentsInput -#define EVALCODE EVAL_PAYMENTS -const char *PaymentsCCaddr = "REpyKi7avsVduqZ3eimncK4uKqSArLTGGK"; -const char *PaymentsNormaladdr = "RHRX8RTMAh2STWe9DHqsvJbzS7ty6aZy3d"; -char PaymentsCChexstr[67] = { "0358f1764f82c63abc7c7455555fd1d3184905e30e819e97667e247e5792b46856" }; -uint8_t PaymentsCCpriv[32] = { 0x03, 0xc9, 0x73, 0xc2, 0xb8, 0x30, 0x3d, 0xbd, 0xc8, 0xd9, 0xbf, 0x02, 0x49, 0xd9, 0x65, 0x61, 0x45, 0xed, 0x9e, 0x93, 0x51, 0xab, 0x8b, 0x2e, 0xe7, 0xc7, 0x40, 0xf1, 0xc4, 0xd2, 0xc0, 0x5b }; -#include "CCcustom.inc" -#undef FUNCNAME -#undef EVALCODE - -// Gateways -#define FUNCNAME IsGatewaysInput -#define EVALCODE EVAL_GATEWAYS -const char *GatewaysCCaddr = "RKWpoK6vTRtq5b9qrRBodLkCzeURHeEk33"; -const char *GatewaysNormaladdr = "RGJKV97ZN1wBfunuMt1tebiiHENNEq73Yh"; // wif UxJFYqEvLAjWPPRvn8NN1fRWscBxQZXZB5BBgc3HiapKVQBYNcmo -char GatewaysCChexstr[67] = { "03ea9c062b9652d8eff34879b504eda0717895d27597aaeb60347d65eed96ccb40" }; -uint8_t GatewaysCCpriv[32] = { 0xf7, 0x4b, 0x5b, 0xa2, 0x7a, 0x5e, 0x9c, 0xda, 0x89, 0xb1, 0xcb, 0xb9, 0xe6, 0x9c, 0x2c, 0x70, 0x85, 0x37, 0xdd, 0x00, 0x7a, 0x67, 0xff, 0x7c, 0x62, 0x1b, 0xe2, 0xfb, 0x04, 0x8f, 0x85, 0xbf }; -#include "CCcustom.inc" -#undef FUNCNAME -#undef EVALCODE - -// Tokens -#define FUNCNAME IsTokensInput -#define EVALCODE EVAL_TOKENS -const char *TokensCCaddr = "RAMvUfoyURBRxAdVeTMHxn3giJZCFWeha2"; -const char *TokensNormaladdr = "RCNgAngYAdrfzujYyPgfbjCGNVQZzCgTad"; -char TokensCChexstr[67] = { "03e6191c70c9c9a28f9fd87089b9488d0e6c02fb629df64979c9cdb6b2b4a68d95" }; -uint8_t TokensCCpriv[32] = { 0x1d, 0x0d, 0x0d, 0xce, 0x2d, 0xd2, 0xe1, 0x9d, 0xf5, 0xb6, 0x26, 0xd5, 0xad, 0xa0, 0xf0, 0x0a, 0xdd, 0x7a, 0x72, 0x7d, 0x17, 0x35, 0xb5, 0xe3, 0x2c, 0x6c, 0xa9, 0xa2, 0x03, 0x16, 0x4b, 0xcf }; -#include "CCcustom.inc" -#undef FUNCNAME -#undef EVALCODE - -#define FUNCNAME IsCClibInput -#define EVALCODE EVAL_FIRSTUSER -const char *CClibNormaladdr = "RVVeUg43rNcq3mZFnvZ8yqagyzqFgUnq4u"; -char CClibCChexstr[67] = { "032447d97655da079729dc024c61088ea415b22f4c15d4810ddaf2069ac6468d2f" }; -uint8_t CClibCCpriv[32] = { 0x57, 0xcf, 0x49, 0x71, 0x7d, 0xb4, 0x15, 0x1b, 0x4f, 0x98, 0xc5, 0x45, 0x8d, 0x26, 0x52, 0x4b, 0x7b, 0xe9, 0xbd, 0x55, 0xd8, 0x20, 0xd6, 0xc4, 0x82, 0x0f, 0xf5, 0xec, 0x6c, 0x1c, 0xa0, 0xc0 }; -#include "CCcustom.inc" -#undef FUNCNAME -#undef EVALCODE - -// ImportGateway -#define FUNCNAME IsImportGatewayInput -#define EVALCODE EVAL_IMPORTGATEWAY -const char *ImportGatewayCCaddr = "RXJT6CRAXHFuQ2UjqdxMj7EfrayF6UJpzZ"; -const char *ImportGatewayNormaladdr = "RNFRho63Ddz1Rh2eGPETykrU4fA8r67S4Y"; -char ImportGatewayCChexstr[67] = { "0397231cfe04ea32d5fafb2206773ec9fba6e15c5a4e86064468bca195f7542714" }; -uint8_t ImportGatewayCCpriv[32] = { 0x65, 0xef, 0x27, 0xeb, 0x3d, 0xb0, 0xb4, 0xae, 0x0f, 0xbc, 0x77, 0xdb, 0xf8, 0x40, 0x48, 0x90, 0x52, 0x20, 0x9e, 0x45, 0x3b, 0x49, 0xd8, 0x97, 0x60, 0x8c, 0x27, 0x4c, 0x59, 0x46, 0xe1, 0xdf }; -#include "CCcustom.inc" -#undef FUNCNAME -#undef EVALCODE - int32_t CClib_initcp(struct CCcontract_info *cp,uint8_t evalcode) { - CPubKey pk; int32_t i; uint8_t pub33[33],check33[33],hash[32]; char CCaddr[64],checkaddr[64],str[67]; - cp->evalcode = evalcode; - cp->ismyvin = IsCClibInput; - memcpy(cp->CCpriv,CClibCCpriv,32); - if ( evalcode == EVAL_FIRSTUSER ) // eventually make a hashchain for each evalcode - { - strcpy(cp->CChexstr,CClibCChexstr); - decode_hex(pub33,33,cp->CChexstr); - pk = buf2pk(pub33); - Getscriptaddress(cp->normaladdr,CScript() << ParseHex(HexStr(pk)) << OP_CHECKSIG); - if ( strcmp(cp->normaladdr,CClibNormaladdr) != 0 ) - fprintf(stderr,"CClib_initcp addr mismatch %s vs %s\n",cp->normaladdr,CClibNormaladdr); - GetCCaddress(cp,cp->unspendableCCaddr,pk); - if ( priv2addr(checkaddr,check33,cp->CCpriv) != 0 ) - { - if ( buf2pk(check33) == pk && strcmp(checkaddr,cp->normaladdr) == 0 ) - { - //fprintf(stderr,"verified evalcode.%d %s %s\n",cp->evalcode,checkaddr,pubkey33_str(str,pub33)); - return(0); - } else fprintf(stderr,"CClib_initcp mismatched privkey -> addr %s vs %s\n",checkaddr,cp->normaladdr); - } - } - else - { - for (i=EVAL_FIRSTUSER; iCCpriv,32); - memcpy(cp->CCpriv,hash,32); - } - if ( priv2addr(cp->normaladdr,pub33,cp->CCpriv) != 0 ) - { - pk = buf2pk(pub33); - for (i=0; i<33; i++) - sprintf(&cp->CChexstr[i*2],"%02x",pub33[i]); - cp->CChexstr[i*2] = 0; - GetCCaddress(cp,cp->unspendableCCaddr,pk); - //printf("evalcode.%d initialized\n",evalcode); - return(0); - } - } return(-1); } struct CCcontract_info *CCinit(struct CCcontract_info *cp, uint8_t evalcode) { - // important to clear because not all members are always initialized! - memset(cp, '\0', sizeof(*cp)); - - cp->evalcode = evalcode; - switch ( evalcode ) - { - case EVAL_ASSETS: - strcpy(cp->unspendableCCaddr,AssetsCCaddr); - strcpy(cp->normaladdr,AssetsNormaladdr); - strcpy(cp->CChexstr,AssetsCChexstr); - memcpy(cp->CCpriv,AssetsCCpriv,32); - //cp->validate = AssetsValidate; - //cp->ismyvin = IsAssetsInput; - break; - case EVAL_FAUCET: - strcpy(cp->unspendableCCaddr,FaucetCCaddr); - strcpy(cp->normaladdr,FaucetNormaladdr); - strcpy(cp->CChexstr,FaucetCChexstr); - memcpy(cp->CCpriv,FaucetCCpriv,32); - //cp->validate = FaucetValidate; - //cp->ismyvin = IsFaucetInput; - break; - case EVAL_REWARDS: - strcpy(cp->unspendableCCaddr,RewardsCCaddr); - strcpy(cp->normaladdr,RewardsNormaladdr); - strcpy(cp->CChexstr,RewardsCChexstr); - memcpy(cp->CCpriv,RewardsCCpriv,32); - //cp->validate = RewardsValidate; - //cp->ismyvin = IsRewardsInput; - break; - case EVAL_DICE: - strcpy(cp->unspendableCCaddr,DiceCCaddr); - strcpy(cp->normaladdr,DiceNormaladdr); - strcpy(cp->CChexstr,DiceCChexstr); - memcpy(cp->CCpriv,DiceCCpriv,32); - //cp->validate = DiceValidate; - //cp->ismyvin = IsDiceInput; - break; - case EVAL_LOTTO: - strcpy(cp->unspendableCCaddr,LottoCCaddr); - strcpy(cp->normaladdr,LottoNormaladdr); - strcpy(cp->CChexstr,LottoCChexstr); - memcpy(cp->CCpriv,LottoCCpriv,32); - //cp->validate = LottoValidate; - //cp->ismyvin = IsLottoInput; - break; - case EVAL_FSM: - strcpy(cp->unspendableCCaddr,FSMCCaddr); - strcpy(cp->normaladdr,FSMNormaladdr); - strcpy(cp->CChexstr,FSMCChexstr); - memcpy(cp->CCpriv,FSMCCpriv,32); - //cp->validate = FSMValidate; - //cp->ismyvin = IsFSMInput; - break; - case EVAL_AUCTION: - strcpy(cp->unspendableCCaddr,AuctionCCaddr); - strcpy(cp->normaladdr,AuctionNormaladdr); - strcpy(cp->CChexstr,AuctionCChexstr); - memcpy(cp->CCpriv,AuctionCCpriv,32); - //cp->validate = AuctionValidate; - //cp->ismyvin = IsAuctionInput; - break; - case EVAL_HEIR: - strcpy(cp->unspendableCCaddr,HeirCCaddr); - strcpy(cp->normaladdr,HeirNormaladdr); - strcpy(cp->CChexstr,HeirCChexstr); - memcpy(cp->CCpriv,HeirCCpriv,32); - //cp->validate = HeirValidate; - //cp->ismyvin = IsHeirInput; - break; - case EVAL_CHANNELS: - strcpy(cp->unspendableCCaddr,ChannelsCCaddr); - strcpy(cp->normaladdr,ChannelsNormaladdr); - strcpy(cp->CChexstr,ChannelsCChexstr); - memcpy(cp->CCpriv,ChannelsCCpriv,32); - //cp->validate = ChannelsValidate; - //cp->ismyvin = IsChannelsInput; - break; - case EVAL_ORACLES: - strcpy(cp->unspendableCCaddr,OraclesCCaddr); - strcpy(cp->normaladdr,OraclesNormaladdr); - strcpy(cp->CChexstr,OraclesCChexstr); - memcpy(cp->CCpriv,OraclesCCpriv,32); - //cp->validate = OraclesValidate; - //cp->ismyvin = IsOraclesInput; - break; - case EVAL_PRICES: - strcpy(cp->unspendableCCaddr,PricesCCaddr); - strcpy(cp->normaladdr,PricesNormaladdr); - strcpy(cp->CChexstr,PricesCChexstr); - memcpy(cp->CCpriv,PricesCCpriv,32); - //cp->validate = PricesValidate; - //cp->ismyvin = IsPricesInput; - break; - case EVAL_PEGS: - strcpy(cp->unspendableCCaddr,PegsCCaddr); - strcpy(cp->normaladdr,PegsNormaladdr); - strcpy(cp->CChexstr,PegsCChexstr); - memcpy(cp->CCpriv,PegsCCpriv,32); - //cp->validate = PegsValidate; - //cp->ismyvin = IsPegsInput; - break; - case EVAL_PAYMENTS: - strcpy(cp->unspendableCCaddr,PaymentsCCaddr); - strcpy(cp->normaladdr,PaymentsNormaladdr); - strcpy(cp->CChexstr,PaymentsCChexstr); - memcpy(cp->CCpriv,PaymentsCCpriv,32); - //cp->validate = PaymentsValidate; - //cp->ismyvin = IsPaymentsInput; - break; - case EVAL_GATEWAYS: - strcpy(cp->unspendableCCaddr,GatewaysCCaddr); - strcpy(cp->normaladdr,GatewaysNormaladdr); - strcpy(cp->CChexstr,GatewaysCChexstr); - memcpy(cp->CCpriv,GatewaysCCpriv,32); - //cp->validate = GatewaysValidate; - //cp->ismyvin = IsGatewaysInput; - break; - - case EVAL_TOKENS: - strcpy(cp->unspendableCCaddr, TokensCCaddr); - strcpy(cp->normaladdr, TokensNormaladdr); - strcpy(cp->CChexstr, TokensCChexstr); - memcpy(cp->CCpriv, TokensCCpriv, 32); - //cp->validate = TokensValidate; - //cp->ismyvin = IsTokensInput; - break; - case EVAL_IMPORTGATEWAY: - strcpy(cp->unspendableCCaddr, ImportGatewayCCaddr); - strcpy(cp->normaladdr, ImportGatewayNormaladdr); - strcpy(cp->CChexstr, ImportGatewayCChexstr); - memcpy(cp->CCpriv, ImportGatewayCCpriv, 32); - //cp->validate = ImportGatewayValidate; - //cp->ismyvin = IsImportGatewayInput; - break; - default: - if ( CClib_initcp(cp,evalcode) < 0 ) - return(0); - break; - } return(cp); } diff --git a/src/cc/CCcustom.inc b/src/cc/CCcustom.inc deleted file mode 100644 index c33ca4f5b..000000000 --- a/src/cc/CCcustom.inc +++ /dev/null @@ -1,17 +0,0 @@ - -bool FUNCNAME(CScript const& scriptSig) -{ - CC *cond; - if (!(cond = GetCryptoCondition(scriptSig))) - return false; - // Recurse the CC tree to find asset condition - auto findEval = [] (CC *cond, struct CCVisitor _) { - bool r = cc_typeId(cond) == CC_Eval && cond->codeLength == 1 && cond->code[0] == EVALCODE; - // false for a match, true for continue - return r ? 0 : 1; - }; - CCVisitor visitor = {findEval, (uint8_t*)"", 0, NULL}; - bool out =! cc_visit(cond, visitor); - cc_free(cond); - return out; -} From 5fa46e1d8dff4892b64145d896916ab194e0fd3d Mon Sep 17 00:00:00 2001 From: Duke Date: Sat, 10 Feb 2024 21:46:36 -0500 Subject: [PATCH 22/78] Delete more CCs #381 --- src/cc/CCHeir.h | 39 ------------------------- src/cc/CCOracles.h | 37 ----------------------- src/cc/CCPegs.h | 18 ------------ src/cc/CCPrices.h | 66 ------------------------------------------ src/cc/CCassets.h | 50 -------------------------------- src/cc/CCauction.h | 33 --------------------- src/cc/CCcustom.cpp | 9 ------ src/cc/CCfaucet.h | 31 -------------------- src/cc/CCfsm.h | 33 --------------------- src/rpc/blockchain.cpp | 1 - 10 files changed, 317 deletions(-) delete mode 100644 src/cc/CCHeir.h delete mode 100644 src/cc/CCOracles.h delete mode 100644 src/cc/CCPegs.h delete mode 100644 src/cc/CCPrices.h delete mode 100644 src/cc/CCassets.h delete mode 100644 src/cc/CCauction.h delete mode 100644 src/cc/CCfaucet.h delete mode 100644 src/cc/CCfsm.h diff --git a/src/cc/CCHeir.h b/src/cc/CCHeir.h deleted file mode 100644 index 2701251b3..000000000 --- a/src/cc/CCHeir.h +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright (c) 2016-2023 The Hush developers -// Distributed under the GPLv3 software license, see the accompanying -// file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html -/****************************************************************************** - * Copyright © 2014-2019 The SuperNET Developers. * - * * - * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * - * the top-level directory of this distribution for the individual copyright * - * holder information and the developer policies on copyright and licensing. * - * * - * Unless otherwise agreed in a custom licensing agreement, no part of the * - * SuperNET software, including this file may be copied, modified, propagated * - * or distributed except according to the terms contained in the LICENSE file * - * * - * Removal or modification of this copyright notice is prohibited. * - * * - ******************************************************************************/ - -#ifndef CC_HEIR_H -#define CC_HEIR_H - -#include "CCinclude.h" -#include "CCtokens.h" - -//#define EVAL_HEIR 0xea - -bool HeirValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn); - -class CoinHelper; -class TokenHelper; - -UniValue HeirFundCoinCaller(int64_t txfee, int64_t coins, std::string heirName, CPubKey heirPubkey, int64_t inactivityTimeSec, std::string memo); -UniValue HeirFundTokenCaller(int64_t txfee, int64_t satoshis, std::string heirName, CPubKey heirPubkey, int64_t inactivityTimeSec, std::string memo, uint256 tokenid); -UniValue HeirClaimCaller(uint256 fundingtxid, int64_t txfee, std::string amount); -UniValue HeirAddCaller(uint256 fundingtxid, int64_t txfee, std::string amount); -UniValue HeirInfo(uint256 fundingtxid); -UniValue HeirList(); - -#endif diff --git a/src/cc/CCOracles.h b/src/cc/CCOracles.h deleted file mode 100644 index 9ab6082a4..000000000 --- a/src/cc/CCOracles.h +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (c) 2016-2023 The Hush developers -// Distributed under the GPLv3 software license, see the accompanying -// file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html -/****************************************************************************** - * Copyright © 2014-2019 The SuperNET Developers. * - * * - * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * - * the top-level directory of this distribution for the individual copyright * - * holder information and the developer policies on copyright and licensing. * - * * - * Unless otherwise agreed in a custom licensing agreement, no part of the * - * SuperNET software, including this file may be copied, modified, propagated * - * or distributed except according to the terms contained in the LICENSE file * - * * - * Removal or modification of this copyright notice is prohibited. * - * * - ******************************************************************************/ - - -#ifndef CC_ORACLES_H -#define CC_ORACLES_H - -#include "CCinclude.h" - -bool OraclesValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn); -UniValue OracleCreate(const CPubKey& pk, int64_t txfee,std::string name,std::string description,std::string format); -UniValue OracleFund(const CPubKey& pk, int64_t txfee,uint256 oracletxid); -UniValue OracleRegister(const CPubKey& pk, int64_t txfee,uint256 oracletxid,int64_t datafee); -UniValue OracleSubscribe(const CPubKey& pk, int64_t txfee,uint256 oracletxid,CPubKey publisher,int64_t amount); -UniValue OracleData(const CPubKey& pk, int64_t txfee,uint256 oracletxid,std::vector data); -// CCcustom -UniValue OracleDataSample(uint256 reforacletxid,uint256 txid); -UniValue OracleDataSamples(uint256 reforacletxid,char* batonaddr,int32_t num); -UniValue OracleInfo(uint256 origtxid); -UniValue OraclesList(); - -#endif diff --git a/src/cc/CCPegs.h b/src/cc/CCPegs.h deleted file mode 100644 index 5cc2ce473..000000000 --- a/src/cc/CCPegs.h +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) 2016-2023 The Hush developers -// Distributed under the GPLv3 software license, see the accompanying -// file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html -/****************************************************************************** - * Copyright © 2014-2019 The SuperNET Developers. * - * * - * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * - * the top-level directory of this distribution for the individual copyright * - * holder information and the developer policies on copyright and licensing. * - * * - * Unless otherwise agreed in a custom licensing agreement, no part of the * - * SuperNET software, including this file may be copied, modified, propagated * - * or distributed except according to the terms contained in the LICENSE file * - * * - * Removal or modification of this copyright notice is prohibited. * - * * - ******************************************************************************/ - diff --git a/src/cc/CCPrices.h b/src/cc/CCPrices.h deleted file mode 100644 index 592a63136..000000000 --- a/src/cc/CCPrices.h +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (c) 2016-2023 The Hush developers -// Distributed under the GPLv3 software license, see the accompanying -// file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html -/****************************************************************************** - * Copyright © 2014-2019 The SuperNET Developers. * - * * - * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * - * the top-level directory of this distribution for the individual copyright * - * holder information and the developer policies on copyright and licensing. * - * * - * Unless otherwise agreed in a custom licensing agreement, no part of the * - * SuperNET software, including this file may be copied, modified, propagated * - * or distributed except according to the terms contained in the LICENSE file * - * * - * Removal or modification of this copyright notice is prohibited. * - * * - ******************************************************************************/ - - -#ifndef CC_PRICES_H -#define CC_PRICES_H - -#include "hush_defs.h" -#include "CCinclude.h" - -int32_t hush_priceget(int64_t *buf64,int32_t ind,int32_t height,int32_t numblocks); -extern void GetHushEarlytxidScriptPub(); -extern CScript HUSH_EARLYTXID_SCRIPTPUB; - -// #define PRICES_DAYWINDOW ((3600*24/ASSETCHAINS_BLOCKTIME) + 1) // defined in hush_defs.h -#define PRICES_TXFEE 10000 -#define PRICES_MAXLEVERAGE 777 -#define PRICES_SMOOTHWIDTH 1 -#define HUSH_MAXPRICES 2048 // must be power of 2 and less than 8192 -#define HUSH_PRICEMASK (~(HUSH_MAXPRICES - 1)) // actually 1111 1000 0000 0000 -#define PRICES_WEIGHT (HUSH_MAXPRICES * 1) // 0000 1000 0000 0000 -#define PRICES_MULT (HUSH_MAXPRICES * 2) // 0001 0000 0000 0000 -#define PRICES_DIV (HUSH_MAXPRICES * 3) // 0001 1000 0000 0000 -#define PRICES_INV (HUSH_MAXPRICES * 4) // 0010 0000 0000 0000 -#define PRICES_MDD (HUSH_MAXPRICES * 5) // 0010 1000 0000 0000 -#define PRICES_MMD (HUSH_MAXPRICES * 6) // 0011 0000 0000 0000 -#define PRICES_MMM (HUSH_MAXPRICES * 7) // 0011 1000 0000 0000 -#define PRICES_DDD (HUSH_MAXPRICES * 8) // 0100 0000 0000 0000 - -//#define PRICES_NORMFACTOR (int64_t)(SATOSHIDEN) -//#define PRICES_POINTFACTOR (int64_t)10000 - -#define PRICES_REVSHAREDUST 10000 -#define PRICES_SUBREVSHAREFEE(amount) ((amount) * 199 / 200) // revshare fee percentage == 0.005 -#define PRICES_MINAVAILFUNDFRACTION 0.1 // leveraged bet limit < fund fraction - -bool PricesValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn); - -// CCcustom -UniValue PricesBet(int64_t txfee,int64_t amount,int16_t leverage,std::vector synthetic); -UniValue PricesAddFunding(int64_t txfee,uint256 bettxid,int64_t amount); -UniValue PricesSetcostbasis(int64_t txfee,uint256 bettxid); -UniValue PricesRekt(int64_t txfee,uint256 bettxid,int32_t rektheight); -UniValue PricesCashout(int64_t txfee,uint256 bettxid); -UniValue PricesInfo(uint256 bettxid,int32_t refheight); -UniValue PricesList(uint32_t filter, CPubKey mypk); -UniValue PricesGetOrderbook(); -UniValue PricesRefillFund(int64_t amount); - - -#endif diff --git a/src/cc/CCassets.h b/src/cc/CCassets.h deleted file mode 100644 index 3b03570f8..000000000 --- a/src/cc/CCassets.h +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (c) 2016-2023 The Hush developers -// Distributed under the GPLv3 software license, see the accompanying -// file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html -/****************************************************************************** - * Copyright © 2014-2019 The SuperNET Developers. * - * * - * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * - * the top-level directory of this distribution for the individual copyright * - * holder information and the developer policies on copyright and licensing. * - * * - * Unless otherwise agreed in a custom licensing agreement, no part of the * - * SuperNET software, including this file may be copied, modified, propagated * - * or distributed except according to the terms contained in the LICENSE file * - * * - * Removal or modification of this copyright notice is prohibited. * - * * - ******************************************************************************/ - - -/* - CCassetstx has the functions that create the EVAL_ASSETS transactions. It is expected that rpc calls would call these functions. For EVAL_ASSETS, the rpc functions are in rpcwallet.cpp - - CCassetsCore has functions that are used in two contexts, both during rpc transaction create time and also during the blockchain validation. Using the identical functions is a good way to prevent them from being mismatched. The must match or the transaction will get rejected. - */ - -#ifndef CC_ASSETS_H -#define CC_ASSETS_H - -#include "CCinclude.h" - -// CCcustom -bool AssetsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn); - -// CCassetsCore -vscript_t EncodeAssetOpRet(uint8_t assetFuncId, uint256 assetid2, int64_t price, std::vector origpubkey); -uint8_t DecodeAssetTokenOpRet(const CScript &scriptPubKey, uint8_t &assetsEvalCode, uint256 &tokenid, uint256 &assetid2, int64_t &price, std::vector &origpubkey); -bool SetAssetOrigpubkey(std::vector &origpubkey,int64_t &price,const CTransaction &tx); -int64_t IsAssetvout(struct CCcontract_info *cp, int64_t &price, std::vector &origpubkey, const CTransaction& tx, int32_t v, uint256 refassetid); -bool ValidateBidRemainder(int64_t remaining_price,int64_t remaining_nValue,int64_t orig_nValue,int64_t received_nValue,int64_t paidprice,int64_t totalprice); -bool ValidateAskRemainder(int64_t remaining_price,int64_t remaining_nValue,int64_t orig_nValue,int64_t received_nValue,int64_t paidprice,int64_t totalprice); -bool ValidateSwapRemainder(int64_t remaining_price,int64_t remaining_nValue,int64_t orig_nValue,int64_t received_nValue,int64_t paidprice,int64_t totalprice); -bool SetBidFillamounts(int64_t &paid,int64_t &remaining_price,int64_t orig_nValue,int64_t &received,int64_t totalprice); -bool SetAskFillamounts(int64_t &paid,int64_t &remaining_price,int64_t orig_nValue,int64_t &received,int64_t totalprice); -bool SetSwapFillamounts(int64_t &paid,int64_t &remaining_price,int64_t orig_nValue,int64_t &received,int64_t totalprice); -int64_t AssetValidateBuyvin(struct CCcontract_info *cp,Eval* eval,int64_t &tmpprice,std::vector &tmporigpubkey,char *CCaddr,char *origaddr,const CTransaction &tx,uint256 refassetid); -int64_t AssetValidateSellvin(struct CCcontract_info *cp,Eval* eval,int64_t &tmpprice,std::vector &tmporigpubkey,char *CCaddr,char *origaddr,const CTransaction &tx,uint256 assetid); -bool AssetCalcAmounts(struct CCcontract_info *cpAssets, int64_t &inputs, int64_t &outputs, Eval* eval, const CTransaction &tx, uint256 assetid); - - -#endif diff --git a/src/cc/CCauction.h b/src/cc/CCauction.h deleted file mode 100644 index becbb86ff..000000000 --- a/src/cc/CCauction.h +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (c) 2016-2023 The Hush developers -// Distributed under the GPLv3 software license, see the accompanying -// file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html -/****************************************************************************** - * Copyright © 2014-2019 The SuperNET Developers. * - * * - * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * - * the top-level directory of this distribution for the individual copyright * - * holder information and the developer policies on copyright and licensing. * - * * - * Unless otherwise agreed in a custom licensing agreement, no part of the * - * SuperNET software, including this file may be copied, modified, propagated * - * or distributed except according to the terms contained in the LICENSE file * - * * - * Removal or modification of this copyright notice is prohibited. * - * * - ******************************************************************************/ - - -#ifndef CC_AUCTION_H -#define CC_AUCTION_H - -#include "CCinclude.h" - -#define EVAL_AUCTION 0xe8 - -bool AuctionValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn); - -std::string AuctionPost(uint64_t txfee,uint256 itemhash,int64_t minbid,char *title,char *description); -std::string AuctionBid(uint64_t txfee,uint256 itemhash,int64_t amount); -std::string AuctionDeliver(uint64_t txfee,uint256 itemhash,uint256 bidtxid); - -#endif diff --git a/src/cc/CCcustom.cpp b/src/cc/CCcustom.cpp index f526cd2fe..a0a6039e1 100644 --- a/src/cc/CCcustom.cpp +++ b/src/cc/CCcustom.cpp @@ -18,15 +18,6 @@ #include "key_io.h" #include "CCinclude.h" -#include "CCassets.h" -#include "CCfaucet.h" -#include "CCauction.h" -#include "CCfsm.h" -#include "CCHeir.h" -#include "CCOracles.h" -#include "CCPrices.h" -#include "CCPegs.h" -#include "CCtokens.h" int32_t CClib_initcp(struct CCcontract_info *cp,uint8_t evalcode) { diff --git a/src/cc/CCfaucet.h b/src/cc/CCfaucet.h deleted file mode 100644 index 4e3c40c1d..000000000 --- a/src/cc/CCfaucet.h +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (c) 2016-2023 The Hush developers -// Distributed under the GPLv3 software license, see the accompanying -// file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html -/****************************************************************************** - * Copyright © 2014-2019 The SuperNET Developers. * - * * - * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * - * the top-level directory of this distribution for the individual copyright * - * holder information and the developer policies on copyright and licensing. * - * * - * Unless otherwise agreed in a custom licensing agreement, no part of the * - * SuperNET software, including this file may be copied, modified, propagated * - * or distributed except according to the terms contained in the LICENSE file * - * * - * Removal or modification of this copyright notice is prohibited. * - * * - ******************************************************************************/ -#ifndef CC_FAUCET_H -#define CC_FAUCET_H -#include "CCinclude.h" -#define EVAL_FAUCET 0xe4 -#define FAUCETSIZE (COIN / 10) - -bool FaucetValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn); - -// CCcustom -UniValue FaucetFund(const CPubKey& mypk,uint64_t txfee,int64_t funds); -UniValue FaucetGet(const CPubKey& mypk,uint64_t txfee); -UniValue FaucetInfo(); - -#endif diff --git a/src/cc/CCfsm.h b/src/cc/CCfsm.h deleted file mode 100644 index 8c6f487f2..000000000 --- a/src/cc/CCfsm.h +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (c) 2016-2023 The Hush developers -// Distributed under the GPLv3 software license, see the accompanying -// file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html -/****************************************************************************** - * Copyright © 2014-2019 The SuperNET Developers. * - * * - * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * - * the top-level directory of this distribution for the individual copyright * - * holder information and the developer policies on copyright and licensing. * - * * - * Unless otherwise agreed in a custom licensing agreement, no part of the * - * SuperNET software, including this file may be copied, modified, propagated * - * or distributed except according to the terms contained in the LICENSE file * - * * - * Removal or modification of this copyright notice is prohibited. * - * * - ******************************************************************************/ - - -#ifndef CC_FSM_H -#define CC_FSM_H - -#include "CCinclude.h" - -#define EVAL_FSM 0xe7 - -bool FSMValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn); - -std::string FSMList(); -std::string FSMInfo(uint256 fsmtxid); -std::string FSMCreate(uint64_t txfee,std::string name,std::string states); - -#endif diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 793dff4ab..b27e01db3 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -40,7 +40,6 @@ #include #include #include "cc/CCinclude.h" -#include "cc/CCPrices.h" using namespace std; From c6aa5e939d27892dd40fe4b526cc7ee39a1ea243 Mon Sep 17 00:00:00 2001 From: Duke Date: Sat, 10 Feb 2024 21:54:36 -0500 Subject: [PATCH 23/78] Delete more CCs #381 --- src/cc/betprotocol.h | 78 ---------- src/cc/dilithium.h | 346 ------------------------------------------- 2 files changed, 424 deletions(-) delete mode 100644 src/cc/betprotocol.h delete mode 100644 src/cc/dilithium.h diff --git a/src/cc/betprotocol.h b/src/cc/betprotocol.h deleted file mode 100644 index b8c4cf49e..000000000 --- a/src/cc/betprotocol.h +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright (c) 2016-2023 The Hush developers -// Distributed under the GPLv3 software license, see the accompanying -// file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html -/****************************************************************************** - * Copyright © 2014-2019 The SuperNET Developers. * - * * - * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * - * the top-level directory of this distribution for the individual copyright * - * holder information and the developer policies on copyright and licensing. * - * * - * Unless otherwise agreed in a custom licensing agreement, no part of the * - * SuperNET software, including this file may be copied, modified, propagated * - * or distributed except according to the terms contained in the LICENSE file * - * * - * Removal or modification of this copyright notice is prohibited. * - * * - ******************************************************************************/ - -#ifndef BETPROTOCOL_H -#define BETPROTOCOL_H - -#include "cc/eval.h" -#include "pubkey.h" -#include "primitives/transaction.h" -#include "cryptoconditions/include/cryptoconditions.h" - - -class MoMProof -{ -public: - MerkleBranch branch; - uint256 notarizationHash; - ADD_SERIALIZE_METHODS; - template - inline void SerializationOp(Stream& s, Operation ser_action) { - READWRITE(branch); - READWRITE(notarizationHash); - } -}; - - - -class BetProtocol -{ -protected: - std::vector playerConditions(); -public: - EvalCode disputeCode; - std::vector players; - std::vector vmParams; - uint32_t waitBlocks; - - // Utility - BetProtocol(EvalCode dc, std::vector ps, uint32_t wb, std::vector vmp) - : disputeCode(dc), waitBlocks(wb), vmParams(vmp), players(ps) {} - std::vector PlayerConditions(); - - // on PANGEA - CC* MakeDisputeCond(); - CMutableTransaction MakeSessionTx(CAmount spendFee); - CMutableTransaction MakeDisputeTx(uint256 signedSessionTxHash, uint256 vmResultHash); - CMutableTransaction MakePostEvidenceTx(uint256 signedSessionTxHash, - int playerIndex, std::vector state); - - // on HUSH - CC* MakePayoutCond(uint256 signedSessionTxHash); - CMutableTransaction MakeStakeTx(CAmount totalPayout, uint256 signedSessionTx); - CMutableTransaction MakeAgreePayoutTx(std::vector payouts, uint256 signedStakeTxHash); - CMutableTransaction MakeImportPayoutTx(std::vector payouts, - CTransaction signedDisputeTx, uint256 signedStakeTxHash, MoMProof momProof); -}; - - - -bool GetOpReturnHash(CScript script, uint256 &hash); - - -#endif /* BETPROTOCOL_H */ diff --git a/src/cc/dilithium.h b/src/cc/dilithium.h deleted file mode 100644 index 91d0a0753..000000000 --- a/src/cc/dilithium.h +++ /dev/null @@ -1,346 +0,0 @@ -// Copyright (c) 2016-2023 The Hush developers -// Distributed under the GPLv3 software license, see the accompanying -// file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html -#include - -#ifndef HUSH_DILITHIUM_H -#define HUSH_DILITHIUM_H - -#define SHAKE128_RATE 168 -#define SHAKE256_RATE 136 - -void shake128_absorb(uint64_t *s, const uint8_t *input, int32_t inlen); -void shake128_squeezeblocks(uint8_t *output, int32_t nblocks, uint64_t *s); -void shake256_absorb(uint64_t *s, const uint8_t *input, int32_t inlen); -void shake256_squeezeblocks(uint8_t *output, int32_t nblocks, uint64_t *s); -void shake128(uint8_t *output, int32_t outlen, const uint8_t *input, int32_t inlen); -void shake256(uint8_t *output, int32_t outlen, const uint8_t *input, int32_t inlen); - -#endif - -#ifndef PARAMS_H -#define PARAMS_H - -#ifndef MODE -#define MODE 3 -#endif - -#define SEEDBYTES 32U -#define CRHBYTES 48U -#define N 256U -#define Q 8380417U -#define QBITS 23U -#define ROOT_OF_UNITY 1753U -#define D 14U -#define GAMMA1 ((Q - 1U)/16U) -#define GAMMA2 (GAMMA1/2U) -#define ALPHA (2U*GAMMA2) - -#if MODE == 0 -#define K 3U -#define L 2U -#define ETA 7U -#define SETABITS 4U -#define BETA 375U -#define OMEGA 64U - -#elif MODE == 1 -#define K 4U -#define L 3U -#define ETA 6U -#define SETABITS 4U -#define BETA 325U -#define OMEGA 80U - -#elif MODE == 2 -#define K 5U -#define L 4U -#define ETA 5U -#define SETABITS 4U -#define BETA 275U -#define OMEGA 96U - -#elif MODE == 3 -#define K 6U -#define L 5U -#define ETA 3U -#define SETABITS 3U -#define BETA 175U -#define OMEGA 120U - -#endif - -#define POL_SIZE_PACKED ((N*QBITS)/8) -#define POLT1_SIZE_PACKED ((N*(QBITS - D))/8) -#define POLT0_SIZE_PACKED ((N*D)/8) -#define POLETA_SIZE_PACKED ((N*SETABITS)/8) -#define POLZ_SIZE_PACKED ((N*(QBITS - 3))/8) -#define POLW1_SIZE_PACKED ((N*4)/8) -#define POLVECK_SIZE_PACKED (K*POL_SIZE_PACKED) -#define POLVECL_SIZE_PACKED (L*POL_SIZE_PACKED) - -#define CRYPTO_PUBLICKEYBYTES (SEEDBYTES + K*POLT1_SIZE_PACKED) -#define CRYPTO_SECRETKEYBYTES (2*SEEDBYTES + (L + K)*POLETA_SIZE_PACKED + CRHBYTES + K*POLT0_SIZE_PACKED) -#define CRYPTO_BYTES (L*POLZ_SIZE_PACKED + (OMEGA + K) + (N/8 + 8)) - -#endif -#ifndef POLY_H -#define POLY_H - -//#include -//#include "params.h" -//#include "fips202.h" - -typedef struct { - uint32_t coeffs[N]; -} poly __attribute__((aligned(32))); - -void poly_reduce(poly *a); -void poly_csubq(poly *a); -void poly_freeze(poly *a); - -void poly_add(poly *c, const poly *a, const poly *b); -void poly_sub(poly *c, const poly *a, const poly *b); -void poly_neg(poly *a); -void poly_shiftl(poly *a, uint32_t k); - -void poly_ntt(poly *a); -void poly_invntt_montgomery(poly *a); -void poly_pointwise_invmontgomery(poly *c, const poly *a, const poly *b); - -void poly_power2round(poly *a1, poly *a0, const poly *a); -void poly_decompose(poly *a1, poly *a0, const poly *a); -uint32_t poly_make_hint(poly *h, const poly *a, const poly *b); -void poly_use_hint(poly *a, const poly *b, const poly *h); - -int poly_chknorm(const poly *a, uint32_t B); -void poly_uniform(poly *a, const uint8_t *buf); -void poly_uniform_eta(poly *a, - const uint8_t seed[SEEDBYTES], - uint8_t nonce); -void poly_uniform_gamma1m1(poly *a, - const uint8_t seed[SEEDBYTES + CRHBYTES], - uint16_t nonce); - -void polyeta_pack(uint8_t *r, const poly *a); -void polyeta_unpack(poly *r, const uint8_t *a); - -void polyt1_pack(uint8_t *r, const poly *a); -void polyt1_unpack(poly *r, const uint8_t *a); - -void polyt0_pack(uint8_t *r, const poly *a); -void polyt0_unpack(poly *r, const uint8_t *a); - -void polyz_pack(uint8_t *r, const poly *a); -void polyz_unpack(poly *r, const uint8_t *a); - -void polyw1_pack(uint8_t *r, const poly *a); -#endif -#ifndef POLYVEC_H -#define POLYVEC_H - -//#include -//#include "params.h" -//#include "poly.h" - -/* Vectors of polynomials of length L */ -typedef struct { - poly vec[L]; -} polyvecl; - -void polyvecl_freeze(polyvecl *v); - -void polyvecl_add(polyvecl *w, const polyvecl *u, const polyvecl *v); - -void polyvecl_ntt(polyvecl *v); -void polyvecl_pointwise_acc_invmontgomery(poly *w, - const polyvecl *u, - const polyvecl *v); - -int polyvecl_chknorm(const polyvecl *v, uint32_t B); - - - -/* Vectors of polynomials of length K */ -typedef struct { - poly vec[K]; -} polyveck; - -void polyveck_reduce(polyveck *v); -void polyveck_csubq(polyveck *v); -void polyveck_freeze(polyveck *v); - -void polyveck_add(polyveck *w, const polyveck *u, const polyveck *v); -void polyveck_sub(polyveck *w, const polyveck *u, const polyveck *v); -void polyveck_shiftl(polyveck *v, uint32_t k); - -void polyveck_ntt(polyveck *v); -void polyveck_invntt_montgomery(polyveck *v); - -int polyveck_chknorm(const polyveck *v, uint32_t B); - -void polyveck_power2round(polyveck *v1, polyveck *v0, const polyveck *v); -void polyveck_decompose(polyveck *v1, polyveck *v0, const polyveck *v); -uint32_t polyveck_make_hint(polyveck *h, - const polyveck *u, - const polyveck *v); -void polyveck_use_hint(polyveck *w, const polyveck *v, const polyveck *h); - -#endif - -#ifndef NTT_H -#define NTT_H - -//#include -//#include "params.h" - -void ntt(uint32_t p[N]); -void invntt_frominvmont(uint32_t p[N]); - -#endif -#ifndef PACKING_H -#define PACKING_H - -//#include "params.h" -//#include "polyvec.h" - -void pack_pk(uint8_t pk[CRYPTO_PUBLICKEYBYTES], - const uint8_t rho[SEEDBYTES], const polyveck *t1); -void pack_sk(uint8_t sk[CRYPTO_SECRETKEYBYTES], - const uint8_t rho[SEEDBYTES], - const uint8_t key[SEEDBYTES], - const uint8_t tr[CRHBYTES], - const polyvecl *s1, - const polyveck *s2, - const polyveck *t0); -void pack_sig(uint8_t sig[CRYPTO_BYTES], - const polyvecl *z, const polyveck *h, const poly *c); - -void unpack_pk(uint8_t rho[SEEDBYTES], polyveck *t1, - const uint8_t pk[CRYPTO_PUBLICKEYBYTES]); -void unpack_sk(uint8_t rho[SEEDBYTES], - uint8_t key[SEEDBYTES], - uint8_t tr[CRHBYTES], - polyvecl *s1, - polyveck *s2, - polyveck *t0, - const uint8_t sk[CRYPTO_SECRETKEYBYTES]); -int unpack_sig(polyvecl *z, polyveck *h, poly *c, - const uint8_t sig[CRYPTO_BYTES]); - -#endif -#ifndef REDUCE_H -#define REDUCE_H - -//#include - -#define MONT 4193792U // 2^32 % Q -#define QINV 4236238847U // -q^(-1) mod 2^32 - -/* a <= Q*2^32 => r < 2*Q */ -uint32_t montgomery_reduce(uint64_t a); - -/* r < 2*Q */ -uint32_t reduce32(uint32_t a); - -/* a < 2*Q => r < Q */ -uint32_t csubq(uint32_t a); - -/* r < Q */ -uint32_t freeze(uint32_t a); - -#endif -#ifndef ROUNDING_H -#define ROUNDING_H - -//#include - -uint32_t power2round(const uint32_t a, uint32_t *a0); -uint32_t decompose(uint32_t a, uint32_t *a0); -uint32_t make_hint(const uint32_t a, const uint32_t b); -uint32_t use_hint(const uint32_t a, const uint32_t hint); - -#endif -#ifndef SIGN_H -#define SIGN_H - -//#include "params.h" -//#include "poly.h" -//#include "polyvec.h" - -void expand_mat(polyvecl mat[K], const uint8_t rho[SEEDBYTES]); -void challenge(poly *c, const uint8_t mu[CRHBYTES], - const polyveck *w1); - -int crypto_sign_keypair(uint8_t *pk, uint8_t *sk); - -int crypto_sign(uint8_t *sm, int32_t *smlen, - const uint8_t *msg, int32_t len, - const uint8_t *sk); - -int crypto_sign_open(uint8_t *m, int32_t *mlen, - const uint8_t *sm, int32_t smlen, - const uint8_t *pk); - -#endif - -#ifndef API_H -#define API_H - -#ifndef MODE -#define MODE 3 -#endif - -#if MODE == 0 -#if CRYPTO_PUBLICKEYBYTES -896U -CRYPTO_PUBLICKEYBYTES size error -#endif -#if CRYPTO_SECRETKEYBYTES -2096U -CRYPTO_SECRETKEYBYTES size error -#endif -#if CRYPTO_BYTES -1387U -CRYPTO_BYTES size error -#endif - -#elif MODE == 1 -#if CRYPTO_PUBLICKEYBYTES -1184U -CRYPTO_PUBLICKEYBYTES size error -#endif -#if CRYPTO_SECRETKEYBYTES -2800U -CRYPTO_SECRETKEYBYTES size error -#endif -#if CRYPTO_BYTES -2044U -CRYPTO_BYTES size error -#endif - -#elif MODE == 2 -#if CRYPTO_PUBLICKEYBYTES -1472U -CRYPTO_PUBLICKEYBYTES size error -#endif -#if CRYPTO_SECRETKEYBYTES -3504U -CRYPTO_SECRETKEYBYTES size error -#endif -#if CRYPTO_BYTES -2701U -CRYPTO_BYTES size error -#endif - -#elif MODE == 3 -#if CRYPTO_PUBLICKEYBYTES -1760U -CRYPTO_PUBLICKEYBYTES size error -#endif -#if CRYPTO_SECRETKEYBYTES -3856U -CRYPTO_SECRETKEYBYTES size error -#endif -#if CRYPTO_BYTES -3366U -CRYPTO_BYTES size error -#endif - -#endif - -#define CRYPTO_ALGNAME "Dilithium" - -int crypto_sign_keypair(uint8_t *pk, uint8_t *sk); -int crypto_sign(uint8_t *sm, int32_t *smlen, const uint8_t *msg, int32_t len, const uint8_t *sk); -int crypto_sign_open(uint8_t *m, int32_t *mlen, const uint8_t *sm, int32_t smlen, const uint8_t *pk); - -#endif From 958bc486d4acf4e445a00aeff28098ce012e229a Mon Sep 17 00:00:00 2001 From: Duke Date: Sat, 10 Feb 2024 22:37:22 -0500 Subject: [PATCH 24/78] Delete more CCs #381 --- src/cc/CCinclude.h | 40 ------- src/cc/CCtokenutils.cpp | 236 ++-------------------------------------- src/cc/CCutils.cpp | 121 ++------------------ src/cc/customcc.cpp | 22 +--- src/script/cc.cpp | 40 +------ 5 files changed, 21 insertions(+), 438 deletions(-) diff --git a/src/cc/CCinclude.h b/src/cc/CCinclude.h index 3af9e0711..9846939fb 100644 --- a/src/cc/CCinclude.h +++ b/src/cc/CCinclude.h @@ -18,41 +18,6 @@ #ifndef CC_INCLUDE_H #define CC_INCLUDE_H -/*! \file CCinclude.h -\brief Cryptoconditions - -CCs for teh lulz - -*/ - -/// \mainpage Brief introduction into cryptocondition contracts -/// There are only a very few types in bitcoin: pay to pubkey, pay to pubkey hash and pay to script hash (p2pk, p2pkh, p2sh). -/// There are actually more that are possible, but those three are 99%+ of bitcoin transactions. -/// So you can pay to a pubkey, or to its hash or to a script's hash. The last is how most of the more complex scripts are invoked. To spend a p2sh vout, you need to provide the redeemscript, -/// this script's hash is what the p2sh address was. -/// All of the above are the standard bitcoin vout types and there should be plenty of materials about it. -/// -/// Cryptoconditions (CC) contracts created a fourth type of vout, the CC vout. This is using the cryptoconditions standard and it is even a different signature mechanism, -/// ed25519 instead of secp256k1. It is basically a big extension to the bitcoin script. There is a special opcode that is added that says it is a CC script. -/// -/// But it gets more interesting. Each CC script has an evalcode. -/// This is just an arbitrary number but what it does is allows to create a self-contained universe of CC utxo that all have the same evalcode and that is -/// how a faucet CC contract differentiates itself from a dice CC contract, the eval code is different. -/// -/// One effect from using a different eval code is that even if the rest of the CC script is the same, the bitcoin address that is calculated is different. -/// What this means is that for each pubkey, there is a unique address for each different eval code! -/// And this allows efficient segregation of one CC contracts transactions from another. -/// The final part that will make it all clear how the funds can be locked inside the contract. -/// This is what makes a contract, a contract. -/// I put both the privkey and pubkey for a randomly chosen address and associate it with each CC contract. -/// That means anybody can sign outputs for that privkey. -/// However, it is a CC output, so in addition to the signature, whatever constraints a CC contract implements must also be satistifed. -/// This allows funds to be locked and yet anybody is able to spend it, assuming they satisfy the CC's rules. -/// -/// One other technical note is that Hush has the insight-explorer extensions built in -/// so it can lookup directly all transactions to any address. -/// This is a key performance boosting thing as if it wasnt there, trying to get all the utxo for an address not in the wallet is quite time consuming. -/// #include #include