Search in sources :

Example 16 with BridgeConstants

use of co.rsk.config.BridgeConstants in project rskj by rsksmart.

the class BridgeSupportTest method registerBtcTransactionLockTxNotWhitelisted.

@Test
public void registerBtcTransactionLockTxNotWhitelisted() throws BlockStoreException, AddressFormatException, IOException {
    BridgeConstants bridgeConstants = config.getBlockchainConfig().getCommonConstants().getBridgeConstants();
    NetworkParameters parameters = bridgeConstants.getBtcParams();
    List<BtcECKey> federation1Keys = Arrays.asList(new BtcECKey[] { BtcECKey.fromPrivate(Hex.decode("fa01")), BtcECKey.fromPrivate(Hex.decode("fa02")) });
    federation1Keys.sort(BtcECKey.PUBKEY_COMPARATOR);
    Federation federation1 = new Federation(federation1Keys, Instant.ofEpochMilli(1000L), 0L, parameters);
    List<BtcECKey> federation2Keys = Arrays.asList(new BtcECKey[] { BtcECKey.fromPrivate(Hex.decode("fb01")), BtcECKey.fromPrivate(Hex.decode("fb02")), BtcECKey.fromPrivate(Hex.decode("fb03")) });
    federation2Keys.sort(BtcECKey.PUBKEY_COMPARATOR);
    Federation federation2 = new Federation(federation2Keys, Instant.ofEpochMilli(2000L), 0L, parameters);
    Repository repository = new RepositoryImpl(config);
    repository.addBalance(PrecompiledContracts.BRIDGE_ADDR, LIMIT_MONETARY_BASE);
    Block executionBlock = Mockito.mock(Block.class);
    Mockito.when(executionBlock.getNumber()).thenReturn(10L);
    Repository track = repository.startTracking();
    // First transaction goes only to the first federation
    BtcTransaction tx1 = new BtcTransaction(this.btcParams);
    tx1.addOutput(Coin.COIN.multiply(5), federation1.getAddress());
    BtcECKey srcKey1 = new BtcECKey();
    tx1.addInput(PegTestUtils.createHash(), 0, ScriptBuilder.createInputScript(null, srcKey1));
    // Second transaction goes only to the second federation
    BtcTransaction tx2 = new BtcTransaction(this.btcParams);
    tx2.addOutput(Coin.COIN.multiply(10), federation2.getAddress());
    BtcECKey srcKey2 = new BtcECKey();
    tx2.addInput(PegTestUtils.createHash(), 0, ScriptBuilder.createInputScript(null, srcKey2));
    // Third transaction has one output to each federation
    // Lock is expected to be done accordingly and utxos assigned accordingly as well
    BtcTransaction tx3 = new BtcTransaction(this.btcParams);
    tx3.addOutput(Coin.COIN.multiply(3), federation1.getAddress());
    tx3.addOutput(Coin.COIN.multiply(4), federation2.getAddress());
    BtcECKey srcKey3 = new BtcECKey();
    tx3.addInput(PegTestUtils.createHash(), 0, ScriptBuilder.createInputScript(null, srcKey3));
    Context btcContext = new Context(bridgeConstants.getBtcParams());
    BtcBlockStore btcBlockStore = new RepositoryBlockStore(config, track, PrecompiledContracts.BRIDGE_ADDR);
    BtcBlockChain btcBlockChain = new SimpleBlockChain(btcContext, btcBlockStore);
    BridgeStorageProvider provider = new BridgeStorageProvider(track, contractAddress, config.getBlockchainConfig().getCommonConstants().getBridgeConstants());
    provider.setNewFederation(federation1);
    provider.setOldFederation(federation2);
    BridgeSupport bridgeSupport = new BridgeSupport(config, track, null, config.getBlockchainConfig().getCommonConstants().getBridgeConstants(), provider, btcBlockStore, btcBlockChain);
    Whitebox.setInternalState(bridgeSupport, "rskExecutionBlock", executionBlock);
    byte[] bits = new byte[1];
    bits[0] = 0x3f;
    List<Sha256Hash> hashes = new ArrayList<>();
    hashes.add(tx1.getHash());
    hashes.add(tx2.getHash());
    hashes.add(tx3.getHash());
    PartialMerkleTree pmt = new PartialMerkleTree(btcParams, bits, hashes, 3);
    List<Sha256Hash> hashlist = new ArrayList<>();
    Sha256Hash merkleRoot = pmt.getTxnHashAndMerkleRoot(hashlist);
    co.rsk.bitcoinj.core.BtcBlock block = new co.rsk.bitcoinj.core.BtcBlock(btcParams, 1, PegTestUtils.createHash(), merkleRoot, 1, 1, 1, new ArrayList<BtcTransaction>());
    btcBlockChain.add(block);
    Transaction rskTx1 = getMockedRskTxWithHash("aa");
    Transaction rskTx2 = getMockedRskTxWithHash("bb");
    Transaction rskTx3 = getMockedRskTxWithHash("cc");
    ((SimpleBlockChain) btcBlockChain).useHighBlock();
    bridgeSupport.registerBtcTransaction(rskTx1, tx1, 1, pmt);
    bridgeSupport.registerBtcTransaction(rskTx2, tx2, 1, pmt);
    bridgeSupport.registerBtcTransaction(rskTx3, tx3, 1, pmt);
    bridgeSupport.save();
    ((SimpleBlockChain) btcBlockChain).useBlock();
    track.commit();
    RskAddress srcKey1RskAddress = new RskAddress(org.ethereum.crypto.ECKey.fromPrivate(srcKey1.getPrivKey()).getAddress());
    RskAddress srcKey2RskAddress = new RskAddress(org.ethereum.crypto.ECKey.fromPrivate(srcKey2.getPrivKey()).getAddress());
    RskAddress srcKey3RskAddress = new RskAddress(org.ethereum.crypto.ECKey.fromPrivate(srcKey3.getPrivKey()).getAddress());
    Assert.assertEquals(0, repository.getBalance(srcKey1RskAddress).asBigInteger().intValue());
    Assert.assertEquals(0, repository.getBalance(srcKey2RskAddress).asBigInteger().intValue());
    Assert.assertEquals(0, repository.getBalance(srcKey3RskAddress).asBigInteger().intValue());
    Assert.assertEquals(LIMIT_MONETARY_BASE, repository.getBalance(PrecompiledContracts.BRIDGE_ADDR));
    BridgeStorageProvider provider2 = new BridgeStorageProvider(repository, PrecompiledContracts.BRIDGE_ADDR, config.getBlockchainConfig().getCommonConstants().getBridgeConstants());
    Assert.assertEquals(0, provider2.getNewFederationBtcUTXOs().size());
    Assert.assertEquals(0, provider2.getOldFederationBtcUTXOs().size());
    Assert.assertEquals(0, provider2.getReleaseRequestQueue().getEntries().size());
    Assert.assertEquals(3, provider2.getReleaseTransactionSet().getEntries().size());
    List<BtcTransaction> releaseTxs = provider2.getReleaseTransactionSet().getEntries().stream().map(e -> e.getTransaction()).sorted(Comparator.comparing(BtcTransaction::getOutputSum)).collect(Collectors.toList());
    // First release tx should correspond to the 5 BTC lock tx
    BtcTransaction releaseTx = releaseTxs.get(0);
    Assert.assertEquals(1, releaseTx.getOutputs().size());
    Assert.assertThat(Coin.COIN.multiply(5).subtract(releaseTx.getOutput(0).getValue()), is(lessThanOrEqualTo(Coin.MILLICOIN)));
    Assert.assertEquals(srcKey1.toAddress(parameters), releaseTx.getOutput(0).getAddressFromP2PKHScript(parameters));
    Assert.assertEquals(1, releaseTx.getInputs().size());
    Assert.assertEquals(tx1.getHash(), releaseTx.getInput(0).getOutpoint().getHash());
    Assert.assertEquals(0, releaseTx.getInput(0).getOutpoint().getIndex());
    // Second release tx should correspond to the 7 (3+4) BTC lock tx
    releaseTx = releaseTxs.get(1);
    Assert.assertEquals(1, releaseTx.getOutputs().size());
    Assert.assertThat(Coin.COIN.multiply(7).subtract(releaseTx.getOutput(0).getValue()), is(lessThanOrEqualTo(Coin.MILLICOIN)));
    Assert.assertEquals(srcKey3.toAddress(parameters), releaseTx.getOutput(0).getAddressFromP2PKHScript(parameters));
    Assert.assertEquals(2, releaseTx.getInputs().size());
    List<TransactionOutPoint> releaseOutpoints = releaseTx.getInputs().stream().map(i -> i.getOutpoint()).sorted(Comparator.comparing(TransactionOutPoint::getIndex)).collect(Collectors.toList());
    Assert.assertEquals(tx3.getHash(), releaseOutpoints.get(0).getHash());
    Assert.assertEquals(tx3.getHash(), releaseOutpoints.get(1).getHash());
    Assert.assertEquals(0, releaseOutpoints.get(0).getIndex());
    Assert.assertEquals(1, releaseOutpoints.get(1).getIndex());
    // Third release tx should correspond to the 10 BTC lock tx
    releaseTx = releaseTxs.get(2);
    Assert.assertEquals(1, releaseTx.getOutputs().size());
    Assert.assertThat(Coin.COIN.multiply(10).subtract(releaseTx.getOutput(0).getValue()), is(lessThanOrEqualTo(Coin.MILLICOIN)));
    Assert.assertEquals(srcKey2.toAddress(parameters), releaseTx.getOutput(0).getAddressFromP2PKHScript(parameters));
    Assert.assertEquals(1, releaseTx.getInputs().size());
    Assert.assertEquals(tx2.getHash(), releaseTx.getInput(0).getOutpoint().getHash());
    Assert.assertEquals(0, releaseTx.getInput(0).getOutpoint().getIndex());
    Assert.assertTrue(provider2.getRskTxsWaitingForSignatures().isEmpty());
    Assert.assertEquals(3, provider2.getBtcTxHashesAlreadyProcessed().size());
}
Also used : SimpleBlockChain(co.rsk.peg.simples.SimpleBlockChain) RskAddress(co.rsk.core.RskAddress) BridgeConstants(co.rsk.config.BridgeConstants) BtcBlockStore(co.rsk.bitcoinj.store.BtcBlockStore) co.rsk.bitcoinj.core(co.rsk.bitcoinj.core) org.ethereum.core(org.ethereum.core) SimpleRskTransaction(co.rsk.peg.simples.SimpleRskTransaction) RepositoryImpl(co.rsk.db.RepositoryImpl) PrepareForTest(org.powermock.core.classloader.annotations.PrepareForTest) Test(org.junit.Test)

