use of org.aion.types.Log in project aion by aionnetwork.
the class AvmTransactionExecutor method buildTransactionSummary.
/**
* Constructs a new execution summary for the given transaction & result pair.
*
* @param transaction The transaction.
* @param result The transaction result.
* @return the summary.
*/
private static AionTxExecSummary buildTransactionSummary(AionTransaction transaction, TransactionResult result) {
List<Log> logs = result.transactionStatus.isSuccess() ? result.logs : new ArrayList<>();
byte[] output = result.copyOfTransactionOutput().orElse(new byte[0]);
AionTxExecSummary.Builder builder = AionTxExecSummary.builderFor(makeReceipt(transaction, logs, result, output)).logs(logs).deletedAccounts(new ArrayList<>()).internalTransactions(result.internalTransactions).result(output);
TransactionStatus resultCode = result.transactionStatus;
if (resultCode.isRejected()) {
builder.markAsRejected();
} else if (resultCode.isFailed()) {
builder.markAsFailed();
}
return builder.build();
}
use of org.aion.types.Log in project aion by aionnetwork.
the class TokenBridgeContractTest method testNonA0AddressTransfer.
@Test
public void testNonA0AddressTransfer() {
// 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[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, 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);
byte[][] signatures = new byte[members.length][];
int i = 0;
for (ECKey k : members) {
signatures[i] = k.sign(payloadHash).toBytes();
i++;
}
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) {
sigChunk1.add(new AddressFVM(Arrays.copyOfRange(sig, 0, 32)));
sigChunk2.add(new AddressFVM(Arrays.copyOfRange(sig, 32, 64)));
sigChunk3.add(new AddressFVM(Arrays.copyOfRange(sig, 64, 96)));
}
callPayload = new AbiEncoder(BridgeFuncSig.SIG_SUBMIT_BUNDLE.getSignature(), new AddressFVM(blockHash), sourceTransactionList, addressList, uintList, sigChunk1, sigChunk2, sigChunk3).encodeBytes();
transferResult = this.contract.execute(callPayload, DEFAULT_NRG);
// / VERIFICATION
// ATB-4 assert that transactionHash is now properly set
// 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(submitBundleContext.copyOfTransactionHash());
assertTrue(transferResult.getStatus().isSuccess());
for (BridgeTransfer b : transfers) {
assertThat(this.repository.getBalance(new AionAddress(b.getRecipient()))).isEqualTo(BigInteger.ONE);
}
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.types.Log in project aion by aionnetwork.
the class BridgeControllerOwnerTest method testTransferOwnership.
@Test
public void testTransferOwnership() {
byte[] transferOwnership = HashUtil.keccak256("ChangedOwner(address)".getBytes());
byte[] newOwner = HashUtil.h256("newOwner".getBytes());
this.controller.initialize();
this.controller.setNewOwner(OWNER_ADDR.toByteArray(), newOwner);
// sanity check
assertThat(this.connector.getNewOwner()).isEqualTo(newOwner);
ErrCode err = this.controller.acceptOwnership(newOwner);
assertThat(err).isEqualTo(ErrCode.NO_ERROR);
assertThat(this.connector.getOwner()).isEqualTo(newOwner);
// check that an event was properly generated
assertThat(this.logs.size()).isEqualTo(1);
Log changedOwnerLog = this.logs.get(0);
assertThat(changedOwnerLog.copyOfData()).isEqualTo(ByteUtil.EMPTY_BYTE_ARRAY);
assertThat(changedOwnerLog.copyOfTopics().get(0)).isEqualTo(transferOwnership);
assertThat(changedOwnerLog.copyOfTopics().get(1)).isEqualTo(newOwner);
}
use of org.aion.types.Log 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.types.Log in project aion by aionnetwork.
the class TxTest method testTxInfoToJsonDetails.
@Test
public void testTxInfoToJsonDetails() {
byte[] emptyByteArray = new byte[32];
Arrays.fill(emptyByteArray, (byte) 0);
AionAddress coinBase = new AionAddress(Arrays.copyOf(emptyByteArray, 32));
byte[] parentHash = HashUtil.h256("parent".getBytes());
byte[] bloom = BloomFilter.create().getBloomFilterBytes();
byte[] difficulty = BigInteger.TEN.toByteArray();
long blockNumber = 1;
long timestamp = System.currentTimeMillis();
byte[] extraData = new byte[0];
byte[] nonce = BigInteger.valueOf(100).toByteArray();
byte[] receiptsRoot = Arrays.copyOf(emptyByteArray, 32);
byte[] transactionsRoot = Arrays.copyOf(emptyByteArray, 32);
byte[] stateRoot = Arrays.copyOf(emptyByteArray, 32);
byte[] solution = new byte[256];
long nrgConsumed = 0L;
long nrgLimit = 0;
byte[] txNonce = ByteUtil.bigIntegerToBytes(BigInteger.ONE);
AionAddress to = new AionAddress(emptyByteArray);
AionAddress from = new AionAddress(emptyByteArray);
byte[] value = ByteUtil.bigIntegerToBytes(BigInteger.TEN);
byte[] data = Arrays.copyOf(emptyByteArray, 32);
long txNrgLimit = 10L;
long txNrgPrice = 10L;
byte type = 0b1;
long txNrgUsed = 5L;
AionTransaction transaction = AionTransaction.createWithoutKey(txNonce, from, to, value, data, txNrgLimit, txNrgPrice, type, null);
AionTxReceipt txReceipt = new AionTxReceipt();
txReceipt.setTransaction(transaction);
txReceipt.setNrgUsed(txNrgUsed);
MiningBlock block = new MiningBlock(parentHash, coinBase, bloom, difficulty, blockNumber, timestamp, extraData, nonce, receiptsRoot, transactionsRoot, stateRoot, List.of(transaction), solution, nrgConsumed, nrgLimit);
byte[] hash = block.getHash();
JSONObject object = Tx.aionTxInfoToDetailsJSON(AionTxInfo.newInstance(txReceipt, block.getHashWrapper(), 0), block);
assertNotNull(object);
assertEquals(ByteUtil.byteArrayToLong(txNonce), object.get("nonce"));
assertEquals(StringUtils.toJsonHex(data), object.get("input"));
assertEquals(StringUtils.toJsonHex(to.toByteArray()), object.get("to"));
assertEquals(StringUtils.toJsonHex(from.toByteArray()), object.get("from"));
assertEquals(txNrgLimit, object.get("nrg"));
assertEquals(StringUtils.toJsonHex(value), object.get("value"));
assertEquals(StringUtils.toJsonHex(txNrgPrice), object.get("nrgPrice"));
assertEquals(new NumericalValue(transaction.getTimestamp()).toHexString(), object.get("timestamp"));
assertEquals(StringUtils.toJsonHex(blockNumber), object.get("blockNumber"));
assertEquals(StringUtils.toJsonHex(hash), object.get("blockHash"));
assertEquals("", object.get("error"));
assertEquals(new NumericalValue(value).toHexString(), object.get("value"));
assertFalse(object.getBoolean("hasInternalTransactions"));
assertTrue(object.getJSONArray("logs").isEmpty());
assertEquals(new NumericalValue(txNrgUsed).toHexString(), object.get("nrgUsed"));
assertEquals(new NumericalValue(txNrgUsed).toHexString(), object.get("gasUsed"));
byte[] onesArray = new byte[32];
byte[] twosArray = new byte[32];
Arrays.fill(onesArray, (byte) 1);
Arrays.fill(twosArray, (byte) 2);
byte[] logData = new byte[32];
Arrays.fill(logData, (byte) 7);
List<byte[]> topics = List.of(onesArray, twosArray);
Log txLog = Log.topicsAndData(to.toByteArray(), topics, logData);
AionTransaction transactionWithLog = AionTransaction.createWithoutKey(txNonce, from, to, value, data, txNrgLimit, txNrgPrice, type, null);
AionTxReceipt txReceiptWithLog = new AionTxReceipt();
txReceiptWithLog.setLogs(List.of(txLog));
txReceiptWithLog.setTransaction(transactionWithLog);
txReceiptWithLog.setNrgUsed(txNrgUsed);
MiningBlock blockWithLog = new MiningBlock(parentHash, coinBase, bloom, difficulty, blockNumber, timestamp, extraData, nonce, receiptsRoot, transactionsRoot, stateRoot, List.of(transactionWithLog), solution, nrgConsumed, nrgLimit);
JSONObject jsonWithLogs = Tx.aionTxInfoToDetailsJSON(AionTxInfo.newInstance(txReceiptWithLog, blockWithLog.getHashWrapper(), 0), blockWithLog);
assertNotNull(jsonWithLogs);
List<Object> jsonArray = jsonWithLogs.getJSONArray("logs").toList();
for (Object log : jsonArray) {
assertEquals(StringUtils.toJsonHex(to.toByteArray()), ((Map) log).get("address"));
assertEquals(StringUtils.toJsonHex(logData), ((Map) log).get("data"));
ArrayList jsonTopics = (ArrayList) ((Map) log).get("topics");
for (int i = 0; i < topics.size(); i++) {
assertEquals(StringUtils.toJsonHex(topics.get(i)), jsonTopics.get(i));
}
}
}
Aggregations