Skip to content

Commit

Permalink
feat: align state and records for self managed contract keys on create (
Browse files Browse the repository at this point in the history
#16095)

Signed-off-by: Luke Lee <[email protected]>
  • Loading branch information
lukelee-sl authored Oct 25, 2024
1 parent 7e19282 commit f5d3e52
Show file tree
Hide file tree
Showing 9 changed files with 38 additions and 40 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@
import com.hedera.hapi.node.base.ContractID;
import com.hedera.hapi.node.base.Duration;
import com.hedera.hapi.node.base.HederaFunctionality;
import com.hedera.hapi.node.base.Key;
import com.hedera.hapi.node.contract.ContractCreateTransactionBody;
import com.hedera.hapi.node.contract.ContractFunctionResult;
import com.hedera.hapi.node.token.CryptoCreateTransactionBody;
Expand Down Expand Up @@ -447,22 +446,20 @@ private ExternalizedRecordCustomizer contractBodyCustomizerFor(
};
}

/**
* Standardizes the given {@link ContractCreateTransactionBody} to not include initcode, gas, and initial balance
* values as these parameters are only set on the top-level HAPI transactions.
*
* @param createdNumber the number of the created contract
* @param op the operation to standardize
* @return the standardized operation
*/
private ContractCreateTransactionBody standardized(
final long createdNumber, @NonNull final ContractCreateTransactionBody op) {
var standardAdminKey = op.adminKey();
if (op.hasAdminKey()) {
final var adminNum =
op.adminKeyOrThrow().contractIDOrElse(ContractID.DEFAULT).contractNumOrElse(0L);
// For mono-service fidelity, don't set an explicit admin key for a self-managed contract
if (createdNumber == adminNum) {
standardAdminKey = null;
}
}
if (needsStandardization(op, standardAdminKey)) {
// Initial balance, gas, and initcode are only set on top-level HAPI transactions
if (needsStandardization(op)) {
return new ContractCreateTransactionBody(
com.hedera.hapi.node.contract.codec.ContractCreateTransactionBodyProtoCodec.INITCODE_SOURCE_UNSET,
standardAdminKey,
op.adminKey(),
0L,
0L,
op.proxyAccountID(),
Expand All @@ -481,8 +478,7 @@ private ContractCreateTransactionBody standardized(
}
}

private boolean needsStandardization(
@NonNull final ContractCreateTransactionBody op, @Nullable final Key standardAdminKey) {
return op.hasInitcode() || op.gas() > 0L || op.initialBalance() > 0L || standardAdminKey != op.adminKey();
private boolean needsStandardization(@NonNull final ContractCreateTransactionBody op) {
return op.hasInitcode() || op.gas() > 0L || op.initialBalance() > 0L;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -417,7 +417,9 @@ void createContractWithSelfAdminParentDispatchesAsExpectedThenMarksCreated() thr
final var pendingId = ContractID.newBuilder().contractNum(666L).build();
final var synthContractCreation = synthContractCreationFromParent(pendingId, parent)
.copyBuilder()
.adminKey((Key) null)
.adminKey(Key.newBuilder()
.contractID(ContractID.newBuilder().contractNum(666L))
.build())
.build();
final var synthAccountCreation =
synthAccountCreationFromHapi(pendingId, CANONICAL_ALIAS, synthContractCreation);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,6 @@
*/
public class TokenServiceApiImpl implements TokenServiceApi {
private static final Logger logger = LogManager.getLogger(TokenServiceApiImpl.class);
private static final Key STANDIN_CONTRACT_KEY =
Key.newBuilder().contractID(ContractID.newBuilder().contractNum(0)).build();

private final WritableAccountStore accountStore;
private final AccountID fundingAccountID;
Expand Down Expand Up @@ -178,7 +176,9 @@ public void finalizeHollowAccountAsContract(@NonNull final AccountID hollowAccou
}
final var accountAsContract = hollowAccount
.copyBuilder()
.key(STANDIN_CONTRACT_KEY)
.key(Key.newBuilder()
.contractID(ContractID.newBuilder().contractNum(hollowAccountId.accountNumOrThrow()))
.build())
.smartContract(true)
.maxAutoAssociations(hollowAccount.numberAssociations())
.build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -193,8 +193,10 @@ void refusesToUpdateKvCountsForNonContract() {

@Test
void finalizesHollowAccountAsContractAsExpected() {
final var numAssociations = 3;
accountStore.put(Account.newBuilder()
.accountId(CONTRACT_ACCOUNT_ID)
.numberAssociations(numAssociations)
.key(IMMUTABILITY_SENTINEL_KEY)
.build());

Expand All @@ -203,8 +205,9 @@ void finalizesHollowAccountAsContractAsExpected() {
assertEquals(1, accountStore.sizeOfAccountState());
final var finalizedAccount = accountStore.getContractById(CONTRACT_ID_BY_NUM);
assertNotNull(finalizedAccount);
assertEquals(STANDIN_CONTRACT_KEY, finalizedAccount.key());
assertEquals(Key.newBuilder().contractID(CONTRACT_ID_BY_NUM).build(), finalizedAccount.key());
assertTrue(finalizedAccount.smartContract());
assertEquals(finalizedAccount.maxAutoAssociations(), numAssociations);
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@

package com.hedera.services.bdd.spec.assertions;

import static com.hedera.services.bdd.suites.HapiSuite.STANDIN_CONTRACT_ID_KEY;
import static com.hederahashgraph.api.proto.java.ContractGetInfoResponse.ContractInfo;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
Expand Down Expand Up @@ -214,12 +213,6 @@ public ContractInfoAsserts adminKey(String expectedKeyName) {
return this;
}

public ContractInfoAsserts hasStandinContractKey() {
registerProvider((spec, o) ->
assertEquals(STANDIN_CONTRACT_ID_KEY, object2ContractInfo(o).getAdminKey(), BAD_ADMIN_KEY));
return this;
}

public ContractInfoAsserts defaultAdminKey() {
registerProvider((spec, o) -> {
final var contractId = object2ContractInfo(o).getContractID();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
import com.hedera.services.bdd.spec.SpecOperation;
import com.hedera.services.bdd.spec.infrastructure.HapiClients;
import com.hedera.services.bdd.spec.keys.KeyShape;
import com.hederahashgraph.api.proto.java.ContractID;
import com.hederahashgraph.api.proto.java.Key;
import com.hederahashgraph.api.proto.java.KeyList;
import edu.umd.cs.findbugs.annotations.NonNull;
Expand Down Expand Up @@ -90,9 +89,6 @@ private static HapiSpec specFrom(@NonNull final DynamicTest test) {
public static final Key EMPTY_KEY =
Key.newBuilder().setKeyList(KeyList.newBuilder().build()).build();

public static final Key STANDIN_CONTRACT_ID_KEY = Key.newBuilder()
.setContractID(ContractID.newBuilder().setContractNum(0).build())
.build();
private static final int BYTES_PER_KB = 1024;
public static final int MAX_CALL_DATA_SIZE = 6 * BYTES_PER_KB;
public static final BigInteger WEIBARS_IN_A_TINYBAR = BigInteger.valueOf(10_000_000_000L);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1029,7 +1029,7 @@ contract, GET_BYTECODE, asHeadlongAddress(factoryEvmAddress.get()), salt)
// check created contract
sourcing(() -> getContractInfo(mergedAliasAddr.get())
.has(contractWith()
.hasStandinContractKey()
.defaultAdminKey()
// fix here
.maxAutoAssociations(0)
.memo(LAZY_MEMO)
Expand Down Expand Up @@ -1131,7 +1131,7 @@ contract, GET_BYTECODE, asHeadlongAddress(factoryEvmAddress.get()), salt)
// check created contract
sourcing(() -> getContractInfo(mergedAliasAddr.get())
.has(contractWith()
.hasStandinContractKey()
.defaultAdminKey()
.maxAutoAssociations(1)
.hasAlreadyUsedAutomaticAssociations(1)
.memo(LAZY_MEMO)
Expand Down Expand Up @@ -1235,7 +1235,7 @@ contract, GET_BYTECODE, asHeadlongAddress(factoryEvmAddress.get()), salt)
// check created contract
sourcing(() -> getContractInfo(mergedAliasAddr.get())
.has(contractWith()
.hasStandinContractKey()
.defaultAdminKey()
.numKvPairs(2)
.maxAutoAssociations(2)
.hasAlreadyUsedAutomaticAssociations(2)
Expand Down Expand Up @@ -1331,7 +1331,7 @@ contract, GET_BYTECODE, asHeadlongAddress(factoryEvmAddress.get()), salt)
// check created contract
sourcing(() -> getContractInfo(mergedAliasAddr.get())
.has(contractWith()
.hasStandinContractKey()
.defaultAdminKey()
.maxAutoAssociations(1)
.hasAlreadyUsedAutomaticAssociations(1)
.memo(LAZY_MEMO)
Expand Down Expand Up @@ -1446,7 +1446,7 @@ contract, GET_BYTECODE, asHeadlongAddress(factoryEvmAddress.get()), salt)
// check created contract
sourcing(() -> getContractInfo(mergedAliasAddr.get())
.has(contractWith()
.hasStandinContractKey()
.defaultAdminKey()
.maxAutoAssociations(1)
.hasAlreadyUsedAutomaticAssociations(1)
.memo(LAZY_MEMO)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import static com.hedera.services.bdd.spec.assertions.TransferListAsserts.noCreditAboveNumber;
import static com.hedera.services.bdd.spec.keys.TrieSigMapGenerator.uniqueWithFullPrefixesFor;
import static com.hedera.services.bdd.spec.queries.QueryVerbs.getAccountBalance;
import static com.hedera.services.bdd.spec.queries.QueryVerbs.getAccountInfo;
import static com.hedera.services.bdd.spec.queries.QueryVerbs.getAliasedAccountInfo;
import static com.hedera.services.bdd.spec.queries.QueryVerbs.getAutoCreatedAccountBalance;
import static com.hedera.services.bdd.spec.queries.QueryVerbs.getTxnRecord;
Expand Down Expand Up @@ -82,6 +83,7 @@
import com.hedera.services.bdd.spec.queries.meta.HapiGetTxnRecord;
import com.hedera.services.bdd.spec.transactions.crypto.HapiCryptoTransfer;
import com.hederahashgraph.api.proto.java.AccountID;
import com.hederahashgraph.api.proto.java.Key;
import com.hederahashgraph.api.proto.java.TokenID;
import com.hederahashgraph.api.proto.java.TokenTransferList;
import com.hederahashgraph.api.proto.java.TokenType;
Expand Down Expand Up @@ -557,6 +559,12 @@ final Stream<DynamicTest> hollowAccountCompletionWithEthereumContractCreate() {
getTxnRecord(TRANSFER_TXN_2).andAllChildRecords().logged();

allRunFor(spec, op2, op3, hapiGetSecondTxnRecord);
// ensure that the finalized contract has a self management key
final var contractIdKey = Key.newBuilder()
.setContractID(spec.registry().getContractId(CONTRACT))
.build();
final var op4 = getAccountInfo(CONTRACT).has(accountWith().key(contractIdKey));
allRunFor(spec, op4);
}));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ contract, GET_BYTECODE, asHeadlongAddress(factoryEvmAddress.get()), salt)
sourcing(() -> getContractInfo(mergedAliasAddr.get())
.has(contractWith()
.numKvPairs(4)
.hasStandinContractKey()
.defaultAdminKey()
.maxAutoAssociations(2)
.hasAlreadyUsedAutomaticAssociations(2)
.memo(LAZY_MEMO)
Expand Down Expand Up @@ -366,7 +366,7 @@ contract, GET_BYTECODE, asHeadlongAddress(factoryEvmAddress.get()), salt)
// check created contract
sourcing(() -> getContractInfo(mergedAliasAddr.get())
.has(contractWith()
.hasStandinContractKey()
.defaultAdminKey()
.maxAutoAssociations(fungibleTransfersSize)
.hasAlreadyUsedAutomaticAssociations(fungibleTransfersSize)
.memo(LAZY_MEMO)
Expand Down Expand Up @@ -565,7 +565,7 @@ contract, GET_BYTECODE, asHeadlongAddress(factoryEvmAddress.get()), salt)
sourcing(() -> getContractInfo(mergedAliasAddr.get())
.has(contractWith()
.numKvPairs(2)
.hasStandinContractKey()
.defaultAdminKey()
.maxAutoAssociations(2)
.hasAlreadyUsedAutomaticAssociations(2)
.memo(LAZY_MEMO)
Expand Down

0 comments on commit f5d3e52

Please sign in to comment.