remove streamer
This commit is contained in:
@@ -261,218 +261,6 @@ UniValue blockToDeltasJSON(const CBlock& block, const CBlockIndex* blockindex)
|
||||
return result;
|
||||
}
|
||||
|
||||
unsigned char hexval(unsigned char c)
|
||||
{
|
||||
if ('0' <= c && c <= '9')
|
||||
return c - '0';
|
||||
else if ('a' <= c && c <= 'f')
|
||||
return c - 'a' + 10;
|
||||
else if ('A' <= c && c <= 'F')
|
||||
return c - 'A' + 10;
|
||||
else abort();
|
||||
}
|
||||
|
||||
void hex2ascii(const string& in, string& out)
|
||||
{
|
||||
out.clear();
|
||||
out.reserve(in.length() / 2);
|
||||
for (string::const_iterator p = in.begin(); p != in.end(); p++)
|
||||
{
|
||||
unsigned char c = hexval(*p);
|
||||
p++;
|
||||
if (p == in.end()) break; // incomplete last digit - should report error
|
||||
c = (c << 4) + hexval(*p); // + takes precedence over <<
|
||||
out.push_back(c);
|
||||
}
|
||||
}
|
||||
|
||||
UniValue getdatafromblock(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() < 1 || params.size() > 2)
|
||||
throw runtime_error(
|
||||
"getdatafromblock \"hash|height\" true/false\n"
|
||||
"\nReturns all the data sent via streamer in block if there was any data in it.\n"
|
||||
"\nArguments:\n"
|
||||
"1. \"hash|height\" (string, required) The block hash or height\n"
|
||||
"2. \"true/false\" (bool, optional) if false do not return the actual data. Default true.\n"
|
||||
"\nResult (for verbose = true):\n"
|
||||
"{\n"
|
||||
" \"streamid\" : \"string\", (string) the name of the stream.\n"
|
||||
" \"firsttxid\" : \"hash\", (string) the first transaction of the stream.\n"
|
||||
" \"firstblockheight\" : \"n\", (numeric) the block the stream starts in.\n"
|
||||
" \"firstdeqid\" : n, (numeric) The sequence id of the first data chunk in this block\n"
|
||||
" \"lastseqid\" : n, (numeric) The sequence id of the last data chunk in this block\n"
|
||||
" \"data\" : \"xxxx\", (string) A hex string containing all the data chunks in this block.\n"
|
||||
"}\n"
|
||||
"\nResult (for verbose=false):\n"
|
||||
" \"streamid\" : \"string\", (string) the name of the stream.\n"
|
||||
" \"firsttxid\" : \"hash\", (string) the first transaction of the stream.\n"
|
||||
" \"firstblockheight\" : \"n\", (numeric) the block the stream starts in.\n"
|
||||
" \"firstdeqid\" : n, (numeric) The sequence id of the first data chunk in this block\n"
|
||||
" \"lastseqid\" : n, (numeric) The sequence id of the last data chunk in this block\n"
|
||||
+ HelpExampleCli("getblock", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09 false\"")
|
||||
+ HelpExampleRpc("getblock", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
|
||||
+ HelpExampleCli("getblock", "12800")
|
||||
+ HelpExampleRpc("getblock", "12800 false")
|
||||
);
|
||||
|
||||
LOCK(cs_main);
|
||||
|
||||
std::string strHash = params[0].get_str();
|
||||
bool fVerbose = true;
|
||||
if (params.size() > 1) {
|
||||
std::string verboseflag = params[1].get_str();
|
||||
if ( verboseflag == "false" )
|
||||
fVerbose = false;
|
||||
}
|
||||
|
||||
// If height is supplied, find the hash
|
||||
if (strHash.size() < (2 * sizeof(uint256))) {
|
||||
// std::stoi allows characters, whereas we want to be strict
|
||||
regex r("[[:digit:]]+");
|
||||
if (!regex_match(strHash, r)) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid block height parameter");
|
||||
}
|
||||
|
||||
int nHeight = -1;
|
||||
try {
|
||||
nHeight = std::stoi(strHash);
|
||||
}
|
||||
catch (const std::exception &e) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid block height parameter");
|
||||
}
|
||||
|
||||
if (nHeight < 0 || nHeight > chainActive.Height()) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Block height out of range");
|
||||
}
|
||||
strHash = chainActive[nHeight]->GetBlockHash().GetHex();
|
||||
}
|
||||
|
||||
uint256 hash(uint256S(strHash));
|
||||
|
||||
if (mapBlockIndex.count(hash) == 0)
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
|
||||
|
||||
CBlock block;
|
||||
CBlockIndex* pblockindex = mapBlockIndex[hash];
|
||||
|
||||
if (fHavePruned && !(pblockindex->nStatus & BLOCK_HAVE_DATA) && pblockindex->nTx > 0)
|
||||
throw JSONRPCError(RPC_INTERNAL_ERROR, "Block not available (pruned data)");
|
||||
|
||||
if(!ReadBlockFromDisk(block, pblockindex,1))
|
||||
throw JSONRPCError(RPC_INTERNAL_ERROR, "Can't read block from disk");
|
||||
|
||||
UniValue result(UniValue::VOBJ);
|
||||
int firstseqid = 0;
|
||||
int lastseqid = 0;
|
||||
int i = 0;
|
||||
int did1 = 0;
|
||||
int skippedtxs = 0;
|
||||
int failed = 0;
|
||||
int getfirstblock = 0;
|
||||
static std::string streamid,firsttxid;
|
||||
static int firsttxnHeight;
|
||||
std::string blockdata;
|
||||
fprintf(stderr, "number of tx in block: %ld\n", block.vtx.size());
|
||||
// Iif block tx size is > 2 then we can do this
|
||||
if ( block.vtx.size() > 2 )
|
||||
{
|
||||
BOOST_FOREACH(const CTransaction&tx, block.vtx)
|
||||
{
|
||||
// ignore first and last TX and any TX that does not have 3 vouts.
|
||||
if ( (i == 0) || (i == (block.vtx.size() -1)) || (tx.vout.size() != 3) )
|
||||
{
|
||||
fprintf(stderr, "skipped tx number: %d\n",i);
|
||||
skippedtxs = skippedtxs + 1;
|
||||
} else {
|
||||
std::string opretstr = HexStr(tx.vout[2].scriptPubKey.begin(), tx.vout[2].scriptPubKey.end());
|
||||
// scriptPubKey is longer than 81, should mean its an OP_RETURN, maybe also check vout == 0 ?
|
||||
if ( opretstr.size() > 81 ) {
|
||||
std::string idstr = opretstr.substr (8,64); // stream ID or txid
|
||||
std::string seqidstr = opretstr.substr (72,8); // sequence ID
|
||||
std::string data = opretstr.substr (80); // data chunk
|
||||
unsigned int seqid;
|
||||
std::stringstream ss;
|
||||
ss << std::hex << seqidstr;
|
||||
ss >> seqid;
|
||||
if ( seqid == 1 ) {
|
||||
streamid = idstr;
|
||||
getfirstblock = 1;
|
||||
} else if ( seqid == 2 ) {
|
||||
firsttxid = idstr;
|
||||
} else if (firsttxid.empty()) {
|
||||
firsttxid.append(idstr);
|
||||
} else if ( firsttxid != idstr ) {
|
||||
printf("firsttxid.%s idstr.%s change firsttxid and wipe streamid?\n",firsttxid.c_str(),idstr.c_str());
|
||||
firsttxid.clear();
|
||||
firsttxid.append(idstr);
|
||||
streamid.clear();
|
||||
firsttxnHeight = 0;
|
||||
}
|
||||
if ( seqid == (lastseqid + 1) || did1 == 0 ) {
|
||||
blockdata.append(data);
|
||||
} else {
|
||||
result.push_back(Pair("error","chunck out of order or missing in this block!"));
|
||||
result.push_back(Pair("lastvalidseqid", (int)lastseqid));
|
||||
break;
|
||||
}
|
||||
if ( did1 == 0 ) {
|
||||
firstseqid = seqid;
|
||||
did1 = 1;
|
||||
}
|
||||
lastseqid = seqid;
|
||||
} else {
|
||||
skippedtxs = skippedtxs + 1;
|
||||
fprintf(stderr, "skipped tx number: %d\n",i);
|
||||
}
|
||||
// function here to extract seqid from first and last TX
|
||||
// we an push the data or not depending on input from RPC.
|
||||
}
|
||||
i = i + 1;
|
||||
}
|
||||
if (streamid.empty() || getfirstblock == 1) {
|
||||
if ( lastseqid == 1) {
|
||||
firsttxid = block.vtx[1].GetHash().GetHex();
|
||||
}
|
||||
uint256 hash; CTransaction firsttx;
|
||||
uint256 firsttxid_256(uint256S(firsttxid));
|
||||
if (GetTransaction(firsttxid_256,firsttx,hash,false)) {
|
||||
if ( streamid.empty() ) {
|
||||
std::string firststreamid = HexStr(firsttx.vout[2].scriptPubKey.begin(), firsttx.vout[2].scriptPubKey.end());
|
||||
streamid.append(firststreamid.substr (8,64));
|
||||
}
|
||||
printf("first stream id changed to: %s\n", streamid.c_str());
|
||||
BlockMap::iterator mi = mapBlockIndex.find(hash);
|
||||
if (mi != mapBlockIndex.end() && (*mi).second) {
|
||||
CBlockIndex* pindex = (*mi).second;
|
||||
printf("found block height: %d\n",pindex->nHeight);
|
||||
if (chainActive.Contains(pindex)) {
|
||||
firsttxnHeight = pindex->nHeight;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
failed = 1;
|
||||
}
|
||||
|
||||
if ( failed == 1 || skippedtxs == i ) {
|
||||
result.push_back(Pair("error","there is no data in this block."));
|
||||
} else {
|
||||
std::string decodedstreamid;
|
||||
hex2ascii(streamid, decodedstreamid);
|
||||
result.push_back(Pair("streamid", decodedstreamid.c_str()));
|
||||
result.push_back(Pair("firsttxid", firsttxid));
|
||||
result.push_back(Pair("firstblockheight", (int)firsttxnHeight));
|
||||
result.push_back(Pair("firstseqid", (int)firstseqid));
|
||||
result.push_back(Pair("lastseqid", (int)lastseqid));
|
||||
if (fVerbose == true) {
|
||||
result.push_back(Pair("data", blockdata));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false)
|
||||
{
|
||||
UniValue result(UniValue::VOBJ);
|
||||
|
||||
Reference in New Issue
Block a user