Search in sources :

Example 81 with PrecompiledTransactionResult

use of org.aion.precompiled.PrecompiledTransactionResult in project aion by aionnetwork.

the class ContractExecutor method executeExternalCall.

/**
 * Returns the result of executing the specified transaction, which is a transaction that calls
 * into a precompiled contract.
 *
 * This method performs verifications, balance transfers, etc. and runs as an external
 * transaction!
 *
 * @param externalState The current state of the world.
 * @param transaction The transaction.
 * @return the execution result.
 */
public static PrecompiledWrappedTransactionResult executeExternalCall(IExternalCapabilitiesForPrecompiled capabilities, IExternalStateForPrecompiled externalState, Transaction transaction) {
    if (externalState == null) {
        throw new NullPointerException("Cannot run using a null externalState!");
    }
    if (transaction == null) {
        throw new NullPointerException("Cannot run null transaction!");
    }
    PrecompiledTransactionContext context = constructTransactionContext(capabilities, transaction, externalState);
    IExternalStateForPrecompiled childExternalState = externalState.newChildExternalState();
    IExternalStateForPrecompiled grandChildExternalState = childExternalState.newChildExternalState();
    PrecompiledTransactionResult result = new PrecompiledTransactionResult(TransactionStatus.successful(), transaction.energyLimit - capabilities.calculateTransactionCost(transaction.copyOfTransactionData(), transaction.isCreate));
    // Perform the rejection checks and return immediately if transaction is rejected.
    performRejectionChecks(childExternalState, transaction, result);
    if (!result.getStatus().isSuccess()) {
        return PrecompiledTransactionResultUtil.createWithCodeAndEnergyRemaining(result.getStatus(), transaction.energyLimit - result.getEnergyRemaining());
    }
    incrementNonceAndDeductEnergyCost(childExternalState, transaction);
    // Ensure that our caller did not erroneously pass us a CREATE transaction.
    if (transaction.isCreate) {
        throw new IllegalStateException("A precompiled contract call cannot be a CREATE!");
    }
    synchronized (PRECOMPILED_LOCK) {
        // Install the external capabilities for precompiled to use.
        CapabilitiesProvider.installExternalCapabilities(capabilities);
        result = runPrecompiledContractCall(grandChildExternalState, context, result, transaction);
        // Remove the newly installed capabilities.
        CapabilitiesProvider.removeExternalCapabilities();
    }
    // up to the child kernel.
    if (result.getStatus().isSuccess()) {
        grandChildExternalState.commit();
    }
    // kernel up to its parent.
    if (!result.getStatus().isRejected()) {
        childExternalState.commit();
    }
    return PrecompiledTransactionResultUtil.createPrecompiledWrappedTransactionResult(result.getStatus(), context.getInternalTransactions(), context.getLogs(), transaction.energyLimit - result.getEnergyRemaining(), result.getReturnData(), context.getDeletedAddresses());
}
Also used : PrecompiledTransactionResult(org.aion.precompiled.PrecompiledTransactionResult)

Example 82 with PrecompiledTransactionResult

use of org.aion.precompiled.PrecompiledTransactionResult in project aion by aionnetwork.

the class ExternalStateForFvm method runInternalPrecompiledContractCall.

/**
 * Executes an internal precompiled contract call and returns the result.
 *
 * @param context The context of the internal transaction.
 * @return the execution result.
 */
@Override
public FastVmTransactionResult runInternalPrecompiledContractCall(ExecutionContext context) {
    PrecompiledTransactionContext precompiledContext = toPrecompiledTransactionContext(context);
    CfgFork cfg = new CfgFork();
    String forkProperty = cfg.getProperties().getProperty("fork0.3.2");
    boolean fork032Enabled = (forkProperty != null) && (blockNumber >= Long.valueOf(forkProperty));
    IExternalStateForPrecompiled precompiledWorldState = new ExternalStateForPrecompiled(this.repository, this.blockNumber, this.isLocalCall, fork032Enabled, this.allowNonceIncrement);
    PrecompiledTransactionResult result = ContractExecutor.executeInternalCall(new ExternalCapabilitiesForPrecompiled(), precompiledWorldState, precompiledContext, context.getTransactionData(), context.getTransactionEnergy());
    return precompiledToFvmResult(result);
}
Also used : PrecompiledTransactionResult(org.aion.precompiled.PrecompiledTransactionResult) IExternalStateForPrecompiled(org.aion.precompiled.type.IExternalStateForPrecompiled) PrecompiledTransactionContext(org.aion.precompiled.type.PrecompiledTransactionContext) ExternalCapabilitiesForPrecompiled(org.aion.zero.impl.vm.precompiled.ExternalCapabilitiesForPrecompiled) CfgFork(org.aion.zero.impl.config.CfgFork) IExternalStateForPrecompiled(org.aion.precompiled.type.IExternalStateForPrecompiled) ExternalStateForPrecompiled(org.aion.zero.impl.vm.precompiled.ExternalStateForPrecompiled)

