示例#1
0
bool mark_spent_outputs(leveldb::WriteBatch& spend_batch,
    const output_point& previous_output, const input_point& spent_inpoint)
{
    data_chunk spent_key = create_spent_key(previous_output),
        spend_value = create_spent_key(spent_inpoint);
    spend_batch.Put(slice(spent_key), slice(spend_value));
    return true;
}
示例#2
0
bool bdb_common::mark_spent_outputs(txn_guard_ptr txn,
    const message::output_point& previous_output,
    const message::input_point& current_input)
{
    readable_data_type spent_key, spend_value;
    spent_key.set(create_spent_key(previous_output));
    spend_value.set(create_spent_key(current_input));
    if (db_spends_->put(txn->get(), spent_key.get(), spend_value.get(),
            DB_NOOVERWRITE) != 0)
        return false;
    return true;
}
bool leveldb_chain_keeper::remove_address(leveldb::WriteBatch& batch,
    const script& output_script, const output_point& outpoint)
{
    payment_address address;
    if (!extract(address, output_script))
        return false;
    data_chunk raw_address = create_address_key(address);
    BITCOIN_ASSERT(!raw_address.empty());
    data_chunk outpoint_value = create_spent_key(outpoint);
    bool is_found = false;
    leveldb_iterator it(address_iterator(db_.addr, raw_address));
    for (; valid_address_iterator(it, raw_address); it->Next())
    {
        if (slice_to_output_point(it->value()) != outpoint)
            continue;
        // We found the address entry we were looking for.
        BITCOIN_ASSERT(!is_found);
        is_found = true;
        // Put changes into batch finally.
        batch.Delete(it->key());
        break;
    }
    BITCOIN_ASSERT(it->status().ok());
    if (!is_found)
        return false;
    return true;
}
bool leveldb_chain_keeper::clear_transaction_data(
    leveldb_transaction_batch& batch, const transaction_type& remove_tx)
{
    const hash_digest& tx_hash = hash_transaction(remove_tx);
    batch.tx.Delete(slice(tx_hash));
    // Remove spends
    // ... spends don't exist for coinbase txs.
    if (!is_coinbase(remove_tx))
        for (uint32_t input_index = 0; input_index < remove_tx.inputs.size();
            ++input_index)
        {
            const transaction_input_type& input =
                remove_tx.inputs[input_index];
            // We could check if the spend matches the inpoint for safety.
            //const input_point inpoint{tx_hash, input_index};
            // Recreate the key...
            data_chunk spent_key = create_spent_key(input.previous_output);
            // ... Perform the delete.
            batch.spend.Delete(slice(spent_key));
        }
    // Remove addresses
    for (uint32_t output_index = 0; output_index < remove_tx.outputs.size();
        ++output_index)
    {
        const transaction_output_type& output =
            remove_tx.outputs[output_index];
        if (!remove_address(batch.addr,
                output.output_script, {tx_hash, output_index}))
            return false;
    }
    return true;
}
示例#5
0
bool bdb_common::add_address(txn_guard_ptr txn,
    const script& output_script, const message::output_point& outpoint)
{
    data_chunk raw_address = create_address_key(output_script);
    if (raw_address.empty())
        return true;
    readable_data_type address_key, output_value;
    address_key.set(raw_address);
    output_value.set(create_spent_key(outpoint));
    if (db_address_->put(txn->get(), address_key.get(),
            output_value.get(), 0) != 0)
        return false;
    return true;
}
示例#6
0
bool bdb_common::fetch_spend(txn_guard_ptr txn,
    const message::output_point& spent_output,
    message::input_point& input_spend)
{
    readable_data_type search_spend;
    search_spend.set(create_spent_key(spent_output));
    writable_data_type raw_spend;
    if (db_spends_->get(txn->get(), search_spend.get(),
            raw_spend.get(), 0) != 0)
        return false;
    const data_chunk raw_spend_data = raw_spend.data();
    deserializer deserial(raw_spend_data);
    input_spend.hash = deserial.read_hash();
    input_spend.index = deserial.read_4_bytes();
    return true;
}
示例#7
0
bool leveldb_common::fetch_spend(const output_point& spent_output,
    input_point& input_spend)
{
    data_chunk spent_key = create_spent_key(spent_output);
    std::string raw_spend;
    leveldb::Status status = db_.spend->Get(
        leveldb::ReadOptions(), slice(spent_key), &raw_spend);
    if (status.IsNotFound())
        return false;
    else if (!status.ok())
    {
        log_fatal(LOG_BLOCKCHAIN) << "fetch_spend: " << status.ToString();
        return false;
    }
    const data_chunk raw_spend_data(raw_spend.begin(), raw_spend.end());
    auto deserial = make_deserializer(
        raw_spend_data.begin(), raw_spend_data.end());
    input_spend.hash = deserial.read_hash();
    input_spend.index = deserial.read_4_bytes();
    return true;
}