// // Utilities: convert hex-encoded Values // (throws error if not hex). // uint256 ParseHashV(const Value& v, string strName) { string strHex; if (v.type() == str_type) strHex = v.get_str(); if (!IsHex(strHex)) // Note: IsHex("") is false throw JSONRPCError(RPC_INVALID_PARAMETER, strName+" must be hexadecimal string (not '"+strHex+"')"); uint256 result; result.SetHex(strHex); return result; }
BOOST_FIXTURE_TEST_CASE(rpc_addmultisig, TestNetFixture) { rpcfn_type addmultisig = tableRPC["addmultisigaddress"]->actor; // old, 65-byte-long: const char address1Hex[] = "0434e3e09f49ea168c5bbf53f877ff4206923858aab7c7e1df25bc263978107c95e35065a27ef6f1b27222db0ec97e0e895eaca603d3ee0d4c060ce3d8a00286c8"; // new, compressed: const char address2Hex[] = "0388c2037017c62240b6b72ac1a2a5f94da790596ebd06177c8572752922165cb4"; Value v; CFreicoinAddress address; BOOST_CHECK_NO_THROW(v = addmultisig(createArgs(1, address1Hex), false)); address.SetString(v.get_str()); BOOST_CHECK(address.IsValid() && address.IsScript()); BOOST_CHECK_NO_THROW(v = addmultisig(createArgs(1, address1Hex, address2Hex), false)); address.SetString(v.get_str()); BOOST_CHECK(address.IsValid() && address.IsScript()); BOOST_CHECK_NO_THROW(v = addmultisig(createArgs(2, address1Hex, address2Hex), false)); address.SetString(v.get_str()); BOOST_CHECK(address.IsValid() && address.IsScript()); BOOST_CHECK_THROW(addmultisig(createArgs(0), false), runtime_error); BOOST_CHECK_THROW(addmultisig(createArgs(1), false), runtime_error); BOOST_CHECK_THROW(addmultisig(createArgs(2, address1Hex), false), runtime_error); BOOST_CHECK_THROW(addmultisig(createArgs(1, ""), false), runtime_error); BOOST_CHECK_THROW(addmultisig(createArgs(1, "NotAValidPubkey"), false), runtime_error); string short1(address1Hex, address1Hex+sizeof(address1Hex)-2); // last byte missing BOOST_CHECK_THROW(addmultisig(createArgs(2, short1.c_str()), false), runtime_error); string short2(address1Hex+1, address1Hex+sizeof(address1Hex)); // first byte missing BOOST_CHECK_THROW(addmultisig(createArgs(2, short2.c_str()), false), runtime_error); }
void ConvertTo(Value& value, bool fAllowNull=false) { if (fAllowNull && value.type() == null_type) return; if (value.type() == str_type) { // reinterpret string as unquoted json value Value value2; string strJSON = value.get_str(); if (!read_string(strJSON, value2)) throw runtime_error(string("Error parsing JSON:")+strJSON); ConvertTo<T>(value2, fAllowNull); value = value2; } else { value = value.get_value<T>(); } }
static QVariant toVariant(const Value& value) { if (value.type() == str_type) { return QVariant(QString::fromStdString(value.get_str())); } if (value.type() == int_type) { return QVariant(value.get_int()); } if (value.type() == real_type) { return QVariant(value.get_real()); } else { throw HootException("Unsupported type."); } }
bool Value::operator==( const Value& lhs ) const { if( this == &lhs ) return true; if( type() != lhs.type() ) return false; switch( type_ ) { case str_type: return get_str() == lhs.get_str(); case obj_type: return get_obj() == lhs.get_obj(); case array_type: return get_array() == lhs.get_array(); case bool_type: return get_bool() == lhs.get_bool(); case int_type: return get_int() == lhs.get_int(); case real_type: return get_real() == lhs.get_real(); case null_type: return true; }; assert( false ); return false; }
entry jsonToEntry(const Value &v) { entry::list_type lst; entry::dictionary_type dict; switch( v.type() ) { case int_type: return v.get_int(); case str_type: return v.get_str(); case array_type: for (Array::const_iterator i = v.get_array().begin(); i != v.get_array().end(); ++i) { lst.push_back( jsonToEntry(*i) ); } return lst; case obj_type: for (Object::const_iterator i = v.get_obj().begin(); i != v.get_obj().end(); ++i) { dict[ i->name_ ] = jsonToEntry(i->value_); } return dict; default: return string("<uninitialized>"); } }
int main(int argc, char* argv[]) { strings add_peers, connect_peers; boost::program_options::options_description extra("Extra options"); extra.add_options() ("addnode", boost::program_options::value<strings>(&add_peers), "Add a node to connect to") ("connect", boost::program_options::value<strings>(&connect_peers), "Connect only to the specified node") ; Configuration conf(argc, argv, extra); try { Auth auth(conf.user(), conf.pass()); // if rpc_user and rpc_pass are not set, all authenticated methods becomes disallowed. // If we have params on the cmdline we run as a command line client contacting a server if (conf.method() != "") { if (conf.method() == "help") { cout << "Usage: " << argv[0] << " [options] [rpc-command param1 param2 ...]\n"; cout << conf << "\n"; cout << "If no rpc-command is specified, " << argv[0] << " start up as a daemon, otherwise it offers commandline access to a running instance\n"; return 1; } if (conf.method() == "version") { cout << argv[0] << " version is: " << FormatVersion(PROTOCOL_VERSION) << "\n"; return 1; } // create URL string url = conf.url(); Client client; // this is a blocking post! Reply reply = client.post(url, RPC::content(conf.method(), conf.params()), auth.headers()); if(reply.status() == Reply::ok) { Object rpc_reply = RPC::reply(reply.content()); Value result = find_value(rpc_reply, "result"); if (result.type() == str_type) cout << result.get_str() << "\n"; else cout << write_formatted(result) << "\n"; return 0; } else { cout << "HTTP error code: " << reply.status() << "\n"; Object rpc_reply = RPC::reply(reply.content()); Object rpc_error = find_value(rpc_reply, "error").get_obj(); Value code = find_value(rpc_error, "code"); Value message = find_value(rpc_error, "message"); cout << "JSON RPC Error code: " << code.get_int() << "\n"; cout << message.get_str() << "\n"; return 1; } } // Else we start the bitcoin node and server! asio::ip::tcp::endpoint proxy_server; if(conf.proxy().size()) { strings host_port; string proxy = conf.proxy(); split(host_port, proxy, is_any_of(":")); if(host_port.size() < 2) host_port.push_back("1080"); proxy_server = asio::ip::tcp::endpoint(asio::ip::address_v4::from_string(host_port[0]), lexical_cast<short>(host_port[1])); } Node node(conf.chain(), conf.data_dir(), conf.listen(), lexical_cast<string>(conf.node_port()), proxy_server, conf.timeout(), ""); // it is also here we specify the use of a proxy! node.setClientVersion("libcoin/bitcoind", vector<string>()); node.verification(conf.verification()); node.validation(conf.validation()); node.persistence(conf.persistance()); node.searchable(conf.searchable()); PortMapper mapper(node.get_io_service(), conf.node_port()); // this will use the Node call if(conf.portmap()) mapper.start(); // use the connect and addnode options to restrict and supplement the irc and endpoint db. for(strings::iterator ep = add_peers.begin(); ep != add_peers.end(); ++ep) node.addPeer(*ep); for(strings::iterator ep = connect_peers.begin(); ep != connect_peers.end(); ++ep) node.connectPeer(*ep); // connect the accounts - first assume there is only one - the wallet.dat Wallet wallet(node, "wallet.dat", conf.data_dir()); // this will also register the needed callbacks // //node.subscribe(wallet); // which will first sync the wallet, then install it as a callback to the blockchain // question was how to get thread nodeThread(&Node::run, &node); // run this as a background thread CReserveKey reservekey(&wallet); Server server(conf.bind(), lexical_cast<string>(conf.port()), filesystem::initial_path().string()); if(conf.ssl()) server.setCredentials(conf.data_dir(), conf.certchain(), conf.privkey()); // Register Server methods. server.registerMethod(method_ptr(new Stop(server)), auth); // Register Node methods. server.registerMethod(method_ptr(new GetBlockHash(node))); server.registerMethod(method_ptr(new GetBlock(node))); server.registerMethod(method_ptr(new GetBlockCount(node))); server.registerMethod(method_ptr(new GetConnectionCount(node))); server.registerMethod(method_ptr(new GetDifficulty(node))); server.registerMethod(method_ptr(new GetInfo(node))); //server.registerMethod(method_ptr(new TxWait(node))); /// The Pool enables you to run a backend for a miner, i.e. your private pool, it also enables you to participate in the "Name of Pool" // We need a list of blocks for the shared mining // ChainAddress address("17uY6a7zUidQrJVvpnFchD1MX1untuAufd"); StaticPayee payee(address.getPubKeyHash()); Pool pool(node, payee); server.registerMethod(method_ptr(new GetWork(pool))); server.registerMethod(method_ptr(new GetBlockTemplate(pool))); server.registerMethod(method_ptr(new SubmitBlock(pool))); Miner miner(pool); miner.setGenerate(conf.generate()); thread miningThread(&Miner::run, &miner); // Register Wallet methods. server.registerMethod(method_ptr(new GetBalance(wallet)), auth); server.registerMethod(method_ptr(new GetNewAddress(wallet)), auth); server.registerMethod(method_ptr(new SendToAddress(wallet)), auth); server.registerMethod(method_ptr(new GetAccountAddress(wallet)), auth); server.registerMethod(method_ptr(new GetAccount(wallet)), auth); server.registerMethod(method_ptr(new SetAccount(wallet)), auth); server.registerMethod(method_ptr(new GetAddressesByAccount(wallet)), auth); server.registerMethod(method_ptr(new SetTxFee(wallet)), auth); server.registerMethod(method_ptr(new GetReceivedByAddress(wallet)), auth); server.registerMethod(method_ptr(new GetReceivedByAccount(wallet)), auth); server.registerMethod(method_ptr(new MoveCmd(wallet)), auth); server.registerMethod(method_ptr(new SendFrom(wallet)), auth); server.registerMethod(method_ptr(new SendMany(wallet)), auth); server.registerMethod(method_ptr(new ListReceivedByAddress(wallet)), auth); server.registerMethod(method_ptr(new ListReceivedByAccount(wallet)), auth); server.registerMethod(method_ptr(new ListTransactions(wallet)), auth); server.registerMethod(method_ptr(new ListAccounts(wallet)), auth); server.registerMethod(method_ptr(new GetWalletTransaction(wallet)), auth); server.registerMethod(method_ptr(new BackupWallet(wallet)), auth); server.registerMethod(method_ptr(new KeypoolRefill(wallet)), auth); server.registerMethod(method_ptr(new WalletPassphraseChange(wallet)), auth); server.registerMethod(method_ptr(new WalletLock(wallet)), auth); server.registerMethod(method_ptr(new EncryptWallet(wallet)), auth); server.registerMethod(method_ptr(new ValidateAddress(wallet)), auth); // this method also takes the io_service from the server to start a deadline timer locking the wallet again. server.registerMethod(method_ptr(new WalletPassphrase(wallet, server.get_io_service())), auth); try { // we keep the server in its own exception scope as we want the other threads to shut down properly if the server exits server.run(); } catch(std::exception& e) { cerr << "Error: " << e.what() << endl; } log_info("Server exited, shutting down Node and Miner...\n"); // getting here means that we have exited from the server (e.g. by the quit method) miner.shutdown(); miningThread.join(); node.shutdown(); nodeThread.join(); return 0; } catch(std::exception& e) { cerr << "Error: " << e.what() << endl; return 1; } }
// ---------------------------------------------------- // Serialization Functions // ---------------------------------------------------- AbstractPlanNode* AbstractPlanNode::fromJSONObject(Object &obj, const catalog::Database *catalog_db) { Value typeValue = find_value(obj, "PLAN_NODE_TYPE"); if (typeValue == Value::null) { throw SerializableEEException(VOLT_EE_EXCEPTION_TYPE_EEEXCEPTION, "AbstractPlanNode::fromJSONObject:" " PLAN_NODE_TYPE value is null"); } string typeString = typeValue.get_str(); AbstractPlanNode* node = plannodeutil::getEmptyPlanNode(stringToPlanNode(typeString)); Value idValue = find_value(obj, "ID"); if (idValue == Value::null) { delete node; throw SerializableEEException(VOLT_EE_EXCEPTION_TYPE_EEEXCEPTION, "AbstractPlanNode::fromJSONObject:" " ID value is null"); } node->m_planNodeId = (int32_t) idValue.get_int(); VOLT_TRACE("Initializing PlanNode %s", node->debug().c_str()); Value inlineNodesValue = find_value(obj,"INLINE_NODES"); if (inlineNodesValue == Value::null) { delete node; throw SerializableEEException(VOLT_EE_EXCEPTION_TYPE_EEEXCEPTION, "AbstractPlanNode::fromJSONObject:" " INLINE_NODES value is null"); } Array inlineNodes = inlineNodesValue.get_array(); for (int ii = 0; ii < inlineNodes.size(); ii++) { AbstractPlanNode* newNode = NULL; try { Object obj = inlineNodes[ii].get_obj(); newNode = AbstractPlanNode::fromJSONObject(obj, catalog_db); } catch (SerializableEEException &ex) { delete newNode; delete node; throw; } // todo: if this throws, new Node can be leaked. // As long as newNode is not NULL, this will not throw. node->addInlinePlanNode(newNode); VOLT_TRACE("Adding inline PlanNode %s for %s", newNode->debug().c_str(), node->debug().c_str()); } Value parentNodeIdsValue = find_value(obj, "PARENT_IDS"); if (parentNodeIdsValue == Value::null) { delete node; throw SerializableEEException(VOLT_EE_EXCEPTION_TYPE_EEEXCEPTION, "AbstractPlanNode::fromJSONObject:" " PARENT_IDS value is null"); } Array parentNodeIdsArray = parentNodeIdsValue.get_array(); for (int ii = 0; ii < parentNodeIdsArray.size(); ii++) { int32_t parentNodeId = (int32_t) parentNodeIdsArray[ii].get_int(); node->m_parentIds.push_back(parentNodeId); } Value childNodeIdsValue = find_value(obj, "CHILDREN_IDS"); if (childNodeIdsValue == Value::null) { delete node; throw SerializableEEException(VOLT_EE_EXCEPTION_TYPE_EEEXCEPTION, "AbstractPlanNode::fromJSONObject:" " CHILDREN_IDS value is null"); } Array childNodeIdsArray = childNodeIdsValue.get_array(); for (int ii = 0; ii < childNodeIdsArray.size(); ii++) { int32_t childNodeId = (int32_t) childNodeIdsArray[ii].get_int(); node->m_childIds.push_back(childNodeId); } Value outputColumnsValue = find_value(obj, "OUTPUT_COLUMNS"); if (outputColumnsValue == Value::null) { delete node; throw SerializableEEException(VOLT_EE_EXCEPTION_TYPE_EEEXCEPTION, "AbstractPlanNode::loadFromJSONObject:" " Can't find OUTPUT_COLUMNS value"); } Array outputColumnsArray = outputColumnsValue.get_array(); for (int ii = 0; ii < outputColumnsArray.size(); ii++) { Value outputColumnValue = outputColumnsArray[ii]; PlanColumn outputColumn = PlanColumn(outputColumnValue.get_obj()); node->m_outputColumnGuids.push_back(outputColumn.getGuid()); } try { node->loadFromJSONObject(obj, catalog_db); } catch (SerializableEEException &ex) { delete node; throw; } return node; }
bool Move::Parse(const PlayerID &player, const std::string &json) { using namespace json_spirit; if (!IsValidPlayerName(player)) return false; Value v; if (!read_string(json, v) || v.type() != obj_type) return false; Object obj = v.get_obj(); if (ExtractField(obj, "msg", v)) { if (v.type() != str_type) return false; message = v.get_str(); } if (ExtractField(obj, "address", v)) { if (v.type() != str_type) return false; const std::string &addr = v.get_str(); if (!addr.empty() && !IsValidBitcoinAddress(addr)) return false; address = addr; } if (ExtractField(obj, "addressLock", v)) { if (v.type() != str_type) return false; const std::string &addr = v.get_str(); if (!addr.empty() && !IsValidBitcoinAddress(addr)) return false; addressLock = addr; } if (ExtractField(obj, "color", v)) { if (v.type() != int_type) return false; color = v.get_int(); if (color >= NUM_TEAM_COLORS) return false; if (!obj.empty()) // Extra fields are not allowed in JSON string return false; this->player = player; return true; } std::set<int> character_indices; for (std::vector<json_spirit::Pair>::iterator it = obj.begin(); it != obj.end(); ++it) { int i = atoi(it->name_); if (i < 0 || strprintf("%d", i) != it->name_) return false; // Number formatting must be strict if (character_indices.count(i)) return false; // Cannot contain duplicate character indices character_indices.insert(i); v = it->value_; if (v.type() != obj_type) return false; Object subobj = v.get_obj(); bool bWaypoints = false; std::vector<Coord> wp; if (!ParseWaypoints(subobj, wp, bWaypoints)) return false; bool bDestruct; if (!ParseDestruct(subobj, bDestruct)) return false; if (bDestruct) { if (bWaypoints) return false; // Cannot combine destruct and waypoints destruct.insert(i); } else if (bWaypoints) waypoints[i] = wp; if (!subobj.empty()) // Extra fields are not allowed in JSON string return false; } this->player = player; return true; }