Merge pull request #248 from svost/ntp
authorCryptoManiac <CryptoManiac@users.noreply.github.com>
Sun, 4 Oct 2015 21:27:45 +0000 (00:27 +0300)
committerCryptoManiac <CryptoManiac@users.noreply.github.com>
Sun, 4 Oct 2015 21:27:45 +0000 (00:27 +0300)
Various ntp files fixes:

src/bitcoinrpc.cpp
src/makefile.bsd
src/makefile.linux-mingw
src/makefile.mingw
src/makefile.osx
src/makefile.unix
src/rpcmining.cpp

index 89592f3..b10cee7 100644 (file)
@@ -1217,9 +1217,7 @@ Array RPCConvertValues(const std::string &strMethod, const std::vector<std::stri
     if (strMethod == "getblocktemplate"       && n > 0) ConvertTo<Object>(params[0]);
     if (strMethod == "listsinceblock"         && n > 1) ConvertTo<int64_t>(params[1]);
 
-    if (strMethod == "scaninput"              && n > 1) ConvertTo<int>(params[1]);
-    if (strMethod == "scaninput"              && n > 2) ConvertTo<double>(params[2]);
-    if (strMethod == "scaninput"              && n > 3) ConvertTo<int>(params[3]);
+    if (strMethod == "scaninput"              && n > 0) ConvertTo<Object>(params[0]);
 
     if (strMethod == "sendalert"              && n > 2) ConvertTo<int64_t>(params[2]);
     if (strMethod == "sendalert"              && n > 3) ConvertTo<int64_t>(params[3]);
index 29c497e..8be6835 100644 (file)
@@ -88,9 +88,14 @@ LIBS+= \
 
 DEBUGFLAGS=-g
 
+xOPT_LEVEL=-O2
+ifeq (${USE_O3}, 1)
+    xOPT_LEVEL=-O3
+endif
+
 # CXXFLAGS can be specified on the make command line, so we use xCXXFLAGS that only
 # adds some defaults in front. Unfortunately, CXXFLAGS=... $(CXXFLAGS) does not work.
-xCXXFLAGS=-O0 -msse2 -pthread -Wall -Wextra -Wno-ignored-qualifiers -Wformat -Wformat-security -Wno-unused-parameter \
+xCXXFLAGS=$(xOPT_LEVEL) -msse2 -pthread -Wall -Wextra -Wno-ignored-qualifiers -Wformat -Wformat-security -Wno-unused-parameter \
     $(DEBUGFLAGS) $(DEFS) $(HARDENING) $(CXXFLAGS)
 
 # LDFLAGS can be specified on the make command line, so we use xLDFLAGS that only
index c34e197..3c65af9 100644 (file)
@@ -50,9 +50,14 @@ LIBS= \
  -l crypto \
  -Wl,-Bstatic -lpthread -Wl,-Bdynamic
 
+xOPT_LEVEL=-O2
+ifeq (${USE_O3}, 1)
+    xOPT_LEVEL=-O3
+endif
+
 DEFS=-D_MT -DWIN32 -D_WINDOWS -DBOOST_THREAD_USE_LIB -DBOOST_SPIRIT_THREADSAFE -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS
 DEBUGFLAGS=-g
-CFLAGS=-O2 -msse2 -w -Wall -Wextra -Wno-ignored-qualifiers -Wformat -Wformat-security -Wno-unused-parameter $(DEBUGFLAGS) $(DEFS) $(INCLUDEPATHS)
+CFLAGS=$(xOPT_LEVEL) -msse2 -w -Wall -Wextra -Wno-ignored-qualifiers -Wformat -Wformat-security -Wno-unused-parameter $(DEBUGFLAGS) $(DEFS) $(INCLUDEPATHS)
 LDFLAGS=-Wl,--dynamicbase -Wl,--nxcompat -static-libgcc -static-libstdc++
 
 ifndef USE_UPNP
index 2f1dd90..c09ed6b 100644 (file)
@@ -38,9 +38,14 @@ LIBS= \
   -l ssl \
   -l crypto
 
+xOPT_LEVEL=-O2
+ifeq (${USE_O3}, 1)
+    xOPT_LEVEL=-O3
+endif
+
 DEFS=-DWIN32 -D_WINDOWS -DBOOST_THREAD_USE_LIB -DBOOST_SPIRIT_THREADSAFE -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS
 DEBUGFLAGS=-g
-CFLAGS=-mthreads -O2 -msse2 -w -Wall -Wextra -Wno-ignored-qualifiers -Wformat -Wformat-security -Wno-unused-parameter $(DEBUGFLAGS) $(DEFS) $(INCLUDEPATHS)
+CFLAGS=-mthreads $(xOPT_LEVEL) -msse2 -w -Wall -Wextra -Wno-ignored-qualifiers -Wformat -Wformat-security -Wno-unused-parameter $(DEBUGFLAGS) $(DEFS) $(INCLUDEPATHS)
 LDFLAGS=-Wl,--dynamicbase -Wl,--nxcompat -Wl,--large-address-aware -static
 
 ifndef USE_UPNP
index 5aa9e9c..cd13d12 100644 (file)
@@ -134,16 +134,16 @@ ifeq (${USE_ASM}, 1)
 OBJS += crypto/scrypt/asm/obj/scrypt-arm.o crypto/scrypt/asm/obj/scrypt-x86.o crypto/scrypt/asm/obj/scrypt-x86_64.o crypto/scrypt/asm/obj/asm-wrapper.o
 
 crypto/scrypt/asm/obj/scrypt-x86.o: crypto/scrypt/asm/scrypt-x86.S
-       $(CXX) -c $(xCXXFLAGS) -MMD -o $@ $<
+       $(CXX) -c $(CFLAGS) -MMD -o $@ $<
 
 crypto/scrypt/asm/obj/scrypt-x86_64.o: crypto/scrypt/asm/scrypt-x86_64.S
-       $(CXX) -c $(xCXXFLAGS) -MMD -o $@ $<
+       $(CXX) -c $(CFLAGS) -MMD -o $@ $<
 
 crypto/scrypt/asm/obj/scrypt-arm.o: crypto/scrypt/asm/scrypt-arm.S
-       $(CXX) -c $(xCXXFLAGS) -MMD -o $@ $<
+       $(CXX) -c $(CFLAGS) -MMD -o $@ $<
 
 crypto/scrypt/asm/obj/asm-wrapper.o: crypto/scrypt/asm/asm-wrapper.cpp
-       $(CXX) -c $(xCXXFLAGS) -MMD -o $@ $<
+       $(CXX) -c $(CFLAGS) -MMD -o $@ $<
 else
 ifeq  (${USE_SSE2}, 1)
 # Intrinsic implementation
@@ -151,13 +151,13 @@ DEFS += -DUSE_SSE2
 OBJS += crypto/scrypt/intrin/obj/scrypt-sse2.o
 
 crypto/scrypt/intrin/obj/scrypt-sse2.o: crypto/scrypt/intrin/scrypt-sse2.cpp
-       $(CXX) -c $(xCXXFLAGS) -MMD -o $@ $<
+       $(CXX) -c $(CFLAGS) -MMD -o $@ $<
 else
 # Generic implementation
 OBJS += crypto/scrypt/generic/obj/scrypt-generic.o
 
 crypto/scrypt/generic/obj/scrypt-generic.o: crypto/scrypt/generic/scrypt-generic.cpp
-       $(CXX) -c $(xCXXFLAGS) -MMD -o $@ $<
+       $(CXX) -c $(CFLAGS) -MMD -o $@ $<
 endif
 endif
 
index 708695d..bc06fc4 100644 (file)
@@ -94,10 +94,14 @@ ifeq (${ARCH}, i686)
     EXT_OPTIONS=-msse2
 endif
 
+xOPT_LEVEL=-O2
+ifeq (${USE_O3}, 1)
+    xOPT_LEVEL=-O3
+endif
 
 # CXXFLAGS can be specified on the make command line, so we use xCXXFLAGS that only
 # adds some defaults in front. Unfortunately, CXXFLAGS=... $(CXXFLAGS) does not work.
-xCXXFLAGS=-O2 $(EXT_OPTIONS) -pthread -Wall -Wextra -Wno-ignored-qualifiers -Wformat -Wformat-security -Wno-unused-parameter \
+xCXXFLAGS=$(xOPT_LEVEL) $(EXT_OPTIONS) -pthread -Wall -Wextra -Wno-ignored-qualifiers -Wformat -Wformat-security -Wno-unused-parameter \
     $(DEBUGFLAGS) $(DEFS) $(HARDENING) $(CXXFLAGS)
 
 # LDFLAGS can be specified on the make command line, so we use xLDFLAGS that only
index a4f9680..63b4e37 100644 (file)
 #include "kernel.h"
 #include "bitcoinrpc.h"
 
+#include <boost/format.hpp>
+#include <boost/assign/list_of.hpp>
+#include <boost/iterator/counting_iterator.hpp>
+
 using namespace json_spirit;
 using namespace std;
 
@@ -69,45 +73,85 @@ Value getmininginfo(const Array& params, bool fHelp)
     return obj;
 }
 
