Skip to content

Commit

Permalink
chore: 15281 cherry pick (#15356)
Browse files Browse the repository at this point in the history
Signed-off-by: David S Bakin <[email protected]>
Signed-off-by: lukelee-sl <[email protected]>
Co-authored-by: David S Bakin <[email protected]>
  • Loading branch information
lukelee-sl and david-bakin-sl authored Sep 5, 2024
1 parent d329741 commit 20a3e24
Show file tree
Hide file tree
Showing 25 changed files with 1,798 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,12 @@
package com.hedera.node.app.service.contract.impl.exec.processors;

import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.CallTranslator;
import com.hedera.node.app.service.contract.impl.exec.systemcontracts.has.getevmaddressalias.EvmAddressAliasTranslator;
import com.hedera.node.app.service.contract.impl.exec.systemcontracts.has.hbarallowance.HbarAllowanceTranslator;
import com.hedera.node.app.service.contract.impl.exec.systemcontracts.has.hbarapprove.HbarApproveTranslator;
import com.hedera.node.app.service.contract.impl.exec.systemcontracts.has.hederaaccountnumalias.HederaAccountNumAliasTranslator;
import com.hedera.node.app.service.contract.impl.exec.systemcontracts.has.isauthorizedraw.IsAuthorizedRawTranslator;
import com.hedera.node.app.service.contract.impl.exec.systemcontracts.has.isvalidalias.IsValidAliasTranslator;
import dagger.Module;
import dagger.Provides;
import dagger.multibindings.IntoSet;
Expand Down Expand Up @@ -58,6 +61,31 @@ static CallTranslator provideHbarApproveTranslator(@NonNull final HbarApproveTra
return translator;
}

@Provides
@Singleton
@IntoSet
@Named("HasTranslators")
static CallTranslator provideEvmAddressAliasTranslator(@NonNull final EvmAddressAliasTranslator translator) {
return translator;
}

@Provides
@Singleton
@IntoSet
@Named("HasTranslators")
static CallTranslator provideHederaAccountNumAliasTranslator(
@NonNull final HederaAccountNumAliasTranslator translator) {
return translator;
}

@Provides
@Singleton
@IntoSet
@Named("HasTranslators")
static CallTranslator provideIsValidAliasTranslator(@NonNull final IsValidAliasTranslator translator) {
return translator;
}

@Provides
@Singleton
@IntoSet
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/*
* Copyright (C) 2023-2024 Hedera Hashgraph, LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.hedera.node.app.service.contract.impl.exec.systemcontracts.has.getevmaddressalias;

import static com.hedera.hapi.node.base.ResponseCodeEnum.INVALID_ACCOUNT_ID;
import static com.hedera.hapi.node.base.ResponseCodeEnum.SUCCESS;
import static com.hedera.node.app.service.contract.impl.exec.systemcontracts.FullResult.successResult;
import static com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.Call.PricedResult.gasOnly;
import static com.hedera.node.app.service.contract.impl.exec.systemcontracts.has.getevmaddressalias.EvmAddressAliasTranslator.EVM_ADDRESS_ALIAS;
import static com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.ReturnTypes.ZERO_ADDRESS;
import static com.hedera.node.app.service.contract.impl.utils.ConversionUtils.asHeadlongAddress;
import static com.hedera.node.app.service.contract.impl.utils.ConversionUtils.explicitFromHeadlong;
import static com.hedera.node.app.service.contract.impl.utils.ConversionUtils.isLongZeroAddress;
import static com.hedera.node.app.service.contract.impl.utils.ConversionUtils.numberOfLongZero;
import static java.util.Objects.requireNonNull;

import com.esaulpaugh.headlong.abi.Address;
import com.hedera.hapi.node.base.ResponseCodeEnum;
import com.hedera.node.app.service.contract.impl.exec.systemcontracts.FullResult;
import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.AbstractCall;
import com.hedera.node.app.service.contract.impl.exec.systemcontracts.has.HasCallAttempt;
import edu.umd.cs.findbugs.annotations.NonNull;

/**
* Implements the {@code evmAddressAlias()} call of the Has system contract.
*/
public class EvmAddressAliasCall extends AbstractCall {
private final Address address;

public EvmAddressAliasCall(@NonNull final HasCallAttempt attempt, final Address address) {
super(attempt.systemContractGasCalculator(), attempt.enhancement(), true);
this.address = requireNonNull(address);
}

/**
* {@inheritDoc}
*/
@Override
public @NonNull PricedResult execute() {
final var explicitAddress = explicitFromHeadlong(address);

// If the address is not a long zero then return fail
if (!isLongZeroAddress(explicitAddress)) {
return gasOnly(fullResultsFor(INVALID_ACCOUNT_ID, ZERO_ADDRESS), INVALID_ACCOUNT_ID, true);
}

final var accountNum = numberOfLongZero(explicitAddress);
final var account = enhancement.nativeOperations().getAccount(accountNum);
// If the account is null or does not have an account id then return bail
if (account == null || !account.hasAccountId()) {
return gasOnly(fullResultsFor(INVALID_ACCOUNT_ID, ZERO_ADDRESS), INVALID_ACCOUNT_ID, true);
}

// If the account does not have an evm address as an alias
if (account.alias().length() != 20) {
return gasOnly(fullResultsFor(INVALID_ACCOUNT_ID, ZERO_ADDRESS), INVALID_ACCOUNT_ID, true);
}

final var aliasAddress = asHeadlongAddress(account.alias().toByteArray());
return gasOnly(fullResultsFor(SUCCESS, aliasAddress), SUCCESS, true);
}

private @NonNull FullResult fullResultsFor(
@NonNull final ResponseCodeEnum responseCode, @NonNull final Address address) {
return successResult(
EVM_ADDRESS_ALIAS.getOutputs().encodeElements((long) responseCode.protoOrdinal(), address),
gasCalculator.viewGasRequirement());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* Copyright (C) 2023-2024 Hedera Hashgraph, LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.hedera.node.app.service.contract.impl.exec.systemcontracts.has.getevmaddressalias;

import static java.util.Objects.requireNonNull;

import com.esaulpaugh.headlong.abi.Address;
import com.esaulpaugh.headlong.abi.Function;
import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.AbstractCallTranslator;
import com.hedera.node.app.service.contract.impl.exec.systemcontracts.has.HasCallAttempt;
import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.ReturnTypes;
import edu.umd.cs.findbugs.annotations.NonNull;
import javax.inject.Inject;
import javax.inject.Singleton;

/**
* Translates {@code evmAddressAlias} calls to the HAS system contract.
*/
@Singleton
public class EvmAddressAliasTranslator extends AbstractCallTranslator<HasCallAttempt> {
public static final Function EVM_ADDRESS_ALIAS =
new Function("getEvmAddressAlias(address)", ReturnTypes.RESPONSE_CODE_ADDRESS);

@Inject
public EvmAddressAliasTranslator() {
// Dagger
}

/**
* {@inheritDoc}
*/
@Override
public @NonNull EvmAddressAliasCall callFrom(@NonNull final HasCallAttempt attempt) {
final Address address = EvmAddressAliasTranslator.EVM_ADDRESS_ALIAS
.decodeCall(attempt.input().toArrayUnsafe())
.get(0);
return new EvmAddressAliasCall(attempt, address);
}

/**
* {@inheritDoc}
*/
@Override
public boolean matches(@NonNull final HasCallAttempt attempt) {
requireNonNull(attempt, "attempt");
return attempt.isSelector(EVM_ADDRESS_ALIAS);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
* Copyright (C) 2024 Hedera Hashgraph, LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.hedera.node.app.service.contract.impl.exec.systemcontracts.has.hederaaccountnumalias;

import static com.hedera.hapi.node.base.ResponseCodeEnum.INVALID_SOLIDITY_ADDRESS;
import static com.hedera.hapi.node.base.ResponseCodeEnum.SUCCESS;
import static com.hedera.node.app.service.contract.impl.exec.systemcontracts.FullResult.successResult;
import static com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.Call.PricedResult.gasOnly;
import static com.hedera.node.app.service.contract.impl.exec.systemcontracts.has.hederaaccountnumalias.HederaAccountNumAliasTranslator.HEDERA_ACCOUNT_NUM_ALIAS;
import static com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.ReturnTypes.ZERO_ADDRESS;
import static com.hedera.node.app.service.contract.impl.utils.ConversionUtils.accountNumberForEvmReference;
import static com.hedera.node.app.service.contract.impl.utils.ConversionUtils.asEvmAddress;
import static com.hedera.node.app.service.contract.impl.utils.ConversionUtils.asHeadlongAddress;
import static java.util.Objects.requireNonNull;

import com.esaulpaugh.headlong.abi.Address;
import com.hedera.hapi.node.base.AccountID;
import com.hedera.hapi.node.base.ResponseCodeEnum;
import com.hedera.node.app.service.contract.impl.exec.systemcontracts.FullResult;
import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.AbstractCall;
import com.hedera.node.app.service.contract.impl.exec.systemcontracts.has.HasCallAttempt;
import edu.umd.cs.findbugs.annotations.NonNull;

public class HederaAccountNumAliasCall extends AbstractCall {
private final Address address;

public HederaAccountNumAliasCall(@NonNull final HasCallAttempt attempt, @NonNull final Address address) {
super(attempt.systemContractGasCalculator(), attempt.enhancement(), true);
this.address = requireNonNull(address);
}

/**
* {@inheritDoc}
*/
@Override
public @NonNull PricedResult execute() {

final long accountNum = accountNumberForEvmReference(address, nativeOperations());
if (accountNum < 0) {
// Invalid: not an alias for any account
return gasOnly(fullResultsFor(INVALID_SOLIDITY_ADDRESS, ZERO_ADDRESS), INVALID_SOLIDITY_ADDRESS, true);
}
final var account = enhancement.nativeOperations().getAccount(accountNum);
if (account == null
|| !account.hasAccountId()
|| !account.accountIdOrElse(AccountID.DEFAULT).hasAccountNum()) {
return gasOnly(fullResultsFor(INVALID_SOLIDITY_ADDRESS, ZERO_ADDRESS), INVALID_SOLIDITY_ADDRESS, true);
}
final var accountAsAddress = asHeadlongAddress(
asEvmAddress(account.accountIdOrElse(AccountID.DEFAULT).accountNumOrElse(0L)));
return gasOnly(fullResultsFor(SUCCESS, accountAsAddress), SUCCESS, true);
}

private @NonNull FullResult fullResultsFor(final ResponseCodeEnum responseCode, final Address address) {
return successResult(
HEDERA_ACCOUNT_NUM_ALIAS.getOutputs().encodeElements((long) responseCode.protoOrdinal(), address),
gasCalculator.viewGasRequirement());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* Copyright (C) 2024 Hedera Hashgraph, LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.hedera.node.app.service.contract.impl.exec.systemcontracts.has.hederaaccountnumalias;

import static java.util.Objects.requireNonNull;

import com.esaulpaugh.headlong.abi.Address;
import com.esaulpaugh.headlong.abi.Function;
import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.AbstractCallTranslator;
import com.hedera.node.app.service.contract.impl.exec.systemcontracts.has.HasCallAttempt;
import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.ReturnTypes;
import edu.umd.cs.findbugs.annotations.NonNull;
import javax.inject.Inject;

public class HederaAccountNumAliasTranslator extends AbstractCallTranslator<HasCallAttempt> {

public static final Function HEDERA_ACCOUNT_NUM_ALIAS =
new Function("getHederaAccountNumAlias(address)", ReturnTypes.RESPONSE_CODE_ADDRESS);

@Inject
public HederaAccountNumAliasTranslator() {
// Dagger
}

/**
* {@inheritDoc}
*/
@Override
public @NonNull HederaAccountNumAliasCall callFrom(@NonNull HasCallAttempt attempt) {
final Address address = HEDERA_ACCOUNT_NUM_ALIAS
.decodeCall(attempt.input().toArrayUnsafe())
.get(0);
return new HederaAccountNumAliasCall(attempt, address);
}

@Override
public boolean matches(@NonNull HasCallAttempt attempt) {
requireNonNull(attempt, "attempt");
return attempt.isSelector(HEDERA_ACCOUNT_NUM_ALIAS);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* Copyright (C) 2024 Hedera Hashgraph, LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.hedera.node.app.service.contract.impl.exec.systemcontracts.has.isvalidalias;

import static com.hedera.hapi.node.base.ResponseCodeEnum.SUCCESS;
import static com.hedera.node.app.service.contract.impl.exec.scope.HederaNativeOperations.NON_CANONICAL_REFERENCE_NUMBER;
import static com.hedera.node.app.service.contract.impl.exec.systemcontracts.FullResult.successResult;
import static com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.Call.PricedResult.gasOnly;
import static com.hedera.node.app.service.contract.impl.exec.systemcontracts.has.isvalidalias.IsValidAliasTranslator.IS_VALID_ALIAS;
import static com.hedera.node.app.service.contract.impl.utils.ConversionUtils.accountNumberForEvmReference;
import static java.util.Objects.requireNonNull;

import com.esaulpaugh.headlong.abi.Address;
import com.hedera.node.app.service.contract.impl.exec.systemcontracts.FullResult;
import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.AbstractCall;
import com.hedera.node.app.service.contract.impl.exec.systemcontracts.has.HasCallAttempt;
import edu.umd.cs.findbugs.annotations.NonNull;

public class IsValidAliasCall extends AbstractCall {

private final Address address;

public IsValidAliasCall(@NonNull final HasCallAttempt attempt, @NonNull final Address address) {
super(attempt.systemContractGasCalculator(), attempt.enhancement(), true);
this.address = requireNonNull(address);
}

/**
* {@inheritDoc}
*/
@Override
public @NonNull PricedResult execute() {

// It is OK if given address is long zero whether it does or doesn't have an EVM alias (which is
// why NON_CANONICAL_REFERENCE_NUMBER is an acceptable result).
final long accountNum = accountNumberForEvmReference(address, nativeOperations());
boolean isValidAlias = accountNum >= 0 || accountNum == NON_CANONICAL_REFERENCE_NUMBER;
return gasOnly(fullResultsFor(isValidAlias), SUCCESS, true);
}

private @NonNull FullResult fullResultsFor(final boolean result) {
return successResult(IS_VALID_ALIAS.getOutputs().encodeElements(result), gasCalculator.viewGasRequirement());
}
}
Loading

0 comments on commit 20a3e24

Please sign in to comment.