use of co.rsk.crypto.Keccak256 in project rskj by rsksmart.
the class BlockUnclesValidationRule method validateUncleList.
/**
* Validate an uncle list.
* It validates that the uncle list is not too large
* It validates that each uncle
* - is not an ancestor
* - is not a used uncle
* - has a common ancestor with the block
*
* @param blockNumber the number of the block containing the uncles
* @param uncles the uncle list to validate
* @param ancestors the list of direct ancestors of the block containing the uncles
* @param used used uncles
* @return true if the uncles in the list are valid, false if not
*/
public boolean validateUncleList(long blockNumber, List<BlockHeader> uncles, Set<Keccak256> ancestors, Set<Keccak256> used) {
if (uncles.size() > uncleListLimit) {
logger.error("Uncle list to big: block.getUncleList().size() > UNCLE_LIST_LIMIT");
panicProcessor.panic(INVALIDUNCLE, "Uncle list to big: block.getUncleList().size() > UNCLE_LIST_LIMIT");
return false;
}
Set<Keccak256> hashes = new HashSet<>();
for (BlockHeader uncle : uncles) {
Block blockForUncleHeader = new Block(uncle);
if (!this.validations.isValid(blockForUncleHeader) || !validateParentNumber(uncle, blockNumber)) {
return false;
}
Keccak256 uncleHash = uncle.getHash();
/* Just checking that the uncle is not added twice */
if (hashes.contains(uncleHash)) {
return false;
}
hashes.add(uncleHash);
if (!validateUnclesAncestors(ancestors, uncleHash) || !validateIfUncleWasNeverUsed(used, uncleHash) || !validateUncleParent(ancestors, blockForUncleHeader)) {
return false;
}
}
return true;
}
use of co.rsk.crypto.Keccak256 in project rskj by rsksmart.
the class Transaction method getEncoded.
public byte[] getEncoded() {
if (rlpEncoded != null) {
return rlpEncoded;
}
// parse null as 0 for nonce
byte[] toEncodeNonce = null;
if (this.nonce == null || this.nonce.length == 1 && this.nonce[0] == 0) {
toEncodeNonce = RLP.encodeElement((byte[]) null);
} else {
toEncodeNonce = RLP.encodeElement(this.nonce);
}
byte[] toEncodeGasPrice = RLP.encodeElement(this.gasPriceRaw);
byte[] toEncodeGasLimit = RLP.encodeElement(this.gasLimit);
byte[] toEncodeReceiveAddress = RLP.encodeRskAddress(this.receiveAddress);
byte[] toEncodeValue = RLP.encodeElement(this.valueRaw);
byte[] toEncodeData = RLP.encodeElement(this.data);
byte[] v;
byte[] r;
byte[] s;
if (signature != null) {
int encodeV;
if (chainId == 0) {
encodeV = signature.v;
} else {
encodeV = signature.v - LOWER_REAL_V;
encodeV += chainId * 2 + CHAIN_ID_INC;
}
v = RLP.encodeByte((byte) encodeV);
r = RLP.encodeElement(BigIntegers.asUnsignedByteArray(signature.r));
s = RLP.encodeElement(BigIntegers.asUnsignedByteArray(signature.s));
} else {
// Since EIP-155 use chainId for v
v = chainId == 0 ? RLP.encodeElement(EMPTY_BYTE_ARRAY) : RLP.encodeByte(chainId);
r = RLP.encodeElement(EMPTY_BYTE_ARRAY);
s = RLP.encodeElement(EMPTY_BYTE_ARRAY);
}
this.rlpEncoded = RLP.encodeList(toEncodeNonce, toEncodeGasPrice, toEncodeGasLimit, toEncodeReceiveAddress, toEncodeValue, toEncodeData, v, r, s);
Keccak256 hash = this.getHash();
this.hash = hash == null ? null : hash.getBytes();
return rlpEncoded;
}
use of co.rsk.crypto.Keccak256 in project rskj by rsksmart.
the class BridgeStorageProviderTest method createInstance.
@Test
public void createInstance() throws IOException {
Repository repository = new RepositoryImpl(config);
BridgeStorageProvider provider = new BridgeStorageProvider(repository, PrecompiledContracts.BRIDGE_ADDR, config.getBlockchainConfig().getCommonConstants().getBridgeConstants());
Map<Sha256Hash, Long> processed = provider.getBtcTxHashesAlreadyProcessed();
Assert.assertNotNull(processed);
Assert.assertTrue(processed.isEmpty());
ReleaseRequestQueue releaseRequestQueue = provider.getReleaseRequestQueue();
Assert.assertNotNull(releaseRequestQueue);
Assert.assertEquals(0, releaseRequestQueue.getEntries().size());
ReleaseTransactionSet releaseTransactionSet = provider.getReleaseTransactionSet();
Assert.assertNotNull(releaseTransactionSet);
Assert.assertEquals(0, releaseTransactionSet.getEntries().size());
SortedMap<Keccak256, BtcTransaction> signatures = provider.getRskTxsWaitingForSignatures();
Assert.assertNotNull(signatures);
Assert.assertTrue(signatures.isEmpty());
List<UTXO> utxos = provider.getNewFederationBtcUTXOs();
Assert.assertNotNull(utxos);
Assert.assertTrue(utxos.isEmpty());
}
use of co.rsk.crypto.Keccak256 in project rskj by rsksmart.
the class BridgeStorageProviderTest method createSaveAndRecreateInstance.
@Test
public void createSaveAndRecreateInstance() throws IOException {
Repository repository = new RepositoryImpl(config);
Repository track = repository.startTracking();
BridgeStorageProvider provider0 = new BridgeStorageProvider(track, PrecompiledContracts.BRIDGE_ADDR, config.getBlockchainConfig().getCommonConstants().getBridgeConstants());
provider0.getBtcTxHashesAlreadyProcessed();
provider0.getReleaseRequestQueue();
provider0.getReleaseTransactionSet();
provider0.getRskTxsWaitingForSignatures();
provider0.getNewFederationBtcUTXOs();
provider0.getOldFederationBtcUTXOs();
provider0.save();
track.commit();
track = repository.startTracking();
RskAddress contractAddress = PrecompiledContracts.BRIDGE_ADDR;
Assert.assertNotNull(repository.getContractDetails(contractAddress));
Assert.assertNotNull(repository.getStorageBytes(contractAddress, new DataWord("btcTxHashesAP".getBytes())));
Assert.assertNotNull(repository.getStorageBytes(contractAddress, new DataWord("releaseRequestQueue".getBytes())));
Assert.assertNotNull(repository.getStorageBytes(contractAddress, new DataWord("releaseTransactionSet".getBytes())));
Assert.assertNotNull(repository.getStorageBytes(contractAddress, new DataWord("rskTxsWaitingFS".getBytes())));
Assert.assertNotNull(repository.getStorageBytes(contractAddress, new DataWord("newFederationBtcUTXOs".getBytes())));
Assert.assertNotNull(repository.getStorageBytes(contractAddress, new DataWord("oldFederationBtcUTXOs".getBytes())));
BridgeStorageProvider provider = new BridgeStorageProvider(track, PrecompiledContracts.BRIDGE_ADDR, config.getBlockchainConfig().getCommonConstants().getBridgeConstants());
Map<Sha256Hash, Long> processed = provider.getBtcTxHashesAlreadyProcessed();
Assert.assertNotNull(processed);
Assert.assertTrue(processed.isEmpty());
ReleaseRequestQueue releaseRequestQueue = provider.getReleaseRequestQueue();
Assert.assertNotNull(releaseRequestQueue);
Assert.assertEquals(0, releaseRequestQueue.getEntries().size());
ReleaseTransactionSet releaseTransactionSet = provider.getReleaseTransactionSet();
Assert.assertNotNull(releaseTransactionSet);
Assert.assertEquals(0, releaseTransactionSet.getEntries().size());
SortedMap<Keccak256, BtcTransaction> signatures = provider.getRskTxsWaitingForSignatures();
Assert.assertNotNull(signatures);
Assert.assertTrue(signatures.isEmpty());
List<UTXO> newUtxos = provider.getNewFederationBtcUTXOs();
Assert.assertNotNull(newUtxos);
Assert.assertTrue(newUtxos.isEmpty());
List<UTXO> oldUtxos = provider.getOldFederationBtcUTXOs();
Assert.assertNotNull(oldUtxos);
Assert.assertTrue(oldUtxos.isEmpty());
}
use of co.rsk.crypto.Keccak256 in project rskj by rsksmart.
the class BridgeSupportTest method addSignatureMultipleInputsPartiallyValid.
@Test
public void addSignatureMultipleInputsPartiallyValid() throws Exception {
// Federation is the genesis federation ATM
Federation federation = bridgeConstants.getGenesisFederation();
Repository repository = new RepositoryImpl(config);
final Keccak256 keccak256 = PegTestUtils.createHash3();
Repository track = repository.startTracking();
BridgeStorageProvider provider = new BridgeStorageProvider(track, PrecompiledContracts.BRIDGE_ADDR, bridgeConstants);
BtcTransaction prevTx1 = new BtcTransaction(btcParams);
TransactionOutput prevOut1 = new TransactionOutput(btcParams, prevTx1, Coin.FIFTY_COINS, federation.getAddress());
prevTx1.addOutput(prevOut1);
BtcTransaction prevTx2 = new BtcTransaction(btcParams);
TransactionOutput prevOut2 = new TransactionOutput(btcParams, prevTx1, Coin.FIFTY_COINS, federation.getAddress());
prevTx2.addOutput(prevOut2);
BtcTransaction prevTx3 = new BtcTransaction(btcParams);
TransactionOutput prevOut3 = new TransactionOutput(btcParams, prevTx1, Coin.FIFTY_COINS, federation.getAddress());
prevTx3.addOutput(prevOut3);
BtcTransaction t = new BtcTransaction(btcParams);
TransactionOutput output = new TransactionOutput(btcParams, t, Coin.COIN, new BtcECKey().toAddress(btcParams));
t.addOutput(output);
t.addInput(prevOut1).setScriptSig(PegTestUtils.createBaseInputScriptThatSpendsFromTheFederation(federation));
t.addInput(prevOut2).setScriptSig(PegTestUtils.createBaseInputScriptThatSpendsFromTheFederation(federation));
t.addInput(prevOut3).setScriptSig(PegTestUtils.createBaseInputScriptThatSpendsFromTheFederation(federation));
provider.getRskTxsWaitingForSignatures().put(keccak256, t);
provider.save();
track.commit();
track = repository.startTracking();
List<LogInfo> logs = new ArrayList<>();
BridgeEventLogger eventLogger = new BridgeEventLoggerImpl(bridgeConstants, logs);
BridgeSupport bridgeSupport = new BridgeSupport(config, track, eventLogger, contractAddress, (Block) null);
// Generate valid signatures for inputs
List<byte[]> derEncodedSigsFirstFed = new ArrayList<>();
List<byte[]> derEncodedSigsSecondFed = new ArrayList<>();
BtcECKey privateKeyOfFirstFed = ((BridgeRegTestConstants) bridgeConstants).getFederatorPrivateKeys().get(0);
BtcECKey privateKeyOfSecondFed = ((BridgeRegTestConstants) bridgeConstants).getFederatorPrivateKeys().get(1);
BtcECKey.ECDSASignature lastSig = null;
for (int i = 0; i < 3; i++) {
Script inputScript = t.getInput(i).getScriptSig();
List<ScriptChunk> chunks = inputScript.getChunks();
byte[] program = chunks.get(chunks.size() - 1).data;
Script redeemScript = new Script(program);
Sha256Hash sighash = t.hashForSignature(i, redeemScript, BtcTransaction.SigHash.ALL, false);
// Sign the last input with a random key
// but keep the good signature for a subsequent call
BtcECKey.ECDSASignature sig = privateKeyOfFirstFed.sign(sighash);
if (i == 2) {
lastSig = sig;
sig = new BtcECKey().sign(sighash);
}
derEncodedSigsFirstFed.add(sig.encodeToDER());
derEncodedSigsSecondFed.add(privateKeyOfSecondFed.sign(sighash).encodeToDER());
}
// Sign with two valid signatuers and one invalid signature
bridgeSupport.addSignature(1, findPublicKeySignedBy(federation.getPublicKeys(), privateKeyOfFirstFed), derEncodedSigsFirstFed, keccak256.getBytes());
bridgeSupport.save();
track.commit();
// Sign with two valid signatuers and one malformed signature
byte[] malformedSignature = new byte[lastSig.encodeToDER().length];
for (int i = 0; i < malformedSignature.length; i++) {
malformedSignature[i] = (byte) i;
}
derEncodedSigsFirstFed.set(2, malformedSignature);
bridgeSupport.addSignature(1, findPublicKeySignedBy(federation.getPublicKeys(), privateKeyOfFirstFed), derEncodedSigsFirstFed, keccak256.getBytes());
bridgeSupport.save();
track.commit();
// Sign with fully valid signatures for same federator
derEncodedSigsFirstFed.set(2, lastSig.encodeToDER());
bridgeSupport.addSignature(1, findPublicKeySignedBy(federation.getPublicKeys(), privateKeyOfFirstFed), derEncodedSigsFirstFed, keccak256.getBytes());
bridgeSupport.save();
track.commit();
// Sign with second federation
bridgeSupport.addSignature(1, findPublicKeySignedBy(federation.getPublicKeys(), privateKeyOfSecondFed), derEncodedSigsSecondFed, keccak256.getBytes());
bridgeSupport.save();
track.commit();
provider = new BridgeStorageProvider(repository, PrecompiledContracts.BRIDGE_ADDR, bridgeConstants);
Assert.assertTrue(provider.getRskTxsWaitingForSignatures().isEmpty());
Assert.assertThat(logs, is(not(empty())));
Assert.assertThat(logs, hasSize(5));
LogInfo releaseTxEvent = logs.get(4);
Assert.assertThat(releaseTxEvent.getTopics(), hasSize(1));
Assert.assertThat(releaseTxEvent.getTopics(), hasItem(Bridge.RELEASE_BTC_TOPIC));
BtcTransaction releaseTx = new BtcTransaction(bridgeConstants.getBtcParams(), ((RLPList) RLP.decode2(releaseTxEvent.getData()).get(0)).get(1).getRLPData());
// Verify all inputs fully signed
for (int i = 0; i < releaseTx.getInputs().size(); i++) {
Script retrievedScriptSig = releaseTx.getInput(i).getScriptSig();
Assert.assertEquals(4, retrievedScriptSig.getChunks().size());
Assert.assertEquals(true, retrievedScriptSig.getChunks().get(1).data.length > 0);
Assert.assertEquals(true, retrievedScriptSig.getChunks().get(2).data.length > 0);
}
}
Aggregations