Example 17 with BridgeConstants

use of co.rsk.config.BridgeConstants in project rskj by rsksmart.

the class BridgeSupportTest method minimumProcessFundsMigrationValue.

@Test
public void minimumProcessFundsMigrationValue() throws IOException, BlockStoreException {
    BridgeConstants bridgeConstants = BridgeRegTestConstants.getInstance();
    Federation oldFederation = bridgeConstants.getGenesisFederation();
    Federation newFederation = new Federation(Collections.singletonList(new BtcECKey(new SecureRandom())), Instant.EPOCH, 5L, bridgeConstants.getBtcParams());
    BridgeStorageProvider provider = mock(BridgeStorageProvider.class);
    when(provider.getFeePerKb()).thenReturn(Coin.MILLICOIN);
    when(provider.getReleaseRequestQueue()).thenReturn(new ReleaseRequestQueue(Collections.emptyList()));
    when(provider.getReleaseTransactionSet()).thenReturn(new ReleaseTransactionSet(Collections.emptySet()));
    when(provider.getOldFederation()).thenReturn(oldFederation);
    when(provider.getNewFederation()).thenReturn(newFederation);
    BlockGenerator blockGenerator = new BlockGenerator();
    // Old federation will be in migration age at block 35
    org.ethereum.core.Block rskCurrentBlock = blockGenerator.createBlock(35, 1);
    Transaction tx = Transaction.create(config, TO_ADDRESS, DUST_AMOUNT, NONCE, GAS_PRICE, GAS_LIMIT, DATA);
    Repository repository = new RepositoryImpl(config);
    Repository track = repository.startTracking();
    BridgeSupport bridgeSupport = new BridgeSupport(config, track, mock(BridgeEventLogger.class), provider, rskCurrentBlock);
    // One MICROCOIN is less than half the fee per kb, which is the minimum funds to migrate,
    // and so it won't be removed from the old federation UTXOs list for migration.
    List<UTXO> unsufficientUTXOsForMigration1 = new ArrayList<>();
    unsufficientUTXOsForMigration1.add(createUTXO(Coin.MICROCOIN, oldFederation.getAddress()));
    when(provider.getOldFederationBtcUTXOs()).thenReturn(unsufficientUTXOsForMigration1);
    bridgeSupport.updateCollections(tx);
    assertThat(unsufficientUTXOsForMigration1.size(), is(1));
    // MILLICOIN is greater than half the fee per kb,
    // and it will be removed from the old federation UTXOs list for migration.
    List<UTXO> sufficientUTXOsForMigration1 = new ArrayList<>();
    sufficientUTXOsForMigration1.add(createUTXO(Coin.MILLICOIN, oldFederation.getAddress()));
    when(provider.getOldFederationBtcUTXOs()).thenReturn(sufficientUTXOsForMigration1);
    bridgeSupport.updateCollections(tx);
    assertThat(sufficientUTXOsForMigration1.size(), is(0));
    // 2 smaller coins should work exactly like 1 MILLICOIN
    List<UTXO> sufficientUTXOsForMigration2 = new ArrayList<>();
    sufficientUTXOsForMigration2.add(createUTXO(Coin.MILLICOIN.divide(2), oldFederation.getAddress()));
    sufficientUTXOsForMigration2.add(createUTXO(Coin.MILLICOIN.divide(2), oldFederation.getAddress()));
    when(provider.getOldFederationBtcUTXOs()).thenReturn(sufficientUTXOsForMigration2);
    bridgeSupport.updateCollections(tx);
    assertThat(sufficientUTXOsForMigration2.size(), is(0));
    // higher fee per kb prevents funds migration
    List<UTXO> unsufficientUTXOsForMigration2 = new ArrayList<>();
    unsufficientUTXOsForMigration2.add(createUTXO(Coin.MILLICOIN, oldFederation.getAddress()));
    when(provider.getOldFederationBtcUTXOs()).thenReturn(unsufficientUTXOsForMigration2);
    when(provider.getFeePerKb()).thenReturn(Coin.COIN);
    bridgeSupport.updateCollections(tx);
    assertThat(unsufficientUTXOsForMigration2.size(), is(1));
}
Also used : SecureRandom(java.security.SecureRandom) BlockGenerator(co.rsk.blockchain.utils.BlockGenerator) co.rsk.bitcoinj.core(co.rsk.bitcoinj.core) org.ethereum.core(org.ethereum.core) SimpleRskTransaction(co.rsk.peg.simples.SimpleRskTransaction) RepositoryImpl(co.rsk.db.RepositoryImpl) BridgeConstants(co.rsk.config.BridgeConstants) BridgeEventLogger(co.rsk.peg.utils.BridgeEventLogger) PrepareForTest(org.powermock.core.classloader.annotations.PrepareForTest) Test(org.junit.Test)

