use of org.aion.precompiled.contracts.ATB.BridgeTransfer in project aion by aionnetwork.
the class BridgeTransferTest method testLowerBoundSignature.
@Test
public void testLowerBoundSignature() {
final byte[] senderAddress = members[0].getAddress();
final byte[] blockHash = HashUtil.h256("blockHash".getBytes());
final byte[] recipient = HashUtil.h256("recipient".getBytes());
final byte[] sourceTransactionHash = HashUtil.h256("transaction".getBytes());
final byte[] aionTransactionHash = HashUtil.h256("aionTransaction".getBytes());
// ensure we have enough balance
state.addBalance(CONTRACT_ADDR, BigInteger.ONE);
BridgeTransfer bundle = BridgeTransfer.getInstance(BigInteger.valueOf(1), recipient, sourceTransactionHash);
byte[] bundleHash = BridgeUtilities.computeBundleHash(blockHash, new BridgeTransfer[] { bundle });
byte[][] signatures = new byte[3][];
for (int i = 0; i < 3; i++) {
signatures[i] = members[i].sign(bundleHash).toBytes();
}
ErrCode code = this.controller.setRelayer(OWNER_ADDR.toByteArray(), senderAddress);
assertThat(code).isEqualTo(ErrCode.NO_ERROR);
BridgeController.ProcessedResults results = this.controller.processBundles(senderAddress, aionTransactionHash, blockHash, new BridgeTransfer[] { bundle }, signatures);
assertThat(results).isNotNull();
assertThat(results.controllerResult).isEqualTo(ErrCode.NO_ERROR);
assertThat(state.getBalance(CONTRACT_ADDR)).isEqualTo(BigInteger.ZERO);
assertThat(state.getBalance(new AionAddress(recipient))).isEqualTo(BigInteger.ONE);
}
use of org.aion.precompiled.contracts.ATB.BridgeTransfer in project aion by aionnetwork.
the class BridgeTransferTest method testBundleMultipleTransferSameRecipient.
// Transfer 511 times, ONE per transfer
// Also thoroughly checks event signatures
@Test
public void testBundleMultipleTransferSameRecipient() {
final byte[] senderAddress = members[0].getAddress();
final byte[] blockHash = HashUtil.h256("blockHash".getBytes());
final byte[] recipient = HashUtil.h256("recipient".getBytes());
final byte[] aionTransactionHash = HashUtil.h256("aionTransactionHash".getBytes());
int transferTotal = 511;
final BigInteger transferTotalBigInteger = BigInteger.valueOf(transferTotal);
state.addBalance(CONTRACT_ADDR, transferTotalBigInteger);
BridgeTransfer[] transfers = new BridgeTransfer[transferTotal];
for (int i = 0; i < transferTotal; i++) {
byte[] randomBytes = new byte[32];
new SecureRandom().nextBytes(randomBytes);
transfers[i] = BridgeTransfer.getInstance(BigInteger.ONE, recipient, randomBytes);
}
ResultHashTuple tuple = executeSignController(senderAddress, blockHash, aionTransactionHash, transfers);
assertThat(tuple.results.controllerResult).isEqualTo(ErrCode.NO_ERROR);
assertThat(state.getBalance(CONTRACT_ADDR)).isEqualTo(BigInteger.ZERO);
assertThat(state.getBalance(new AionAddress(recipient))).isEqualTo(transferTotalBigInteger);
// 511 transfer events + 1 distributed event
assertThat(this.context.getLogs().size()).isEqualTo(512);
List<Log> logs = this.context.getLogs();
for (int i = 0; i < 511; i++) {
List<byte[]> topics = logs.get(i).copyOfTopics();
assertThat(topics.get(0)).isEqualTo(BridgeEventSig.DISTRIBUTED.getHashed());
assertThat(topics.get(1)).isEqualTo(transfers[i].getSourceTransactionHash());
assertThat(topics.get(2)).isEqualTo(transfers[i].getRecipient());
assertThat(topics.get(3)).isEqualTo(PrecompiledUtilities.pad(transfers[i].getTransferValueByteArray(), 32));
}
// for the last element
{
List<byte[]> topics = logs.get(511).copyOfTopics();
assertThat(topics.get(0)).isEqualTo(BridgeEventSig.PROCESSED_BUNDLE.getHashed());
assertThat(topics.get(1)).isEqualTo(blockHash);
assertThat(topics.get(2)).isEqualTo(tuple.bundleHash);
}
}
use of org.aion.precompiled.contracts.ATB.BridgeTransfer in project aion by aionnetwork.
the class BridgeTransferTest method testTransferZeroBundle.
@Test
public void testTransferZeroBundle() {
final byte[] senderAddress = members[0].getAddress();
final byte[] blockHash = HashUtil.h256("blockHash".getBytes());
final byte[] recipient = HashUtil.h256("recipient".getBytes());
final byte[] sourceTransactionHash = HashUtil.h256("transaction".getBytes());
final byte[] aionTransactionHash = HashUtil.h256("aionTransaction".getBytes());
state.addBalance(CONTRACT_ADDR, BigInteger.ONE);
BridgeTransfer bundle = BridgeTransfer.getInstance(BigInteger.ZERO, recipient, sourceTransactionHash);
byte[] bundleHash = BridgeUtilities.computeBundleHash(blockHash, new BridgeTransfer[] { bundle });
byte[][] signatures = new byte[5][];
for (int i = 0; i < 5; i++) {
signatures[i] = members[i].sign(bundleHash).toBytes();
}
ErrCode code = this.controller.setRelayer(OWNER_ADDR.toByteArray(), senderAddress);
assertThat(code).isEqualTo(ErrCode.NO_ERROR);
BridgeController.ProcessedResults results = this.controller.processBundles(senderAddress, aionTransactionHash, blockHash, new BridgeTransfer[] { bundle }, signatures);
assertThat(results).isNotNull();
assertThat(results.controllerResult).isEqualTo(ErrCode.INVALID_TRANSFER);
assertThat(state.getBalance(CONTRACT_ADDR)).isEqualTo(BigInteger.ONE);
assertThat(state.getBalance(new AionAddress(recipient))).isEqualTo(BigInteger.ZERO);
}
use of org.aion.precompiled.contracts.ATB.BridgeTransfer in project aion by aionnetwork.
the class TokenBridgeContractTest method testTransferToSameAddressTwiceInOneBundle.
@Test
public void testTransferToSameAddressTwiceInOneBundle() {
BridgeTransfer[] transfers = new BridgeTransfer[10];
// generate a unique sourceTransactionHash for each transfer
for (int i = 0; i < 10; i++) {
// send to the same addr more than once
if (i == 2 || i == 3) {
byte[] sourceTransactionHashDefault = HashUtil.h256(Integer.toString(2).getBytes());
transfers[i] = BridgeTransfer.getInstance(BigInteger.ONE, AddressSpecs.computeA0Address(HashUtil.h256(Integer.toHexString(2).getBytes())), sourceTransactionHashDefault);
} else {
// generate a unique sourceTransactionHash for each transfer
byte[] sourceTransactionHash = HashUtil.h256(Integer.toString(i).getBytes());
transfers[i] = BridgeTransfer.getInstance(BigInteger.ONE, AddressSpecs.computeA0Address(HashUtil.h256(Integer.toHexString(i).getBytes())), sourceTransactionHash);
}
}
ReturnDataFromSetup fromSetup = setupForTest(transfers, members);
PrecompiledTransactionContext submitBundleContext = fromSetup.submitBundleContext;
byte[] blockHash = fromSetup.blockHash;
byte[] payloadHash = fromSetup.payloadHash;
byte[] callPayload = fromSetup.callPayload;
PrecompiledTransactionResult transferResult = this.contract.execute(callPayload, DEFAULT_NRG);
// / VERIFICATION
assertTrue(transferResult.getStatus().isSuccess());
int i = 0;
for (BridgeTransfer b : transfers) {
if (i == 2 || i == 3) {
assertThat(this.repository.getBalance(new AionAddress(b.getRecipient()))).isEqualTo(BigInteger.TWO);
} else {
assertThat(this.repository.getBalance(new AionAddress(b.getRecipient()))).isEqualTo(BigInteger.ONE);
}
i++;
}
assertThat(this.repository.getBalance(CONTRACT_ADDR)).isEqualTo(BigInteger.ZERO);
// context verification
// we expect on successful output:
// 10 internal transactions (that all succeed)
// 10 Distributed events
// 1 ProcessedBundle Event
assertThat(submitBundleContext.getInternalTransactions().size()).isEqualTo(10);
i = 0;
for (InternalTransaction tx : submitBundleContext.getInternalTransactions()) {
// verify the internal transaction is not rejected
assertThat(tx.isRejected).isFalse();
// verify the from is the contract address
assertThat(tx.sender).isEqualTo(CONTRACT_ADDR);
// verify that we sent the correct amount
assertThat(tx.value.intValueExact()).isEqualTo(1);
// verify that the recipient is what we intended (in the order we submitted)
assertThat(tx.destination).isEqualTo(new AionAddress(transfers[i].getRecipient()));
i++;
}
// check that proper events are emit
assertThat(submitBundleContext.getLogs().size()).isEqualTo(11);
i = 0;
for (Log l : submitBundleContext.getLogs()) {
// verify address is correct
assertThat(l.copyOfAddress()).isEqualTo(CONTRACT_ADDR.toByteArray());
List<byte[]> topics = l.copyOfTopics();
// on the 11th log, it should be the processed bundle event
if (i == 10) {
assertThat(topics.get(0)).isEqualTo(BridgeEventSig.PROCESSED_BUNDLE.getHashed());
assertThat(topics.get(1)).isEqualTo(blockHash);
assertThat(topics.get(2)).isEqualTo(payloadHash);
continue;
}
// otherwise we expect a Distributed event
assertThat(topics.get(0)).isEqualTo(BridgeEventSig.DISTRIBUTED.getHashed());
assertThat(topics.get(1)).isEqualTo(transfers[i].getSourceTransactionHash());
assertThat(topics.get(2)).isEqualTo(transfers[i].getRecipient());
assertThat(new BigInteger(1, topics.get(3))).isEqualTo(transfers[i].getTransferValue());
i++;
}
}
use of org.aion.precompiled.contracts.ATB.BridgeTransfer in project aion by aionnetwork.
the class TokenBridgeContractTest method testTransferHugeListLength.
@Test
public void testTransferHugeListLength() {
BridgeTransfer[] transfers = new BridgeTransfer[10];
for (int i = 0; i < 10; i++) {
// generate a unique sourceTransactionHash for each transfer
byte[] sourceTransactionHash = HashUtil.h256(Integer.toString(i).getBytes());
transfers[i] = BridgeTransfer.getInstance(BigInteger.ONE, AddressSpecs.computeA0Address(HashUtil.h256(Integer.toHexString(i).getBytes())), sourceTransactionHash);
}
// setup
ReturnDataFromSetup fromSetup = setupForTest(transfers, members);
PrecompiledTransactionContext submitBundleContext = fromSetup.submitBundleContext;
byte[] payloadHash = fromSetup.payloadHash;
byte[] callPayload = fromSetup.callPayload;
callPayload[50] = (byte) 0x128;
PrecompiledTransactionResult transferResult = this.contract.execute(callPayload, DEFAULT_NRG);
assertEquals("FAILURE", transferResult.getStatus().causeOfError);
// VERIFICATION failure
assertThat(this.contract.execute(ByteUtil.merge(BridgeFuncSig.PURE_ACTION_MAP.getBytes(), payloadHash), 21000L).getReturnData()).isEqualTo(new byte[32]);
assertEquals("FAILURE", transferResult.getStatus().causeOfError);
// check that nothing has been changed from the failed transfer
for (BridgeTransfer b : transfers) {
assertThat(this.repository.getBalance(new AionAddress(b.getRecipient()))).isEqualTo(BigInteger.ZERO);
}
assertThat(this.repository.getBalance(CONTRACT_ADDR)).isEqualTo(BigInteger.valueOf(10));
assertThat(submitBundleContext.getInternalTransactions()).isEmpty();
assertThat(submitBundleContext.getLogs()).isEmpty();
}
Aggregations