From f9dd23be9d765fbb40cf35303010ea9838b5f1d2 Mon Sep 17 00:00:00 2001 From: Miguel Freitas Date: Thu, 24 Dec 2015 15:32:27 -0200 Subject: [PATCH] experimenting with username <-> uid mapping. might be useful to implement twitter translation apis requiring user_id. --- src/bitcoinrpc.cpp | 4 +++ src/bitcoinrpc.h | 2 ++ src/main.cpp | 71 ++++++++++++++++++++++++++++++++++++++++++++++ src/main.h | 4 +++ src/twister.cpp | 32 +++++++++++++++++++++ 5 files changed, 113 insertions(+) diff --git a/src/bitcoinrpc.cpp b/src/bitcoinrpc.cpp index 513979de..dcbbc85b 100644 --- a/src/bitcoinrpc.cpp +++ b/src/bitcoinrpc.cpp @@ -285,6 +285,8 @@ static const CRPCCommand vRPCCommands[] = { "getpieceavailability", &getpieceavailability, false, true, true }, { "getpiecemaxseen", &getpiecemaxseen, false, true, true }, { "peekpost", &peekpost, false, true, true }, + { "usernametouid", &usernametouid, false, true, true }, + { "uidtousername", &uidtousername, false, true, true }, }; CRPCTable::CRPCTable() @@ -1365,6 +1367,8 @@ Array RPCConvertValues(const std::string &strMethod, const std::vector 1) ConvertTo(params[1]); if (strMethod == "peekpost" && n > 1) ConvertTo(params[1]); if (strMethod == "peekpost" && n > 3) ConvertTo(params[3]); + if (strMethod == "uidtousername" && n > 0) ConvertTo(params[0]); + if (strMethod == "usernametouid" && n > 1) ConvertTo(params[1]);; return params; } diff --git a/src/bitcoinrpc.h b/src/bitcoinrpc.h index 03b92e91..cebdb693 100644 --- a/src/bitcoinrpc.h +++ b/src/bitcoinrpc.h @@ -237,5 +237,7 @@ extern json_spirit::Value leavegroup(const json_spirit::Array& params, bool fHel extern json_spirit::Value getpieceavailability(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value getpiecemaxseen(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value peekpost(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value uidtousername(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value usernametouid(const json_spirit::Array& params, bool fHelp); #endif diff --git a/src/main.cpp b/src/main.cpp index ff0ca714..3acf6bfc 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -406,6 +406,77 @@ bool CheckUsername(const std::string &userName, CValidationState &state) return true; } + +bool TxNumToUsername(unsigned int txNum, string &username) +{ + username = ""; + + if( txNum >= pindexBest->nChainTx ) + return error("TxNumToUsername : txNum out of range"); + + int begin=0; + int end=nBestHeight; + CBlockIndex *pindex; + do { + pindex = FindBlockByHeight((begin+end)/2); + if( txNum < pindex->nChainTx - pindex->nTx ) { + end = pindex->nHeight; + } else if ( txNum < pindex->nChainTx ) { + break; + } else { + begin = pindex->nHeight; + } + } while( 1 ); + + unsigned int txIdx = txNum - (pindex->nChainTx - pindex->nTx); + + CBlock block; + if (!ReadBlockFromDisk(block, pindex)) + return false; + + CTransaction &tx = block.vtx[txIdx]; + username = tx.GetUsername(); + return true; +} + +bool UsernameToTxNum(const string &username, int *txNum, bool last) +{ + CTransaction tx; + uint256 hashBlock; + if( !last ) { + return error("UsernameToTxNum : first not implemented"); + } else { + int maxHeight = -1; + if( !GetTransaction( username, tx, hashBlock, maxHeight) ) { + return false; + } + } + + if (!mapBlockIndex.count(hashBlock)) + return error("UsernameToTxNum : mapBlockIndex error"); + + CBlockIndex* pindex = mapBlockIndex[hashBlock]; + CBlock block; + if (!ReadBlockFromDisk(block, pindex)) + return false; + + unsigned int txIdx = 0; + while( txIdx < block.vtx.size() && + block.vtx[txIdx].GetUsername() != username ) { + txIdx++; + } + + if( txIdx >= block.vtx.size() ) + return error("UsernameToTxNum : username not found in block.vtx"); + + //printf("username: %s block: %d txIdx:%d nTx: %d chainTx:%d\n", + // username.c_str(), pindex->nHeight, txIdx, pindex->nTx, pindex->nChainTx); + + *txNum = (pindex->nChainTx - pindex->nTx) + txIdx; + return true; +} + + bool DoTxProofOfWork(CTransaction& tx) { CBigNum bnTarget; diff --git a/src/main.h b/src/main.h index ba37ed00..b296d06a 100644 --- a/src/main.h +++ b/src/main.h @@ -269,6 +269,10 @@ inline bool AllowFree(double dPriority) bool CheckUsername(const std::string &userName, CValidationState &state); +bool TxNumToUsername(unsigned int txNum, string &username); + +bool UsernameToTxNum(const string &username, int *txNum, bool last = true); + bool DoTxProofOfWork(CTransaction& tx); // Context-independent validity checks diff --git a/src/twister.cpp b/src/twister.cpp index db1f9daa..7fb1617a 100644 --- a/src/twister.cpp +++ b/src/twister.cpp @@ -4188,3 +4188,35 @@ Value peekpost(const Array& params, bool fHelp) return ret; } +Value uidtousername(const Array& params, bool fHelp) +{ + if (fHelp || params.size() < 1 || params.size() > 1 ) + throw runtime_error( + "uidtousername \n" + "convert uid to username"); + + int uid = params[0].get_int(); + + string strUsername; + if( !TxNumToUsername(uid, strUsername) ) + throw JSONRPCError(RPC_INTERNAL_ERROR, "TxNumToUsername failed"); + + return Value(strUsername); +} + +Value usernametouid(const Array& params, bool fHelp) +{ + if (fHelp || params.size() < 1 || params.size() > 2 ) + throw runtime_error( + "uidtousername [last=true]\n" + "convert username to uid"); + + string strUsername = params[0].get_str(); + bool last = (params.size() > 1) ? params[1].get_bool() : true; + + int uid; + if( !UsernameToTxNum(strUsername, &uid, last) ) + throw JSONRPCError(RPC_INTERNAL_ERROR, "UsernameToTxNum failed"); + + return Value(uid); +}