Example 18 with BridgeConstants

use of co.rsk.config.BridgeConstants in project rskj by rsksmart.

the class BridgeSupportTest method getBridgeSupportWithMocksForWhitelistTests.

private BridgeSupport getBridgeSupportWithMocksForWhitelistTests(LockWhitelist mockedWhitelist) throws IOException {
    BridgeConstants constantsMock = mock(BridgeConstants.class);
    when(constantsMock.getBtcParams()).thenReturn(NetworkParameters.fromID(NetworkParameters.ID_REGTEST));
    when(constantsMock.getLockWhitelistChangeAuthorizer()).thenReturn(BridgeRegTestConstants.getInstance().getLockWhitelistChangeAuthorizer());
    BridgeStorageProvider providerMock = mock(BridgeStorageProvider.class);
    when(providerMock.getLockWhitelist()).thenReturn(mockedWhitelist);
    BridgeSupport result = new BridgeSupport(config, null, null, config.getBlockchainConfig().getCommonConstants().getBridgeConstants(), providerMock, null, null);
    Whitebox.setInternalState(result, "bridgeConstants", constantsMock);
    return result;
}
Also used : BridgeConstants(co.rsk.config.BridgeConstants)

Example 19 with BridgeConstants

use of co.rsk.config.BridgeConstants in project rskj by rsksmart.

