Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 16 additions & 11 deletions .github/workflows/gradle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,31 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, macOS-latest, windows-latest]
java: [ '8', '11', '15' ]
os: [ubuntu-22.04, macOS-15-intel, windows-2019]
java: ['11', '15']
distribution: ['zulu']
gradle: ['4.10.3']
fail-fast: false
name: JAVA ${{ matrix.java }} OS ${{ matrix.os }}
name: JAVA ${{ matrix.distribution }} ${{ matrix.java }} OS ${{ matrix.os }} Gradle ${{ matrix.gradle }}
steps:
- uses: actions/checkout@v1
- name: Git checkout
uses: actions/checkout@v4
- name: Set up JDK
uses: actions/setup-java@v1
uses: actions/setup-java@v4
with:
distribution: ${{ matrix.distribution }}
java-version: ${{ matrix.java }}
- name: Build with Gradle
uses: gradle/gradle-build-action@v1
- name: Set up Gradle
uses: gradle/actions/setup-gradle@v4
with:
gradle-version: 6.9
arguments: build --stacktrace
gradle-version: ${{ matrix.gradle }}
- name: Run Gradle
run: gradle build --stacktrace
- name: Upload Test Results and Reports
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v4
if: always()
with:
name: bitcoinj-core-test-results-jdk${{ matrix.java }}-${{ matrix.os }}
name: bitcoinj-core-test-results-jdk${{ matrix.java }}-${{ matrix.os }}-${{ matrix.gradle }}
path: |
core/build/reports/tests/test/
core/build/test-results/test/
4 changes: 2 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
buildscript {
repositories {
jcenter()
mavenCentral()
}

dependencies {
Expand All @@ -10,7 +10,7 @@ buildscript {

allprojects {
repositories {
jcenter()
mavenCentral()
}

group = 'org.bitcoinj'
Expand Down
5 changes: 3 additions & 2 deletions core/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ apply plugin: 'com.google.protobuf'
apply plugin: 'maven'
apply plugin: 'eclipse'

version = '0.15.10.bisq.16'
version = '0.15.10.bisq.17'
archivesBaseName = 'bitcoinj-core'
eclipse.project.name = 'bitcoinj-core'

Expand All @@ -15,12 +15,13 @@ dependencies {
implementation 'org.slf4j:slf4j-api:1.7.30'
implementation 'net.jcip:jcip-annotations:1.0'
compileOnly 'org.fusesource.leveldbjni:leveldbjni-all:1.8'
testImplementation 'junit:junit:4.13'
testImplementation 'junit:junit:4.13.1'
testImplementation 'org.easymock:easymock:3.2'
testImplementation 'com.fasterxml.jackson.core:jackson-databind:2.5.2'
testImplementation 'org.slf4j:slf4j-jdk14:1.7.30'
testImplementation 'com.h2database:h2:1.3.167'
testImplementation 'org.fusesource.leveldbjni:leveldbjni-all:1.8'
testImplementation 'org.hamcrest:hamcrest-library:1.3'
}

sourceCompatibility = 1.7
Expand Down
96 changes: 78 additions & 18 deletions core/src/main/java/org/bitcoinj/core/StoredBlock.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@

import org.bitcoinj.store.BlockStore;
import org.bitcoinj.store.BlockStoreException;
import com.google.common.base.Objects;

import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.util.Locale;
import java.util.Objects;

import static com.google.common.base.Preconditions.checkState;

Expand All @@ -37,16 +37,31 @@
*/
public class StoredBlock {

// A BigInteger representing the total amount of work done so far on this chain. As of May 2011 it takes 8
// bytes to represent this field, so 12 bytes should be plenty for now.
public static final int CHAIN_WORK_BYTES = 12;
public static final byte[] EMPTY_BYTES = new byte[CHAIN_WORK_BYTES];
public static final int COMPACT_SERIALIZED_SIZE = Block.HEADER_SIZE + CHAIN_WORK_BYTES + 4; // for height

private Block header;
private BigInteger chainWork;
private int height;
// A BigInteger representing the total amount of work done so far on this chain. As of June 22, 2024, it takes 12
// unsigned bytes to store this value, so developers should use the V2 format.
private static final int CHAIN_WORK_BYTES_V1 = 12;
// A BigInteger representing the total amount of work done so far on this chain.
private static final int CHAIN_WORK_BYTES_V2 = 32;
// Height is an int.
private static final int HEIGHT_BYTES = 4;
// Used for padding.
private static final byte[] EMPTY_BYTES = new byte[CHAIN_WORK_BYTES_V2]; // fit larger format
/** Number of bytes serialized by {@link #serializeCompact(ByteBuffer)} */
public static final int COMPACT_SERIALIZED_SIZE = Block.HEADER_SIZE + CHAIN_WORK_BYTES_V1 + HEIGHT_BYTES;
/** Number of bytes serialized by {@link #serializeCompactV2(ByteBuffer)} */
public static final int COMPACT_SERIALIZED_SIZE_V2 = Block.HEADER_SIZE + CHAIN_WORK_BYTES_V2 + HEIGHT_BYTES;

private final Block header;
private final BigInteger chainWork;
private final int height;

/**
* Create a StoredBlock from a (header-only) {@link Block}, chain work value, and block height
*
* @param header A Block object with only a header (no transactions should be included)
* @param chainWork Calculated chainWork for this block
* @param height block height for this block
*/
public StoredBlock(Block header, BigInteger chainWork, int height) {
this.header = header;
this.chainWork = chainWork;
Expand Down Expand Up @@ -91,7 +106,7 @@ public boolean equals(Object o) {

@Override
public int hashCode() {
return Objects.hashCode(header, chainWork, height);
return Objects.hash(header, chainWork, height);
}

/**
Expand All @@ -115,13 +130,35 @@ public StoredBlock getPrev(BlockStore store) throws BlockStoreException {
return store.get(getHeader().getPrevBlockHash());
}

/** Serializes the stored block to a custom packed format. Used by {@link CheckpointManager}. */
/**
* Serializes the stored block to a custom packed format. Used internally.
* As of June 22, 2024, it takes 12 unsigned bytes to store the chain work value,
* so developers should use {@link #serializeCompactV2(ByteBuffer)}.
*
* @param buffer buffer to write to
*/
public void serializeCompact(ByteBuffer buffer) {
byte[] chainWorkBytes = getChainWork().toByteArray();
checkState(chainWorkBytes.length <= CHAIN_WORK_BYTES, "Ran out of space to store chain work!");
if (chainWorkBytes.length < CHAIN_WORK_BYTES) {
byte[] chainWorkBytes = Utils.bigIntegerToBytes(getChainWork(), CHAIN_WORK_BYTES_V1);
if (chainWorkBytes.length < CHAIN_WORK_BYTES_V1) {
// Pad to the right size.
buffer.put(EMPTY_BYTES, 0, CHAIN_WORK_BYTES_V1 - chainWorkBytes.length);
}
buffer.put(chainWorkBytes);
buffer.putInt(getHeight());
byte[] bytes = getHeader().unsafeBitcoinSerialize();
buffer.put(bytes, 0, Block.HEADER_SIZE); // Trim the trailing 00 byte (zero transactions).
}

/**
* Serializes the stored block to a custom packed format. Used internally.
*
* @param buffer buffer to write to
*/
public void serializeCompactV2(ByteBuffer buffer) {
byte[] chainWorkBytes = Utils.bigIntegerToBytes(getChainWork(), CHAIN_WORK_BYTES_V2);
if (chainWorkBytes.length < CHAIN_WORK_BYTES_V2) {
// Pad to the right size.
buffer.put(EMPTY_BYTES, 0, CHAIN_WORK_BYTES - chainWorkBytes.length);
buffer.put(EMPTY_BYTES, 0, CHAIN_WORK_BYTES_V2 - chainWorkBytes.length);
}
buffer.put(chainWorkBytes);
buffer.putInt(getHeight());
Expand All @@ -131,9 +168,32 @@ public void serializeCompact(ByteBuffer buffer) {
buffer.put(bytes, 0, Block.HEADER_SIZE); // Trim the trailing 00 byte (zero transactions).
}

/** De-serializes the stored block from a custom packed format. Used by {@link CheckpointManager}. */
/**
* Deserializes the stored block from a custom packed format. Used internally.
* As of June 22, 2024, it takes 12 unsigned bytes to store the chain work value,
* so developers should use {@link #deserializeCompactV2(NetworkParameters, ByteBuffer)}.
*
* @param buffer data to deserialize
* @return deserialized stored block
*/
public static StoredBlock deserializeCompact(NetworkParameters params, ByteBuffer buffer) throws ProtocolException {
byte[] chainWorkBytes = new byte[StoredBlock.CHAIN_WORK_BYTES];
byte[] chainWorkBytes = new byte[StoredBlock.CHAIN_WORK_BYTES_V1];
buffer.get(chainWorkBytes);
BigInteger chainWork = new BigInteger(1, chainWorkBytes);
int height = buffer.getInt(); // +4 bytes
byte[] header = new byte[Block.HEADER_SIZE + 1]; // Extra byte for the 00 transactions length.
buffer.get(header, 0, Block.HEADER_SIZE);
return new StoredBlock(params.getDefaultSerializer().makeBlock(header), chainWork, height);
}

/**
* Deserializes the stored block from a custom packed format. Used internally.
*
* @param buffer data to deserialize
* @return deserialized stored block
*/
public static StoredBlock deserializeCompactV2(NetworkParameters params, ByteBuffer buffer) throws ProtocolException {
byte[] chainWorkBytes = new byte[StoredBlock.CHAIN_WORK_BYTES_V2];
buffer.get(chainWorkBytes);
BigInteger chainWork = new BigInteger(1, chainWorkBytes);
int height = buffer.getInt(); // +4 bytes
Expand Down
7 changes: 7 additions & 0 deletions core/src/main/java/org/bitcoinj/core/Utils.java
Original file line number Diff line number Diff line change
Expand Up @@ -417,6 +417,13 @@ public static void setMockClock(long mockClockSeconds) {
mockTime = new Date(mockClockSeconds * 1000);
}

/**
* Clears the mock clock and sleep
*/
public static void resetMocking() {
mockTime = null;
}

/**
* Returns the current time, or a mocked out equivalent.
*/
Expand Down
Loading