use of co.rsk.peg.btcLockSender.BtcLockSenderProvider in project rskj by rsksmart.
the class PeginInformationTest method parse_fromPeginInstructions_withoutBtcLockSender_withoutBtcRefundAddress.
@Test
public void parse_fromPeginInstructions_withoutBtcLockSender_withoutBtcRefundAddress() throws PeginInstructionsException {
// Arrange
BtcTransaction btcTx = new BtcTransaction(networkParameters);
BtcLockSenderProvider btcLockSenderProviderMock = mock(BtcLockSenderProvider.class);
when(btcLockSenderProviderMock.tryGetBtcLockSender(btcTx)).thenReturn(Optional.empty());
BtcECKey address2Key = new BtcECKey();
RskAddress rskDestinationAddressFromPeginInstructions = new RskAddress(ECKey.fromPublicOnly(address2Key.getPubKey()).getAddress());
PeginInstructionsVersion1 peginInstructionsMock = mock(PeginInstructionsVersion1.class);
when(peginInstructionsMock.getProtocolVersion()).thenReturn(1);
when(peginInstructionsMock.getRskDestinationAddress()).thenReturn(rskDestinationAddressFromPeginInstructions);
when(peginInstructionsMock.getBtcRefundAddress()).thenReturn(Optional.empty());
PeginInstructionsProvider peginInstructionsProviderMock = mock(PeginInstructionsProvider.class);
when(peginInstructionsProviderMock.buildPeginInstructions(btcTx)).thenReturn(Optional.of(peginInstructionsMock));
ActivationConfig.ForBlock activationsMock = mock(ActivationConfig.ForBlock.class);
when(activationsMock.isActive(ConsensusRule.RSKIP170)).thenReturn(true);
// Act
PeginInformation peginInformation = new PeginInformation(btcLockSenderProviderMock, peginInstructionsProviderMock, activationsMock);
peginInformation.parse(btcTx);
// Assert
Assert.assertEquals(1, peginInformation.getProtocolVersion());
Assert.assertEquals(rskDestinationAddressFromPeginInstructions, peginInformation.getRskDestinationAddress());
Assert.assertNull(peginInformation.getBtcRefundAddress());
Assert.assertNull(peginInformation.getSenderBtcAddress());
Assert.assertEquals(TxSenderAddressType.UNKNOWN, peginInformation.getSenderBtcAddressType());
}
use of co.rsk.peg.btcLockSender.BtcLockSenderProvider in project rskj by rsksmart.
the class PeginInformationTest method parse_withBtcLockSender_withPeginInstructions_preIris.
@Test
public void parse_withBtcLockSender_withPeginInstructions_preIris() throws PeginInstructionsException {
// Arrange
BtcECKey address1Key = new BtcECKey();
RskAddress rskDestinationAddressFromBtcLockSender = new RskAddress(ECKey.fromPublicOnly(address1Key.getPubKey()).getAddress());
Address btcRefundAddressFromBtcLockSender = address1Key.toAddress(networkParameters);
TxSenderAddressType senderBtcAddressType = TxSenderAddressType.P2PKH;
BtcTransaction btcTx = new BtcTransaction(networkParameters);
BtcLockSender btcLockSenderMock = mock(P2pkhBtcLockSender.class);
when(btcLockSenderMock.getRskAddress()).thenReturn(rskDestinationAddressFromBtcLockSender);
when(btcLockSenderMock.getBTCAddress()).thenReturn(btcRefundAddressFromBtcLockSender);
when(btcLockSenderMock.getTxSenderAddressType()).thenReturn(senderBtcAddressType);
BtcLockSenderProvider btcLockSenderProviderMock = mock(BtcLockSenderProvider.class);
when(btcLockSenderProviderMock.tryGetBtcLockSender(btcTx)).thenReturn(Optional.of(btcLockSenderMock));
BtcECKey address2Key = new BtcECKey();
RskAddress rskDestinationAddressFromPeginInstructions = new RskAddress(ECKey.fromPublicOnly(address2Key.getPubKey()).getAddress());
Address btcRefundAddressFromPeginInstructions = address2Key.toAddress(networkParameters);
PeginInstructionsVersion1 peginInstructionsMock = mock(PeginInstructionsVersion1.class);
when(peginInstructionsMock.getProtocolVersion()).thenReturn(1);
when(peginInstructionsMock.getRskDestinationAddress()).thenReturn(rskDestinationAddressFromPeginInstructions);
when(peginInstructionsMock.getBtcRefundAddress()).thenReturn(Optional.of(btcRefundAddressFromPeginInstructions));
PeginInstructionsProvider peginInstructionsProviderMock = mock(PeginInstructionsProvider.class);
when(peginInstructionsProviderMock.buildPeginInstructions(btcTx)).thenReturn(Optional.of(peginInstructionsMock));
ActivationConfig.ForBlock activationsMock = mock(ActivationConfig.ForBlock.class);
when(activationsMock.isActive(ConsensusRule.RSKIP170)).thenReturn(false);
// Act
PeginInformation peginInformation = new PeginInformation(btcLockSenderProviderMock, peginInstructionsProviderMock, activationsMock);
peginInformation.parse(btcTx);
// Assert
Assert.assertEquals(0, peginInformation.getProtocolVersion());
Assert.assertEquals(rskDestinationAddressFromBtcLockSender, peginInformation.getRskDestinationAddress());
Assert.assertEquals(btcRefundAddressFromBtcLockSender, peginInformation.getBtcRefundAddress());
Assert.assertEquals(btcRefundAddressFromBtcLockSender, peginInformation.getSenderBtcAddress());
Assert.assertEquals(senderBtcAddressType, peginInformation.getSenderBtcAddressType());
Assert.assertNotEquals(rskDestinationAddressFromPeginInstructions, peginInformation.getRskDestinationAddress());
Assert.assertNotEquals(btcRefundAddressFromPeginInstructions, peginInformation.getBtcRefundAddress());
}
use of co.rsk.peg.btcLockSender.BtcLockSenderProvider in project rskj by rsksmart.
the class BridgeSupportTest method processPegIn_errorParsingPeginInstructions_afterRskip170_refundSender.
@Test
public void processPegIn_errorParsingPeginInstructions_afterRskip170_refundSender() throws IOException, PeginInstructionsException {
// Arrange
ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class);
when(activations.isActive(ConsensusRule.RSKIP170)).thenReturn(true);
Repository repository = createRepository();
BtcECKey srcKey1 = new BtcECKey();
ECKey key = ECKey.fromPublicOnly(srcKey1.getPubKey());
RskAddress rskAddress = new RskAddress(key.getAddress());
Address btcSenderAddress = srcKey1.toAddress(btcParams);
BtcTransaction btcTx = new BtcTransaction(btcParams);
btcTx.addOutput(Coin.COIN.multiply(10), bridgeConstants.getGenesisFederation().getAddress());
btcTx.addInput(PegTestUtils.createHash(1), 0, new Script(new byte[] {}));
BridgeStorageProvider provider = mock(BridgeStorageProvider.class);
ReleaseTransactionSet releaseTransactionSet = new ReleaseTransactionSet(new HashSet<>());
when(provider.getReleaseTransactionSet()).thenReturn(releaseTransactionSet);
BtcLockSenderProvider btcLockSenderProvider = getBtcLockSenderProvider(TxSenderAddressType.P2PKH, btcSenderAddress, rskAddress);
PeginInstructionsProvider peginInstructionsProvider = mock(PeginInstructionsProvider.class);
when(peginInstructionsProvider.buildPeginInstructions(btcTx)).thenThrow(PeginInstructionsException.class);
BridgeSupport bridgeSupport = getBridgeSupport(bridgeConstants, provider, repository, btcLockSenderProvider, peginInstructionsProvider, mock(Block.class), mock(BtcBlockStoreWithCache.Factory.class), activations);
// Act
try {
bridgeSupport.processPegIn(btcTx, mock(Transaction.class), 0, mock(Sha256Hash.class));
// Should have thrown a RegisterBtcTransactionException
Assert.fail();
} catch (Exception ex) {
// Assert
Assert.assertTrue(ex instanceof RegisterBtcTransactionException);
Assert.assertEquals(1, releaseTransactionSet.getEntries().size());
// Check rejection tx input was created from btc tx and sent to the btc refund address indicated by the user
boolean successfulRejection = false;
for (ReleaseTransactionSet.Entry e : releaseTransactionSet.getEntries()) {
BtcTransaction refundTx = e.getTransaction();
if (refundTx.getInput(0).getOutpoint().getHash() == btcTx.getHash() && refundTx.getOutput(0).getScriptPubKey().getToAddress(btcParams).equals(btcSenderAddress)) {
successfulRejection = true;
break;
}
}
Assert.assertTrue(successfulRejection);
}
}
use of co.rsk.peg.btcLockSender.BtcLockSenderProvider in project rskj by rsksmart.
the class BridgeSupportTest method assertLockingCap.
private void assertLockingCap(boolean shouldLock, boolean isLockingCapEnabled, Coin lockingCap, Coin amountSentToNewFed, Coin amountSentToOldFed, Coin amountInNewFed, Coin amountInOldFed) throws BlockStoreException, IOException, BridgeIllegalArgumentException {
// Configure if locking cap should be evaluated
ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class);
when(activations.isActive(ConsensusRule.RSKIP134)).thenReturn(isLockingCapEnabled);
BridgeConstants bridgeConstants = mock(BridgeConstants.class);
when(bridgeConstants.getLegacyMinimumPeginTxValueInSatoshis()).thenReturn(Coin.SATOSHI);
when(bridgeConstants.getBtcParams()).thenReturn(BridgeRegTestConstants.getInstance().getBtcParams());
when(bridgeConstants.getBtc2RskMinimumAcceptableConfirmations()).thenReturn(1);
when(bridgeConstants.getGenesisFeePerKb()).thenReturn(BridgeRegTestConstants.getInstance().getGenesisFeePerKb());
when(bridgeConstants.getMaxRbtc()).thenReturn(BridgeRegTestConstants.getInstance().getMaxRbtc());
// Configure locking cap
when(bridgeConstants.getInitialLockingCap()).thenReturn(lockingCap);
Repository repository = createRepository();
Federation oldFederation = this.getFederation(bridgeConstants);
BridgeStorageProvider provider = new BridgeStorageProvider(repository, PrecompiledContracts.BRIDGE_ADDR, bridgeConstants, activations);
// We need a random new fed
provider.setNewFederation(this.getFederation(bridgeConstants, Arrays.asList(BtcECKey.fromPrivate(Hex.decode("fb01")), BtcECKey.fromPrivate(Hex.decode("fb02")), BtcECKey.fromPrivate(Hex.decode("fb03")))));
// Use genesis fed as old
provider.setOldFederation(oldFederation);
Coin currentFunds = Coin.ZERO;
// Configure existing utxos in both federations
if (amountInOldFed != null) {
UTXO utxo = new UTXO(Sha256Hash.wrap(HashUtil.randomHash()), 0, amountInOldFed, 1, false, new Script(new byte[] {}));
provider.getOldFederationBtcUTXOs().add(utxo);
currentFunds = currentFunds.add(amountInOldFed);
}
if (amountInNewFed != null) {
UTXO utxo = new UTXO(Sha256Hash.wrap(HashUtil.randomHash()), 0, amountInNewFed, 1, false, new Script(new byte[] {}));
provider.getNewFederationBtcUTXOs().add(utxo);
currentFunds = currentFunds.add(amountInNewFed);
}
// Fund bridge in RBTC, substracting the funds that we are indicating were locked in the federations (which means a user locked)
co.rsk.core.Coin bridgeBalance = LIMIT_MONETARY_BASE.subtract(co.rsk.core.Coin.fromBitcoin(currentFunds));
repository.addBalance(PrecompiledContracts.BRIDGE_ADDR, bridgeBalance);
// The locking cap shouldn't be surpassed by the initial configuration
Assert.assertFalse(isLockingCapEnabled && currentFunds.isGreaterThan(lockingCap));
Coin lockValue = Coin.ZERO;
int newUtxos = 0;
// Create transaction setting the outputs to the configured values
BtcTransaction tx = new BtcTransaction(bridgeConstants.getBtcParams());
if (amountSentToOldFed != null) {
tx.addOutput(amountSentToOldFed, provider.getOldFederation().getAddress());
lockValue = lockValue.add(amountSentToOldFed);
newUtxos++;
}
if (amountSentToNewFed != null) {
tx.addOutput(amountSentToNewFed, provider.getNewFederation().getAddress());
lockValue = lockValue.add(amountSentToNewFed);
newUtxos++;
}
BtcECKey srcKey = new BtcECKey();
tx.addInput(PegTestUtils.createHash(1), 0, ScriptBuilder.createInputScript(null, srcKey));
// Create header and PMT
byte[] bits = new byte[1];
bits[0] = 0x3f;
List<Sha256Hash> hashes = new ArrayList<>();
hashes.add(tx.getHash());
PartialMerkleTree pmt = new PartialMerkleTree(bridgeConstants.getBtcParams(), bits, hashes, 1);
Sha256Hash merkleRoot = pmt.getTxnHashAndMerkleRoot(new ArrayList<>());
co.rsk.bitcoinj.core.BtcBlock registerHeader = new co.rsk.bitcoinj.core.BtcBlock(bridgeConstants.getBtcParams(), 1, PegTestUtils.createHash(1), merkleRoot, 1, 1, 1, new ArrayList<BtcTransaction>());
BtcBlockStoreWithCache btcBlockStore = mock(BtcBlockStoreWithCache.class);
BtcBlockStoreWithCache.Factory mockFactory = mock(BtcBlockStoreWithCache.Factory.class);
when(mockFactory.newInstance(repository, bridgeConstants, provider, activations)).thenReturn(btcBlockStore);
Block executionBlock = Mockito.mock(Block.class);
when(executionBlock.getNumber()).thenReturn(10L);
// Get the tx sender public key
byte[] data = tx.getInput(0).getScriptSig().getChunks().get(1).data;
BtcECKey senderBtcKey = BtcECKey.fromPublicOnly(data);
// Whitelist the addresses
LockWhitelist whitelist = provider.getLockWhitelist();
Address address = senderBtcKey.toAddress(bridgeConstants.getBtcParams());
whitelist.put(address, new OneOffWhiteListEntry(address, lockValue));
// The address is whitelisted
Assert.assertThat(whitelist.isWhitelisted(address), is(true));
BridgeSupport bridgeSupport = getBridgeSupport(bridgeConstants, provider, repository, new BtcLockSenderProvider(), new PeginInstructionsProvider(), executionBlock, mockFactory, activations);
// Simulate blockchain
int height = 1;
mockChainOfStoredBlocks(btcBlockStore, registerHeader, height + bridgeConstants.getBtc2RskMinimumAcceptableConfirmations(), height);
Transaction rskTx = mock(Transaction.class);
Keccak256 hash = new Keccak256(HashUtil.keccak256(new byte[] {}));
when(rskTx.getHash()).thenReturn(hash);
// Try to register tx
bridgeSupport.registerBtcTransaction(rskTx, tx.bitcoinSerialize(), height, pmt.bitcoinSerialize());
bridgeSupport.save();
// If the address is no longer whitelisted, it means it was consumed, whether the lock was rejected by lockingCap or not
Assert.assertThat(whitelist.isWhitelisted(address), is(false));
// The Btc transaction should have been processed
assertTrue(bridgeSupport.isBtcTxHashAlreadyProcessed(tx.getHash()));
co.rsk.core.Coin totalAmountExpectedToHaveBeenLocked = co.rsk.core.Coin.fromBitcoin(shouldLock ? lockValue : Coin.ZERO);
RskAddress srcKeyRskAddress = new RskAddress(org.ethereum.crypto.ECKey.fromPrivate(srcKey.getPrivKey()).getAddress());
// Verify amount was locked
Assert.assertEquals(totalAmountExpectedToHaveBeenLocked, repository.getBalance(srcKeyRskAddress));
Assert.assertEquals(bridgeBalance.subtract(totalAmountExpectedToHaveBeenLocked), repository.getBalance(PrecompiledContracts.BRIDGE_ADDR));
if (!shouldLock) {
// Release tx should have been created directly to the signatures stack
BtcTransaction releaseTx = provider.getReleaseTransactionSet().getEntries().iterator().next().getTransaction();
Assert.assertNotNull(releaseTx);
// returns the funds to the sender
Assert.assertEquals(1, releaseTx.getOutputs().size());
Assert.assertEquals(address, releaseTx.getOutputs().get(0).getAddressFromP2PKHScript(bridgeConstants.getBtcParams()));
Assert.assertEquals(lockValue, releaseTx.getOutputs().get(0).getValue().add(releaseTx.getFee()));
// Uses the same UTXO(s)
Assert.assertEquals(newUtxos, releaseTx.getInputs().size());
for (int i = 0; i < newUtxos; i++) {
TransactionInput input = releaseTx.getInput(i);
Assert.assertEquals(tx.getHash(), input.getOutpoint().getHash());
Assert.assertEquals(i, input.getOutpoint().getIndex());
}
}
}
use of co.rsk.peg.btcLockSender.BtcLockSenderProvider in project rskj by rsksmart.
the class BridgeSupportTest method validationsForRegisterBtcTransaction_invalid_block_merkle_root.
@Test
public void validationsForRegisterBtcTransaction_invalid_block_merkle_root() throws IOException, BlockStoreException, BridgeIllegalArgumentException {
BridgeStorageProvider mockBridgeStorageProvider = mock(BridgeStorageProvider.class);
when(mockBridgeStorageProvider.getHeightIfBtcTxhashIsAlreadyProcessed(any(Sha256Hash.class))).thenReturn(Optional.empty());
BtcBlockStoreWithCache.Factory btcBlockStoreFactory = mock(BtcBlockStoreWithCache.Factory.class);
BtcBlockStoreWithCache btcBlockStore = mock(BtcBlockStoreWithCache.class);
when(btcBlockStoreFactory.newInstance(any(Repository.class), any(), any(), any())).thenReturn(btcBlockStore);
// Create transaction
BtcTransaction tx = new BtcTransaction(bridgeConstants.getBtcParams());
BtcECKey srcKey = new BtcECKey();
tx.addInput(PegTestUtils.createHash(1), 0, ScriptBuilder.createInputScript(null, srcKey));
// Create tx and PMT. Also create a btc block, that has not relation with tx and PMT.
// The tx will be rejected because merkle block doesn't match.
byte[] bits = new byte[1];
bits[0] = 0x3f;
List<Sha256Hash> hashes = new ArrayList<>();
hashes.add(tx.getHash());
PartialMerkleTree pmt = new PartialMerkleTree(bridgeConstants.getBtcParams(), bits, hashes, 1);
co.rsk.bitcoinj.core.BtcBlock btcBlock = new co.rsk.bitcoinj.core.BtcBlock(bridgeConstants.getBtcParams(), 1, PegTestUtils.createHash(), Sha256Hash.ZERO_HASH, 1, 1, 1, new ArrayList<>());
int height = 1;
mockChainOfStoredBlocks(btcBlockStore, btcBlock, height + bridgeConstants.getBtc2RskMinimumAcceptableConfirmations(), height);
BridgeSupport bridgeSupport = new BridgeSupport(bridgeConstants, mockBridgeStorageProvider, mock(BridgeEventLogger.class), new BtcLockSenderProvider(), new PeginInstructionsProvider(), mock(Repository.class), mock(Block.class), mock(Context.class), mock(FederationSupport.class), btcBlockStoreFactory, mock(ActivationConfig.ForBlock.class));
Assert.assertFalse(bridgeSupport.validationsForRegisterBtcTransaction(tx.getHash(), height, pmt.bitcoinSerialize(), tx.bitcoinSerialize()));
}
Aggregations