the class BridgeEventLoggerImplTest method logCommitFederation.

@Test
public void logCommitFederation() {
    // Setup event logger
    BridgeConstants constantsMock = mock(BridgeConstants.class);
    when(constantsMock.getFederationActivationAge()).thenReturn(BridgeRegTestConstants.getInstance().getFederationActivationAge());
    List<LogInfo> eventLogs = new LinkedList<>();
    BridgeEventLogger eventLogger = new BridgeEventLoggerImpl(constantsMock, eventLogs);
    // Setup parameters for test method call
    Block executionBlock = mock(Block.class);
    when(executionBlock.getTimestamp()).thenReturn(15005L);
    when(executionBlock.getNumber()).thenReturn(15L);
    Federation oldFederation = new Federation(Arrays.asList(BtcECKey.fromPublicOnly(Hex.decode("036bb9eab797eadc8b697f0e82a01d01cabbfaaca37e5bafc06fdc6fdd38af894a")), BtcECKey.fromPublicOnly(Hex.decode("031da807c71c2f303b7f409dd2605b297ac494a563be3b9ca5f52d95a43d183cc5")), BtcECKey.fromPublicOnly(Hex.decode("025eefeeeed5cdc40822880c7db1d0a88b7b986945ed3fc05a0b45fe166fe85e12")), BtcECKey.fromPublicOnly(Hex.decode("03c67ad63527012fd4776ae892b5dc8c56f80f1be002dc65cd520a2efb64e37b49"))), Instant.ofEpochMilli(15005L), 15L, NetworkParameters.fromID(NetworkParameters.ID_REGTEST));
    Federation newFederation = new Federation(Arrays.asList(BtcECKey.fromPublicOnly(Hex.decode("0346cb6b905e4dee49a862eeb2288217d06afcd4ace4b5ca77ebedfbc6afc1c19d")), BtcECKey.fromPublicOnly(Hex.decode("0269a0dbe7b8f84d1b399103c466fb20531a56b1ad3a7b44fe419e74aad8c46db7")), BtcECKey.fromPublicOnly(Hex.decode("026192d8ab41bd402eb0431457f6756a3f3ce15c955c534d2b87f1e0372d8ba338"))), Instant.ofEpochMilli(5005L), 0L, NetworkParameters.fromID(NetworkParameters.ID_REGTEST));
    // Do method call
    eventLogger.logCommitFederation(executionBlock, oldFederation, newFederation);
    // Assert
    Assert.assertEquals(1, eventLogs.size());
    // Assert address that made the log
    LogInfo result = eventLogs.get(0);
    Assert.assertArrayEquals(PrecompiledContracts.BRIDGE_ADDR.getBytes(), result.getAddress());
    // Assert log topics
    Assert.assertEquals(1, result.getTopics().size());
    Assert.assertEquals(Bridge.COMMIT_FEDERATION_TOPIC, result.getTopics().get(0));
    // Assert log data
    Assert.assertNotNull(result.getData());
    List<RLPElement> rlpData = RLP.decode2(result.getData());
    Assert.assertEquals(1, rlpData.size());
    RLPList dataList = (RLPList) rlpData.get(0);
    Assert.assertEquals(3, dataList.size());
    // Assert old federation data
    RLPList oldFedData = (RLPList) dataList.get(0);
    Assert.assertEquals(2, oldFedData.size());
    Assert.assertArrayEquals(oldFederation.getAddress().getHash160(), oldFedData.get(0).getRLPData());
    RLPList oldFedPubKeys = (RLPList) oldFedData.get(1);
    Assert.assertEquals(4, oldFedPubKeys.size());
    for (int i = 0; i < 4; i++) {
        Assert.assertEquals(oldFederation.getPublicKeys().get(i), BtcECKey.fromPublicOnly(oldFedPubKeys.get(i).getRLPData()));
    }
    // Assert new federation data
    RLPList newFedData = (RLPList) dataList.get(1);
    Assert.assertEquals(2, newFedData.size());
    Assert.assertArrayEquals(newFederation.getAddress().getHash160(), newFedData.get(0).getRLPData());
    RLPList newFedPubKeys = (RLPList) newFedData.get(1);
    Assert.assertEquals(3, newFedPubKeys.size());
    for (int i = 0; i < 3; i++) {
        Assert.assertEquals(newFederation.getPublicKeys().get(i), BtcECKey.fromPublicOnly(newFedPubKeys.get(i).getRLPData()));
    }
    // Assert new federation activation block number
    Assert.assertEquals(15L + BridgeRegTestConstants.getInstance().getFederationActivationAge(), Long.valueOf(new String(dataList.get(2).getRLPData(), StandardCharsets.UTF_8)).longValue());
}
Also used : LogInfo(org.ethereum.vm.LogInfo) LinkedList(java.util.LinkedList) RLPList(org.ethereum.util.RLPList) Federation(co.rsk.peg.Federation) RLPElement(org.ethereum.util.RLPElement) Block(org.ethereum.core.Block) BridgeConstants(co.rsk.config.BridgeConstants) Test(org.junit.Test)

Aggregations

BridgeConstants (co.rsk.config.BridgeConstants)19 Test (org.junit.Test)15 PrepareForTest (org.powermock.core.classloader.annotations.PrepareForTest)13 RskAddress (co.rsk.core.RskAddress)10 RepositoryImpl (co.rsk.db.RepositoryImpl)10 SimpleRskTransaction (co.rsk.peg.simples.SimpleRskTransaction)10 co.rsk.bitcoinj.core (co.rsk.bitcoinj.core)9 org.ethereum.core (org.ethereum.core)8 BtcBlockStore (co.rsk.bitcoinj.store.BtcBlockStore)7 SimpleBlockChain (co.rsk.peg.simples.SimpleBlockChain)5 BridgeEventLogger (co.rsk.peg.utils.BridgeEventLogger)3 Repository (org.ethereum.core.Repository)3 TransactionSignature (co.rsk.bitcoinj.crypto.TransactionSignature)2 Script (co.rsk.bitcoinj.script.Script)2 BlockGenerator (co.rsk.blockchain.utils.BlockGenerator)2 RskSystemProperties (co.rsk.config.RskSystemProperties)2 Block (org.ethereum.core.Block)2 RLPList (org.ethereum.util.RLPList)2 ScriptBuilder (co.rsk.bitcoinj.script.ScriptBuilder)1 ScriptChunk (co.rsk.bitcoinj.script.ScriptChunk)1