Example 83 with PrecompiledTransactionResult

use of org.aion.precompiled.PrecompiledTransactionResult in project aion by aionnetwork.

the class TokenBridgeContractTest method testTransferRingLocked.

// william test
@Test
public void testTransferRingLocked() {
    // 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 (byte[] k : members) {
        encodingList.add(new AddressFVM(k));
    }
    // not initializing the ring
    // set relayer
    byte[] callPayload = new AbiEncoder(BridgeFuncSig.SIG_SET_RELAYER.getSignature(), new AddressFVM(members[0])).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]), 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 = capabilities.blake2b("blockHash".getBytes());
    BridgeTransfer[] transfers = new BridgeTransfer[5];
    for (int i = 0; i < 5; i++) {
        // generate a unique sourceTransactionHash for each transfer
        byte[] sourceTransactionHash = capabilities.blake2b(Integer.toString(i).getBytes());
        transfers[i] = BridgeTransfer.getInstance(BigInteger.ONE, capabilities.computeA0Address(capabilities.blake2b(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 (byte[] k : members) {
        signatures[i] = capabilities.sign(k, payloadHash);
        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 - 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 modified 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();
}
Also used : Uint128FVM(org.aion.precompiled.encoding.Uint128FVM) AionAddress(org.aion.types.AionAddress) AddressFVM(org.aion.precompiled.encoding.AddressFVM) AbiEncoder(org.aion.precompiled.encoding.AbiEncoder) ListFVM(org.aion.precompiled.encoding.ListFVM) PrecompiledTransactionResult(org.aion.precompiled.PrecompiledTransactionResult) PrecompiledTransactionContext(org.aion.precompiled.type.PrecompiledTransactionContext) Test(org.junit.Test)

Example 84 with PrecompiledTransactionResult

use of org.aion.precompiled.PrecompiledTransactionResult in project aion by aionnetwork.

the class TokenBridgeContractTest method testGetNewOwner.

@Test
public void testGetNewOwner() {
    // override defaults
    this.contract = new TokenBridgeContract(context(OWNER_ADDR, CONTRACT_ADDR), ExternalStateForTests.usingRepository(this.repository), OWNER_ADDR, CONTRACT_ADDR);
    this.connector = this.contract.getConnector();
    byte[] newOwner = capabilities.computeA0Address(capabilities.blake2b("newOwner".getBytes()));
    byte[] payload = new AbiEncoder(BridgeFuncSig.SIG_CHANGE_OWNER.getSignature(), new AddressFVM(newOwner)).encodeBytes();
    System.out.println("encoded payload: " + ByteUtil.toHexString(payload));
    assertThat(this.connector.getInitialized()).isFalse();
    PrecompiledTransactionResult setResult = this.contract.execute(payload, DEFAULT_NRG);
    assertThat(this.connector.getInitialized()).isTrue();
    assertTrue(setResult.getStatus().isSuccess());
    PrecompiledTransactionResult result = this.contract.execute(BridgeFuncSig.PURE_NEW_OWNER.getBytes(), DEFAULT_NRG);
    assertThat(result.getReturnData()).isEqualTo(newOwner);
    assertThat(result.getEnergyRemaining()).isEqualTo(0L);
}
Also used : PrecompiledTransactionResult(org.aion.precompiled.PrecompiledTransactionResult) AbiEncoder(org.aion.precompiled.encoding.AbiEncoder) AddressFVM(org.aion.precompiled.encoding.AddressFVM) Test(org.junit.Test)

Example 85 with PrecompiledTransactionResult

use of org.aion.precompiled.PrecompiledTransactionResult in project aion by aionnetwork.

the class TokenBridgeContractTest method testRemoveRingMember.

@Test
public void testRemoveRingMember() {
    // override defaults
    this.contract = new TokenBridgeContract(context(OWNER_ADDR, CONTRACT_ADDR), ExternalStateForTests.usingRepository(this.repository), OWNER_ADDR, CONTRACT_ADDR);
    this.connector = this.contract.getConnector();
    ListFVM encodingList = new ListFVM();
    for (byte[] k : members) {
        encodingList.add(new AddressFVM(k));
    }
    // address null - fail
    byte[] payload = new AbiEncoder(BridgeFuncSig.SIG_RING_REMOVE_MEMBER.getSignature()).encodeBytes();
    PrecompiledTransactionResult result = this.contract.execute(payload, DEFAULT_NRG);
    assertEquals("FAILURE", result.getStatus().causeOfError);
    // add new member - fail
    byte[] sig = new AbiEncoder(BridgeFuncSig.SIG_RING_REMOVE_MEMBER.getSignature(), encodingList).encodeBytes();
    // the new member
    byte[] newMember = getRandomAddr();
    byte[] payload2 = new byte[4 + 32];
    System.arraycopy(sig, 0, payload2, 0, 4);
    System.arraycopy(newMember, 0, payload2, 4, 32);
    PrecompiledTransactionResult result2 = this.contract.execute(payload2, DEFAULT_NRG);
    assertEquals("FAILURE", result2.getStatus().causeOfError);
    // initialize ring
    byte[] ring = new AbiEncoder(BridgeFuncSig.SIG_RING_INITIALIZE.getSignature(), encodingList).encodeBytes();
    this.contract.execute(ring, DEFAULT_NRG);
    // remove member - fail, member does not exist
    byte[] sig3 = new AbiEncoder(BridgeFuncSig.SIG_RING_REMOVE_MEMBER.getSignature(), encodingList).encodeBytes();
    // the new member
    byte[] newMember3 = getRandomAddr();
    byte[] payload3 = new byte[4 + 32];
    System.arraycopy(sig3, 0, payload3, 0, 4);
    System.arraycopy(newMember3, 0, payload3, 4, 32);
    PrecompiledTransactionResult result3 = this.contract.execute(payload3, DEFAULT_NRG);
    assertEquals("FAILURE", result3.getStatus().causeOfError);
    // remove member - success, member exists
    byte[] sig4 = new AbiEncoder(BridgeFuncSig.SIG_RING_REMOVE_MEMBER.getSignature(), encodingList).encodeBytes();
    byte[] payload4 = new byte[4 + 32];
    System.arraycopy(sig4, 0, payload4, 0, 4);
    System.arraycopy(members[0], 0, payload4, 4, 32);
    PrecompiledTransactionResult result4 = this.contract.execute(payload4, DEFAULT_NRG);
    assertTrue(result4.getStatus().isSuccess());
}
Also used : PrecompiledTransactionResult(org.aion.precompiled.PrecompiledTransactionResult) AddressFVM(org.aion.precompiled.encoding.AddressFVM) AbiEncoder(org.aion.precompiled.encoding.AbiEncoder) ListFVM(org.aion.precompiled.encoding.ListFVM) Test(org.junit.Test)

Aggregations

PrecompiledTransactionResult (org.aion.precompiled.PrecompiledTransactionResult)114 Test (org.junit.Test)103 PrecompiledTransactionContext (org.aion.precompiled.type.PrecompiledTransactionContext)39 AionAddress (org.aion.types.AionAddress)36 TokenBridgeContract (org.aion.precompiled.contracts.ATB.TokenBridgeContract)26 ECKey (org.aion.crypto.ECKey)25 AbiEncoder (org.aion.precompiled.encoding.AbiEncoder)25 AddressFVM (org.aion.precompiled.encoding.AddressFVM)25 AbiEncoder (org.aion.zero.impl.precompiled.encoding.AbiEncoder)25 AddressFVM (org.aion.zero.impl.precompiled.encoding.AddressFVM)25 BigInteger (java.math.BigInteger)24 ListFVM (org.aion.precompiled.encoding.ListFVM)23 ListFVM (org.aion.zero.impl.precompiled.encoding.ListFVM)23 BridgeTransfer (org.aion.precompiled.contracts.ATB.BridgeTransfer)16 ContractFactory (org.aion.precompiled.ContractFactory)12 Uint128FVM (org.aion.precompiled.encoding.Uint128FVM)11 Uint128FVM (org.aion.zero.impl.precompiled.encoding.Uint128FVM)11 PrecompiledContract (org.aion.precompiled.type.PrecompiledContract)10 InternalTransaction (org.aion.types.InternalTransaction)7 Log (org.aion.types.Log)6