//
// 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;
}
Example #2
0
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);
}
Example #3
0
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>();
    }
}
Example #4
0
 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;
}
Example #6
0
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>");
    }
}
Example #7
0
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;
    }
}
Example #8
0
// ----------------------------------------------------
//  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;
}
Example #9
0
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;
}