+// scaninput '{"txid":"95d640426fe66de866a8cf2d0601d2c8cf3ec598109b4d4ffa7fd03dad6d35ce","difficulty":0.01, "days":10}'
 Value scaninput(const Array& params, bool fHelp)
 {
-    if (fHelp || params.size() > 4 || params.size() < 2)
+    if (fHelp || params.size() != 1)
         throw runtime_error(
-            "scaninput <txid> <nout> [difficulty] [days]\n"
-            "Scan specified input for suitable kernel solutions.\n"
-            "    [difficulty] - upper limit for difficulty, current difficulty by default;\n"
-            "    [days] - time window, 365 days by default.\n"
+            "scaninput {\"txid\":txid, \"vout\":[vout1, vout2, ..., voutN], \"difficulty\":difficulty, \"days\":days}\n"
+            "Scan specified transaction or input for suitable kernel solutions.\n"
+            "    difficulty - upper limit for difficulty, current difficulty by default;\n"
+            "    days - time window, 90 days by default.\n"
         );
 
+    RPCTypeCheck(params, boost::assign::list_of(obj_type));
+
+    Object scanParams = params[0].get_obj();
+
+    const Value& txid_v = find_value(scanParams, "txid");
+    if (txid_v.type() != str_type)
+        throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, missing txid key");
 
-    uint256 hash;
-    hash.SetHex(params[0].get_str());
+    string txid = txid_v.get_str();
+    if (!IsHex(txid))
+        throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected hex txid");
 
-    uint32_t nOut = params[1].get_int(), nBits = GetNextTargetRequired(pindexBest, true), nDays = 365;
+    uint256 hash(txid);
+    int32_t nDays = 90;
+    uint32_t nBits = GetNextTargetRequired(pindexBest, true);
 
-    if (params.size() > 2)
+    const Value& diff_v = find_value(scanParams, "difficulty");
+    if (diff_v.type() == real_type)
     {
+        double dDiff = diff_v.get_real();
+        if (dDiff <= 0)
+            throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, diff must be greater than zero");
+
         CBigNum bnTarget(nPoWBase);
         bnTarget *= 1000;
-        bnTarget /= (int) (params[2].get_real() * 1000);
+        bnTarget /= (int) (dDiff * 1000);
         nBits = bnTarget.GetCompact();
     }
 
-    if (params.size() > 3)
+    const Value& days_v = find_value(scanParams, "days");
+    if (days_v.type() == int_type)
     {
-        nDays = params[3].get_int();
+        nDays = days_v.get_int();
+        if (nDays <= 0)
+            throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, interval length must be greater than zero");
     }
 
+
     CTransaction tx;
     uint256 hashBlock = 0;
     if (GetTransaction(hash, tx, hashBlock))
     {
-        if (nOut > tx.vout.size())
-            throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Incorrect output number");
-
         if (hashBlock == 0)
             throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Unable to find transaction in the blockchain");
 
+        vector<int> vInputs(0);
+        const Value& inputs_v = find_value(scanParams, "vout");
+        if (inputs_v.type() == array_type)
+        {
+            Array inputs = inputs_v.get_array();
+            BOOST_FOREACH(const Value &v_out, inputs)
+            {
+                int nOut = v_out.get_int();
+                if (nOut < 0 || nOut > (int)tx.vout.size() - 1)
+                {
+                    stringstream strErrorMsg;
+                    strErrorMsg << boost::format("Invalid parameter, input number %d is out of range") % nOut;
+                    throw JSONRPCError(RPC_INVALID_PARAMETER, strErrorMsg.str());
+                }
+
+                vInputs.push_back(nOut);
+            }
+        }
+        else
+        {
+            vInputs = vector<int>(boost::counting_iterator<int>( 0 ), boost::counting_iterator<int>( tx.vout.size() ));
+        }
+
         CTxDB txdb("r");
 
         CBlock block;
@@ -130,36 +174,48 @@ Value scaninput(const Array& params, bool fHelp)
         // Only count coins meeting min age requirement
         if (nStakeMinAge + block.nTime > interval.first)
             interval.first += (nStakeMinAge + block.nTime - interval.first);
-        interval.second = interval.first + nDays * 86400;
-
-        // Build static part of kernel
-        CDataStream ssKernel(SER_GETHASH, 0);
-        ssKernel << nStakeModifier;
-        ssKernel << block.nTime << (txindex.pos.nTxPos - txindex.pos.nBlockPos) << tx.nTime << nOut;
-        CDataStream::const_iterator itK = ssKernel.begin();
+        interval.second = interval.first + nDays * nOneDay;
 
-        std::vector<std::pair<uint256, uint32_t> > solutions;
-        if (ScanKernelForward((unsigned char *)&itK[0], nBits, tx.nTime, tx.vout[nOut].nValue, interval, solutions))
+        Array results;
+        BOOST_FOREACH(const int &nOut, vInputs)
         {
-            Array results;
-
-            BOOST_FOREACH(const PAIRTYPE(uint256, uint32_t) solution, solutions)
+            // Check for spent flag
+            // It doesn't make sense to scan spent inputs.
+            if (!txindex.vSpent[nOut].IsNull())
+                continue;
+
+            // Skip zero value outputs
+            if (tx.vout[nOut].nValue == 0)
+                continue;
+
+            // Build static part of kernel
+            CDataStream ssKernel(SER_GETHASH, 0);
+            ssKernel << nStakeModifier;
+            ssKernel << block.nTime << (txindex.pos.nTxPos - txindex.pos.nBlockPos) << tx.nTime << nOut;
+            CDataStream::const_iterator itK = ssKernel.begin();
+
+            std::vector<std::pair<uint256, uint32_t> > result;
+            if (ScanKernelForward((unsigned char *)&itK[0], nBits, tx.nTime, tx.vout[nOut].nValue, interval, result))
             {
-
-                Object item;
-                item.push_back(Pair("hash", solution.first.GetHex()));
-                item.push_back(Pair("time", DateTimeStrFormat(solution.second)));
-
-                results.push_back(item);
+                BOOST_FOREACH(const PAIRTYPE(uint256, uint32_t) solution, result)
+                {
+                    Object item;
+                    item.push_back(Pair("nout", nOut));
+                    item.push_back(Pair("hash", solution.first.GetHex()));
+                    item.push_back(Pair("time", DateTimeStrFormat(solution.second)));
+
+                    results.push_back(item);
+                }
             }
-
-            return results;
         }
+
+        if (results.size() == 0)
+            return false;
+
+        return results;
     }
     else
         throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available about transaction");
-
-    return Value::null;
 }
 
 Value getworkex(const Array& params, bool fHelp)