use of org.aion.precompiled.type.IExternalCapabilitiesForPrecompiled in project aion by aionnetwork.
the class TotalCurrencyContract method executeUpdateTotalBalance.
private PrecompiledTransactionResult executeUpdateTotalBalance(byte[] input, long nrg) {
// update total portion
if (nrg < COST) {
return new PrecompiledTransactionResult(TransactionStatus.nonRevertedFailure("OUT_OF_NRG"), 0);
}
if (input.length < 114) {
return new PrecompiledTransactionResult(TransactionStatus.nonRevertedFailure("FAILURE"), 0);
}
// process input data
int offset = 0;
PrecompiledDataWord chainId = PrecompiledDataWord.fromInt(input[0]);
offset++;
byte signum = input[1];
offset++;
byte[] amount = new byte[16];
byte[] sign = new byte[96];
System.arraycopy(input, offset, amount, 0, 16);
offset += 16;
System.arraycopy(input, offset, sign, 0, 96);
IExternalCapabilitiesForPrecompiled capabilities = CapabilitiesProvider.getExternalCapabilities();
byte[] payload = new byte[18];
System.arraycopy(input, 0, payload, 0, 18);
boolean b = capabilities.verifyEd25519Signature(payload, sign);
if (!b) {
return new PrecompiledTransactionResult(TransactionStatus.nonRevertedFailure("FAILURE"), 0);
}
// verify public key matches owner
if (!this.ownerAddress.equals(new AionAddress(capabilities.getEd25519Address(sign)))) {
return new PrecompiledTransactionResult(TransactionStatus.nonRevertedFailure("FAILURE"), 0);
}
// payload processing
IPrecompiledDataWord totalCurr = this.externalState.getStorageValue(this.address, chainId);
BigInteger totalCurrBI = totalCurr == null ? BigInteger.ZERO : BIUtil.toBI(totalCurr.copyOfData());
BigInteger value = BIUtil.toBI(amount);
if (signum != 0x0 && signum != 0x1) {
return new PrecompiledTransactionResult(TransactionStatus.nonRevertedFailure("FAILURE"), 0);
}
BigInteger finalValue;
if (signum == 0x0) {
// addition
finalValue = totalCurrBI.add(value);
} else {
// subtraction
if (value.compareTo(totalCurrBI) > 0) {
return new PrecompiledTransactionResult(TransactionStatus.nonRevertedFailure("FAILURE"), 0);
}
finalValue = totalCurrBI.subtract(value);
}
// store result and successful exit
this.externalState.addStorageValue(this.address, chainId, PrecompiledDataWord.fromBytes(finalValue.toByteArray()));
return new PrecompiledTransactionResult(TransactionStatus.successful(), nrg - COST);
}
use of org.aion.precompiled.type.IExternalCapabilitiesForPrecompiled in project aion by aionnetwork.
the class BridgeController method processBundles.
/**
* Assume bundleHash is not from external source, but rather calculated on our side (on the I/O
* layer), when {@link BridgeTransfer} list was being created.
*
* @param caller, address of the calling account. Used to check whether the address calling is
* the relay or not.
* @param sourceBlockHash, hash of a block on the source blockchain, each block may contain 1 to
* N bundles. Used as part of the bundleHash to tie a bundle to a block.
* @param transfers, {@link BridgeTransfer}
* @param signatures, a list of signatures from signatories that have signed the bundles.
* @return {@code ErrCode} indicating whether operation was successful
* @implNote assume the inputs are properly formatted
* @implNote will check whether any bundles are {@code 0} value transfers. In such a case, it
* indicates that the bridge has faulted, so we should immediately fail all transfers.
* @implNote {@link BridgeDeserializer} implicitly places a max size for each list to 512.
*/
public ProcessedResults processBundles(@Nonnull final byte[] caller, @Nonnull final byte[] transactionHash, @Nonnull final byte[] sourceBlockHash, @Nonnull final BridgeTransfer[] transfers, @Nonnull final byte[][] signatures) {
if (!isRingLocked())
return processError(ErrCode.RING_NOT_LOCKED);
if (!isRelayer(caller))
return processError(ErrCode.NOT_RELAYER);
if (!isWithinSignatureBounds(signatures.length))
return processError(ErrCode.INVALID_SIGNATURE_BOUNDS);
/*
* Computes a unique identifier of the transfer hash for each sourceBlockHash,
* uniqueness relies on the fact that each
*/
// verify bundleHash
byte[] hash = computeBundleHash(sourceBlockHash, transfers);
// previously successfully broadcast in.
if (bundleProcessed(hash)) {
// ATB 6-1, fixed bug: emit stored transactionHash instead of input transaction Hash
emitSuccessfulTransactionHash(this.connector.getBundle(hash));
return processSuccess(Collections.emptyList());
}
int signed = 0;
IExternalCapabilitiesForPrecompiled capabilities = CapabilitiesProvider.getExternalCapabilities();
for (byte[] sigBytes : signatures) {
if (capabilities.verifyISig(hash, sigBytes) && this.connector.getActiveMember(capabilities.getISigAddress(sigBytes))) {
signed++;
}
}
int minThresh = this.connector.getMinThresh();
if (signed < minThresh)
return processError(ErrCode.NOT_ENOUGH_SIGNATURES);
// otherwise, we're clear to proceed with transfers
List<PrecompiledTransactionResult> results = new ArrayList<>();
for (BridgeTransfer b : transfers) {
if (b.getTransferValue().compareTo(BigInteger.ZERO) == 0)
return processError(ErrCode.INVALID_TRANSFER);
/*
* Tricky here, we distinguish between two types of failures here:
*
* 1) A balance failure indicates we've failed to load the bridge with
* enough currency to execute, this means the whole transaction should
* fail and cause the bridge to exit
*
* 2) Any other failure indicates that either the contract had code,
* which means the contract is now considered null.
*
* For how this is documented, check the {@code Transferable}
* interface documentation.
*/
PrecompiledTransactionResult result;
if ((result = transferable.transfer(b.getRecipient(), b.getTransferValue())).getStatus().isFailed())
// no need to return list of transactions, since they're all being dropped
return processError(ErrCode.INVALID_TRANSFER);
// otherwise if transfer was successful
if (result.getStatus().isSuccess())
if (!emitDistributed(b.getSourceTransactionHash(), b.getRecipient(), b.getTransferValue()))
return processError(ErrCode.INVALID_TRANSFER);
results.add(result);
}
this.connector.setBundle(hash, transactionHash);
emitProcessedBundle(sourceBlockHash, hash);
return processSuccess(results);
}
Aggregations