Sha256Hash: some tweaks and renamings in the API (backwards compatible).

This commit is contained in:
Mike Hearn 2015-03-05 13:59:15 -08:00
parent bf60a925bc
commit 6aa4e51de6
15 changed files with 47 additions and 41 deletions

View File

@ -562,13 +562,13 @@ public class Block extends Message {
maybeParseHeader();
Block block = new Block(params);
block.nonce = nonce;
block.prevBlockHash = prevBlockHash.duplicate();
block.merkleRoot = getMerkleRoot().duplicate();
block.prevBlockHash = prevBlockHash;
block.merkleRoot = getMerkleRoot();
block.version = version;
block.time = time;
block.difficultyTarget = difficultyTarget;
block.transactions = null;
block.hash = getHash().duplicate();
block.hash = getHash();
return block;
}

View File

@ -54,10 +54,16 @@ public class Sha256Hash implements Serializable, Comparable<Sha256Hash> {
this.bytes = Utils.HEX.decode(hexString);
}
/**
* Calculates the (one-time) hash of contents and returns it as a new wrapped hash.
*/
/** Use Sha256Hash.hash(byte[]) instead: this old name is ambiguous */
@Deprecated
public static Sha256Hash create(byte[] contents) {
return hash(contents);
}
/**
* Calculates the (one-time) hash of contents and returns it.
*/
public static Sha256Hash hash(byte[] contents) {
try {
MessageDigest digest = MessageDigest.getInstance("SHA-256");
return new Sha256Hash(digest.digest(contents));
@ -66,10 +72,16 @@ public class Sha256Hash implements Serializable, Comparable<Sha256Hash> {
}
}
/** Use hashTwice(byte[]) instead: this old name is ambiguous. */
@Deprecated
public static Sha256Hash createDouble(byte[] contents) {
return hashTwice(contents);
}
/**
* Calculates the hash of the hash of the contents. This is a standard operation in Bitcoin.
*/
public static Sha256Hash createDouble(byte[] contents) {
public static Sha256Hash hashTwice(byte[] contents) {
return new Sha256Hash(Utils.doubleDigest(contents));
}
@ -81,7 +93,7 @@ public class Sha256Hash implements Serializable, Comparable<Sha256Hash> {
public static Sha256Hash hashFileContents(File f) throws IOException {
FileInputStream in = new FileInputStream(f);
try {
return create(ByteStreams.toByteArray(in));
return hash(ByteStreams.toByteArray(in));
} finally {
in.close();
}
@ -96,9 +108,9 @@ public class Sha256Hash implements Serializable, Comparable<Sha256Hash> {
}
/**
* Hash code of the byte array as calculated by {@link Arrays#hashCode()}. Note the difference between a SHA256
* secure bytes and the type of quick/dirty bytes used by the Java hashCode method which is designed for use in
* bytes tables.
* Returns the last four bytes of the wrapped hash. This should be unique enough to be a suitable hash code even for
* blocks, where the goal is to try and get the first bytes to be zeros (i.e. the value as a big integer lower
* than the target value).
*/
@Override
public int hashCode() {
@ -118,14 +130,13 @@ public class Sha256Hash implements Serializable, Comparable<Sha256Hash> {
return new BigInteger(1, bytes);
}
/**
* Returns the internal byte array, without defensively copying. Therefore do NOT modify the returned array.
*/
public byte[] getBytes() {
return bytes;
}
public Sha256Hash duplicate() {
return new Sha256Hash(bytes);
}
@Override
public int compareTo(Sha256Hash o) {
int thisCode = this.hashCode();

View File

@ -180,7 +180,7 @@ public class MnemonicCode {
entropy[ii] |= 1 << (7 - jj);
// Take the digest of the entropy.
byte[] hash = Sha256Hash.create(entropy).getBytes();
byte[] hash = Sha256Hash.hash(entropy).getBytes();
boolean[] hashBits = bytesToBits(hash);
// Check all the checksum bits.
@ -204,7 +204,7 @@ public class MnemonicCode {
// We take initial entropy of ENT bits and compute its
// checksum by taking first ENT / 32 bits of its SHA256 hash.
byte[] hash = Sha256Hash.create(entropy).getBytes();
byte[] hash = Sha256Hash.hash(entropy).getBytes();
boolean[] hashBits = bytesToBits(hash);
boolean[] entropyBits = bytesToBits(entropy);

View File

@ -77,7 +77,7 @@ public class HttpDiscovery implements PeerDiscovery {
if (pubkey != null) {
if (!Arrays.equals(proto.getPubkey().toByteArray(), pubkey.getPubKey()))
throw new PeerDiscoveryException("Public key mismatch");
Sha256Hash hash = Sha256Hash.create(proto.getPeerSeeds().toByteArray());
Sha256Hash hash = Sha256Hash.hash(proto.getPeerSeeds().toByteArray());
pubkey.verifyOrThrow(hash.getBytes(), proto.getSignature().toByteArray());
}
PeerSeedProtos.PeerSeeds seeds = PeerSeedProtos.PeerSeeds.parseFrom(proto.getPeerSeeds());

View File

@ -101,7 +101,7 @@ public class PaymentChannelClientConnection {
throws IOException, ValueOutOfRangeException {
// Glue the object which vends/ingests protobuf messages in order to manage state to the network object which
// reads/writes them to the wire in length prefixed form.
channelClient = new PaymentChannelClient(wallet, myKey, maxValue, Sha256Hash.create(serverId.getBytes()), timeWindow,
channelClient = new PaymentChannelClient(wallet, myKey, maxValue, Sha256Hash.hash(serverId.getBytes()), timeWindow,
userKeySetup, new PaymentChannelClient.ClientConnection() {
@Override
public void sendToServer(Protos.TwoWayChannelMessage msg) {

View File

@ -167,7 +167,7 @@ public class BlockTest {
Arrays.fill(outputScript, (byte) ScriptOpCodes.OP_FALSE);
tx.addOutput(new TransactionOutput(params, null, Coin.SATOSHI, outputScript));
tx.addInput(new TransactionInput(params, null, new byte[] {(byte) ScriptOpCodes.OP_FALSE},
new TransactionOutPoint(params, 0, Sha256Hash.create(new byte[] {1}))));
new TransactionOutPoint(params, 0, Sha256Hash.hash(new byte[]{1}))));
int origTxLength = 8 + 2 + 8 + 1 + 10 + 40 + 1 + 1;
assertEquals(tx.bitcoinSerialize().length, tx.length);
assertEquals(origTxLength, tx.length);
@ -182,7 +182,7 @@ public class BlockTest {
assertEquals(block.length, origBlockLen + tx.length);
assertEquals(tx.length, origTxLength - 1);
block.getTransactions().get(1).addInput(new TransactionInput(params, null, new byte[] {(byte) ScriptOpCodes.OP_FALSE},
new TransactionOutPoint(params, 0, Sha256Hash.create(new byte[] {1}))));
new TransactionOutPoint(params, 0, Sha256Hash.hash(new byte[]{1}))));
assertEquals(block.length, origBlockLen + tx.length);
assertEquals(tx.length, origTxLength + 41); // - 1 + 40 + 1 + 1
}

View File

@ -87,7 +87,7 @@ public class ECKeyTest {
List<ListenableFuture<ECKey.ECDSASignature>> sigFutures = Lists.newArrayList();
final ECKey key = new ECKey();
for (byte i = 0; i < ITERATIONS; i++) {
final Sha256Hash hash = Sha256Hash.create(new byte[]{i});
final Sha256Hash hash = Sha256Hash.hash(new byte[]{i});
sigFutures.add(executor.submit(new Callable<ECKey.ECDSASignature>() {
@Override
public ECKey.ECDSASignature call() throws Exception {
@ -247,7 +247,7 @@ public class ECKeyTest {
public void keyRecovery() throws Exception {
ECKey key = new ECKey();
String message = "Hello World!";
Sha256Hash hash = Sha256Hash.create(message.getBytes());
Sha256Hash hash = Sha256Hash.hash(message.getBytes());
ECKey.ECDSASignature sig = key.sign(hash);
key = ECKey.fromPublicOnly(key.getPubKeyPoint());
boolean found = false;
@ -346,7 +346,7 @@ public class ECKeyTest {
ECKey encryptedKey = unencryptedKey.encrypt(keyCrypter, aesKey);
String message = "Goodbye Jupiter!";
Sha256Hash hash = Sha256Hash.create(message.getBytes());
Sha256Hash hash = Sha256Hash.hash(message.getBytes());
ECKey.ECDSASignature sig = encryptedKey.sign(hash, aesKey);
unencryptedKey = ECKey.fromPublicOnly(unencryptedKey.getPubKeyPoint());
boolean found = false;

View File

@ -981,7 +981,7 @@ public class FullBlockTestGenerator {
NewBlock b49 = createNextBlock(b44, chainHeadHeight + 16, out15, null);
byte[] b49MerkleHash = Sha256Hash.ZERO_HASH.getBytes().clone();
b49MerkleHash[1] = (byte) 0xDE;
b49.block.setMerkleRoot(Sha256Hash.create(b49MerkleHash));
b49.block.setMerkleRoot(Sha256Hash.hash(b49MerkleHash));
b49.solve();
blocks.add(new BlockAndValidity(b49, false, true, b44.getHash(), chainHeadHeight + 15, "b49"));

View File

@ -708,7 +708,7 @@ public class PeerTest extends TestWithNetworkConnections {
Transaction t2 = new Transaction(unitTestParams);
t2.setLockTime(999999);
// Add a fake input to t3 that goes nowhere.
Sha256Hash t3 = Sha256Hash.create("abc".getBytes(Charset.forName("UTF-8")));
Sha256Hash t3 = Sha256Hash.hash("abc".getBytes(Charset.forName("UTF-8")));
t2.addInput(new TransactionInput(unitTestParams, t2, new byte[]{}, new TransactionOutPoint(unitTestParams, 0, t3)));
t2.getInput(0).setSequenceNumber(0xDEADBEEF);
t2.addOutput(COIN, new ECKey());
@ -842,9 +842,9 @@ public class PeerTest extends TestWithNetworkConnections {
@Override
public void bitcoinSerializeToStream(OutputStream stream) throws IOException {
// Add some hashes.
addItem(new InventoryItem(InventoryItem.Type.Transaction, Sha256Hash.create(new byte[] { 1 })));
addItem(new InventoryItem(InventoryItem.Type.Transaction, Sha256Hash.create(new byte[] { 2 })));
addItem(new InventoryItem(InventoryItem.Type.Transaction, Sha256Hash.create(new byte[] { 3 })));
addItem(new InventoryItem(InventoryItem.Type.Transaction, Sha256Hash.hash(new byte[]{1})));
addItem(new InventoryItem(InventoryItem.Type.Transaction, Sha256Hash.hash(new byte[]{2})));
addItem(new InventoryItem(InventoryItem.Type.Transaction, Sha256Hash.hash(new byte[]{3})));
// Write out a copy that's truncated in the middle.
ByteArrayOutputStream bos = new ByteArrayOutputStream();

View File

@ -157,7 +157,7 @@ public class ChildKeyDerivationTest {
assertFalse(decryptedKey2.isEncrypted());
assertEquals(key2, decryptedKey2);
Sha256Hash hash = Sha256Hash.create("the mainstream media won't cover it. why is that?".getBytes());
Sha256Hash hash = Sha256Hash.hash("the mainstream media won't cover it. why is that?".getBytes());
try {
derivedKey2.sign(hash);
fail();

View File

@ -290,7 +290,7 @@ public class ChannelConnectionTest extends TestWithWallet {
// Tests various aspects of channel resuming.
Utils.setMockClock();
final Sha256Hash someServerId = Sha256Hash.create(new byte[]{});
final Sha256Hash someServerId = Sha256Hash.hash(new byte[]{});
// Open up a normal channel.
ChannelTestUtils.RecordingPair pair = ChannelTestUtils.makeRecorders(serverWallet, mockBroadcaster);
@ -340,7 +340,7 @@ public class ChannelConnectionTest extends TestWithWallet {
pair.server.receiveMessage(Protos.TwoWayChannelMessage.newBuilder()
.setType(MessageType.CLIENT_VERSION)
.setClientVersion(Protos.ClientVersion.newBuilder()
.setPreviousChannelContractHash(ByteString.copyFrom(Sha256Hash.create(new byte[]{0x03}).getBytes()))
.setPreviousChannelContractHash(ByteString.copyFrom(Sha256Hash.hash(new byte[]{0x03}).getBytes()))
.setMajor(CLIENT_MAJOR_VERSION).setMinor(42))
.build());
pair.serverRecorder.checkNextMsg(MessageType.SERVER_VERSION);

View File

@ -33,7 +33,7 @@ public class PaymentChannelClientTest {
wallet = createMock(Wallet.class);
ecKey = createMock(ECKey.class);
maxValue = Coin.COIN;
serverHash = Sha256Hash.create("serverId".getBytes());
serverHash = Sha256Hash.hash("serverId".getBytes());
connection = createMock(IPaymentChannelClient.ClientConnection.class);
clientVersionCapture = new Capture<TwoWayChannelMessage>();
}

View File

@ -292,7 +292,7 @@ public class PaymentChannelStateTest extends TestWithWallet {
Utils.rollMockClock(60 * 60 * 2 + 60 * 5);
// Now store the client state in a stored state object which handles the rebroadcasting
clientState.doStoreChannelInWallet(Sha256Hash.create(new byte[]{}));
clientState.doStoreChannelInWallet(Sha256Hash.hash(new byte[]{}));
TxFuturePair clientBroadcastedMultiSig = broadcasts.take();
TxFuturePair broadcastRefund = broadcasts.take();
assertEquals(clientBroadcastedMultiSig.tx.getHash(), multisigContract.getHash());

View File

@ -25,10 +25,6 @@ import org.bitcoinj.store.UnreadableWalletException;
import org.bitcoinj.utils.BriefLogFormatter;
import org.bitcoinj.utils.Threading;
import com.google.common.collect.Lists;
import org.bitcoinj.wallet.AbstractKeyChainEventListener;
import org.bitcoinj.wallet.DeterministicKeyChain;
import org.bitcoinj.wallet.KeyChain;
import org.bitcoinj.wallet.Protos;
import org.junit.Before;
import org.junit.Test;
import org.spongycastle.crypto.params.KeyParameter;
@ -42,7 +38,7 @@ import static org.junit.Assert.*;
public class DeterministicKeyChainTest {
private DeterministicKeyChain chain;
private final byte[] ENTROPY = Sha256Hash.create("don't use a string seed like this in real life".getBytes()).getBytes();
private final byte[] ENTROPY = Sha256Hash.hash("don't use a string seed like this in real life".getBytes()).getBytes();
@Before
public void setup() {

View File

@ -22,7 +22,6 @@ import org.bitcoinj.params.MainNetParams;
import org.bitcoinj.utils.BriefLogFormatter;
import org.bitcoinj.utils.Threading;
import com.google.common.collect.ImmutableList;
import org.bitcoinj.wallet.*;
import org.junit.Before;
import org.junit.Test;
import org.spongycastle.crypto.params.KeyParameter;
@ -65,7 +64,7 @@ public class KeyChainGroupTest {
}
private MarriedKeyChain createMarriedKeyChain() {
byte[] entropy = Sha256Hash.create("don't use a seed like this in real life".getBytes()).getBytes();
byte[] entropy = Sha256Hash.hash("don't use a seed like this in real life".getBytes()).getBytes();
DeterministicSeed seed = new DeterministicSeed(entropy, "", MnemonicCode.BIP39_STANDARDISATION_TIME_SECS);
MarriedKeyChain chain = MarriedKeyChain.builder()
.seed(seed)