use of org.aion.precompiled.contracts.ATB.BridgeTransfer in project aion by aionnetwork.
the class TokenBridgeContractTest method testTransferFailLength.
@Test
public void testTransferFailLength() {
// instantiate a bundle with 1 transfer and 1 validator
// input byte should have length 404
ECKey[] members = new ECKey[] { ECKeyFac.inst().create() };
int n = 1;
BridgeTransfer[] transfers = new BridgeTransfer[n];
for (int i = 0; i < n; 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);
byte[] callPayload = fromSetup.callPayload;
// loops through all possible shorter length and check for failure
int i;
for (i = 1; i < 404; i++) {
byte[] input = new byte[i];
System.arraycopy(callPayload, 0, input, 0, i);
PrecompiledTransactionResult result = this.contract.execute(input, DEFAULT_NRG);
assertEquals("FAILURE", result.getStatus().causeOfError);
}
System.out.println("fail count: " + i);
// try with more bytes than expected
byte[] input = new byte[555];
System.arraycopy(callPayload, 0, input, 0, 404);
PrecompiledTransactionResult result = this.contract.execute(input, DEFAULT_NRG);
assertTrue(result.getStatus().isSuccess());
}
use of org.aion.precompiled.contracts.ATB.BridgeTransfer in project aion by aionnetwork.
the class TokenBridgeContractTest method testTransferInsufficientValidatorSignatures.
@Test
public void testTransferInsufficientValidatorSignatures() {
// override defaults
PrecompiledTransactionContext initializationContext = context(OWNER_ADDR, CONTRACT_ADDR);
this.contract = new TokenBridgeContract(initializationContext, ExternalStateForTests.usingRepository(this.repository), OWNER_ADDR, CONTRACT_ADDR);
this.connector = this.contract.getConnector();
ListFVM encodingList = new ListFVM();
for (ECKey k : members) {
encodingList.add(new AddressFVM(k.getAddress()));
}
byte[] payload = new AbiEncoder(BridgeFuncSig.SIG_RING_INITIALIZE.getSignature(), encodingList).encodeBytes();
PrecompiledTransactionResult result = this.contract.execute(payload, DEFAULT_NRG);
assertTrue(result.getStatus().isSuccess());
// set relayer
byte[] callPayload = new AbiEncoder(BridgeFuncSig.SIG_SET_RELAYER.getSignature(), new AddressFVM(members[0].getAddress())).encodeBytes();
PrecompiledTransactionResult transferResult = this.contract.execute(callPayload, DEFAULT_NRG);
assertTrue(transferResult.getStatus().isSuccess());
// override defaults
this.repository.addBalance(CONTRACT_ADDR, BigInteger.TEN);
// we create a new token bridge contract here because we
// need to change the execution context
PrecompiledTransactionContext submitBundleContext = context(new AionAddress(members[0].getAddress()), CONTRACT_ADDR);
this.contract = new TokenBridgeContract(submitBundleContext, ExternalStateForTests.usingRepository(this.repository), OWNER_ADDR, CONTRACT_ADDR);
this.connector = this.contract.getConnector();
// assemble the payload
byte[] blockHash = HashUtil.h256("blockHash".getBytes());
BridgeTransfer[] transfers = new BridgeTransfer[5];
for (int i = 0; i < 5; 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);
}
byte[] payloadHash = BridgeUtilities.computeBundleHash(blockHash, transfers);
// ATB-4, do one assert here to check that transactionHash is not set
assertThat(this.contract.execute(ByteUtil.merge(BridgeFuncSig.PURE_ACTION_MAP.getBytes(), payloadHash), 21000L).getReturnData()).isEqualTo(ByteUtil.EMPTY_WORD);
// only give 3/5 signatures
byte[][] signatures = new byte[3][];
signatures[0] = members[0].sign(payloadHash).toBytes();
signatures[1] = members[1].sign(payloadHash).toBytes();
signatures[2] = members[1].sign(payloadHash).toBytes();
ListFVM sourceTransactionList = new ListFVM();
ListFVM addressList = new ListFVM();
ListFVM uintList = new ListFVM();
for (BridgeTransfer b : transfers) {
sourceTransactionList.add(new AddressFVM(b.getSourceTransactionHash()));
addressList.add(new AddressFVM(b.getRecipient()));
uintList.add(new Uint128FVM(PrecompiledUtilities.pad(b.getTransferValue().toByteArray(), 16)));
}
ListFVM sigChunk1 = new ListFVM();
ListFVM sigChunk2 = new ListFVM();
ListFVM sigChunk3 = new ListFVM();
for (byte[] sig : signatures) {
// add incorrect signatures, copies [0:32] for all chunks
sigChunk1.add(new AddressFVM(Arrays.copyOfRange(sig, 0, 32)));
sigChunk2.add(new AddressFVM(Arrays.copyOfRange(sig, 0, 32)));
sigChunk3.add(new AddressFVM(Arrays.copyOfRange(sig, 0, 32)));
}
callPayload = new AbiEncoder(BridgeFuncSig.SIG_SUBMIT_BUNDLE.getSignature(), new AddressFVM(blockHash), sourceTransactionList, addressList, uintList, sigChunk1, sigChunk2, sigChunk3).encodeBytes();
// input will include 5 transfers and 3 validators with incorrect signatures
transferResult = this.contract.execute(callPayload, DEFAULT_NRG);
// / VERIFICATION
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();
}
use of org.aion.precompiled.contracts.ATB.BridgeTransfer in project aion by aionnetwork.
the class BridgeTransferTest method testDoubleBundleSend.
@Test
public void testDoubleBundleSend() {
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("aionTransactionHash".getBytes());
// ensure we have enough balance
state.addBalance(CONTRACT_ADDR, BigInteger.TWO);
BridgeTransfer transfer = BridgeTransfer.getInstance(BigInteger.ONE, recipient, sourceTransactionHash);
executeSignController(senderAddress, blockHash, aionTransactionHash, new BridgeTransfer[] { transfer });
final byte[] secondAionTransactionHash = HashUtil.h256("secondAionTransactionHash".getBytes());
// try second time, should still be succesful
ResultHashTuple tuple = executeSignController(senderAddress, blockHash, secondAionTransactionHash, new BridgeTransfer[] { transfer });
// check status of result
assertThat(tuple.results.controllerResult).isEqualTo(ErrCode.NO_ERROR);
assertThat(this.context.getLogs().size()).isEqualTo(1);
assertThat(this.context.getLogs().get(0).copyOfTopics().get(0)).isEqualTo(BridgeEventSig.SUCCESSFUL_TXHASH.getHashed());
assertThat(this.context.getLogs().get(0).copyOfTopics().get(1)).isEqualTo(aionTransactionHash);
// one transfer should have gone through, second shouldn't
assertThat(state.getBalance(CONTRACT_ADDR)).isEqualTo(BigInteger.ONE);
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 testBridgeTransferOne.
@Test
public void testBridgeTransferOne() {
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("aionTransactionHash".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[members.length][];
for (int i = 0; i < members.length; 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);
}
use of org.aion.precompiled.contracts.ATB.BridgeTransfer in project aion by aionnetwork.
the class BridgeTransferTest method testBeyondUpperBoundSignatures.
@Test
public void testBeyondUpperBoundSignatures() {
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[6][];
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_SIGNATURE_BOUNDS);
assertThat(state.getBalance(CONTRACT_ADDR)).isEqualTo(BigInteger.ONE);
assertThat(state.getBalance(new AionAddress(recipient))).isEqualTo(BigInteger.ZERO);
}
Aggregations