use of co.rsk.bitcoinj.core.StoredBlock in project rskj by rsksmart.
the class BridgeSupport method getBtcTransactionConfirmationsGetCost.
public Long getBtcTransactionConfirmationsGetCost(Object[] args) {
final long BASIC_COST = 27_000;
final long STEP_COST = 315;
// 72 * 2. 72 is the cost of the hash operation
final long DOUBLE_HASH_COST = 144;
Sha256Hash btcBlockHash;
int branchHashesSize;
try {
btcBlockHash = Sha256Hash.wrap((byte[]) args[1]);
Object[] merkleBranchHashesArray = (Object[]) args[3];
branchHashesSize = merkleBranchHashesArray.length;
} catch (NullPointerException | IllegalArgumentException e) {
return BASIC_COST;
}
// Dynamic cost based on the depth of the block that contains
// the transaction. Find such depth first, then calculate
// the cost.
Context.propagate(btcContext);
try {
this.ensureBtcBlockStore();
final StoredBlock block = btcBlockStore.getFromCache(btcBlockHash);
// Block not found, default to basic cost
if (block == null) {
return BASIC_COST;
}
final int bestChainHeight = getBtcBlockchainBestChainHeight();
// Make sure calculated depth is >= 0
final int blockDepth = Math.max(0, bestChainHeight - block.getHeight());
// Block too deep, default to basic cost
if (blockDepth > BTC_TRANSACTION_CONFIRMATION_MAX_DEPTH) {
return BASIC_COST;
}
return BASIC_COST + blockDepth * STEP_COST + branchHashesSize * DOUBLE_HASH_COST;
} catch (IOException | BlockStoreException e) {
logger.warn("getBtcTransactionConfirmationsGetCost btcBlockHash:{} there was a problem " + "gathering the block depth while calculating the gas cost. " + "Defaulting to basic cost.", btcBlockHash, e);
return BASIC_COST;
}
}
use of co.rsk.bitcoinj.core.StoredBlock in project rskj by rsksmart.
the class BridgeSupport method getBtcBlockchainBlockHeaderByHeight.
public byte[] getBtcBlockchainBlockHeaderByHeight(int height) throws BlockStoreException, IOException {
Context.propagate(btcContext);
this.ensureBtcBlockStore();
StoredBlock block = btcBlockStore.getStoredBlockAtMainChainHeight(height);
return serializeBlockHeader(block);
}
use of co.rsk.bitcoinj.core.StoredBlock in project rskj by rsksmart.
the class BridgeSupport method getLowestBlock.
/**
* Returns the first bitcoin block we have. It is either a checkpoint or the genesis
*/
private StoredBlock getLowestBlock() throws IOException {
InputStream checkpoints = this.getCheckPoints();
if (checkpoints == null) {
BtcBlock genesis = bridgeConstants.getBtcParams().getGenesisBlock();
return new StoredBlock(genesis, genesis.getWork(), 0);
}
CheckpointManager manager = new CheckpointManager(bridgeConstants.getBtcParams(), checkpoints);
long time = getActiveFederation().getCreationTime().toEpochMilli();
// Go back 1 week to match CheckpointManager.checkpoint() behaviour
time -= 86400 * 7;
return manager.getCheckpointBefore(time);
}
use of co.rsk.bitcoinj.core.StoredBlock in project rskj by rsksmart.
the class BridgeSupport method getBtcBlockchainBlockLocator.
/**
* @deprecated
* Returns an array of block hashes known by the bridge contract.
* Federators can use this to find what is the latest block in the mainchain the bridge has.
* @return a List of bitcoin block hashes
*/
@Deprecated
public List<Sha256Hash> getBtcBlockchainBlockLocator() throws IOException, BlockStoreException {
StoredBlock initialBtcStoredBlock = this.getLowestBlock();
final int maxHashesToInform = 100;
List<Sha256Hash> blockLocator = new ArrayList<>();
StoredBlock cursor = getBtcBlockchainChainHead();
int bestBlockHeight = cursor.getHeight();
blockLocator.add(cursor.getHeader().getHash());
if (bestBlockHeight > initialBtcStoredBlock.getHeight()) {
boolean stop = false;
int i = 0;
try {
while (blockLocator.size() <= maxHashesToInform && !stop) {
int blockHeight = (int) (bestBlockHeight - Math.pow(2, i));
if (blockHeight <= initialBtcStoredBlock.getHeight()) {
blockLocator.add(initialBtcStoredBlock.getHeader().getHash());
stop = true;
} else {
cursor = this.getPrevBlockAtHeight(cursor, blockHeight);
blockLocator.add(cursor.getHeader().getHash());
}
i++;
}
} catch (Exception e) {
logger.error("Failed to walk the block chain whilst constructing a locator");
panicProcessor.panic("btcblockchain", "Failed to walk the block chain whilst constructing a locator");
throw new RuntimeException(e);
}
if (!stop) {
blockLocator.add(initialBtcStoredBlock.getHeader().getHash());
}
}
return blockLocator;
}
use of co.rsk.bitcoinj.core.StoredBlock in project rskj by rsksmart.
the class RepositoryBtcBlockStoreWithCacheTest method getInMainchain.
@Test
public void getInMainchain() throws BlockStoreException {
Repository repository = createRepository();
BtcBlockStoreWithCache.Factory btcBlockStoreFactory = new RepositoryBtcBlockStoreWithCache.Factory(bridgeConstants.getBtcParams());
int blockHeight = 100;
BtcBlock genesis = networkParameters.getGenesisBlock();
StoredBlock storedBlock1 = createStoredBlock(genesis, blockHeight, 0);
BridgeStorageProvider provider = mock(BridgeStorageProvider.class);
when(provider.getBtcBestBlockHashByHeight(blockHeight)).thenReturn(Optional.of(storedBlock1.getHeader().getHash()));
ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class);
BtcBlockStoreWithCache btcBlockStore = btcBlockStoreFactory.newInstance(repository, bridgeConstants, provider, activations);
btcBlockStore.put(storedBlock1);
Optional<StoredBlock> blockOptional = btcBlockStore.getInMainchain(blockHeight);
Assert.assertTrue(blockOptional.isPresent());
Assert.assertEquals(storedBlock1, blockOptional.get());
}
Aggregations