Skip to content

Commit

Permalink
Merge branch 'develop' into 6038-D-crypto-create-handler-impl
Browse files Browse the repository at this point in the history
  • Loading branch information
Neeharika-Sompalli committed May 3, 2023
2 parents 18ab0d5 + 5b74adc commit a7f5d13
Show file tree
Hide file tree
Showing 152 changed files with 3,462 additions and 590 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@
import com.swirlds.common.system.NodeId;
import com.swirlds.common.system.Platform;
import com.swirlds.common.system.state.notifications.IssListener;
import com.swirlds.common.system.state.notifications.NewRecoveredStateListener;
import com.swirlds.common.system.state.notifications.NewSignedStateListener;
import dagger.BindsInstance;
import dagger.Component;
Expand Down Expand Up @@ -206,6 +207,8 @@ public interface ServicesApp {

NewSignedStateListener newSignedStateListener();

Optional<NewRecoveredStateListener> maybeNewRecoveredStateListener();

Supplier<NotificationEngine> notificationEngine();

BackingStore<AccountID, HederaAccount> backingAccounts();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@
import com.swirlds.common.system.SwirldState;
import com.swirlds.common.system.address.AddressBook;
import com.swirlds.common.system.events.Event;
import com.swirlds.common.system.state.notifications.NewRecoveredStateListener;
import com.swirlds.common.threading.manager.AdHocThreadManager;
import com.swirlds.fchashmap.FCHashMap;
import com.swirlds.jasperdb.VirtualDataSourceJasperDB;
Expand Down Expand Up @@ -353,6 +354,8 @@ private ServicesApp internalInit(
.build();
APPS.save(selfId, app);
}
app.maybeNewRecoveredStateListener().ifPresent(listener -> platform.getNotificationEngine()
.register(NewRecoveredStateListener.class, listener));

if (dualState == null) {
dualState = new DualStateImpl();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@
import static com.hedera.node.app.service.mono.txns.crypto.helpers.AllowanceHelpers.getCryptoGrantedAllowancesList;
import static com.hedera.node.app.service.mono.txns.crypto.helpers.AllowanceHelpers.getFungibleGrantedTokenAllowancesList;
import static com.hedera.node.app.service.mono.txns.crypto.helpers.AllowanceHelpers.getNftGrantedAllowancesList;
import static com.hedera.node.app.service.mono.utils.EntityIdUtils.EVM_ADDRESS_SIZE;
import static com.hedera.node.app.service.mono.utils.EntityIdUtils.asAccount;
import static com.hedera.node.app.service.mono.utils.EntityIdUtils.asHexedEvmAddress;
import static com.hedera.node.app.service.mono.utils.EntityIdUtils.isOfEvmAddressSize;
import static com.hedera.node.app.service.mono.utils.EntityIdUtils.readableId;
import static com.hedera.node.app.service.mono.utils.EntityNum.fromAccountId;
import static com.hedera.node.app.service.mono.utils.EvmTokenUtil.asEvmTokenInfo;
Expand Down Expand Up @@ -418,7 +418,7 @@ public Optional<CryptoGetInfoResponse.AccountInfo> infoForAccount(
.setMaxAutomaticTokenAssociations(account.getMaxAutomaticAssociations())
.setEthereumNonce(account.getEthereumNonce());
Optional.ofNullable(account.getProxy()).map(EntityId::toGrpcAccountId).ifPresent(info::setProxyAccountID);
if (account.getAlias().size() != EVM_ADDRESS_SIZE) {
if (!isOfEvmAddressSize(account.getAlias())) {
info.setAlias(account.getAlias());
}
final var tokenRels = tokenRels(this, account, maxTokensForAccountInfo);
Expand All @@ -431,7 +431,7 @@ public Optional<CryptoGetInfoResponse.AccountInfo> infoForAccount(
}

private String getContractAccountId(final JKey key, final AccountID accountID, final ByteString alias) {
if (alias.size() == EVM_ADDRESS_SIZE) {
if (isOfEvmAddressSize(alias)) {
return CommonUtils.hex(ByteStringUtils.unwrapUnsafelyIfPossible(alias));
}
// If we can recover an Ethereum EOA address from the account key, we should return that
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@

import static com.hedera.node.app.service.evm.accounts.HederaEvmContractAliases.isMirror;
import static com.hedera.node.app.service.mono.context.properties.StaticPropertiesHolder.STATIC_PROPERTIES;
import static com.hedera.node.app.service.mono.utils.EntityIdUtils.EVM_ADDRESS_SIZE;
import static com.hedera.node.app.service.mono.utils.EntityIdUtils.isAlias;
import static com.hedera.node.app.service.mono.utils.EntityIdUtils.isOfEvmAddressSize;
import static com.hedera.node.app.service.mono.utils.EntityNum.MISSING_NUM;
import static com.hedera.node.app.service.mono.utils.MiscUtils.isSerializedProtoKey;

Expand Down Expand Up @@ -179,7 +179,7 @@ private Result resolveInternal(
var result = Result.KNOWN_ALIAS;
if (isAlias(idOrAlias)) {
final var alias = idOrAlias.getAlias();
if (alias.size() == EVM_ADDRESS_SIZE) {
if (isOfEvmAddressSize(alias)) {
final var evmAddress = alias.toByteArray();
if (isMirror(evmAddress)) {
offerMirrorId(evmAddress, resolvingAction);
Expand Down Expand Up @@ -207,7 +207,7 @@ private Result resolveInternalFungible(
var result = Result.KNOWN_ALIAS;
if (isAlias(adjust.getAccountID())) {
final var alias = adjust.getAccountID().getAlias();
if (alias.size() == EVM_ADDRESS_SIZE) {
if (isOfEvmAddressSize(alias)) {
final var evmAddress = alias.toByteArray();
if (isMirror(evmAddress)) {
offerMirrorId(
Expand Down Expand Up @@ -247,7 +247,7 @@ private void perceiveResult(
if (assetChange > 0) {
if (isSerializedProtoKey(alias)) {
perceivedCreations++;
} else if (alias.size() == EVM_ADDRESS_SIZE) {
} else if (isOfEvmAddressSize(alias)) {
perceivedLazyCreations++;
} else {
perceivedInvalidCreations++;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

package com.hedera.node.app.service.mono.legacy.core.jproto;

import static com.hedera.node.app.service.mono.utils.EntityIdUtils.EVM_ADDRESS_SIZE;
import static com.hedera.node.app.service.mono.utils.EntityIdUtils.isOfEvmAddressSize;

import com.google.protobuf.ByteString;
import com.hederahashgraph.api.proto.java.ContractID;
Expand Down Expand Up @@ -81,6 +81,6 @@ public boolean isEmpty() {

@Override
public boolean isValid() {
return !isEmpty() && evmAddress.length == EVM_ADDRESS_SIZE;
return !isEmpty() && isOfEvmAddressSize(evmAddress);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

package com.hedera.node.app.service.mono.legacy.core.jproto;

import static com.hedera.node.app.service.mono.utils.EntityIdUtils.EVM_ADDRESS_SIZE;
import static com.hedera.node.app.service.mono.utils.EntityIdUtils.isOfEvmAddressSize;

/**
* This is a special type of key, which _does not_ map to proto Key. It's used only internally.
Expand Down Expand Up @@ -63,7 +63,7 @@ public boolean isEmpty() {

@Override
public boolean isValid() {
return !(isEmpty() || (evmAddress.length != EVM_ADDRESS_SIZE));
return !(isEmpty() || (!isOfEvmAddressSize(evmAddress)));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ public SafeLookupResult<AccountSigningMetadata> aliasableAccountSigningMetaFor(
final AccountID idOrAlias, final @Nullable LinkedRefs linkedRefs) {
if (isAlias(idOrAlias)) {
final var alias = idOrAlias.getAlias();
if (alias.size() == EVM_ADDRESS_SIZE) {
if (isOfEvmAddressSize(alias)) {
final var evmAddress = alias.toByteArray();
if (aliasManager.isMirror(evmAddress)) {
return lookupAccountByNumber(EntityNum.fromMirror(evmAddress), linkedRefs);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import com.hedera.node.app.service.mono.state.expiry.ExpiringCreations;
import com.hedera.node.app.service.mono.state.exports.AccountsExporter;
import com.hedera.node.app.service.mono.state.exports.BalancesExporter;
import com.hedera.node.app.service.mono.state.exports.ExportingRecoveredStateListener;
import com.hedera.node.app.service.mono.state.exports.ServicesSignedStateListener;
import com.hedera.node.app.service.mono.state.exports.SignedStateBalancesExporter;
import com.hedera.node.app.service.mono.state.exports.ToStringAccountsExporter;
Expand Down Expand Up @@ -67,6 +68,7 @@
import com.hedera.node.app.service.mono.state.virtual.VirtualBlobValue;
import com.hedera.node.app.service.mono.state.virtual.VirtualMapFactory;
import com.hedera.node.app.service.mono.store.schedule.ScheduleStore;
import com.hedera.node.app.service.mono.stream.RecordStreamManager;
import com.hedera.node.app.service.mono.stream.RecordsRunningHashLeaf;
import com.hedera.node.app.service.mono.utils.EntityNum;
import com.hedera.node.app.service.mono.utils.JvmSystemExits;
Expand All @@ -80,15 +82,18 @@
import com.swirlds.common.notification.listeners.PlatformStatusChangeListener;
import com.swirlds.common.notification.listeners.ReconnectCompleteListener;
import com.swirlds.common.notification.listeners.StateWriteToDiskCompleteListener;
import com.swirlds.common.system.InitTrigger;
import com.swirlds.common.system.NodeId;
import com.swirlds.common.system.Platform;
import com.swirlds.common.system.address.AddressBook;
import com.swirlds.common.system.state.notifications.IssListener;
import com.swirlds.common.system.state.notifications.NewRecoveredStateListener;
import com.swirlds.common.system.state.notifications.NewSignedStateListener;
import com.swirlds.common.utility.CommonUtils;
import dagger.Binds;
import dagger.Module;
import dagger.Provides;
import edu.umd.cs.findbugs.annotations.NonNull;
import edu.umd.cs.findbugs.annotations.Nullable;
import java.io.PrintStream;
import java.nio.charset.Charset;
Expand Down Expand Up @@ -155,6 +160,20 @@ static BalancesExporter bindBalancesExporter(
}
}

@Provides
@Singleton
static Optional<NewRecoveredStateListener> provideMaybeRecoveredStateListener(
@NonNull final InitTrigger initTrigger,
@NonNull final RecordStreamManager recordStreamManager,
@NonNull final BalancesExporter balancesExporter,
@NonNull final NodeId nodeId) {
if (initTrigger == InitTrigger.EVENT_STREAM_RECOVERY) {
return Optional.of(new ExportingRecoveredStateListener(recordStreamManager, balancesExporter, nodeId));
} else {
return Optional.empty();
}
}

@Binds
@Singleton
SystemFilesManager bindSysFilesManager(HfsSystemFilesManager hfsSystemFilesManager);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* Copyright (C) 2023 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.mono.state.exports;

import com.hedera.node.app.service.mono.stream.RecordStreamManager;
import com.swirlds.common.system.InitTrigger;
import com.swirlds.common.system.NodeId;
import com.swirlds.common.system.state.notifications.NewRecoveredStateListener;
import com.swirlds.common.system.state.notifications.NewRecoveredStateNotification;
import edu.umd.cs.findbugs.annotations.NonNull;
import java.util.Objects;

/**
* A tiny {@link NewRecoveredStateListener}, registered <i>only</i> when {@code ServicesState#init()} is called with
* {@link InitTrigger#EVENT_STREAM_RECOVERY}, that upon receiving a recovered state notification
* <ol>
* <li>Freezes the record stream (hence flushing any pending items to a final file); and,</li>
* <li>Exports the account balances from the recovered state.</li>
* </ol>
*/
public class ExportingRecoveredStateListener implements NewRecoveredStateListener {
private final RecordStreamManager recordStreamManager;
private final BalancesExporter balancesExporter;
private final NodeId nodeId;

public ExportingRecoveredStateListener(
@NonNull final RecordStreamManager recordStreamManager,
@NonNull final BalancesExporter balancesExporter,
@NonNull final NodeId nodeId) {
this.recordStreamManager = Objects.requireNonNull(recordStreamManager);
this.balancesExporter = Objects.requireNonNull(balancesExporter);
this.nodeId = Objects.requireNonNull(nodeId);
}

@Override
public void notify(@NonNull final NewRecoveredStateNotification notification) {
recordStreamManager.setInFreeze(true);
balancesExporter.exportBalancesFrom(
notification.getSwirldState(), notification.getConsensusTimestamp(), nodeId);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
import java.io.InputStreamReader;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HexFormat;
import java.util.List;
import java.util.Objects;
Expand Down Expand Up @@ -96,9 +97,43 @@ public BlocklistAccountCreator(
* Makes sure that all blocked accounts contained in the blocklist resource are present in state, and creates them if necessary.
*/
public void createMissingAccounts() {
final List<String> fileLines = readFileLines();
if (fileLines.isEmpty()) return;

final List<BlockedInfo> blocklist = parseBlockList(fileLines);

if (!blocklist.isEmpty()) {
final var blockedToCreate = blocklist.stream()
.filter(blockedAccount ->
aliasManager.lookupIdBy(blockedAccount.evmAddress).equals(MISSING_NUM))
.collect(Collectors.toSet());

for (final var blockedInfo : blockedToCreate) {
final var newId = ids.newAccountId(); // get the next available new account ID
final var account = blockedAccountWith(blockedInfo);
accounts.put(newId, account); // add the account with the corresponding newId to state
accountsCreated.add(account); // add the account to the list of accounts created by this class
aliasManager.link(
blockedInfo.evmAddress,
EntityNum.fromAccountId(newId)); // link the EVM address alias to the new account ID
}
}
}

private List<String> readFileLines() {
final List<String> fileLines;
try {
fileLines = readPrivateKeyBlocklist(blocklistResourceName);
} catch (Exception e) {
log.error("Failed to read blocklist resource {}", blocklistResourceName, e);
return Collections.emptyList();
}
return fileLines;
}

private List<BlockedInfo> parseBlockList(final List<String> fileLines) {
final List<BlockedInfo> blocklist;
try {
final var fileLines = readPrivateKeyBlocklist(blocklistResourceName);
final var columnHeaderLine = fileLines.get(0);
final var blocklistLines = fileLines.subList(1, fileLines.size());
final var columnCount = columnHeaderLine.split(",").length;
Expand All @@ -107,26 +142,9 @@ public void createMissingAccounts() {
.toList();
} catch (IllegalArgumentException iae) {
log.error("Failed to parse blocklist", iae);
return;
} catch (Exception e) {
log.error("Failed to read blocklist resource {}", blocklistResourceName, e);
return;
}

final var blockedToCreate = blocklist.stream()
.filter(blockedAccount ->
aliasManager.lookupIdBy(blockedAccount.evmAddress).equals(MISSING_NUM))
.collect(Collectors.toSet());

for (final var blockedInfo : blockedToCreate) {
final var newId = ids.newAccountId(); // get the next available new account ID
final var account = blockedAccountWith(blockedInfo);
accounts.put(newId, account); // add the account with the corresponding newId to state
accountsCreated.add(account); // add the account to the list of accounts created by this class
aliasManager.link(
blockedInfo.evmAddress,
EntityNum.fromAccountId(newId)); // link the EVM address alias to the new account ID
return Collections.emptyList();
}
return blocklist;
}

@NonNull
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ public ServicesTxnManager(
this.blocklistAccountCreator = Objects.requireNonNull(blocklistAccountCreator);
}

private boolean needToPublishMigrationRecords = true;
private boolean isFirstTransaction = true;
private boolean createdStreamableRecord;

public void process(TxnAccessor accessor, Instant consensusTime, long submittingMember) {
Expand All @@ -104,7 +104,7 @@ public void process(TxnAccessor accessor, Instant consensusTime, long submitting
rewardCalculator.reset();
ledger.begin();

if (needToPublishMigrationRecords) {
if (isFirstTransaction) {
if (bootstrapProperties.getBooleanProperty(PropertyNames.ACCOUNTS_BLOCKLIST_ENABLED)) {
blocklistAccountCreator.createMissingAccounts();
}
Expand All @@ -113,7 +113,7 @@ public void process(TxnAccessor accessor, Instant consensusTime, long submitting
// state) shows that it needs to do so; our responsibility here is just to give it
// the opportunity
migrationRecordsManager.publishMigrationRecords(consensusTime);
needToPublishMigrationRecords = false;
isFirstTransaction = false;
}
if (accessor.isTriggeredTxn()) {
scopedTriggeredProcessing.run();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@
import static com.hedera.node.app.service.mono.ledger.properties.TokenRelProperty.IS_KYC_GRANTED;
import static com.hedera.node.app.service.mono.ledger.properties.TokenRelProperty.TOKEN_BALANCE;
import static com.hedera.node.app.service.mono.state.submerkle.EntityId.MISSING_ENTITY_ID;
import static com.hedera.node.app.service.mono.utils.EntityIdUtils.ECDSA_SECP256K1_ALIAS_SIZE;
import static com.hedera.node.app.service.mono.utils.EntityIdUtils.EVM_ADDRESS_SIZE;
import static com.hedera.node.app.service.mono.utils.EntityIdUtils.accountIdFromEvmAddress;
import static com.hedera.node.app.service.mono.utils.EntityIdUtils.isOfEcdsaAddressSize;
import static com.hedera.node.app.service.mono.utils.EntityIdUtils.isOfEvmAddressSize;
import static com.hedera.node.app.service.mono.utils.EntityIdUtils.readableId;
import static com.hedera.node.app.service.mono.utils.EntityIdUtils.tokenIdFromEvmAddress;
import static com.hedera.node.app.service.mono.utils.EvmTokenUtil.asEvmTokenInfo;
Expand Down Expand Up @@ -368,9 +368,9 @@ public Address getAddressOrAlias(final Address address) {
alias = staticEntityAccess.alias(address);
}
if (!alias.isEmpty()) {
if (alias.size() == EVM_ADDRESS_SIZE) {
if (isOfEvmAddressSize(alias)) {
return Address.wrap(Bytes.wrap(alias.toByteArray()));
} else if (alias.size() == ECDSA_SECP256K1_ALIAS_SIZE && alias.startsWith(ECDSA_KEY_ALIAS_PREFIX)) {
} else if (isOfEcdsaAddressSize(alias) && alias.startsWith(ECDSA_KEY_ALIAS_PREFIX)) {
final byte[] value = recoverAddressFromPubKey(alias.substring(2).toByteArray());
if (value.length > 0) {
return Address.wrap(Bytes.wrap(value));
Expand Down
Loading

0 comments on commit a7f5d13

Please sign in to comment.