All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.google.bitcoin.store.FullPrunedBlockStore Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2012 Matt Corallo.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.bitcoin.store;

import com.google.bitcoin.core.Sha256Hash;
import com.google.bitcoin.core.StoredBlock;
import com.google.bitcoin.core.StoredTransactionOutput;
import com.google.bitcoin.core.StoredUndoableBlock;

/**
 * 

An implementor of FullPrunedBlockStore saves StoredBlock objects to some storage mechanism.

* *

In addition to keeping tack of a chain using {@link StoredBlock}s, it should also keep track of a second * copy of the chain which holds {@link StoredUndoableBlock}s. In this way, an application can perform a * headers-only initial sync and then use that information to more efficiently download a locally verified * full copy of the block chain.

* *

A FullPrunedBlockStore should function well as a standard {@link BlockStore} and then be able to * trivially switch to being used as a FullPrunedBlockStore.

* *

It should store the {@link StoredUndoableBlock}s of a number of recent blocks before verifiedHead.height and * all those after verifiedHead.height. * It is advisable to store any {@link StoredUndoableBlock} which has a height > verifiedHead.height - N. * Because N determines the memory usage, it is recommended that N be customizable. N should be chosen such that * re-orgs beyond that point are vanishingly unlikely, for example, a few thousand blocks is a reasonable choice.

* *

It must store the {@link StoredBlock} of all blocks.

* *

A FullPrunedBlockStore contains a map of hashes to [Full]StoredBlock. The hash is the double digest of the * Bitcoin serialization of the block header, not the header with the extra data as well.

* *

A FullPrunedBlockStore also contains a map of hash+index to StoredTransactionOutput. Again, the hash is * a standard Bitcoin double-SHA256 hash of the transaction.

* *

FullPrunedBlockStores are thread safe.

*/ public interface FullPrunedBlockStore extends BlockStore { /** *

Saves the given {@link StoredUndoableBlock} and {@link StoredBlock}. Calculates keys from the {@link StoredBlock}

* *

Though not required for proper function of a FullPrunedBlockStore, any user of a FullPrunedBlockStore should ensure * that a StoredUndoableBlock for each block up to the fully verified chain head has been added to this block store using * this function (not put(StoredBlock)), so that the ability to perform reorgs is maintained.

* * @throws BlockStoreException if there is a problem with the underlying storage layer, such as running out of disk space. */ void put(StoredBlock storedBlock, StoredUndoableBlock undoableBlock) throws BlockStoreException; /** * Returns the StoredBlock that was added as a StoredUndoableBlock given a hash. The returned values block.getHash() * method will be equal to the parameter. If no such block is found, returns null. */ StoredBlock getOnceUndoableStoredBlock(Sha256Hash hash) throws BlockStoreException; /** * Returns a {@link StoredUndoableBlock} whose block.getHash() method will be equal to the parameter. If no such * block is found, returns null. Note that this may return null more often than get(Sha256Hash hash) as not all * {@link StoredBlock}s have a {@link StoredUndoableBlock} copy stored as well. */ StoredUndoableBlock getUndoBlock(Sha256Hash hash) throws BlockStoreException; /** * Gets a {@link StoredTransactionOutput} with the given hash and index, or null if none is found */ StoredTransactionOutput getTransactionOutput(Sha256Hash hash, long index) throws BlockStoreException; /** * Adds a {@link StoredTransactionOutput} to the list of unspent TransactionOutputs */ void addUnspentTransactionOutput(StoredTransactionOutput out) throws BlockStoreException; /** * Removes a {@link StoredTransactionOutput} from the list of unspent TransactionOutputs * Note that the coinbase of the genesis block should NEVER be spendable and thus never in the list. * @throws BlockStoreException if there is an underlying storage issue, or out was not in the list. */ void removeUnspentTransactionOutput(StoredTransactionOutput out) throws BlockStoreException; /** * True if this store has any unspent outputs from a transaction with a hash equal to the first parameter * @param numOutputs the number of outputs the given transaction has */ boolean hasUnspentOutputs(Sha256Hash hash, int numOutputs) throws BlockStoreException; /** * Returns the {@link StoredBlock} that represents the top of the chain of greatest total work that has * been fully verified and the point in the chain at which the unspent transaction output set in this * store represents. */ StoredBlock getVerifiedChainHead() throws BlockStoreException; /** * Sets the {@link StoredBlock} that represents the top of the chain of greatest total work that has been * fully verified. It should generally be set after a batch of updates to the transaction unspent output set, * before a call to commitDatabaseBatchWrite. * * If chainHead has a greater height than the non-verified chain head (ie that set with * {@link BlockStore.setChainHead}) the non-verified chain head should be set to the one set here. * In this way a class using a FullPrunedBlockStore only in full-verification mode can ignore the regular * {@link BlockStore} functions implemented as a part of a FullPrunedBlockStore. */ void setVerifiedChainHead(StoredBlock chainHead) throws BlockStoreException; /** *

Begins/Commits/Aborts a database transaction.

* *

If abortDatabaseBatchWrite() is called by the same thread that called beginDatabaseBatchWrite(), * any data writes between this call and abortDatabaseBatchWrite() made by the same thread * should be discarded.

* *

Furthermore, any data written after a call to beginDatabaseBatchWrite() should not be readable * by any other threads until commitDatabaseBatchWrite() has been called by this thread. * Multiple calls to beginDatabaseBatchWrite() in any given thread should be ignored and treated as one call.

*/ void beginDatabaseBatchWrite() throws BlockStoreException; void commitDatabaseBatchWrite() throws BlockStoreException; void abortDatabaseBatchWrite() throws BlockStoreException; }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy