Skip to content

Commit

Permalink
added a test when a tx is already processed do not modify the state
Browse files Browse the repository at this point in the history
  • Loading branch information
julianlen committed Dec 13, 2024
1 parent c4825b2 commit c7fa076
Showing 1 changed file with 69 additions and 31 deletions.
100 changes: 69 additions & 31 deletions rskj-core/src/test/java/co/rsk/peg/RegisterBtcTransactionIT.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@
import org.ethereum.config.blockchain.upgrades.ActivationConfig;
import org.ethereum.config.blockchain.upgrades.ActivationConfigsForTest;
import org.ethereum.core.*;
import org.ethereum.crypto.ECKey;
import org.ethereum.vm.PrecompiledContracts;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.util.*;

Expand All @@ -36,66 +38,102 @@ public class RegisterBtcTransactionIT {
private final BridgeConstants bridgeConstants = BridgeMainNetConstants.getInstance();
private final NetworkParameters btcParams = bridgeConstants.getBtcParams();
private final BridgeSupportBuilder bridgeSupportBuilder = BridgeSupportBuilder.builder();
private Repository track;
private Repository repository;
private Block rskExecutionBlock;
private FederationSupport federationSupport;
private BridgeStorageProvider bridgeStorageProvider;
private BtcTransaction bitcoinTransaction;
private PartialMerkleTree pmtWithTransactions;
private int btcBlockWithPmtHeight;
private Transaction rskTx;
private ECKey ecKey;
private RskAddress rskReceiver;
private BridgeSupport bridgeSupport;
private BridgeEventLoggerImpl bridgeEventLogger;
private Coin btcTransferred;

@BeforeEach
void setUp() throws Exception{
rskTx = TransactionUtils.createTransaction();
repository = BridgeSupportTestUtil.createRepository();
track = repository.startTracking();

@Test
void whenRegisterALegacyBtcTransaction_shouldRegisterTheNewUtxoAndTransferTheRbtcBalance() throws Exception {
// Arrange
ActivationConfig.ForBlock activations = ActivationConfigsForTest.all().forBlock(0);
Repository repository = BridgeSupportTestUtil.createRepository();
Repository track = repository.startTracking();
Block rskExecutionBlock = getRskExecutionBlock();
rskExecutionBlock = getRskExecutionBlock();

BtcLockSenderProvider btcLockSenderProvider = new BtcLockSenderProvider();
FeePerKbSupport feePerKbSupport = getFeePerKbSupport(repository, bridgeConstants);

Federation federation = P2shErpFederationBuilder.builder().build();
FederationStorageProvider federationStorageProvider = getFederationStorageProvider(track, federation);
FederationSupport federationSupport = getFederationSupport(federationStorageProvider, activations, bridgeConstants.getFederationConstants());

BtcECKey btcPublicKey = BitcoinTestUtils.getBtcEcKeyFromSeed("seed");
Coin btcTransferred = bridgeConstants.getMinimumPeginTxValue(activations);
BtcTransaction bitcoinTransaction = createPegInTransaction(federationSupport.getActiveFederation().getAddress(), btcTransferred, btcPublicKey);
TransactionOutput output = bitcoinTransaction.getOutput(0);
List<UTXO> expectedFederationUtxos = Collections.singletonList(getUtxo(bitcoinTransaction, output));
federationSupport = getFederationSupport(federationStorageProvider, activations, bridgeConstants.getFederationConstants());

BridgeStorageProvider bridgeStorageProvider = new BridgeStorageProvider(track, PrecompiledContracts.BRIDGE_ADDR, bridgeConstants.getBtcParams(), activations);
bridgeStorageProvider = new BridgeStorageProvider(track, PrecompiledContracts.BRIDGE_ADDR, bridgeConstants.getBtcParams(), activations);
BtcBlockStoreWithCache.Factory btcBlockStoreFactory = new RepositoryBtcBlockStoreWithCache.Factory(bridgeConstants.getBtcParams(), 100, 100);
BtcBlockStoreWithCache btcBlockStoreWithCache = btcBlockStoreFactory.newInstance(track, bridgeConstants, bridgeStorageProvider, activations);

PartialMerkleTree pmtWithTransactions = createValidPmtForTransactions(Collections.singletonList(bitcoinTransaction.getHash()), bridgeConstants.getBtcParams());
int btcBlockWithPmtHeight = bridgeConstants.getBtcHeightWhenPegoutTxIndexActivates() + bridgeConstants.getPegoutTxIndexGracePeriodInBtcBlocks();
BtcECKey btcPublicKey = BitcoinTestUtils.getBtcEcKeyFromSeed("seed");
ecKey = ECKey.fromPublicOnly(btcPublicKey.getPubKey());
rskReceiver = new RskAddress(ecKey.getAddress());
btcTransferred = bridgeConstants.getMinimumPeginTxValue(activations);
bitcoinTransaction = createPegInTransaction(federationSupport.getActiveFederation().getAddress(), btcTransferred, btcPublicKey);

pmtWithTransactions = createValidPmtForTransactions(Collections.singletonList(bitcoinTransaction.getHash()), bridgeConstants.getBtcParams());
btcBlockWithPmtHeight = bridgeConstants.getBtcHeightWhenPegoutTxIndexActivates() + bridgeConstants.getPegoutTxIndexGracePeriodInBtcBlocks();
int chainHeight = btcBlockWithPmtHeight + bridgeConstants.getBtc2RskMinimumAcceptableConfirmations();

BridgeEventLoggerImpl bridgeEventLogger = spy(new BridgeEventLoggerImpl(bridgeConstants, activations, new ArrayList<>()));
bridgeEventLogger = spy(new BridgeEventLoggerImpl(bridgeConstants, activations, new ArrayList<>()));

recreateChainFromPmt(btcBlockStoreWithCache, chainHeight, pmtWithTransactions, btcBlockWithPmtHeight, bridgeConstants.getBtcParams());

bridgeStorageProvider.save();
bridgeSupport = getBridgeSupport(bridgeEventLogger, bridgeStorageProvider, activations, federationSupport, feePerKbSupport, rskExecutionBlock, btcBlockStoreFactory, track, btcLockSenderProvider);
}

BridgeSupport bridgeSupport = getBridgeSupport(bridgeEventLogger, bridgeStorageProvider, activations, federationSupport, feePerKbSupport, rskExecutionBlock, btcBlockStoreFactory, track, btcLockSenderProvider);

Transaction rskTx = TransactionUtils.createTransaction();
org.ethereum.crypto.ECKey key = org.ethereum.crypto.ECKey.fromPublicOnly(btcPublicKey.getPubKey());
@Test
void whenRegisterALegacyBtcTransaction_shouldRegisterTheNewUtxoAndTransferTheRbtcBalance() throws Exception {
// Arrange
TransactionOutput output = bitcoinTransaction.getOutput(0);
List<UTXO> expectedFederationUtxos = Collections.singletonList(getUtxo(bitcoinTransaction, output));

RskAddress receiver = new RskAddress(key.getAddress());
co.rsk.core.Coin receiverBalance = track.getBalance(receiver);
co.rsk.core.Coin receiverBalance = track.getBalance(rskReceiver);
co.rsk.core.Coin expectedReceiverBalance = receiverBalance.add(co.rsk.core.Coin.fromBitcoin(btcTransferred));

// Act
bridgeSupport.registerBtcTransaction(rskTx, bitcoinTransaction.bitcoinSerialize(), btcBlockWithPmtHeight, pmtWithTransactions.bitcoinSerialize());

bridgeSupport.save();
track.commit();
registerBtcTransactionAndCommit();

// Assert
Optional<Long> heightIfBtcTxHashIsAlreadyProcessed = bridgeStorageProvider.getHeightIfBtcTxhashIsAlreadyProcessed(bitcoinTransaction.getHash());

assertTrue(heightIfBtcTxHashIsAlreadyProcessed.isPresent());
assertEquals(rskExecutionBlock.getNumber(), heightIfBtcTxHashIsAlreadyProcessed.get());
assertEquals(expectedFederationUtxos, federationSupport.getActiveFederationBtcUTXOs());
assertEquals(expectedReceiverBalance, repository.getBalance(receiver));
assertEquals(expectedReceiverBalance, repository.getBalance(rskReceiver));

verify(bridgeEventLogger, times(1)).logPeginBtc(rskReceiver, bitcoinTransaction, btcTransferred, 0);

}

@Test
void whenRegisterARepeatedLegacyBtcTransaction_shouldNotPerformAnyChange() throws Exception {
// Arrange
registerBtcTransactionAndCommit();

verify(bridgeEventLogger, times(1)).logPeginBtc(receiver, bitcoinTransaction, btcTransferred, 0);
RskAddress receiverBalance = new RskAddress(ecKey.getAddress());
co.rsk.core.Coin expectedReceiverBalance = track.getBalance(receiverBalance);
List<UTXO> expectedFederationUTXOs = federationSupport.getActiveFederationBtcUTXOs();

// Act
registerBtcTransactionAndCommit();

// Assert
assertEquals(expectedFederationUTXOs, federationSupport.getActiveFederationBtcUTXOs());
assertEquals(expectedReceiverBalance, repository.getBalance(receiverBalance));
}

private void registerBtcTransactionAndCommit() throws Exception {
bridgeSupport.registerBtcTransaction(rskTx, bitcoinTransaction.bitcoinSerialize(), btcBlockWithPmtHeight, pmtWithTransactions.bitcoinSerialize());
bridgeSupport.save();
track.commit();
}

private static UTXO getUtxo(BtcTransaction bitcoinTransaction, TransactionOutput output) {
Expand Down

0 comments on commit c7fa076

Please sign in to comment.