diff --git a/hedera-node/src/main/java/com/hedera/services/ServicesState.java b/hedera-node/src/main/java/com/hedera/services/ServicesState.java index e1d18b6e3098..45ed38e8ff64 100644 --- a/hedera-node/src/main/java/com/hedera/services/ServicesState.java +++ b/hedera-node/src/main/java/com/hedera/services/ServicesState.java @@ -25,7 +25,7 @@ import com.hedera.services.context.properties.BootstrapProperties; import com.hedera.services.context.properties.StandardizedPropertySources; import com.hedera.services.exceptions.ContextNotFoundException; -import com.hedera.services.sigs.sourcing.ScopedSigBytesProvider; +import com.hedera.services.sigs.sourcing.SigMapPubKeyToSigBytes; import com.hedera.services.state.merkle.MerkleAccount; import com.hedera.services.state.merkle.MerkleBlobMeta; import com.hedera.services.state.merkle.MerkleDiskFs; @@ -284,11 +284,8 @@ public synchronized void handleTransaction( public void expandSignatures(SwirldTransaction platformTxn) { try { final var accessor = ctx.expandHandleSpan().track(platformTxn); - expandIn( - accessor, - ctx.lookupRetryingKeyOrder(), - new ScopedSigBytesProvider(accessor), - ctx.sigFactoryCreator()::createScopedFactory); + final var pkToSigFn = new SigMapPubKeyToSigBytes(accessor.getSigMap()); + expandIn(accessor, ctx.lookupRetryingKeyOrder(), pkToSigFn); } catch (InvalidProtocolBufferException e) { log.warn("expandSignatures called with non-gRPC txn!", e); } catch (Exception race) { diff --git a/hedera-node/src/main/java/com/hedera/services/context/ServicesContext.java b/hedera-node/src/main/java/com/hedera/services/context/ServicesContext.java index d0ded65b917a..f78922a166f3 100644 --- a/hedera-node/src/main/java/com/hedera/services/context/ServicesContext.java +++ b/hedera-node/src/main/java/com/hedera/services/context/ServicesContext.java @@ -189,10 +189,9 @@ import com.hedera.services.records.TxnAwareRecordsHistorian; import com.hedera.services.records.TxnIdRecentHistory; import com.hedera.services.security.ops.SystemOpPolicies; -import com.hedera.services.sigs.factories.SigFactoryCreator; import com.hedera.services.sigs.metadata.DelegatingSigMetadataLookup; import com.hedera.services.sigs.order.HederaSigningOrder; -import com.hedera.services.sigs.sourcing.DefaultSigBytesProvider; +import com.hedera.services.sigs.sourcing.SigMapPubKeyToSigBytes; import com.hedera.services.sigs.verification.PrecheckKeyReqs; import com.hedera.services.sigs.verification.PrecheckVerifier; import com.hedera.services.sigs.verification.SyncVerifier; @@ -309,11 +308,9 @@ import com.hedera.services.usage.crypto.CryptoOpsUsage; import com.hedera.services.usage.file.FileOpsUsage; import com.hedera.services.usage.schedule.ScheduleOpsUsage; -import com.hedera.services.utils.JvmSystemExits; import com.hedera.services.utils.MiscUtils; import com.hedera.services.utils.Pause; import com.hedera.services.utils.SleepingPause; -import com.hedera.services.utils.SystemExits; import com.hederahashgraph.api.proto.java.AccountID; import com.hederahashgraph.api.proto.java.HederaFunctionality; import com.hederahashgraph.api.proto.java.TokenID; @@ -424,8 +421,6 @@ public class ServicesContext { private static final Logger log = LogManager.getLogger(ServicesContext.class); - private SystemExits systemExits = new JvmSystemExits(); - /* Injected dependencies. */ ServicesState state; @@ -443,7 +438,6 @@ public class ServicesContext { private HederaFs hfs; private NodeInfo nodeInfo; private StateView currentView; - private AccountID accountId; private AnswerFlow answerFlow; private HcsAnswers hcsAnswers; private FileNumbers fileNums; @@ -501,7 +495,6 @@ public class ServicesContext { private NetworkController networkGrpc; private GrpcServerManager grpc; private TxnResponseHelper txnResponseHelper; - private SigFactoryCreator sigFactoryCreator; private BlobStorageSource bytecodeDb; private HapiOpPermissions hapiOpPermissions; private EntityAutoRenewal entityAutoRenewal; @@ -622,13 +615,6 @@ public void rebuildStoreViewsIfPresent() { } } - public SigFactoryCreator sigFactoryCreator() { - if (sigFactoryCreator == null) { - sigFactoryCreator = new SigFactoryCreator(); - } - return sigFactoryCreator; - } - public NonBlockingHandoff nonBlockingHandoff() { if (nonBlockingHandoff == null) { nonBlockingHandoff = new NonBlockingHandoff(recordStreamManager(), nodeLocalProperties()); @@ -754,10 +740,7 @@ public LedgerValidator ledgerValidator() { public InHandleActivationHelper activationHelper() { if (activationHelper == null) { - activationHelper = new InHandleActivationHelper( - backedKeyOrder(), - characteristics(), - txnCtx()::accessor); + activationHelper = new InHandleActivationHelper(characteristics(), txnCtx()::accessor); } return activationHelper; } @@ -1172,7 +1155,8 @@ public PrecheckVerifier precheckVerifier() { if (precheckVerifier == null) { Predicate isQueryPayment = queryPaymentTestFor(effectiveNodeAccount()); PrecheckKeyReqs reqs = new PrecheckKeyReqs(keyOrder(), lookupRetryingKeyOrder(), isQueryPayment); - precheckVerifier = new PrecheckVerifier(syncVerifier(), reqs, DefaultSigBytesProvider.DEFAULT_SIG_BYTES); + precheckVerifier = new PrecheckVerifier( + syncVerifier(), reqs, accessor -> new SigMapPubKeyToSigBytes(accessor.getSigMap())); } return precheckVerifier; } @@ -2124,10 +2108,6 @@ public void setScheduleStore(ScheduleStore scheduleStore) { this.scheduleStore = scheduleStore; } - void setSystemExits(SystemExits systemExits) { - this.systemExits = systemExits; - } - private AccountID effectiveNodeAccount() { final var info = nodeInfo(); /* If we do not have a self account, we must be zero-stake and will never process a query payment. */ diff --git a/hedera-node/src/main/java/com/hedera/services/contracts/execution/TxnAwareSoliditySigsVerifier.java b/hedera-node/src/main/java/com/hedera/services/contracts/execution/TxnAwareSoliditySigsVerifier.java index 56046255b943..79cbb7b8dd5f 100644 --- a/hedera-node/src/main/java/com/hedera/services/contracts/execution/TxnAwareSoliditySigsVerifier.java +++ b/hedera-node/src/main/java/com/hedera/services/contracts/execution/TxnAwareSoliditySigsVerifier.java @@ -26,6 +26,7 @@ import com.hedera.services.legacy.core.jproto.JKey; import com.hedera.services.sigs.PlatformSigOps; import com.hedera.services.sigs.factories.BodySigningSigFactory; +import com.hedera.services.sigs.sourcing.SigMapPubKeyToSigBytes; import com.hedera.services.sigs.verification.SyncVerifier; import com.hedera.services.state.merkle.MerkleAccount; import com.hedera.services.state.merkle.MerkleEntityId; @@ -39,7 +40,6 @@ import static com.hedera.services.keys.HederaKeyActivation.ONLY_IF_SIG_IS_VALID; import static com.hedera.services.keys.HederaKeyActivation.isActive; -import static com.hedera.services.sigs.sourcing.DefaultSigBytesProvider.DEFAULT_SIG_BYTES; import static com.hedera.services.state.merkle.MerkleEntityId.fromAccountId; import static java.util.stream.Collectors.toList; @@ -71,12 +71,13 @@ public boolean allRequiredKeysAreActive(Set touched) { if (requiredKeys.isEmpty()) { return true; } else { + final var accessor = txnCtx.accessor(); return check.allKeysAreActive( requiredKeys, syncVerifier, - txnCtx.accessor(), + accessor, PlatformSigOps::createEd25519PlatformSigsFrom, - DEFAULT_SIG_BYTES::allPartiesSigBytesFor, + new SigMapPubKeyToSigBytes(accessor.getSigMap()), BodySigningSigFactory::new, (key, sigsFn) -> isActive(key, sigsFn, ONLY_IF_SIG_IS_VALID), HederaKeyActivation::pkToSigMapFrom); diff --git a/hedera-node/src/main/java/com/hedera/services/keys/HederaKeyActivation.java b/hedera-node/src/main/java/com/hedera/services/keys/HederaKeyActivation.java index ec34949cef76..86e7879fc6b0 100644 --- a/hedera-node/src/main/java/com/hedera/services/keys/HederaKeyActivation.java +++ b/hedera-node/src/main/java/com/hedera/services/keys/HederaKeyActivation.java @@ -23,10 +23,6 @@ import com.hedera.services.legacy.core.jproto.JKey; import com.hedera.services.legacy.core.jproto.JKeyList; import com.hedera.services.legacy.core.jproto.JThresholdKey; -import com.hedera.services.legacy.crypto.SignatureStatus; -import com.hedera.services.sigs.order.HederaSigningOrder; -import com.hedera.services.sigs.order.SigningOrderResult; -import com.hedera.services.sigs.order.SigningOrderResultFactory; import com.hedera.services.utils.TxnAccessor; import com.swirlds.common.crypto.TransactionSignature; import com.swirlds.common.crypto.VerificationStatus; @@ -62,21 +58,19 @@ private HederaKeyActivation(){ * taken together, activate the payer's Hedera key. * * @param accessor the txn to evaluate. - * @param keyOrder a resource to determine the payer's Hedera key. - * @param summaryFactory a resource to summarize the result of the key determination. - * @return whether the payer's Hedera key is active. + * @return whether the payer's Hedera key is active */ - public static boolean payerSigIsActive( - TxnAccessor accessor, - HederaSigningOrder keyOrder, - SigningOrderResultFactory summaryFactory - ) { - SigningOrderResult payerSummary = keyOrder.keysForPayer(accessor.getTxn(), summaryFactory); + public static boolean payerSigIsActive(TxnAccessor accessor) { + final var sigMeta = accessor.getSigMeta(); + + if (sigMeta == null) { + throw new IllegalArgumentException("Cannot test payer sig activation without rationalized sig meta"); + } + if (!sigMeta.couldRationalizePayer()) { + return false; + } - return isActive( - payerSummary.getPayerKey(), - pkToSigMapFrom(accessor.getPlatformTxn().getSignatures()), - ONLY_IF_SIG_IS_VALID); + return isActive(sigMeta.payerKey(), sigMeta.pkToVerifiedSigFn(), ONLY_IF_SIG_IS_VALID); } /** diff --git a/hedera-node/src/main/java/com/hedera/services/keys/InHandleActivationHelper.java b/hedera-node/src/main/java/com/hedera/services/keys/InHandleActivationHelper.java index 588aee0edad5..1495b7b853c8 100644 --- a/hedera-node/src/main/java/com/hedera/services/keys/InHandleActivationHelper.java +++ b/hedera-node/src/main/java/com/hedera/services/keys/InHandleActivationHelper.java @@ -21,12 +21,9 @@ */ import com.hedera.services.legacy.core.jproto.JKey; -import com.hedera.services.sigs.order.HederaSigningOrder; import com.hedera.services.utils.TxnAccessor; import com.hederahashgraph.api.proto.java.TransactionBody; import com.swirlds.common.crypto.TransactionSignature; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; import java.util.Collections; import java.util.List; @@ -36,7 +33,6 @@ import java.util.function.Supplier; import static com.hedera.services.keys.HederaKeyTraversal.visitSimpleKeys; -import static com.hedera.services.sigs.Rationalization.IN_HANDLE_SUMMARY_FACTORY; /** * Provides information about the Ed25519 keys that compose the Hedera keys @@ -49,18 +45,12 @@ * @author Michael Tinker */ public class InHandleActivationHelper { - private static final Logger log = LogManager.getLogger(InHandleActivationHelper.class); - private static final List NO_OTHER_PARTIES = null; private static final TxnAccessor NO_LAST_ACCESSOR = null; private static final Function NO_LAST_SIGS_FN = null; static Activation activation = HederaKeyActivation::isActive; - static Function< - List, - Function> sigsFnSource = HederaKeyActivation::pkToSigMapFrom; - private final HederaSigningOrder keyOrderer; private final CharacteristicsFactory characteristics; private final Supplier accessorSource; @@ -68,17 +58,11 @@ public class InHandleActivationHelper { private TxnAccessor accessor = NO_LAST_ACCESSOR; private Function sigsFn = NO_LAST_SIGS_FN; - public InHandleActivationHelper( - HederaSigningOrder keyOrderer, - CharacteristicsFactory characteristics, - Supplier accessorSource - ) { - this.keyOrderer = keyOrderer; + public InHandleActivationHelper(CharacteristicsFactory characteristics, Supplier accessorSource) { this.characteristics = characteristics; this.accessorSource = accessorSource; } - /** * Returns true if the set of Ed25519 signing keys for the active transaction * suffice to meet the signing requirements of all Hedera keys prerequisite @@ -150,16 +134,13 @@ private boolean arePartiesActive( private void ensureUpToDate() { var current = accessorSource.get(); if (accessor != current) { - var otherOrderingResult = keyOrderer.keysForOtherParties(current.getTxn(), IN_HANDLE_SUMMARY_FACTORY); - if (otherOrderingResult.hasErrorReport()) { - var errorReport = otherOrderingResult.getErrorReport(); - log.debug("Allowing active other-party sigs: {} ({})!", errorReport, errorReport.getResponseCode()); - otherParties = Collections.emptyList(); + final var sigMeta = current.getSigMeta(); + if (sigMeta.couldRationalizeOthers()) { + otherParties = sigMeta.othersReqSigs(); } else { - otherParties = otherOrderingResult.getOrderedKeys(); + otherParties = Collections.emptyList(); } - var sigs = current.getPlatformTxn().getSignatures(); - sigsFn = sigsFnSource.apply(sigs); + sigsFn = sigMeta.pkToVerifiedSigFn(); accessor = current; } } diff --git a/hedera-node/src/main/java/com/hedera/services/keys/StandardSyncActivationCheck.java b/hedera-node/src/main/java/com/hedera/services/keys/StandardSyncActivationCheck.java index ce2671e12f90..cd3d8919f772 100644 --- a/hedera-node/src/main/java/com/hedera/services/keys/StandardSyncActivationCheck.java +++ b/hedera-node/src/main/java/com/hedera/services/keys/StandardSyncActivationCheck.java @@ -26,7 +26,6 @@ import com.hedera.services.sigs.sourcing.PubKeyToSigBytes; import com.hedera.services.sigs.verification.SyncVerifier; import com.hedera.services.utils.TxnAccessor; -import com.hederahashgraph.api.proto.java.Transaction; import com.swirlds.common.crypto.TransactionSignature; import java.util.List; @@ -39,13 +38,12 @@ public static boolean allKeysAreActive( SyncVerifier syncVerifier, TxnAccessor accessor, PlatformSigsFactory sigsFactory, - Function sigBytesProvider, + PubKeyToSigBytes sigBytes, Function scopedSigProvider, BiPredicate> isActive, Function, Function> sigsFnProvider ) { var sigFactory = scopedSigProvider.apply(accessor); - var sigBytes = sigBytesProvider.apply(accessor.getSignedTxnWrapper()); var creationResult = sigsFactory.createEd25519From(keys, sigBytes, sigFactory); if (creationResult.hasFailed()) { diff --git a/hedera-node/src/main/java/com/hedera/services/keys/SyncActivationCheck.java b/hedera-node/src/main/java/com/hedera/services/keys/SyncActivationCheck.java index 0c55478cdf41..54bf111542cc 100644 --- a/hedera-node/src/main/java/com/hedera/services/keys/SyncActivationCheck.java +++ b/hedera-node/src/main/java/com/hedera/services/keys/SyncActivationCheck.java @@ -26,7 +26,6 @@ import com.hedera.services.sigs.sourcing.PubKeyToSigBytes; import com.hedera.services.sigs.verification.SyncVerifier; import com.hedera.services.utils.TxnAccessor; -import com.hederahashgraph.api.proto.java.Transaction; import com.swirlds.common.crypto.TransactionSignature; import java.util.List; @@ -40,7 +39,7 @@ boolean allKeysAreActive( SyncVerifier syncVerifier, TxnAccessor accessor, PlatformSigsFactory sigsFactory, - Function sigBytesProvider, + PubKeyToSigBytes pkToSigFn, Function scopedSigProvider, BiPredicate> isActive, Function, Function> sigsFnProvider); diff --git a/hedera-node/src/main/java/com/hedera/services/legacy/services/state/AwareProcessLogic.java b/hedera-node/src/main/java/com/hedera/services/legacy/services/state/AwareProcessLogic.java index 20d7062db1cf..189accdfcb2d 100644 --- a/hedera-node/src/main/java/com/hedera/services/legacy/services/state/AwareProcessLogic.java +++ b/hedera-node/src/main/java/com/hedera/services/legacy/services/state/AwareProcessLogic.java @@ -23,7 +23,8 @@ import com.google.protobuf.InvalidProtocolBufferException; import com.hedera.services.context.ServicesContext; import com.hedera.services.legacy.crypto.SignatureStatus; -import com.hedera.services.sigs.sourcing.ScopedSigBytesProvider; +import com.hedera.services.sigs.factories.BodySigningSigFactory; +import com.hedera.services.sigs.sourcing.SigMapPubKeyToSigBytes; import com.hedera.services.state.logic.ServicesTxnManager; import com.hedera.services.state.submerkle.ExpirableTxnRecord; import com.hedera.services.stream.RecordStreamObject; @@ -42,7 +43,6 @@ import static com.hedera.services.keys.HederaKeyActivation.payerSigIsActive; import static com.hedera.services.legacy.crypto.SignatureStatusCode.SUCCESS_VERIFY_ASYNC; import static com.hedera.services.sigs.HederaToPlatformSigOps.rationalizeIn; -import static com.hedera.services.sigs.Rationalization.IN_HANDLE_SUMMARY_FACTORY; import static com.hederahashgraph.api.proto.java.ResponseCodeEnum.FAIL_INVALID; import static com.hederahashgraph.api.proto.java.ResponseCodeEnum.INVALID_ACCOUNT_ID; import static com.hederahashgraph.api.proto.java.ResponseCodeEnum.INVALID_CONTRACT_ID; @@ -200,7 +200,7 @@ private void process(TxnAccessor accessor) { private boolean hasActivePayerSig(TxnAccessor accessor) { try { - return payerSigIsActive(accessor, ctx.backedKeyOrder(), IN_HANDLE_SUMMARY_FACTORY); + return payerSigIsActive(accessor); } catch (Exception edgeCase) { log.warn("Almost inconceivably, when testing payer sig activation:", edgeCase); } @@ -208,13 +208,12 @@ private boolean hasActivePayerSig(TxnAccessor accessor) { } private SignatureStatus rationalizeWithPreConsensusSigs(TxnAccessor accessor) { - var sigProvider = new ScopedSigBytesProvider(accessor); var sigStatus = rationalizeIn( accessor, ctx.syncVerifier(), ctx.backedKeyOrder(), - sigProvider, - ctx.sigFactoryCreator()::createScopedFactory); + new SigMapPubKeyToSigBytes(accessor.getSigMap()), + new BodySigningSigFactory(accessor)); if (!sigStatus.isError()) { if (sigStatus.getStatusCode() == SUCCESS_VERIFY_ASYNC) { ctx.speedometers().cycleAsyncVerifications(); diff --git a/hedera-node/src/main/java/com/hedera/services/sigs/Expansion.java b/hedera-node/src/main/java/com/hedera/services/sigs/Expansion.java index 4b42f0da1f1c..0ccc0a2d4695 100644 --- a/hedera-node/src/main/java/com/hedera/services/sigs/Expansion.java +++ b/hedera-node/src/main/java/com/hedera/services/sigs/Expansion.java @@ -9,9 +9,9 @@ * 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. @@ -26,17 +26,13 @@ import com.hedera.services.sigs.order.SigStatusOrderResultFactory; import com.hedera.services.sigs.order.SigningOrderResult; import com.hedera.services.sigs.sourcing.PubKeyToSigBytes; -import com.hedera.services.sigs.sourcing.PubKeyToSigBytesProvider; import com.hedera.services.utils.PlatformTxnAccessor; -import com.hedera.services.utils.SignedTxnAccessor; -import com.hederahashgraph.api.proto.java.Transaction; import com.hederahashgraph.api.proto.java.TransactionBody; import com.swirlds.common.crypto.TransactionSignature; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import java.util.function.BiFunction; -import java.util.function.Function; import static com.hedera.services.legacy.crypto.SignatureStatusCode.SUCCESS; import static com.hedera.services.sigs.PlatformSigOps.createEd25519PlatformSigsFrom; @@ -45,28 +41,27 @@ class Expansion { private static final Logger log = LogManager.getLogger(Expansion.class); - private final PlatformTxnAccessor txnAccessor; + private final PubKeyToSigBytes pkToSigFn; private final HederaSigningOrder keyOrderer; - private final PubKeyToSigBytesProvider sigsProvider; + private final PlatformTxnAccessor txnAccessor; private final TxnScopedPlatformSigFactory sigFactory; public Expansion( PlatformTxnAccessor txnAccessor, HederaSigningOrder keyOrderer, - PubKeyToSigBytesProvider sigsProvider, - Function sigFactoryCreator + PubKeyToSigBytes pkToSigFn, + TxnScopedPlatformSigFactory sigFactory ) { this.txnAccessor = txnAccessor; + this.sigFactory = sigFactory; this.keyOrderer = keyOrderer; - this.sigsProvider = sigsProvider; - - sigFactory = sigFactoryCreator.apply(txnAccessor); + this.pkToSigFn = pkToSigFn; } public SignatureStatus execute() { log.debug("Expanding crypto sigs from Hedera sigs for txn {}...", txnAccessor::getSignedTxnWrapper); - var payerStatus = expand(sigsProvider::payerSigBytesFor, keyOrderer::keysForPayer); - if ( SUCCESS != payerStatus.getStatusCode() ) { + var payerStatus = expand(pkToSigFn, keyOrderer::keysForPayer); + if (SUCCESS != payerStatus.getStatusCode()) { if (log.isDebugEnabled()) { log.debug( "Failed expanding Hedera payer sigs for txn {}: {}", @@ -75,8 +70,8 @@ public SignatureStatus execute() { } return payerStatus; } - var otherStatus = expand(sigsProvider::otherPartiesSigBytesFor, keyOrderer::keysForOtherParties); - if ( SUCCESS != otherStatus.getStatusCode() ) { + var otherStatus = expand(pkToSigFn, keyOrderer::keysForOtherParties); + if (SUCCESS != otherStatus.getStatusCode()) { if (log.isDebugEnabled()) { log.debug( "Failed expanding other Hedera sigs for txn {}: {}", @@ -88,7 +83,7 @@ public SignatureStatus execute() { } private SignatureStatus expand( - Function sigsFn, + PubKeyToSigBytes pkToSigFn, BiFunction> keysFn ) { var orderResult = keysFn.apply(txnAccessor.getTxn(), HederaToPlatformSigOps.PRE_HANDLE_SUMMARY_FACTORY); @@ -96,8 +91,7 @@ private SignatureStatus expand( return orderResult.getErrorReport(); } - var creationResult = createEd25519PlatformSigsFrom( - orderResult.getOrderedKeys(), sigsFn.apply(txnAccessor.getSignedTxnWrapper()), sigFactory); + var creationResult = createEd25519PlatformSigsFrom(orderResult.getOrderedKeys(), pkToSigFn, sigFactory); if (!creationResult.hasFailed()) { txnAccessor.getPlatformTxn().addAll(creationResult.getPlatformSigs().toArray(new TransactionSignature[0])); } diff --git a/hedera-node/src/main/java/com/hedera/services/sigs/HederaToPlatformSigOps.java b/hedera-node/src/main/java/com/hedera/services/sigs/HederaToPlatformSigOps.java index 4e45fcb6f58f..90be3398d445 100644 --- a/hedera-node/src/main/java/com/hedera/services/sigs/HederaToPlatformSigOps.java +++ b/hedera-node/src/main/java/com/hedera/services/sigs/HederaToPlatformSigOps.java @@ -22,20 +22,18 @@ import com.hedera.services.legacy.core.jproto.JKey; import com.hedera.services.legacy.crypto.SignatureStatus; +import com.hedera.services.sigs.factories.BodySigningSigFactory; import com.hedera.services.sigs.factories.TxnScopedPlatformSigFactory; import com.hedera.services.sigs.order.HederaSigningOrder; import com.hedera.services.sigs.order.SigStatusOrderResultFactory; -import com.hedera.services.sigs.sourcing.PubKeyToSigBytesProvider; +import com.hedera.services.sigs.sourcing.PubKeyToSigBytes; import com.hedera.services.sigs.verification.SyncVerifier; import com.hedera.services.utils.PlatformTxnAccessor; -import com.hedera.services.utils.SignedTxnAccessor; import com.hedera.services.utils.TxnAccessor; import com.hederahashgraph.api.proto.java.Transaction; import com.swirlds.common.crypto.Signature; import com.swirlds.common.crypto.VerificationStatus; -import java.util.function.Function; - /** * Provides two operations that act in-place on the {@link Signature} list of a * {@link com.swirlds.common.Transaction} whose contents are known to be a valid @@ -85,20 +83,19 @@ public class HederaToPlatformSigOps { * it silently. * * - * @param txnAccessor the accessor for the platform txn. - * @param keyOrderer facility for listing Hedera keys required to sign the gRPC txn. - * @param sigsProvider source of crypto sigs for the simple keys in the Hedera key leaves. - * @return a representation of the outcome. + * @param txnAccessor the accessor for the platform txn + * @param keyOrderer facility for listing Hedera keys required to sign the gRPC txn + * @param pkToSigFn source of crypto sigs for the simple keys in the Hedera key leaves + * @return a representation of the outcome */ public static SignatureStatus expandIn( PlatformTxnAccessor txnAccessor, HederaSigningOrder keyOrderer, - PubKeyToSigBytesProvider sigsProvider, - Function sigFactoryCreator + PubKeyToSigBytes pkToSigFn ) { txnAccessor.getPlatformTxn().clear(); - return new Expansion(txnAccessor, keyOrderer, sigsProvider, sigFactoryCreator).execute(); + return new Expansion(txnAccessor, keyOrderer, pkToSigFn, new BodySigningSigFactory(txnAccessor)).execute(); } /** @@ -119,24 +116,25 @@ public static SignatureStatus expandIn( * processing and return a {@link SignatureStatus} representing this error. * * - * @param txnAccessor the accessor for the platform txn. - * @param syncVerifier facility for synchronously verifying a cryptographic signature. - * @param keyOrderer facility for listing Hedera keys required to sign the gRPC txn. - * @param sigsProvider source of crypto sigs for the simple keys in the Hedera key leaves. + * @param txnAccessor the accessor for the platform txn + * @param syncVerifier facility for synchronously verifying a cryptographic signature + * @param keyOrderer facility for listing Hedera keys required to sign the gRPC txn + * @param pkToSigFnProvider source of crypto sigs for the simple keys in the Hedera key leaves + * @param sigFactoryCreator source of Platform sigs scoped to the active txn * @return a representation of the outcome. */ public static SignatureStatus rationalizeIn( TxnAccessor txnAccessor, SyncVerifier syncVerifier, HederaSigningOrder keyOrderer, - PubKeyToSigBytesProvider sigsProvider, - Function sigFactoryCreator + PubKeyToSigBytes pkToSigFnProvider, + TxnScopedPlatformSigFactory sigFactoryCreator ) { return new Rationalization( txnAccessor, syncVerifier, keyOrderer, - sigsProvider, + pkToSigFnProvider, sigFactoryCreator ).execute(); } diff --git a/hedera-node/src/main/java/com/hedera/services/sigs/PlatformSigOps.java b/hedera-node/src/main/java/com/hedera/services/sigs/PlatformSigOps.java index 1fc119e4a826..5e6dfe7e5814 100644 --- a/hedera-node/src/main/java/com/hedera/services/sigs/PlatformSigOps.java +++ b/hedera-node/src/main/java/com/hedera/services/sigs/PlatformSigOps.java @@ -73,11 +73,10 @@ private static void createPlatformSigFor( } try { - var sigBytes = sigBytesFn.sigBytesFor(ed25519Key.getEd25519()); + final var keyBytes = ed25519Key.getEd25519(); + final var sigBytes = sigBytesFn.sigBytesFor(keyBytes); if (sigBytes.length > 0) { - var sig = copyFrom(sigBytes); - var cryptoKey = copyFrom(ed25519Key.getEd25519()); - result.getPlatformSigs().add(factory.create(cryptoKey, sig)); + result.getPlatformSigs().add(factory.create(keyBytes, sigBytes)); } } catch (KeyPrefixMismatchException kmpe) { /* Nbd if a signature map is ambiguous for a key linked to a scheduled transaction. */ diff --git a/hedera-node/src/main/java/com/hedera/services/sigs/Rationalization.java b/hedera-node/src/main/java/com/hedera/services/sigs/Rationalization.java index c7c26c61a301..27f0f56f1160 100644 --- a/hedera-node/src/main/java/com/hedera/services/sigs/Rationalization.java +++ b/hedera-node/src/main/java/com/hedera/services/sigs/Rationalization.java @@ -20,6 +20,7 @@ * ‍ */ +import com.hedera.services.legacy.core.jproto.JKey; import com.hedera.services.legacy.crypto.SignatureStatus; import com.hedera.services.legacy.crypto.SignatureStatusCode; import com.hedera.services.sigs.factories.TxnScopedPlatformSigFactory; @@ -27,20 +28,16 @@ import com.hedera.services.sigs.order.SigStatusOrderResultFactory; import com.hedera.services.sigs.order.SigningOrderResult; import com.hedera.services.sigs.sourcing.PubKeyToSigBytes; -import com.hedera.services.sigs.sourcing.PubKeyToSigBytesProvider; import com.hedera.services.sigs.verification.SyncVerifier; +import com.hedera.services.utils.RationalizedSigMeta; import com.hedera.services.utils.TxnAccessor; import com.hederahashgraph.api.proto.java.ResponseCodeEnum; -import com.hederahashgraph.api.proto.java.Transaction; import com.hederahashgraph.api.proto.java.TransactionBody; import com.swirlds.common.crypto.TransactionSignature; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; import java.util.ArrayList; import java.util.List; import java.util.function.BiFunction; -import java.util.function.Function; import static com.hedera.services.legacy.crypto.SignatureStatusCode.SUCCESS; import static com.hedera.services.sigs.PlatformSigOps.createEd25519PlatformSigsFrom; @@ -49,60 +46,79 @@ import static com.swirlds.common.crypto.VerificationStatus.UNKNOWN; public class Rationalization { - private static final Logger log = LogManager.getLogger(Rationalization.class); - public final static SigStatusOrderResultFactory IN_HANDLE_SUMMARY_FACTORY = new SigStatusOrderResultFactory(true); - private final SyncVerifier syncVerifier; - private final List txnSigs; private final TxnAccessor txnAccessor; + private final SyncVerifier syncVerifier; + private final PubKeyToSigBytes pkToSigFn; private final HederaSigningOrder keyOrderer; - private final PubKeyToSigBytesProvider sigsProvider; private final TxnScopedPlatformSigFactory sigFactory; + private JKey reqPayerSig = null; + private List reqOthersSigs = null; + private List txnSigs; + private SigningOrderResult lastOrderResult; + public Rationalization( TxnAccessor txnAccessor, SyncVerifier syncVerifier, HederaSigningOrder keyOrderer, - PubKeyToSigBytesProvider sigsProvider, - Function sigFactoryCreator + PubKeyToSigBytes pkToSigFn, + TxnScopedPlatformSigFactory sigFactory ) { + this.pkToSigFn = pkToSigFn; + this.keyOrderer = keyOrderer; + this.sigFactory = sigFactory; this.txnAccessor = txnAccessor; this.syncVerifier = syncVerifier; - this.keyOrderer = keyOrderer; - this.sigsProvider = sigsProvider; txnSigs = txnAccessor.getPlatformTxn().getSignatures(); - sigFactory = sigFactoryCreator.apply(txnAccessor); } public SignatureStatus execute() { + var verifiedSync = false; + SignatureStatus otherFailure = null; List realPayerSigs = new ArrayList<>(), realOtherPartySigs = new ArrayList<>(); - var payerStatus = expandIn( - realPayerSigs, sigsProvider::payerSigBytesFor, keyOrderer::keysForPayer); + final var payerStatus = expandIn(realPayerSigs, keyOrderer::keysForPayer); if (!SUCCESS.equals(payerStatus.getStatusCode())) { + txnAccessor.setSigMeta(RationalizedSigMeta.noneAvailable()); return payerStatus; } - var otherPartiesStatus = expandIn( - realOtherPartySigs, sigsProvider::otherPartiesSigBytesFor, keyOrderer::keysForOtherParties); + reqPayerSig = lastOrderResult.getPayerKey(); + + final var otherPartiesStatus = expandIn(realOtherPartySigs, keyOrderer::keysForOtherParties); if (!SUCCESS.equals(otherPartiesStatus.getStatusCode())) { - return otherPartiesStatus; + otherFailure = otherPartiesStatus; + } else { + reqOthersSigs = lastOrderResult.getOrderedKeys(); } - var rationalizedPayerSigs = rationalize(realPayerSigs, 0); - var rationalizedOtherPartySigs = rationalize(realOtherPartySigs, realPayerSigs.size()); - + final var rationalizedPayerSigs = rationalize(realPayerSigs, 0); + final var rationalizedOtherPartySigs = rationalize(realOtherPartySigs, realPayerSigs.size()); if (rationalizedPayerSigs == realPayerSigs || rationalizedOtherPartySigs == realOtherPartySigs) { - txnAccessor.getPlatformTxn().clear(); - txnAccessor.getPlatformTxn().addAll(rationalizedPayerSigs.toArray(new TransactionSignature[0])); - txnAccessor.getPlatformTxn().addAll(rationalizedOtherPartySigs.toArray(new TransactionSignature[0])); - log.warn("Verified crypto sigs synchronously for txn {}", txnAccessor.getSignedTxnWrapper()); - return syncSuccess(); + txnSigs = new ArrayList<>(); + txnSigs.addAll(rationalizedPayerSigs); + txnSigs.addAll(rationalizedOtherPartySigs); + verifiedSync = true; + } + + makeRationalizedMetaAccessible(); + + if (otherFailure != null) { + return otherFailure; + } else { + return verifiedSync ? syncSuccess() : asyncSuccess(); } + } - return asyncSuccess(); + private void makeRationalizedMetaAccessible() { + if (reqOthersSigs == null) { + txnAccessor.setSigMeta(RationalizedSigMeta.forPayerOnly(reqPayerSig, txnSigs)); + } else { + txnAccessor.setSigMeta(RationalizedSigMeta.forPayerAndOthers(reqPayerSig, reqOthersSigs, txnSigs)); + } } private List rationalize(List realSigs, int startingAt) { @@ -129,20 +145,17 @@ private boolean allStatusesAreKnown(List sigs) { private SignatureStatus expandIn( List target, - Function sigsFn, BiFunction> keysFn ) { - SigningOrderResult orderResult = - keysFn.apply(txnAccessor.getTxn(), IN_HANDLE_SUMMARY_FACTORY); - if (orderResult.hasErrorReport()) { - return orderResult.getErrorReport(); + lastOrderResult = keysFn.apply(txnAccessor.getTxn(), IN_HANDLE_SUMMARY_FACTORY); + if (lastOrderResult.hasErrorReport()) { + return lastOrderResult.getErrorReport(); } - PlatformSigsCreationResult creationResult = createEd25519PlatformSigsFrom( - orderResult.getOrderedKeys(), sigsFn.apply(txnAccessor.getSignedTxnWrapper()), sigFactory); - if (creationResult.hasFailed()) { - return creationResult.asSignatureStatus(true, txnAccessor.getTxnId()); + final var creation = createEd25519PlatformSigsFrom(lastOrderResult.getOrderedKeys(), pkToSigFn, sigFactory); + if (creation.hasFailed()) { + return creation.asSignatureStatus(true, txnAccessor.getTxnId()); } - target.addAll(creationResult.getPlatformSigs()); + target.addAll(creation.getPlatformSigs()); return successFor(true, txnAccessor); } @@ -157,7 +170,7 @@ private SignatureStatus asyncSuccess() { private SignatureStatus success(SignatureStatusCode code) { return new SignatureStatus( code, ResponseCodeEnum.OK, - true, txnAccessor.getTxn().getTransactionID(), + true, txnAccessor.getTxnId(), null, null, null, null); } } diff --git a/hedera-node/src/main/java/com/hedera/services/sigs/factories/BodySigningSigFactory.java b/hedera-node/src/main/java/com/hedera/services/sigs/factories/BodySigningSigFactory.java index 04d047f6e836..91632e2d8121 100644 --- a/hedera-node/src/main/java/com/hedera/services/sigs/factories/BodySigningSigFactory.java +++ b/hedera-node/src/main/java/com/hedera/services/sigs/factories/BodySigningSigFactory.java @@ -20,7 +20,6 @@ * ‍ */ -import com.google.protobuf.ByteString; import com.hedera.services.utils.TxnAccessor; import com.swirlds.common.crypto.TransactionSignature; @@ -39,10 +38,7 @@ public BodySigningSigFactory(TxnAccessor accessor) { } @Override - public TransactionSignature create(ByteString publicKey, ByteString sigBytes) { - return PlatformSigFactory.createEd25519( - publicKey.toByteArray(), - sigBytes.toByteArray(), - accessor.getTxnBytes()); + public TransactionSignature create(byte[] publicKey, byte[] sigBytes) { + return PlatformSigFactory.createEd25519(publicKey, sigBytes, accessor.getTxnBytes()); } } diff --git a/hedera-node/src/main/java/com/hedera/services/sigs/factories/SigFactoryCreator.java b/hedera-node/src/main/java/com/hedera/services/sigs/factories/SigFactoryCreator.java deleted file mode 100644 index 5bc66c3932e8..000000000000 --- a/hedera-node/src/main/java/com/hedera/services/sigs/factories/SigFactoryCreator.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.hedera.services.sigs.factories; - -/*- - * ‌ - * Hedera Services Node - * ​ - * Copyright (C) 2018 - 2021 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. - * ‍ - */ - -import com.hedera.services.utils.TxnAccessor; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -public class SigFactoryCreator { - private static final Logger log = LogManager.getLogger(SigFactoryCreator.class); - - public TxnScopedPlatformSigFactory createScopedFactory(TxnAccessor accessor) { - return new BodySigningSigFactory(accessor); - } -} diff --git a/hedera-node/src/main/java/com/hedera/services/sigs/factories/TxnScopedPlatformSigFactory.java b/hedera-node/src/main/java/com/hedera/services/sigs/factories/TxnScopedPlatformSigFactory.java index f9859431fa75..82396e8ec946 100644 --- a/hedera-node/src/main/java/com/hedera/services/sigs/factories/TxnScopedPlatformSigFactory.java +++ b/hedera-node/src/main/java/com/hedera/services/sigs/factories/TxnScopedPlatformSigFactory.java @@ -20,7 +20,6 @@ * ‍ */ -import com.google.protobuf.ByteString; import com.swirlds.common.crypto.TransactionSignature; /** @@ -39,5 +38,5 @@ public interface TxnScopedPlatformSigFactory { * the cryptographic signature to use in creating the platform sig. * @return a platform sig for the scoped transaction. */ - TransactionSignature create(ByteString publicKey, ByteString sigBytes); + TransactionSignature create(byte[] publicKey, byte[] sigBytes); } diff --git a/hedera-node/src/main/java/com/hedera/services/sigs/order/SigningOrderResult.java b/hedera-node/src/main/java/com/hedera/services/sigs/order/SigningOrderResult.java index 98b7bf43d144..00eee8238304 100644 --- a/hedera-node/src/main/java/com/hedera/services/sigs/order/SigningOrderResult.java +++ b/hedera-node/src/main/java/com/hedera/services/sigs/order/SigningOrderResult.java @@ -61,7 +61,7 @@ public SigningOrderResult(List orderedKeys, Optional errorReport) { } public boolean hasKnownOrder() { - return !errorReport.isPresent(); + return errorReport.isEmpty(); } public boolean hasErrorReport() { diff --git a/hedera-node/src/main/java/com/hedera/services/sigs/sourcing/DefaultSigBytesProvider.java b/hedera-node/src/main/java/com/hedera/services/sigs/sourcing/DefaultSigBytesProvider.java deleted file mode 100644 index 9d37617bcb09..000000000000 --- a/hedera-node/src/main/java/com/hedera/services/sigs/sourcing/DefaultSigBytesProvider.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.hedera.services.sigs.sourcing; - -/*- - * ‌ - * Hedera Services Node - * ​ - * Copyright (C) 2018 - 2021 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. - * ‍ - */ - -import com.hederahashgraph.api.proto.java.Transaction; - -/** - * Convenience implementation of {@link PubKeyToSigBytesProvider}. - * - * @author Michael Tinker - */ -public enum DefaultSigBytesProvider implements PubKeyToSigBytesProvider { - DEFAULT_SIG_BYTES; - - @Override - public PubKeyToSigBytes payerSigBytesFor(Transaction signedTxn) { - return PubKeyToSigBytes.forPayer(signedTxn); - } - - @Override - public PubKeyToSigBytes otherPartiesSigBytesFor(Transaction signedTxn) { - return PubKeyToSigBytes.forOtherParties(signedTxn); - } - - @Override - public PubKeyToSigBytes allPartiesSigBytesFor(Transaction signedTxn) { - return PubKeyToSigBytes.forAllParties(signedTxn); - } -} diff --git a/hedera-node/src/main/java/com/hedera/services/sigs/sourcing/PubKeyToSigBytes.java b/hedera-node/src/main/java/com/hedera/services/sigs/sourcing/PubKeyToSigBytes.java index 078f455ace90..548c0e1cbe48 100644 --- a/hedera-node/src/main/java/com/hedera/services/sigs/sourcing/PubKeyToSigBytes.java +++ b/hedera-node/src/main/java/com/hedera/services/sigs/sourcing/PubKeyToSigBytes.java @@ -21,9 +21,6 @@ */ import com.hederahashgraph.api.proto.java.SignatureMap; -import com.hederahashgraph.api.proto.java.Transaction; - -import static com.hedera.services.legacy.proto.utils.CommonUtils.extractSignatureMapOrUseDefault; /** * Defines a type that is a source of the cryptographic signatures associated to @@ -54,49 +51,4 @@ public interface PubKeyToSigBytes { * @throws Exception if the desired cryptographic signature is unavailable. */ byte[] sigBytesFor(byte[] pubKey) throws Exception; - - /** - * Create a {@code PubKeyToSigBytes} implementation backed by the given map. - * - * @param sigMap a list of public-key-to-cryptographic-signature map entries. - * @return a source of raw signatures that encapsulates this mapping. - */ - static PubKeyToSigBytes from(SignatureMap sigMap) { - return new SigMapPubKeyToSigBytes(sigMap); - } - - /** - * Create a {@code PubKeyToSigBytes} implementation backed by the cryptographic - * signatures associated to the payer of a given gRPC transaction. - * - * @param signedTxn a gRPC transaction. - * @return a source of the raw signatures associated to the payer for the txn. - */ - static PubKeyToSigBytes forPayer(Transaction signedTxn) { - return from(extractSignatureMapOrUseDefault(signedTxn)); - } - - /** - * Create a {@code PubKeyToSigBytes} implementation backed by the cryptographic - * signatures associated to entities involved in non-payer roles for a given - * gRPC transaction. - * - * @param signedTxn a gRPC transaction. - * @return a source of the raw signatures associated non-payer roles in the txn. - */ - static PubKeyToSigBytes forOtherParties(Transaction signedTxn) { - return forPayer(signedTxn); - } - - /** - * Create a {@code PubKeyToSigBytes} implementation backed by the cryptographic - * signatures associated to entities involved in non-payer roles for a given - * gRPC transaction. - * - * @param signedTxn a gRPC transaction. - * @return a source of the raw signatures associated non-payer roles in the txn. - */ - static PubKeyToSigBytes forAllParties(Transaction signedTxn) { - return forPayer(signedTxn); - } } diff --git a/hedera-node/src/main/java/com/hedera/services/sigs/sourcing/PubKeyToSigBytesProvider.java b/hedera-node/src/main/java/com/hedera/services/sigs/sourcing/PubKeyToSigBytesProvider.java deleted file mode 100644 index 458768dd6ba2..000000000000 --- a/hedera-node/src/main/java/com/hedera/services/sigs/sourcing/PubKeyToSigBytesProvider.java +++ /dev/null @@ -1,58 +0,0 @@ -package com.hedera.services.sigs.sourcing; - -/*- - * ‌ - * Hedera Services Node - * ​ - * Copyright (C) 2018 - 2021 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. - * ‍ - */ - -import com.hederahashgraph.api.proto.java.Transaction; - -/** - * Defines a type that can provide {@link PubKeyToSigBytes} sources scoped - * to entities assuming the payer and non-payer roles in a given transaction. - * - * @author Michael Tinker - */ -public interface PubKeyToSigBytesProvider { - /** - * Get a {@link PubKeyToSigBytes} providing the cryptographic signatures - * for the payer of a given gRPC transaction. - * - * @param signedTxn the txn of interest. - * @return a source of the payer signatures. - */ - PubKeyToSigBytes payerSigBytesFor(Transaction signedTxn); - - /** - * Get a {@link PubKeyToSigBytes} providing the cryptographic signatures - * for entities involved in a non-payer role in a given gRPC transaction. - * - * @param signedTxn the txn of interest. - * @return a source of the signatures for entities in non-payer roles. - */ - PubKeyToSigBytes otherPartiesSigBytesFor(Transaction signedTxn); - - /** - * Get a {@link PubKeyToSigBytes} providing the cryptographic signatures - * for all entities involved in a given gRPC transaction (payer first). - * - * @param signedTxn the txn of interest. - * @return a source of the signatures for entities in all roles. - */ - PubKeyToSigBytes allPartiesSigBytesFor(Transaction signedTxn); -} diff --git a/hedera-node/src/main/java/com/hedera/services/sigs/sourcing/ScopedSigBytesProvider.java b/hedera-node/src/main/java/com/hedera/services/sigs/sourcing/ScopedSigBytesProvider.java deleted file mode 100644 index 7bfa3a3e06a5..000000000000 --- a/hedera-node/src/main/java/com/hedera/services/sigs/sourcing/ScopedSigBytesProvider.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.hedera.services.sigs.sourcing; - -/*- - * ‌ - * Hedera Services Node - * ​ - * Copyright (C) 2018 - 2021 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. - * ‍ - */ - -import com.hedera.services.utils.TxnAccessor; -import com.hederahashgraph.api.proto.java.Transaction; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -public class ScopedSigBytesProvider implements PubKeyToSigBytesProvider { - private static final Logger log = LogManager.getLogger(ScopedSigBytesProvider.class); - - final PubKeyToSigBytes delegate; - - public ScopedSigBytesProvider(TxnAccessor accessor) { - delegate = new SigMapPubKeyToSigBytes(accessor.getSigMap()); - } - - @Override - public PubKeyToSigBytes payerSigBytesFor(Transaction ignore) { - return delegate; - } - - @Override - public PubKeyToSigBytes otherPartiesSigBytesFor(Transaction ignore) { - return delegate; - } - - @Override - public PubKeyToSigBytes allPartiesSigBytesFor(Transaction ignore) { - return delegate; - } -} diff --git a/hedera-node/src/main/java/com/hedera/services/sigs/sourcing/SigMapPubKeyToSigBytes.java b/hedera-node/src/main/java/com/hedera/services/sigs/sourcing/SigMapPubKeyToSigBytes.java index 7fb23891ef3a..c79aeaec61ca 100644 --- a/hedera-node/src/main/java/com/hedera/services/sigs/sourcing/SigMapPubKeyToSigBytes.java +++ b/hedera-node/src/main/java/com/hedera/services/sigs/sourcing/SigMapPubKeyToSigBytes.java @@ -45,7 +45,7 @@ public class SigMapPubKeyToSigBytes implements PubKeyToSigBytes { private final SignatureMap sigMap; - SigMapPubKeyToSigBytes(SignatureMap sigMap) { + public SigMapPubKeyToSigBytes(SignatureMap sigMap) { this.sigMap = sigMap; } diff --git a/hedera-node/src/main/java/com/hedera/services/sigs/verification/PrecheckVerifier.java b/hedera-node/src/main/java/com/hedera/services/sigs/verification/PrecheckVerifier.java index 342d3d60ad9b..4529b7ed36ee 100644 --- a/hedera-node/src/main/java/com/hedera/services/sigs/verification/PrecheckVerifier.java +++ b/hedera-node/src/main/java/com/hedera/services/sigs/verification/PrecheckVerifier.java @@ -25,8 +25,8 @@ import com.hedera.services.sigs.factories.BodySigningSigFactory; import com.hedera.services.sigs.factories.TxnScopedPlatformSigFactory; import com.hedera.services.sigs.sourcing.PubKeyToSigBytes; -import com.hedera.services.sigs.sourcing.PubKeyToSigBytesProvider; import com.hedera.services.utils.SignedTxnAccessor; +import com.hedera.services.utils.TxnAccessor; import com.swirlds.common.crypto.TransactionSignature; import java.util.List; @@ -52,16 +52,16 @@ public class PrecheckVerifier { private final SyncVerifier syncVerifier; private final PrecheckKeyReqs precheckKeyReqs; - private final PubKeyToSigBytesProvider provider; + private final Function pkToSigFnProvider; public PrecheckVerifier( SyncVerifier syncVerifier, PrecheckKeyReqs precheckKeyReqs, - PubKeyToSigBytesProvider provider + Function pkToSigFnProvider ) { - this.provider = provider; this.syncVerifier = syncVerifier; this.precheckKeyReqs = precheckKeyReqs; + this.pkToSigFnProvider = pkToSigFnProvider; } /** @@ -86,9 +86,9 @@ public boolean hasNecessarySignatures(SignedTxnAccessor accessor) throws Excepti } private List getAvailSigs(List reqKeys, SignedTxnAccessor accessor) throws Exception { - PubKeyToSigBytes sigBytes = provider.allPartiesSigBytesFor(accessor.getSignedTxnWrapper()); + final var pkToSigFn = pkToSigFnProvider.apply(accessor); TxnScopedPlatformSigFactory sigFactory = new BodySigningSigFactory(accessor); - PlatformSigsCreationResult creationResult = createEd25519PlatformSigsFrom(reqKeys, sigBytes, sigFactory); + PlatformSigsCreationResult creationResult = createEd25519PlatformSigsFrom(reqKeys, pkToSigFn, sigFactory); if (creationResult.hasFailed()) { throw creationResult.getTerminatingEx(); } else { diff --git a/hedera-node/src/main/java/com/hedera/services/utils/PlatformTxnAccessor.java b/hedera-node/src/main/java/com/hedera/services/utils/PlatformTxnAccessor.java index ae3e034fd1ce..b4787db59769 100644 --- a/hedera-node/src/main/java/com/hedera/services/utils/PlatformTxnAccessor.java +++ b/hedera-node/src/main/java/com/hedera/services/utils/PlatformTxnAccessor.java @@ -35,6 +35,8 @@ public class PlatformTxnAccessor extends SignedTxnAccessor { private final SwirldTransaction platformTxn; + private RationalizedSigMeta sigMeta = null; + public PlatformTxnAccessor(SwirldTransaction platformTxn) throws InvalidProtocolBufferException { super(platformTxn.getContents()); this.platformTxn = platformTxn; @@ -59,4 +61,14 @@ public static PlatformTxnAccessor uncheckedAccessorFor(SwirldTransaction platfor public SwirldTransaction getPlatformTxn() { return platformTxn; } + + @Override + public void setSigMeta(RationalizedSigMeta sigMeta) { + this.sigMeta = sigMeta; + } + + @Override + public RationalizedSigMeta getSigMeta() { + return sigMeta; + } } diff --git a/hedera-node/src/main/java/com/hedera/services/utils/RationalizedSigMeta.java b/hedera-node/src/main/java/com/hedera/services/utils/RationalizedSigMeta.java new file mode 100644 index 000000000000..ecb0cee12ce0 --- /dev/null +++ b/hedera-node/src/main/java/com/hedera/services/utils/RationalizedSigMeta.java @@ -0,0 +1,143 @@ +package com.hedera.services.utils; + +/*- + * ‌ + * Hedera Services Node + * ​ + * Copyright (C) 2018 - 2021 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. + * ‍ + */ + +import com.hedera.services.legacy.core.jproto.JKey; +import com.hedera.services.sigs.Rationalization; +import com.swirlds.common.SwirldDualState; +import com.swirlds.common.SwirldTransaction; +import com.swirlds.common.crypto.TransactionSignature; + +import java.time.Instant; +import java.util.List; +import java.util.function.Function; + +import static com.hedera.services.keys.HederaKeyActivation.pkToSigMapFrom; + +/** + * A simple wrapper around the three outputs of the {@link Rationalization#execute()} process. + * + * These outputs are, + *
    + *
  1. The payer key required to sign the active transaction.
  2. + *
  3. The list of other-party keys (if any) required to sign the active transaction.
  4. + *
  5. The mapping from a public key to the verified {@link TransactionSignature} for that key. + *
+ * + * If a transaction is invalid, it is possible that one or both of the payer key and the list + * of other-party keys will be unavailable. So this wrapper class can be constructed using one + * of three factories: {@link RationalizedSigMeta#noneAvailable()}, + * {@link RationalizedSigMeta#forPayerOnly(JKey, List)}, and {@link RationalizedSigMeta#forPayerAndOthers(JKey, List, List)}. + * (There is no factory for just other-party signatures, because without a payer signature + * {@link com.hedera.services.ServicesState#handleTransaction(long, boolean, Instant, Instant, SwirldTransaction, SwirldDualState)} + * will abort almost immediately.) + * + * Note that the mapping from public key to verified {@link TransactionSignature} is equivalent + * to just the list of verified {@link TransactionSignature}s, since each {@link TransactionSignature} + * instance includes the relevant public key. We construct the function in this class just + * to avoid repeating that work twice in {@code handleTransaction}. + */ +public class RationalizedSigMeta { + private static final RationalizedSigMeta NONE_AVAIL = new RationalizedSigMeta(); + + private final JKey payerReqSig; + private final List othersReqSigs; + private final List rationalizedSigs; + private final Function pkToVerifiedSigFn; + + private RationalizedSigMeta() { + payerReqSig = null; + othersReqSigs = null; + rationalizedSigs = null; + pkToVerifiedSigFn = null; + } + + private RationalizedSigMeta( + JKey payerReqSig, + List othersReqSigs, + List rationalizedSigs, + Function pkToVerifiedSigFn + ) { + this.payerReqSig = payerReqSig; + this.othersReqSigs = othersReqSigs; + this.rationalizedSigs = rationalizedSigs; + this.pkToVerifiedSigFn = pkToVerifiedSigFn; + } + + public static RationalizedSigMeta noneAvailable() { + return NONE_AVAIL; + } + + public static RationalizedSigMeta forPayerOnly( + JKey payerReqSig, + List rationalizedSigs + ) { + return forPayerAndOthers(payerReqSig, null, rationalizedSigs); + } + + public static RationalizedSigMeta forPayerAndOthers( + JKey payerReqSig, + List othersReqSigs, + List rationalizedSigs + ) { + return new RationalizedSigMeta( + payerReqSig, + othersReqSigs, + rationalizedSigs, + pkToSigMapFrom(rationalizedSigs)); + } + + public boolean couldRationalizePayer() { + return payerReqSig != null; + } + + public boolean couldRationalizeOthers() { + return othersReqSigs != null; + } + + public List verifiedSigs() { + if (rationalizedSigs == null) { + throw new IllegalStateException("Verified signatures could not be rationalized"); + } + return rationalizedSigs; + } + + public JKey payerKey() { + if (payerReqSig == null) { + throw new IllegalStateException("Payer required signing keys could not be rationalized"); + } + return payerReqSig; + } + + public List othersReqSigs() { + if (othersReqSigs == null) { + throw new IllegalStateException("Other-party required signing keys could not be rationalized"); + } + return othersReqSigs; + } + + public Function pkToVerifiedSigFn() { + if (pkToVerifiedSigFn == null) { + throw new IllegalStateException("Verified signatures could not be rationalized"); + } + return pkToVerifiedSigFn; + } +} diff --git a/hedera-node/src/main/java/com/hedera/services/utils/TxnAccessor.java b/hedera-node/src/main/java/com/hedera/services/utils/TxnAccessor.java index e8c28c43b66b..e9aceaba2726 100644 --- a/hedera-node/src/main/java/com/hedera/services/utils/TxnAccessor.java +++ b/hedera-node/src/main/java/com/hedera/services/utils/TxnAccessor.java @@ -34,41 +34,36 @@ * parts of a Hedera Services gRPC {@link Transaction}. */ public interface TxnAccessor { - int numSigPairs(); - int sigMapSize(); - + int numSigPairs(); SignatureMap getSigMap(); + default void setSigMeta(RationalizedSigMeta sigMeta) { + throw new UnsupportedOperationException(); + } + default RationalizedSigMeta getSigMeta() { + throw new UnsupportedOperationException(); + } + long getOfferedFee(); + AccountID getPayer(); + TransactionID getTxnId(); HederaFunctionality getFunction(); - byte[] getTxnBytes(); - byte[] getMemoUtf8Bytes(); - + String getMemo(); boolean memoHasZeroByte(); + byte[] getHash(); + byte[] getTxnBytes(); + byte[] getSignedTxnWrapperBytes(); Transaction getSignedTxnWrapper(); - TransactionBody getTxn(); - TransactionID getTxnId(); - - AccountID getPayer(); - - byte[] getSignedTxnWrapperBytes(); - - byte[] getHash(); - - String getMemo(); - boolean canTriggerTxn(); - boolean isTriggeredTxn(); - ScheduleID getScheduleRef(); - long getOfferedFee(); - - default SwirldTransaction getPlatformTxn() { throw new UnsupportedOperationException(); } + default SwirldTransaction getPlatformTxn() { + throw new UnsupportedOperationException(); + } } diff --git a/hedera-node/src/test/java/com/hedera/services/ServicesStateTest.java b/hedera-node/src/test/java/com/hedera/services/ServicesStateTest.java index 59e944a7c5af..12f44022e70f 100644 --- a/hedera-node/src/test/java/com/hedera/services/ServicesStateTest.java +++ b/hedera-node/src/test/java/com/hedera/services/ServicesStateTest.java @@ -30,7 +30,6 @@ import com.hedera.services.legacy.crypto.SignatureStatus; import com.hedera.services.records.AccountRecordsHistorian; import com.hedera.services.records.TxnIdRecentHistory; -import com.hedera.services.sigs.factories.SigFactoryCreator; import com.hedera.services.sigs.order.HederaSigningOrder; import com.hedera.services.sigs.order.SigningOrderResult; import com.hedera.services.state.expiry.ExpiryManager; @@ -203,7 +202,6 @@ private void setup() { logic = mock(ProcessLogic.class); ctx = mock(ServicesContext.class); - given(ctx.sigFactoryCreator()).willReturn(new SigFactoryCreator()); given(ctx.id()).willReturn(self); given(ctx.logic()).willReturn(logic); @@ -736,7 +734,6 @@ void expandsSigs() throws InvalidProtocolBufferException { // then: assertEquals(1, platformTxn.getSignatures().size()); assertEquals(mockPk, ByteString.copyFrom(platformTxn.getSignatures().get(0).getExpandedPublicKeyDirect())); - verify(ctx).sigFactoryCreator(); } @Test diff --git a/hedera-node/src/test/java/com/hedera/services/context/ServicesContextTest.java b/hedera-node/src/test/java/com/hedera/services/context/ServicesContextTest.java index b81a63c4d4b4..f5a29abe3be3 100644 --- a/hedera-node/src/test/java/com/hedera/services/context/ServicesContextTest.java +++ b/hedera-node/src/test/java/com/hedera/services/context/ServicesContextTest.java @@ -88,7 +88,6 @@ import com.hedera.services.records.RecordCache; import com.hedera.services.records.TxnAwareRecordsHistorian; import com.hedera.services.security.ops.SystemOpPolicies; -import com.hedera.services.sigs.factories.SigFactoryCreator; import com.hedera.services.sigs.order.HederaSigningOrder; import com.hedera.services.sigs.verification.PrecheckVerifier; import com.hedera.services.sigs.verification.SyncVerifier; @@ -505,7 +504,6 @@ void hasExpectedStakedInfrastructure() { assertThat(ctx.semVers(), instanceOf(SemanticVersions.class)); assertThat(ctx.freezeGrpc(), instanceOf(FreezeController.class)); assertThat(ctx.contractsGrpc(), instanceOf(ContractController.class)); - assertThat(ctx.sigFactoryCreator(), instanceOf(SigFactoryCreator.class)); assertThat(ctx.activationHelper(), instanceOf(InHandleActivationHelper.class)); assertThat(ctx.characteristics(), instanceOf(CharacteristicsFactory.class)); assertThat(ctx.nodeDiligenceScreen(), instanceOf(AwareNodeDiligenceScreen.class)); @@ -557,7 +555,6 @@ void shouldInitFees() throws Exception { given(diskFs.contentsOf(any())).willReturn(fileContents); ServicesContext ctx = new ServicesContext(nodeId, platform, state, propertySources); - ctx.setSystemExits(ignore -> {}); var subject = ctx.systemFilesManager(); assertSame(networkCtx, ctx.networkCtx()); diff --git a/hedera-node/src/test/java/com/hedera/services/keys/HederaKeyActivationTest.java b/hedera-node/src/test/java/com/hedera/services/keys/HederaKeyActivationTest.java index e3ff6f2609df..f15aa3d3d231 100644 --- a/hedera-node/src/test/java/com/hedera/services/keys/HederaKeyActivationTest.java +++ b/hedera-node/src/test/java/com/hedera/services/keys/HederaKeyActivationTest.java @@ -22,6 +22,8 @@ import com.hedera.services.legacy.core.jproto.JKey; import com.hedera.services.legacy.core.jproto.JKeyList; +import com.hedera.services.utils.RationalizedSigMeta; +import com.hedera.services.utils.TxnAccessor; import com.hedera.test.factories.keys.KeyTree; import com.hedera.test.factories.sigs.SigWrappers; import com.swirlds.common.crypto.TransactionSignature; @@ -42,12 +44,13 @@ import static com.hedera.test.factories.keys.NodeFactory.threshold; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.BDDMockito.any; import static org.mockito.BDDMockito.given; import static org.mockito.BDDMockito.mock; -public class HederaKeyActivationTest { +class HederaKeyActivationTest { static JKey complexKey; byte[] pk = "PK".getBytes(); byte[] sig = "SIG".getBytes(); @@ -76,13 +79,13 @@ private static void setupAll() throws Throwable { } @BeforeEach - public void setup() { + void setup() { sigsFn = (Function) mock(Function.class); tests = (BiPredicate) mock(BiPredicate.class); } @Test - public void revocationServiceActivatesWithOneTopLevelSig() { + void revocationServiceActivatesWithOneTopLevelSig() { // setup: KeyActivationCharacteristics characteristics = RevocationServiceCharacteristics.forTopLevelFile((JKeyList) complexKey); @@ -98,7 +101,7 @@ public void revocationServiceActivatesWithOneTopLevelSig() { } @Test - public void revocationServiceiRequiresOneTopLevelSig() { + void revocationServiceiRequiresOneTopLevelSig() { // setup: KeyActivationCharacteristics characteristics = RevocationServiceCharacteristics.forTopLevelFile((JKeyList) complexKey); @@ -114,7 +117,7 @@ public void revocationServiceiRequiresOneTopLevelSig() { } @Test - public void mapSupplierReflectsInputList() { + void mapSupplierReflectsInputList() { // setup: List presentSigs = List.of(mockSigFn.apply(0), mockSigFn.apply(1)); TransactionSignature missingSig = mockSigFn.apply(2); @@ -136,7 +139,7 @@ public void mapSupplierReflectsInputList() { } @Test - public void topLevelListActivatesOnlyIfAllChildrenAreActive() { + void topLevelListActivatesOnlyIfAllChildrenAreActive() { given(sigsFn.apply(any())).willReturn(INVALID_SIG).willReturn(VALID_SIG); // when: @@ -144,7 +147,7 @@ public void topLevelListActivatesOnlyIfAllChildrenAreActive() { } @Test - public void topLevelActivatesIfAllChildrenAreActive() { + void topLevelActivatesIfAllChildrenAreActive() { given(sigsFn.apply(any())) .willReturn(VALID_SIG) .willReturn(INVALID_SIG).willReturn(INVALID_SIG).willReturn(INVALID_SIG).willReturn(VALID_SIG) @@ -154,4 +157,24 @@ public void topLevelActivatesIfAllChildrenAreActive() { // when: assertTrue(isActive(complexKey, sigsFn, ONLY_IF_SIG_IS_VALID)); } + + @Test + void throwsIfNoSigMetaHasBeenRationalized() { + // setup: + final var accessor = mock(TxnAccessor.class); + + // expect: + assertThrows(IllegalArgumentException.class, () -> HederaKeyActivation.payerSigIsActive(accessor)); + } + + @Test + void immediatelyReturnsFalseForNoRationalizedPayerData() { + // setup: + final var accessor = mock(TxnAccessor.class); + + given(accessor.getSigMeta()).willReturn(RationalizedSigMeta.noneAvailable()); + + // expect: + assertFalse(HederaKeyActivation.payerSigIsActive(accessor)); + } } diff --git a/hedera-node/src/test/java/com/hedera/services/keys/InHandleActivationHelperTest.java b/hedera-node/src/test/java/com/hedera/services/keys/InHandleActivationHelperTest.java index 5a0b7e99f75f..d583183773bc 100644 --- a/hedera-node/src/test/java/com/hedera/services/keys/InHandleActivationHelperTest.java +++ b/hedera-node/src/test/java/com/hedera/services/keys/InHandleActivationHelperTest.java @@ -22,21 +22,14 @@ import com.hedera.services.legacy.core.jproto.JEd25519Key; import com.hedera.services.legacy.core.jproto.JKey; -import com.hedera.services.legacy.crypto.SignatureStatus; -import com.hedera.services.sigs.order.HederaSigningOrder; -import com.hedera.services.sigs.order.SigningOrderResult; import com.hedera.services.utils.PlatformTxnAccessor; -import com.hedera.test.utils.IdUtils; +import com.hedera.services.utils.RationalizedSigMeta; import com.hederahashgraph.api.proto.java.CryptoTransferTransactionBody; import com.hederahashgraph.api.proto.java.TransactionBody; -import com.hederahashgraph.api.proto.java.TransactionID; -import com.swirlds.common.SwirldTransaction; import com.swirlds.common.crypto.TransactionSignature; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.junit.platform.runner.JUnitPlatform; -import org.junit.runner.RunWith; import java.util.ArrayList; import java.util.List; @@ -45,33 +38,23 @@ import java.util.function.Function; import static com.hedera.services.keys.DefaultActivationCharacteristics.DEFAULT_ACTIVATION_CHARACTERISTICS; -import static com.hedera.services.sigs.Rationalization.IN_HANDLE_SUMMARY_FACTORY; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.BDDMockito.any; import static org.mockito.BDDMockito.given; import static org.mockito.BDDMockito.mock; import static org.mockito.BDDMockito.never; -import static org.mockito.BDDMockito.times; import static org.mockito.BDDMockito.verify; -@RunWith(JUnitPlatform.class) class InHandleActivationHelperTest { private byte[] scopedTxnBytes = "ANYTHING".getBytes(); private JKey other = new JEd25519Key("other".getBytes()); private JKey scheduled = new JEd25519Key("scheduled".getBytes()); List required = List.of(other, scheduled); - private SigningOrderResult successful = - IN_HANDLE_SUMMARY_FACTORY.forValidOrder(required); - private SigningOrderResult impermissible = - IN_HANDLE_SUMMARY_FACTORY.forMissingAccount( - IdUtils.asAccount("1.2.3"), - TransactionID.getDefaultInstance()); - - SwirldTransaction platformTxn; - HederaSigningOrder keyOrderer; + PlatformTxnAccessor accessor; + RationalizedSigMeta sigMeta; TransactionSignature sig; CharacteristicsFactory characteristicsFactory; Function sigsFn; @@ -79,50 +62,44 @@ class InHandleActivationHelperTest { InHandleActivationHelper.Activation activation; - Function< - List, - Function> sigsFnSource; - InHandleActivationHelper subject; @BeforeEach @SuppressWarnings("unchecked") - public void setup() throws Exception { + void setup() { scheduled.setForScheduledTxn(true); - keyOrderer = mock(HederaSigningOrder.class); - given(keyOrderer.keysForOtherParties(any(), any())).willReturn(successful); - characteristicsFactory = mock(CharacteristicsFactory.class); given(characteristicsFactory.inferredFor(any())).willReturn(DEFAULT_ACTIVATION_CHARACTERISTICS); - platformTxn = mock(SwirldTransaction.class); - given(platformTxn.getSignatures()).willReturn(sigs); + sigMeta = mock(RationalizedSigMeta.class); + given(sigMeta.verifiedSigs()).willReturn(sigs); + given(sigMeta.couldRationalizeOthers()).willReturn(true); + given(sigMeta.othersReqSigs()).willReturn(required); + accessor = mock(PlatformTxnAccessor.class); - given(accessor.getPlatformTxn()).willReturn(platformTxn); given(accessor.getTxnBytes()).willReturn(scopedTxnBytes); + given(accessor.getSigMeta()).willReturn(sigMeta); sig = mock(TransactionSignature.class); sigsFn = mock(Function.class); - sigsFnSource = - (Function, Function>) mock(Function.class); + given(sigMeta.pkToVerifiedSigFn()).willReturn(sigsFn); - subject = new InHandleActivationHelper(keyOrderer, characteristicsFactory, () -> accessor); + subject = new InHandleActivationHelper(characteristicsFactory, () -> accessor); activation = mock(InHandleActivationHelper.Activation.class); InHandleActivationHelper.activation = activation; - InHandleActivationHelper.sigsFnSource = sigsFnSource; } @Test @SuppressWarnings("unchecked") - public void usesEmptyKeysOnErrorReport() { + void usesEmptyKeysOnErrorReport() { // setup: BiPredicate tests = (BiPredicate) mock(BiPredicate.class); - given(keyOrderer.keysForOtherParties(any(), any())).willReturn(impermissible); + given(sigMeta.couldRationalizeOthers()).willReturn(false); // when: boolean ans = subject.areOtherPartiesActive(tests); @@ -136,7 +113,7 @@ public void usesEmptyKeysOnErrorReport() { @Test @SuppressWarnings("unchecked") - public void usesExpectedSigsFnForOthers() { + void usesExpectedSigsFnForOthers() { // setup: BiPredicate tests = (BiPredicate) mock(BiPredicate.class); @@ -153,11 +130,10 @@ public void usesExpectedSigsFnForOthers() { @Test @SuppressWarnings("unchecked") - public void usesExpectedKeysForOtherPartiesActive() { + void usesExpectedKeysForOtherPartiesActive() { // setup: BiPredicate tests = (BiPredicate) mock(BiPredicate.class); - given(sigsFnSource.apply(any())).willReturn(sigsFn); given(activation.test(other, sigsFn, tests, DEFAULT_ACTIVATION_CHARACTERISTICS)).willReturn(true); // when: @@ -167,17 +143,14 @@ public void usesExpectedKeysForOtherPartiesActive() { // then: assertTrue(ans); assertTrue(ansAgain); - // and: - verify(keyOrderer, times(1)).keysForOtherParties(any(), any()); } @Test @SuppressWarnings("unchecked") - public void usesExpectedKeysForScheduled() { + void usesExpectedKeysForScheduled() { // setup: BiPredicate tests = (BiPredicate) mock(BiPredicate.class); - given(sigsFnSource.apply(any())).willReturn(sigsFn); given(activation.test(scheduled, sigsFn, tests, DEFAULT_ACTIVATION_CHARACTERISTICS)).willReturn(true); // when: @@ -189,11 +162,10 @@ public void usesExpectedKeysForScheduled() { @Test @SuppressWarnings("unchecked") - public void countsScheduledKeysAsExpected() { + void countsScheduledKeysAsExpected() { // setup: BiConsumer visitor = (BiConsumer) mock(BiConsumer.class); - given(sigsFnSource.apply(any())).willReturn(sigsFn); given(sigsFn.apply(scheduled.getEd25519())).willReturn(sig); // when: @@ -204,9 +176,8 @@ public void countsScheduledKeysAsExpected() { } @AfterEach - public void cleanup() { + void cleanup() { InHandleActivationHelper.activation = HederaKeyActivation::isActive; - InHandleActivationHelper.sigsFnSource = HederaKeyActivation::pkToSigMapFrom; } private TransactionBody nonFileDelete() { diff --git a/hedera-node/src/test/java/com/hedera/services/keys/StandardSyncActivationCheckTest.java b/hedera-node/src/test/java/com/hedera/services/keys/StandardSyncActivationCheckTest.java index fb6801eb79e5..ffd2eb2f95a8 100644 --- a/hedera-node/src/test/java/com/hedera/services/keys/StandardSyncActivationCheckTest.java +++ b/hedera-node/src/test/java/com/hedera/services/keys/StandardSyncActivationCheckTest.java @@ -58,7 +58,6 @@ class StandardSyncActivationCheckTest { PlatformSigsFactory sigsFactory; TxnScopedPlatformSigFactory scopedSig; Function sigsFn; - Function sigBytesProvider; Function scopedSigProvider; BiPredicate> isActive; Function, Function> sigsFnProvider; @@ -77,8 +76,6 @@ private void setup() throws Exception { given(accessor.getSignedTxnWrapper()).willReturn(signedTxn); isActive = mock(BiPredicate.class); syncVerifier = mock(SyncVerifier.class); - sigBytesProvider = mock(Function.class); - given(sigBytesProvider.apply(signedTxn)).willReturn(sigBytes); sigsFnProvider = mock(Function.class); given(sigsFnProvider.apply(sigs)).willReturn(sigsFn); scopedSig = mock(TxnScopedPlatformSigFactory.class); @@ -100,7 +97,7 @@ public void happyPathFlows() { syncVerifier, accessor, sigsFactory, - sigBytesProvider, + sigBytes, scopedSigProvider, isActive, sigsFnProvider); @@ -123,7 +120,7 @@ public void failsOnInActive() { syncVerifier, accessor, sigsFactory, - sigBytesProvider, + sigBytes, scopedSigProvider, isActive, sigsFnProvider); @@ -144,7 +141,7 @@ public void shortCircuitsOnCreationFailure() { syncVerifier, accessor, sigsFactory, - sigBytesProvider, + sigBytes, scopedSigProvider, isActive, sigsFnProvider); diff --git a/hedera-node/src/test/java/com/hedera/services/sigs/HederaToPlatformSigOpsTest.java b/hedera-node/src/test/java/com/hedera/services/sigs/HederaToPlatformSigOpsTest.java index 4ae2e1a7c8c3..62aceb72254b 100644 --- a/hedera-node/src/test/java/com/hedera/services/sigs/HederaToPlatformSigOpsTest.java +++ b/hedera-node/src/test/java/com/hedera/services/sigs/HederaToPlatformSigOpsTest.java @@ -30,14 +30,12 @@ import com.hedera.services.sigs.order.SigStatusOrderResultFactory; import com.hedera.services.sigs.order.SigningOrderResult; import com.hedera.services.sigs.sourcing.PubKeyToSigBytes; -import com.hedera.services.sigs.sourcing.PubKeyToSigBytesProvider; import com.hedera.services.sigs.verification.SyncVerifier; import com.hedera.services.utils.PlatformTxnAccessor; import com.hedera.test.factories.keys.KeyTree; import com.hedera.test.factories.txns.PlatformTxnFactory; import com.hedera.test.factories.txns.SignedTxnFactory; import com.hederahashgraph.api.proto.java.ResponseCodeEnum; -import com.hederahashgraph.api.proto.java.Transaction; import com.swirlds.common.crypto.TransactionSignature; import com.swirlds.common.crypto.VerificationStatus; import org.junit.jupiter.api.BeforeAll; @@ -62,7 +60,7 @@ import static org.mockito.BDDMockito.given; import static org.mockito.BDDMockito.mock; -public class HederaToPlatformSigOpsTest { +class HederaToPlatformSigOpsTest { static List payerKey; static List otherKeys; SignatureStatus successStatus; @@ -71,8 +69,7 @@ public class HederaToPlatformSigOpsTest { SignatureStatus asyncSuccessStatus; SignatureStatus sigCreationFailureStatus; SignatureStatus rationalizingFailureStatus; - PubKeyToSigBytes payerSigBytes; - PubKeyToSigBytes othersSigBytes; + PubKeyToSigBytes allSigBytes; PlatformTxnAccessor platformTxn; HederaSigningOrder keyOrdering; @@ -87,8 +84,7 @@ private static void setupAll() throws Throwable { @BeforeEach private void setup() throws Throwable { - payerSigBytes = mock(PubKeyToSigBytes.class); - othersSigBytes = mock(PubKeyToSigBytes.class); + allSigBytes = mock(PubKeyToSigBytes.class); keyOrdering = mock(HederaSigningOrder.class); platformTxn = new PlatformTxnAccessor(PlatformTxnFactory.from(newSignedSystemDelete().get())); successStatus = new SignatureStatus( @@ -131,8 +127,10 @@ private void wellBehavedOrdersAndSigSources(SigStatusOrderResultFactory factory) given(keyOrdering.keysForOtherParties(platformTxn.getTxn(), factory)) .willReturn(new SigningOrderResult<>(otherKeys)); // and: - given(payerSigBytes.sigBytesFor(any())).willReturn("1".getBytes()); - given(othersSigBytes.sigBytesFor(any())).willReturn("2".getBytes()).willReturn("3".getBytes()); + given(allSigBytes.sigBytesFor(any())) + .willReturn("1".getBytes()) + .willReturn("2".getBytes()) + .willReturn("3".getBytes()); } @Test @@ -141,7 +139,7 @@ void includesSuccessfulExpansions() throws Exception { wellBehavedOrdersAndSigSourcesPreHandle(); // when: - SignatureStatus status = expandIn(platformTxn, keyOrdering, sigBytesProvider, BodySigningSigFactory::new); + SignatureStatus status = expandIn(platformTxn, keyOrdering, allSigBytes); // then: assertEquals(successStatus.toString(), status.toString()); @@ -154,7 +152,7 @@ void returnsImmediatelyOnPayerKeyOrderFailure() { .willReturn(new SigningOrderResult<>(failureStatus)); // when: - SignatureStatus status = expandIn(platformTxn, keyOrdering, sigBytesProvider, BodySigningSigFactory::new); + SignatureStatus status = expandIn(platformTxn, keyOrdering, allSigBytes); // then: assertEquals(failureStatus.toString(), status.toString()); @@ -167,13 +165,13 @@ void doesntAddSigsIfCreationResultIsNotSuccess() throws Exception { given(keyOrdering.keysForOtherParties(platformTxn.getTxn(), PRE_HANDLE_SUMMARY_FACTORY)) .willReturn(new SigningOrderResult<>(otherKeys)); // and: - given(payerSigBytes.sigBytesFor(any())).willReturn("1".getBytes()); - given(othersSigBytes.sigBytesFor(any())) + given(allSigBytes.sigBytesFor(any())) + .willReturn("1".getBytes()) .willReturn("2".getBytes()) .willThrow(KeyPrefixMismatchException.class); // when: - SignatureStatus status = expandIn(platformTxn, keyOrdering, sigBytesProvider, BodySigningSigFactory::new); + SignatureStatus status = expandIn(platformTxn, keyOrdering, allSigBytes); // then: assertEquals(successStatus.toString(), status.toString()); @@ -190,12 +188,12 @@ void rationalizesMissingSigs() throws Exception { platformTxn, ALWAYS_VALID, keyOrdering, - sigBytesProvider, - BodySigningSigFactory::new); + allSigBytes, + new BodySigningSigFactory(platformTxn)); // then: assertEquals(syncSuccessStatus.toString(), status.toString()); - assertEquals(expectedSigsWithNoErrors(), platformTxn.getPlatformTxn().getSignatures()); + assertEquals(expectedSigsWithNoErrors(), platformTxn.getSigMeta().verifiedSigs()); assertTrue(allVerificationStatusesAre(VerificationStatus.VALID::equals)); } @@ -209,8 +207,8 @@ void stopImmediatelyOnPayerKeyOrderFailure() { platformTxn, ALWAYS_VALID, keyOrdering, - sigBytesProvider, - BodySigningSigFactory::new); + allSigBytes, + new BodySigningSigFactory(platformTxn)); // then: assertEquals(rationalizingFailureStatus.toString(), status.toString()); @@ -228,8 +226,8 @@ void stopImmediatelyOnOtherPartiesKeyOrderFailure() throws Exception { platformTxn, ALWAYS_VALID, keyOrdering, - sigBytesProvider, - BodySigningSigFactory::new); + allSigBytes, + new BodySigningSigFactory(platformTxn)); // then: assertEquals(rationalizingFailureStatus.toString(), status.toString()); @@ -242,8 +240,8 @@ void stopImmediatelyOnOtherPartiesSigCreationFailure() throws Exception { given(keyOrdering.keysForOtherParties(platformTxn.getTxn(), IN_HANDLE_SUMMARY_FACTORY)) .willReturn(new SigningOrderResult<>(otherKeys)); // and: - given(payerSigBytes.sigBytesFor(any())).willReturn("1".getBytes()); - given(othersSigBytes.sigBytesFor(any())) + given(allSigBytes.sigBytesFor(any())) + .willReturn("1".getBytes()) .willReturn("2".getBytes()) .willThrow(KeyPrefixMismatchException.class); @@ -252,8 +250,8 @@ void stopImmediatelyOnOtherPartiesSigCreationFailure() throws Exception { platformTxn, ALWAYS_VALID, keyOrdering, - sigBytesProvider, - BodySigningSigFactory::new); + allSigBytes, + new BodySigningSigFactory(platformTxn)); // then: assertEquals(sigCreationFailureStatus.toString(), status.toString()); @@ -279,12 +277,12 @@ void rationalizesOnlyMissingSigs() throws Exception { platformTxn, syncVerifier, keyOrdering, - sigBytesProvider, - BodySigningSigFactory::new); + allSigBytes, + new BodySigningSigFactory(platformTxn)); // then: assertEquals(syncSuccessStatus.toString(), status.toString()); - assertEquals(expectedSigsWithNoErrors(), platformTxn.getPlatformTxn().getSignatures()); + assertEquals(expectedSigsWithNoErrors(), platformTxn.getSigMeta().verifiedSigs()); assertTrue(allVerificationStatusesAre(VerificationStatus.VALID::equals)); } @@ -300,12 +298,12 @@ void rationalizesSigsWithUnknownStatus() throws Exception { platformTxn, ALWAYS_VALID, keyOrdering, - sigBytesProvider, - BodySigningSigFactory::new); + allSigBytes, + new BodySigningSigFactory(platformTxn)); // then: assertEquals(syncSuccessStatus.toString(), status.toString()); - assertEquals(expectedSigsWithNoErrors(), platformTxn.getPlatformTxn().getSignatures()); + assertEquals(expectedSigsWithNoErrors(), platformTxn.getSigMeta().verifiedSigs()); assertTrue(allVerificationStatusesAre(VerificationStatus.VALID::equals)); } @@ -326,8 +324,8 @@ void doesNothingToTxnIfAllSigsAreRational() throws Exception { platformTxn, syncVerifier, keyOrdering, - sigBytesProvider, - BodySigningSigFactory::new); + allSigBytes, + new BodySigningSigFactory(platformTxn)); // then: assertEquals(asyncSuccessStatus.toString(), status.toString()); @@ -337,7 +335,7 @@ void doesNothingToTxnIfAllSigsAreRational() throws Exception { } private boolean allVerificationStatusesAre(Predicate statusPred) { - return platformTxn.getPlatformTxn().getSignatures().stream() + return platformTxn.getSigMeta().verifiedSigs().stream() .map(TransactionSignature::getSignatureStatus) .allMatch(statusPred); } @@ -359,21 +357,4 @@ private TransactionSignature dummyFor(JKey key, String sig) { sig.getBytes(), platformTxn.getTxnBytes()); } - - PubKeyToSigBytesProvider sigBytesProvider = new PubKeyToSigBytesProvider() { - @Override - public PubKeyToSigBytes payerSigBytesFor(Transaction signedTxn) { - return payerSigBytes; - } - - @Override - public PubKeyToSigBytes otherPartiesSigBytesFor(Transaction signedTxn) { - return othersSigBytes; - } - - @Override - public PubKeyToSigBytes allPartiesSigBytesFor(Transaction signedTxn) { - throw new AssertionError("Irrelevant to this operation!"); - } - }; } diff --git a/hedera-node/src/test/java/com/hedera/services/sigs/PlatformSigOpsTest.java b/hedera-node/src/test/java/com/hedera/services/sigs/PlatformSigOpsTest.java index 6415742473f1..7cfd99d30263 100644 --- a/hedera-node/src/test/java/com/hedera/services/sigs/PlatformSigOpsTest.java +++ b/hedera-node/src/test/java/com/hedera/services/sigs/PlatformSigOpsTest.java @@ -51,7 +51,7 @@ import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; -public class PlatformSigOpsTest { +class PlatformSigOpsTest { private final byte[] EMPTY_SIG = new byte[0]; private final byte[] MOCK_SIG = "FIRST".getBytes(); private final byte[][] MORE_MOCK_SIGS = new byte[][] { @@ -92,9 +92,9 @@ void createsOnlyNonDegenerateSigs() throws Throwable { kt.traverseLeaves(leaf -> { ByteString pk = leaf.asKey().getEd25519(); if (nextSigIndex.get() == 0) { - verify(sigFactory).create(pk, ByteString.copyFrom(MOCK_SIG)); + verify(sigFactory).create(pk.toByteArray(), MOCK_SIG); } else { - verify(sigFactory, never()).create(pk, ByteString.copyFrom(EMPTY_SIG)); + verify(sigFactory, never()).create(pk.toByteArray(), EMPTY_SIG); } nextSigIndex.addAndGet(1); }); @@ -116,7 +116,7 @@ void createsSigsInTraversalOrder() throws Throwable { kt.traverseLeaves(leaf -> { ByteString pk = leaf.asKey().getEd25519(); byte[] sigBytes = (nextSigIndex.get() == 0) ? MOCK_SIG : MORE_MOCK_SIGS[nextSigIndex.get() - 1]; - verify(sigFactory).create(pk, ByteString.copyFrom(sigBytes)); + verify(sigFactory).create(pk.toByteArray(), sigBytes); nextSigIndex.addAndGet(1); }); } diff --git a/hedera-node/src/test/java/com/hedera/services/sigs/RationalizationTest.java b/hedera-node/src/test/java/com/hedera/services/sigs/RationalizationTest.java new file mode 100644 index 000000000000..1da8f0b8415c --- /dev/null +++ b/hedera-node/src/test/java/com/hedera/services/sigs/RationalizationTest.java @@ -0,0 +1,125 @@ +package com.hedera.services.sigs; + +/*- + * ‌ + * Hedera Services Node + * ​ + * Copyright (C) 2018 - 2021 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. + * ‍ + */ + +import com.hedera.services.legacy.core.jproto.JKey; +import com.hedera.services.legacy.crypto.SignatureStatus; +import com.hedera.services.sigs.factories.TxnScopedPlatformSigFactory; +import com.hedera.services.sigs.order.HederaSigningOrder; +import com.hedera.services.sigs.order.SigningOrderResult; +import com.hedera.services.sigs.sourcing.PubKeyToSigBytes; +import com.hedera.services.sigs.verification.SyncVerifier; +import com.hedera.services.utils.RationalizedSigMeta; +import com.hedera.services.utils.TxnAccessor; +import com.hedera.test.factories.scenarios.TxnHandlingScenario; +import com.hedera.test.utils.IdUtils; +import com.hederahashgraph.api.proto.java.TransactionBody; +import com.hederahashgraph.api.proto.java.TransactionID; +import com.swirlds.common.SwirldTransaction; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import static com.hedera.services.sigs.Rationalization.IN_HANDLE_SUMMARY_FACTORY; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.verify; + +@ExtendWith(MockitoExtension.class) +class RationalizationTest { + private final JKey payerKey = TxnHandlingScenario.MISC_ACCOUNT_KT.asJKeyUnchecked(); + private final TransactionID txnId = TransactionID.getDefaultInstance(); + private final TransactionBody txn = TransactionBody.getDefaultInstance(); + private final SigningOrderResult generalError = + IN_HANDLE_SUMMARY_FACTORY.forGeneralError(txnId); + private final SigningOrderResult othersError = + IN_HANDLE_SUMMARY_FACTORY.forImmutableContract(IdUtils.asContract("0.0.1234"), txnId); + + @Mock + private SwirldTransaction swirldsTxn; + @Mock + private TxnAccessor txnAccessor; + @Mock + private SyncVerifier syncVerifier; + @Mock + private HederaSigningOrder keyOrderer; + @Mock + private TxnScopedPlatformSigFactory sigFactory; + @Mock + private PubKeyToSigBytes pkToSigFn; + @Mock + private SigningOrderResult mockOrderResult; + + private Rationalization subject; + + @BeforeEach + void setUp() { + given(txnAccessor.getTxn()).willReturn(txn); + given(txnAccessor.getPlatformTxn()).willReturn(swirldsTxn); + + subject = new Rationalization(txnAccessor, syncVerifier, keyOrderer, pkToSigFn, sigFactory); + } + + @Test + void setsUnavailableMetaIfCannotListPayerKey() { + // setup: + ArgumentCaptor captor = ArgumentCaptor.forClass(RationalizedSigMeta.class); + + given(keyOrderer.keysForPayer(txn, IN_HANDLE_SUMMARY_FACTORY)).willReturn(generalError); + + // when: + final var result = subject.execute(); + + // then: + assertEquals(result, generalError.getErrorReport()); + // and: + verify(txnAccessor).setSigMeta(captor.capture()); + assertSame(RationalizedSigMeta.noneAvailable(), captor.getValue()); + } + + @Test + void propagatesFailureIfCouldNotExpandOthersKeys() { + // setup: + ArgumentCaptor captor = ArgumentCaptor.forClass(RationalizedSigMeta.class); + + given(mockOrderResult.getPayerKey()).willReturn(payerKey); + given(keyOrderer.keysForPayer(txn, IN_HANDLE_SUMMARY_FACTORY)).willReturn(mockOrderResult); + given(keyOrderer.keysForOtherParties(txn, IN_HANDLE_SUMMARY_FACTORY)).willReturn(othersError); + + // when: + final var result = subject.execute(); + + // then: + assertEquals(result, othersError.getErrorReport()); + // and: + verify(txnAccessor).setSigMeta(captor.capture()); + final var sigMeta = captor.getValue(); + assertTrue(sigMeta.couldRationalizePayer()); + assertFalse(sigMeta.couldRationalizeOthers()); + assertSame(payerKey, sigMeta.payerKey()); + } +} diff --git a/hedera-node/src/test/java/com/hedera/services/sigs/SigOpsRegressionTest.java b/hedera-node/src/test/java/com/hedera/services/sigs/SigOpsRegressionTest.java index a801f4872400..42ecd37a803e 100644 --- a/hedera-node/src/test/java/com/hedera/services/sigs/SigOpsRegressionTest.java +++ b/hedera-node/src/test/java/com/hedera/services/sigs/SigOpsRegressionTest.java @@ -34,14 +34,14 @@ import com.hedera.services.sigs.order.HederaSigningOrder; import com.hedera.services.sigs.order.SigningOrderResult; import com.hedera.services.sigs.order.SigningOrderResultFactory; -import com.hedera.services.sigs.sourcing.DefaultSigBytesProvider; -import com.hedera.services.sigs.sourcing.PubKeyToSigBytes; +import com.hedera.services.sigs.sourcing.SigMapPubKeyToSigBytes; import com.hedera.services.sigs.verification.SyncVerifier; import com.hedera.services.state.merkle.MerkleAccount; import com.hedera.services.state.merkle.MerkleEntityId; import com.hedera.services.stats.MiscRunningAvgs; import com.hedera.services.stats.MiscSpeedometers; import com.hedera.services.utils.PlatformTxnAccessor; +import com.hedera.services.utils.RationalizedSigMeta; import com.hedera.test.factories.scenarios.TxnHandlingScenario; import com.hedera.test.factories.txns.CryptoCreateFactory; import com.hederahashgraph.api.proto.java.HederaFunctionality; @@ -87,7 +87,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.BDDMockito.mock; -public class SigOpsRegressionTest { +class SigOpsRegressionTest { private HederaFs hfs; private MiscRunningAvgs runningAvgs; private MiscSpeedometers speedometers; @@ -107,7 +107,7 @@ public class SigOpsRegressionTest { private BiPredicate targetWaclSigns = (txn, function) -> mockSystemOpPolicies.check(txn, function) != AUTHORIZED; - public static boolean otherPartySigsAreActive( + static boolean otherPartySigsAreActive( PlatformTxnAccessor accessor, HederaSigningOrder keyOrder, SigningOrderResultFactory summaryFactory @@ -115,7 +115,7 @@ public static boolean otherPartySigsAreActive( return otherPartySigsAreActive(accessor, keyOrder, summaryFactory, DEFAULT_ACTIVATION_CHARACTERISTICS); } - public static boolean otherPartySigsAreActive( + static boolean otherPartySigsAreActive( PlatformTxnAccessor accessor, HederaSigningOrder keyOrder, SigningOrderResultFactory summaryFactory, @@ -134,7 +134,7 @@ public static boolean otherPartySigsAreActive( } @Test - public void setsExpectedPlatformSigsForCryptoCreate() throws Throwable { + void setsExpectedPlatformSigsForCryptoCreate() throws Throwable { // given: setupFor(CRYPTO_CREATE_RECEIVER_SIG_SCENARIO); @@ -147,7 +147,7 @@ public void setsExpectedPlatformSigsForCryptoCreate() throws Throwable { } @Test - public void setsExpectedErrorForBadPayer() throws Throwable { + void setsExpectedErrorForBadPayer() throws Throwable { // given: setupFor(INVALID_PAYER_ID_SCENARIO); @@ -160,7 +160,7 @@ public void setsExpectedErrorForBadPayer() throws Throwable { } @Test - public void setsExpectedErrorAndSigsForMissingTargetAccount() throws Throwable { + void setsExpectedErrorAndSigsForMissingTargetAccount() throws Throwable { // given: setupFor(CRYPTO_UPDATE_MISSING_ACCOUNT_SCENARIO); @@ -173,7 +173,7 @@ public void setsExpectedErrorAndSigsForMissingTargetAccount() throws Throwable { } @Test - public void rationalizesExpectedPlatformSigsForCryptoCreate() throws Throwable { + void rationalizesExpectedPlatformSigsForCryptoCreate() throws Throwable { // given: setupFor(CRYPTO_CREATE_RECEIVER_SIG_SCENARIO); // and: @@ -184,13 +184,13 @@ public void rationalizesExpectedPlatformSigsForCryptoCreate() throws Throwable { // then: statusMatches(syncSuccessStatus); - assertEquals(expectedSigs, platformTxn.getPlatformTxn().getSignatures()); + assertEquals(expectedSigs, platformTxn.getSigMeta().verifiedSigs()); // and: allVerificationStatusesAre(vs -> !VerificationStatus.UNKNOWN.equals(vs)); } @Test - public void rubberstampsCorrectPlatformSigsForCryptoCreate() throws Throwable { + void rubberstampsCorrectPlatformSigsForCryptoCreate() throws Throwable { // given: setupFor(CRYPTO_CREATE_RECEIVER_SIG_SCENARIO); // and: @@ -208,13 +208,13 @@ public void rubberstampsCorrectPlatformSigsForCryptoCreate() throws Throwable { } @Test - public void validatesComplexPayerSigActivation() throws Throwable { + void validatesComplexPayerSigActivation() throws Throwable { // given: setupFor(CRYPTO_CREATE_COMPLEX_PAYER_RECEIVER_SIG_SCENARIO); // and: List unknownSigs = PlatformSigOps.createEd25519PlatformSigsFrom( List.of(COMPLEX_KEY_ACCOUNT_KT.asJKey(), CryptoCreateFactory.DEFAULT_ACCOUNT_KT.asJKey()), - PubKeyToSigBytes.from(platformTxn.getSignedTxnWrapper().getSigMap()), + new SigMapPubKeyToSigBytes(platformTxn.getSignedTxnWrapper().getSigMap()), new BodySigningSigFactory(platformTxn) ).getPlatformSigs(); List knownSigs = asKind(List.of( @@ -233,13 +233,13 @@ public void validatesComplexPayerSigActivation() throws Throwable { } @Test - public void deniesInactiveComplexPayerSig() throws Throwable { + void deniesInactiveComplexPayerSig() throws Throwable { // given: setupFor(CRYPTO_CREATE_COMPLEX_PAYER_RECEIVER_SIG_SCENARIO); // and: List unknownSigs = PlatformSigOps.createEd25519PlatformSigsFrom( List.of(COMPLEX_KEY_ACCOUNT_KT.asJKey(), CryptoCreateFactory.DEFAULT_ACCOUNT_KT.asJKey()), - PubKeyToSigBytes.from(platformTxn.getSignedTxnWrapper().getSigMap()), + new SigMapPubKeyToSigBytes(platformTxn.getSignedTxnWrapper().getSigMap()), new BodySigningSigFactory(platformTxn) ).getPlatformSigs(); List knownSigs = asKind(List.of( @@ -258,13 +258,13 @@ public void deniesInactiveComplexPayerSig() throws Throwable { } @Test - public void validatesComplexOtherPartySigActivation() throws Throwable { + void validatesComplexOtherPartySigActivation() throws Throwable { // given: setupFor(CRYPTO_UPDATE_COMPLEX_KEY_ACCOUNT_SCENARIO); // and: List unknownSigs = PlatformSigOps.createEd25519PlatformSigsFrom( List.of(DEFAULT_PAYER_KT.asJKey(), COMPLEX_KEY_ACCOUNT_KT.asJKey()), - PubKeyToSigBytes.from(platformTxn.getSignedTxnWrapper().getSigMap()), + new SigMapPubKeyToSigBytes(platformTxn.getSignedTxnWrapper().getSigMap()), new BodySigningSigFactory(platformTxn) ).getPlatformSigs(); List knownSigs = asKind(List.of( @@ -284,13 +284,13 @@ public void validatesComplexOtherPartySigActivation() throws Throwable { } @Test - public void deniesInactiveComplexOtherPartySig() throws Throwable { + void deniesInactiveComplexOtherPartySig() throws Throwable { // given: setupFor(CRYPTO_UPDATE_COMPLEX_KEY_ACCOUNT_SCENARIO); // and: List unknownSigs = PlatformSigOps.createEd25519PlatformSigsFrom( List.of(DEFAULT_PAYER_KT.asJKey(), COMPLEX_KEY_ACCOUNT_KT.asJKey()), - PubKeyToSigBytes.from(platformTxn.getSignedTxnWrapper().getSigMap()), + new SigMapPubKeyToSigBytes(platformTxn.getSignedTxnWrapper().getSigMap()), new BodySigningSigFactory(platformTxn) ).getPlatformSigs(); List knownSigs = asKind(List.of( @@ -310,13 +310,13 @@ public void deniesInactiveComplexOtherPartySig() throws Throwable { } @Test - public void deniesSecondInactiveComplexOtherPartySig() throws Throwable { + void deniesSecondInactiveComplexOtherPartySig() throws Throwable { // given: setupFor(CRYPTO_UPDATE_COMPLEX_KEY_ACCOUNT_ADD_NEW_KEY_SCENARIO); // and: List unknownSigs = PlatformSigOps.createEd25519PlatformSigsFrom( List.of(DEFAULT_PAYER_KT.asJKey(), COMPLEX_KEY_ACCOUNT_KT.asJKey(), NEW_ACCOUNT_KT.asJKey()), - PubKeyToSigBytes.from(platformTxn.getSignedTxnWrapper().getSigMap()), + new SigMapPubKeyToSigBytes(platformTxn.getSignedTxnWrapper().getSigMap()), new BodySigningSigFactory(platformTxn) ).getPlatformSigs(); List knownSigs = asKind(List.of( @@ -344,13 +344,13 @@ private List expectedCryptoCreateScenarioSigs() throws Thr List.of( DEFAULT_PAYER_KT.asJKey(), CryptoCreateFactory.DEFAULT_ACCOUNT_KT.asJKey()), - PubKeyToSigBytes.from(platformTxn.getSignedTxnWrapper().getSigMap()), + new SigMapPubKeyToSigBytes(platformTxn.getSignedTxnWrapper().getSigMap()), new BodySigningSigFactory(platformTxn) ).getPlatformSigs(); } private boolean allVerificationStatusesAre(Predicate statusPred) { - return platformTxn.getPlatformTxn().getSignatures().stream() + return platformTxn.getSigMeta().verifiedSigs().stream() .map(TransactionSignature::getSignatureStatus) .allMatch(statusPred); } @@ -360,16 +360,17 @@ private void statusMatches(SignatureStatus expectedStatus) { } private boolean invokePayerSigActivationScenario(List knownSigs) { - platformTxn.getPlatformTxn().clear(); - platformTxn.getPlatformTxn().addAll(knownSigs.toArray(new TransactionSignature[0])); HederaSigningOrder keysOrder = new HederaSigningOrder( new MockEntityNumbers(), defaultLookupsFor(null, () -> accounts, () -> null, ref -> null, ref -> null), updateAccountSigns, targetWaclSigns, new MockGlobalDynamicProps()); + final var impliedOrdering = keysOrder.keysForPayer(platformTxn.getTxn(), IN_HANDLE_SUMMARY_FACTORY); + final var impliedKey = impliedOrdering.getPayerKey(); + platformTxn.setSigMeta(RationalizedSigMeta.forPayerOnly(impliedKey, new ArrayList<>(knownSigs))); - return payerSigIsActive(platformTxn, keysOrder, IN_HANDLE_SUMMARY_FACTORY); + return payerSigIsActive(platformTxn); } private boolean invokeOtherPartySigActivationScenario(List knownSigs) { @@ -398,10 +399,11 @@ private SignatureStatus invokeExpansionScenario() { targetWaclSigns, new MockGlobalDynamicProps()); - return expandIn(platformTxn, keyOrder, DefaultSigBytesProvider.DEFAULT_SIG_BYTES, BodySigningSigFactory::new); + final var pkToSigFn = new SigMapPubKeyToSigBytes(platformTxn.getSigMap()); + return expandIn(platformTxn, keyOrder, pkToSigFn); } - private SignatureStatus invokeRationalizationScenario() throws Exception { + private SignatureStatus invokeRationalizationScenario() { SyncVerifier syncVerifier = new CryptoEngine()::verifySync; SigMetadataLookup sigMetaLookups = defaultLookupsFor(hfs, () -> accounts, () -> null, ref -> null, ref -> null); HederaSigningOrder keyOrder = new HederaSigningOrder( @@ -415,8 +417,8 @@ private SignatureStatus invokeRationalizationScenario() throws Exception { platformTxn, syncVerifier, keyOrder, - DefaultSigBytesProvider.DEFAULT_SIG_BYTES, - BodySigningSigFactory::new); + new SigMapPubKeyToSigBytes(platformTxn.getSigMap()), + new BodySigningSigFactory(platformTxn)); } private void setupFor(TxnHandlingScenario scenario) throws Throwable { @@ -442,7 +444,7 @@ private void setupFor(TxnHandlingScenario scenario) throws Throwable { } else { PlatformSigsCreationResult payerResult = PlatformSigOps.createEd25519PlatformSigsFrom( payerKeys.getOrderedKeys(), - PubKeyToSigBytes.forPayer(platformTxn.getSignedTxnWrapper()), + new SigMapPubKeyToSigBytes(platformTxn.getSigMap()), new BodySigningSigFactory(platformTxn) ); expectedSigs.addAll(payerResult.getPlatformSigs()); @@ -453,7 +455,7 @@ private void setupFor(TxnHandlingScenario scenario) throws Throwable { } else { PlatformSigsCreationResult otherResult = PlatformSigOps.createEd25519PlatformSigsFrom( otherKeys.getOrderedKeys(), - PubKeyToSigBytes.forOtherParties(platformTxn.getSignedTxnWrapper()), + new SigMapPubKeyToSigBytes(platformTxn.getSigMap()), new BodySigningSigFactory(platformTxn) ); if (!otherResult.hasFailed()) { diff --git a/hedera-node/src/test/java/com/hedera/services/sigs/SigVerifierRegressionTest.java b/hedera-node/src/test/java/com/hedera/services/sigs/SigVerifierRegressionTest.java index ce6a25d38127..10a262c00986 100644 --- a/hedera-node/src/test/java/com/hedera/services/sigs/SigVerifierRegressionTest.java +++ b/hedera-node/src/test/java/com/hedera/services/sigs/SigVerifierRegressionTest.java @@ -28,6 +28,7 @@ import com.hedera.services.legacy.exception.KeyPrefixMismatchException; import com.hedera.services.security.ops.SystemOpPolicies; import com.hedera.services.sigs.order.HederaSigningOrder; +import com.hedera.services.sigs.sourcing.SigMapPubKeyToSigBytes; import com.hedera.services.sigs.utils.PrecheckUtils; import com.hedera.services.sigs.verification.PrecheckKeyReqs; import com.hedera.services.sigs.verification.PrecheckVerifier; @@ -52,7 +53,6 @@ import static com.hedera.services.security.ops.SystemOpAuthorization.AUTHORIZED; import static com.hedera.services.sigs.metadata.DelegatingSigMetadataLookup.defaultLookupsFor; import static com.hedera.services.sigs.metadata.DelegatingSigMetadataLookup.defaultLookupsPlusAccountRetriesFor; -import static com.hedera.services.sigs.sourcing.DefaultSigBytesProvider.DEFAULT_SIG_BYTES; import static com.hedera.test.CiConditions.isInCircleCi; import static com.hedera.test.factories.scenarios.BadPayerScenarios.INVALID_PAYER_ID_SCENARIO; import static com.hedera.test.factories.scenarios.CryptoTransferScenarios.CRYPTO_TRANSFER_RECEIVER_SIG_SCENARIO; @@ -236,7 +236,8 @@ private void setupFor(TxnHandlingScenario scenario) throws Throwable { isQueryPayment = PrecheckUtils.queryPaymentTestFor(DEFAULT_NODE); SyncVerifier syncVerifier = new CryptoEngine()::verifySync; precheckKeyReqs = new PrecheckKeyReqs(keyOrder, retryingKeyOrder, isQueryPayment); - precheckVerifier = new PrecheckVerifier(syncVerifier, precheckKeyReqs, DEFAULT_SIG_BYTES); + final var pkToSigFn = new SigMapPubKeyToSigBytes(platformTxn.getSigMap()); + precheckVerifier = new PrecheckVerifier(syncVerifier, precheckKeyReqs, ignore -> pkToSigFn); } } diff --git a/hedera-node/src/test/java/com/hedera/services/sigs/factories/BodySigningSigFactoryTest.java b/hedera-node/src/test/java/com/hedera/services/sigs/factories/BodySigningSigFactoryTest.java index 29289c31cf9d..6547fa570487 100644 --- a/hedera-node/src/test/java/com/hedera/services/sigs/factories/BodySigningSigFactoryTest.java +++ b/hedera-node/src/test/java/com/hedera/services/sigs/factories/BodySigningSigFactoryTest.java @@ -20,7 +20,6 @@ * ‍ */ -import com.google.protobuf.ByteString; import com.hedera.services.utils.SignedTxnAccessor; import com.swirlds.common.crypto.TransactionSignature; import org.junit.jupiter.api.Assertions; @@ -33,9 +32,9 @@ import static org.mockito.BDDMockito.given; import static org.mockito.BDDMockito.mock; -public class BodySigningSigFactoryTest { +class BodySigningSigFactoryTest { @Test - public void createsExpectedSig() { + void createsExpectedSig() { // setup: SignedTxnAccessor accessor = mock(SignedTxnAccessor.class); given(accessor.getTxnBytes()).willReturn(data); @@ -44,7 +43,7 @@ public void createsExpectedSig() { BodySigningSigFactory subject = new BodySigningSigFactory(accessor); // when: - TransactionSignature actualSig = subject.create(ByteString.copyFrom(pk), ByteString.copyFrom(sig)); + TransactionSignature actualSig = subject.create(pk, sig); // then: Assertions.assertEquals(EXPECTED_SIG, actualSig); diff --git a/hedera-node/src/test/java/com/hedera/services/sigs/factories/PlatformSigFactoryTest.java b/hedera-node/src/test/java/com/hedera/services/sigs/factories/PlatformSigFactoryTest.java index 12cd71168875..a3e0f5799908 100644 --- a/hedera-node/src/test/java/com/hedera/services/sigs/factories/PlatformSigFactoryTest.java +++ b/hedera-node/src/test/java/com/hedera/services/sigs/factories/PlatformSigFactoryTest.java @@ -49,8 +49,8 @@ public class PlatformSigFactoryTest { public static byte[] sig = SIG.getBytes(); public static byte[] data = DATA.getBytes(); - static byte[] pk = PK.getBytes(); - static TransactionSignature EXPECTED_SIG = new TransactionSignature( + public static byte[] pk = PK.getBytes(); + public static TransactionSignature EXPECTED_SIG = new TransactionSignature( CONTENTS.getBytes(), 0, sig.length, pk, 0, pk.length, diff --git a/hedera-node/src/test/java/com/hedera/services/sigs/factories/SigFactoryCreatorTest.java b/hedera-node/src/test/java/com/hedera/services/sigs/factories/SigFactoryCreatorTest.java deleted file mode 100644 index bf10b424ccae..000000000000 --- a/hedera-node/src/test/java/com/hedera/services/sigs/factories/SigFactoryCreatorTest.java +++ /dev/null @@ -1,84 +0,0 @@ -package com.hedera.services.sigs.factories; - -/*- - * ‌ - * Hedera Services Node - * ​ - * Copyright (C) 2018 - 2021 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. - * ‍ - */ - -import com.hedera.services.state.merkle.MerkleEntityId; -import com.hedera.services.state.merkle.MerkleSchedule; -import com.hedera.services.utils.SignedTxnAccessor; -import com.hederahashgraph.api.proto.java.AccountAmount; -import com.hederahashgraph.api.proto.java.AccountID; -import com.hederahashgraph.api.proto.java.CryptoTransferTransactionBody; -import com.hederahashgraph.api.proto.java.SignedTransaction; -import com.hederahashgraph.api.proto.java.Transaction; -import com.hederahashgraph.api.proto.java.TransactionBody; -import com.hederahashgraph.api.proto.java.TransferList; -import com.swirlds.fcmap.FCMap; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.instanceOf; -import static org.mockito.BDDMockito.mock; - -public class SigFactoryCreatorTest { - FCMap scheduledTxns; - - SignedTxnAccessor accessor; - - SigFactoryCreator subject; - - @BeforeEach - @SuppressWarnings("unchecked") - void setUp() { - scheduledTxns = (FCMap) mock(FCMap.class); - - subject = new SigFactoryCreator(); - } - - @Test - public void usesBodyBytesForNonScheduleTxn() { - givenScopedTxn(withoutLinkedSchedule()); - - // when: - var factory = subject.createScopedFactory(accessor); - - // then: - assertThat(factory, instanceOf(BodySigningSigFactory.class)); - } - - private void givenScopedTxn(TransactionBody txn) { - accessor = SignedTxnAccessor.uncheckedFrom(Transaction.newBuilder() - .setSignedTransactionBytes(SignedTransaction.newBuilder() - .setBodyBytes(txn.toByteString()).build().toByteString()) - .build()); - } - - private TransactionBody withoutLinkedSchedule() { - return TransactionBody.newBuilder() - .setMemo("You won't want to hear this.") - .setCryptoTransfer(CryptoTransferTransactionBody.newBuilder() - .setTransfers(TransferList.newBuilder() - .addAccountAmounts(AccountAmount.newBuilder() - .setAmount(123L) - .setAccountID(AccountID.newBuilder().setAccountNum(75231))))) - .build(); - } -} diff --git a/hedera-node/src/test/java/com/hedera/services/sigs/sourcing/ScopedSigBytesProviderTest.java b/hedera-node/src/test/java/com/hedera/services/sigs/sourcing/ScopedSigBytesProviderTest.java deleted file mode 100644 index 9b26d49ffc2f..000000000000 --- a/hedera-node/src/test/java/com/hedera/services/sigs/sourcing/ScopedSigBytesProviderTest.java +++ /dev/null @@ -1,73 +0,0 @@ -package com.hedera.services.sigs.sourcing; - -/*- - * ‌ - * Hedera Services Node - * ​ - * Copyright (C) 2018 - 2021 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. - * ‍ - */ - -import com.google.protobuf.InvalidProtocolBufferException; -import com.hedera.services.utils.SignedTxnAccessor; -import com.hederahashgraph.api.proto.java.AccountAmount; -import com.hederahashgraph.api.proto.java.AccountID; -import com.hederahashgraph.api.proto.java.CryptoTransferTransactionBody; -import com.hederahashgraph.api.proto.java.SignedTransaction; -import com.hederahashgraph.api.proto.java.Transaction; -import com.hederahashgraph.api.proto.java.TransactionBody; -import com.hederahashgraph.api.proto.java.TransferList; -import org.junit.jupiter.api.Test; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.instanceOf; -import static org.junit.jupiter.api.Assertions.assertSame; - -class ScopedSigBytesProviderTest { - SignedTxnAccessor accessor; - - ScopedSigBytesProvider subject; - - @Test - void usesStandardDelegate() throws InvalidProtocolBufferException { - givenSubject(withoutLinkedSchedule()); - - // expect: - assertThat(subject.delegate, instanceOf(SigMapPubKeyToSigBytes.class)); - // and: - assertSame(subject.payerSigBytesFor(null), subject.otherPartiesSigBytesFor(null)); - assertSame(subject.otherPartiesSigBytesFor(null), subject.allPartiesSigBytesFor(null)); - } - - private void givenSubject(TransactionBody txn) throws InvalidProtocolBufferException { - accessor = new SignedTxnAccessor(Transaction.newBuilder() - .setSignedTransactionBytes(SignedTransaction.newBuilder() - .setBodyBytes(txn.toByteString()) - .build().toByteString()) - .build()); - subject = new ScopedSigBytesProvider(accessor); - } - - private TransactionBody withoutLinkedSchedule() { - return TransactionBody.newBuilder() - .setMemo("You won't want to hear this.") - .setCryptoTransfer(CryptoTransferTransactionBody.newBuilder() - .setTransfers(TransferList.newBuilder() - .addAccountAmounts(AccountAmount.newBuilder() - .setAmount(123L) - .setAccountID(AccountID.newBuilder().setAccountNum(75231))))) - .build(); - } -} diff --git a/hedera-node/src/test/java/com/hedera/services/sigs/sourcing/SigMapPubKeyToSigBytesTest.java b/hedera-node/src/test/java/com/hedera/services/sigs/sourcing/SigMapPubKeyToSigBytesTest.java index d2ceecf446ad..1b310ce2a053 100644 --- a/hedera-node/src/test/java/com/hedera/services/sigs/sourcing/SigMapPubKeyToSigBytesTest.java +++ b/hedera-node/src/test/java/com/hedera/services/sigs/sourcing/SigMapPubKeyToSigBytesTest.java @@ -23,6 +23,8 @@ import com.google.protobuf.ByteString; import com.hedera.services.legacy.exception.KeyPrefixMismatchException; import com.hedera.services.legacy.proto.utils.CommonUtils; +import com.hedera.services.utils.PlatformTxnAccessor; +import com.hedera.services.utils.SignedTxnAccessor; import com.hedera.test.factories.keys.KeyFactory; import com.hedera.test.factories.keys.KeyTree; import com.hedera.test.factories.keys.KeyTreeLeaf; @@ -50,50 +52,22 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; -public class SigMapPubKeyToSigBytesTest { +class SigMapPubKeyToSigBytesTest { private final byte[] EMPTY_SIG = { }; private final KeyTree payerKt = KeyTree.withRoot(list(ed25519(true), ed25519(true), ed25519(true), ecdsa384(true), rsa3072(true))); private final KeyTree otherKt = KeyTree.withRoot(list(ed25519(true), ed25519(true), ed25519(true))); private final KeyFactory defaultFactory = KeyFactory.getDefaultInstance(); - private final KeyFactory overlapFactory = new KeyFactory(OverlappingKeyGenerator.withDefaultOverlaps()); - private final SigMapGenerator ambigSigMapGen = SigMapGenerator.withAmbiguousPrefixes(); @Test - public void getsExpectedSigBytesForPayer() throws Throwable { + void getsExpectedSigBytesForOtherParties() throws Throwable { // given: Transaction signedTxn = newSignedSystemDelete() .payerKt(payerKt) .nonPayerKts(otherKt) .get(); - PubKeyToSigBytes subject = PubKeyToSigBytes.forPayer(signedTxn); - - // expect: - lookupsMatch(payerKt, defaultFactory, CommonUtils.extractTransactionBodyBytes(signedTxn), subject); - } - - @Test - public void getsExpectedSigBytesForOtherParties() throws Throwable { - // given: - Transaction signedTxn = newSignedSystemDelete() - .payerKt(payerKt) - .nonPayerKts(otherKt) - .get(); - PubKeyToSigBytes subject = PubKeyToSigBytes.forOtherParties(signedTxn); - - // expect: - lookupsMatch(otherKt, defaultFactory, CommonUtils.extractTransactionBodyBytes(signedTxn), subject); - } - - @Test - public void getsExpectedSigBytesForAllParties() throws Throwable { - // given: - Transaction signedTxn = newSignedSystemDelete() - .payerKt(payerKt) - .nonPayerKts(otherKt) - .get(); - PubKeyToSigBytes subject = PubKeyToSigBytes.forAllParties(signedTxn); + PubKeyToSigBytes subject = new SigMapPubKeyToSigBytes(SignedTxnAccessor.uncheckedFrom(signedTxn).getSigMap()); // expect: lookupsMatch(payerKt, defaultFactory, CommonUtils.extractTransactionBodyBytes(signedTxn), subject); @@ -101,7 +75,7 @@ public void getsExpectedSigBytesForAllParties() throws Throwable { } @Test - public void rejectsNonUniqueSigBytes() { + void rejectsNonUniqueSigBytes() { // given: String str = "TEST_STRING"; byte[] pubKey = str.getBytes(StandardCharsets.UTF_8); diff --git a/hedera-node/src/test/java/com/hedera/services/sigs/verification/PrecheckKeyReqsTest.java b/hedera-node/src/test/java/com/hedera/services/sigs/verification/PrecheckKeyReqsTest.java index e36dcd58676f..dfa7031de2a5 100644 --- a/hedera-node/src/test/java/com/hedera/services/sigs/verification/PrecheckKeyReqsTest.java +++ b/hedera-node/src/test/java/com/hedera/services/sigs/verification/PrecheckKeyReqsTest.java @@ -69,7 +69,7 @@ private void setup() { } @Test - public void throwsGenericExceptionAsExpected() throws Exception { + void throwsGenericExceptionAsExpected() { given(keyOrder.keysForPayer(txn, PRE_HANDLE_SUMMARY_FACTORY)) .willReturn(new SigningOrderResult<>(PAYER_KEYS)); given(keyOrderModuloRetry.keysForOtherParties(txn, PRE_HANDLE_SUMMARY_FACTORY)) @@ -81,7 +81,7 @@ public void throwsGenericExceptionAsExpected() throws Exception { } @Test - public void throwsInvalidAccountAsExpected() throws Exception { + void throwsInvalidAccountAsExpected() { given(keyOrder.keysForPayer(txn, PRE_HANDLE_SUMMARY_FACTORY)) .willReturn(new SigningOrderResult<>(PAYER_KEYS)); given(keyOrderModuloRetry.keysForOtherParties(txn, PRE_HANDLE_SUMMARY_FACTORY)) @@ -93,7 +93,7 @@ public void throwsInvalidAccountAsExpected() throws Exception { } @Test - public void throwsInvalidPayerAccountAsExpected() throws Exception { + void throwsInvalidPayerAccountAsExpected() { given(keyOrder.keysForPayer(txn, PRE_HANDLE_SUMMARY_FACTORY)) .willReturn(factory.forInvalidAccount(invalidAccount, txnId)); givenImpliedSubject(FOR_NON_QUERY_PAYMENT); @@ -103,7 +103,7 @@ public void throwsInvalidPayerAccountAsExpected() throws Exception { } @Test - public void usesStdKeyOrderForNonQueryPayment() throws Exception { + void usesStdKeyOrderForNonQueryPayment() throws Exception { given(keyOrder.keysForPayer(txn, PRE_HANDLE_SUMMARY_FACTORY)) .willReturn(new SigningOrderResult<>(PAYER_KEYS)); givenImpliedSubject(FOR_NON_QUERY_PAYMENT); @@ -119,7 +119,7 @@ public void usesStdKeyOrderForNonQueryPayment() throws Exception { } @Test - public void usesBothOrderForQueryPayments() throws Exception { + void usesBothOrderForQueryPayments() throws Exception { given(keyOrder.keysForPayer(txn, PRE_HANDLE_SUMMARY_FACTORY)) .willReturn(new SigningOrderResult<>(PAYER_KEYS)); given(keyOrderModuloRetry.keysForOtherParties(txn, PRE_HANDLE_SUMMARY_FACTORY)) diff --git a/hedera-node/src/test/java/com/hedera/services/sigs/verification/PrecheckVerifierTest.java b/hedera-node/src/test/java/com/hedera/services/sigs/verification/PrecheckVerifierTest.java index b39414526ee3..c79d8b88e5bc 100644 --- a/hedera-node/src/test/java/com/hedera/services/sigs/verification/PrecheckVerifierTest.java +++ b/hedera-node/src/test/java/com/hedera/services/sigs/verification/PrecheckVerifierTest.java @@ -25,7 +25,6 @@ import com.hedera.services.sigs.PlatformSigOps; import com.hedera.services.sigs.factories.BodySigningSigFactory; import com.hedera.services.sigs.sourcing.PubKeyToSigBytes; -import com.hedera.services.sigs.sourcing.PubKeyToSigBytesProvider; import com.hedera.services.utils.PlatformTxnAccessor; import com.hedera.test.factories.keys.KeyTree; import com.hedera.test.factories.txns.PlatformTxnFactory; @@ -74,14 +73,13 @@ public class PrecheckVerifierTest { private int i = 0; @Override - public byte[] sigBytesFor(byte[] pubKey) throws Exception { + public byte[] sigBytesFor(byte[] pubKey) { return VALID_SIG_BYTES[i++]; } }; private static List expectedSigs = EMPTY_LIST; private PrecheckKeyReqs precheckKeyReqs; - private PubKeyToSigBytesProvider provider; private PrecheckVerifier subject; @BeforeAll @@ -96,14 +94,12 @@ static void setupAll() throws Throwable { @BeforeEach void setup() { - provider = mock(PubKeyToSigBytesProvider.class); precheckKeyReqs = mock(PrecheckKeyReqs.class); } @Test - public void affirmsValidSignatures() throws Exception { + void affirmsValidSignatures() throws Exception { given(precheckKeyReqs.getRequiredKeys(txnBody)).willReturn(reqKeys); - given(provider.allPartiesSigBytesFor(txn)).willReturn(VALID_PROVIDER_FACTORY.get()); AtomicReference> actualSigsVerified = new AtomicReference<>(); givenImpliedSubject(sigs -> { actualSigsVerified.set(sigs); @@ -119,9 +115,8 @@ public void affirmsValidSignatures() throws Exception { } @Test - public void rejectsInvalidSignatures() throws Exception { + void rejectsInvalidSignatures() throws Exception { given(precheckKeyReqs.getRequiredKeys(txnBody)).willReturn(reqKeys); - given(provider.allPartiesSigBytesFor(txn)).willReturn(VALID_PROVIDER_FACTORY.get()); AtomicReference> actualSigsVerified = new AtomicReference<>(); givenImpliedSubject(sigs -> { actualSigsVerified.set(sigs); @@ -137,19 +132,21 @@ public void rejectsInvalidSignatures() throws Exception { } @Test - public void propagatesSigCreationFailure() throws Exception { + void propagatesSigCreationFailure() throws Exception { given(precheckKeyReqs.getRequiredKeys(txnBody)).willReturn(reqKeys); - given(provider.allPartiesSigBytesFor(txn)).willReturn(bytes -> { - throw new KeyPrefixMismatchException("Oops!"); - }); - givenImpliedSubject(ALWAYS_VALID); + subject = new PrecheckVerifier( + ALWAYS_VALID, + precheckKeyReqs, + ignore -> bytes -> { + throw new KeyPrefixMismatchException("Oops!"); + }); // expect: assertThrows(KeyPrefixMismatchException.class, () -> subject.hasNecessarySignatures(accessor)); } @Test - public void rejectsGivenInvalidPayerException() throws Exception { + void rejectsGivenInvalidPayerException() throws Exception { given(precheckKeyReqs.getRequiredKeys(txnBody)).willThrow(new InvalidPayerAccountException()); givenImpliedSubject(ALWAYS_VALID); @@ -158,7 +155,7 @@ public void rejectsGivenInvalidPayerException() throws Exception { } @Test - public void propagatesOtherKeyLookupExceptions() throws Exception { + void propagatesOtherKeyLookupExceptions() throws Exception { given(precheckKeyReqs.getRequiredKeys(txnBody)).willThrow(new IllegalStateException()); givenImpliedSubject(ALWAYS_VALID); @@ -167,7 +164,7 @@ public void propagatesOtherKeyLookupExceptions() throws Exception { } @Test - public void affirmsValidSignaturesInSignedTxn() throws Exception { + void affirmsValidSignaturesInSignedTxn() throws Exception { //setUp SignedTransaction signedTransaction = SignedTransaction.newBuilder().setBodyBytes( txnBody.toByteString()).build(); @@ -178,7 +175,6 @@ public void affirmsValidSignaturesInSignedTxn() throws Exception { //given given(precheckKeyReqs.getRequiredKeys(TransactionBody.parseFrom(signedTransaction.getBodyBytes()))). willReturn(reqKeys); - given(provider.allPartiesSigBytesFor(signedTxn)).willReturn(VALID_PROVIDER_FACTORY.get()); AtomicReference> actualSigsVerified = new AtomicReference<>(); givenImpliedSubject(sigs -> { actualSigsVerified.set(sigs); @@ -194,6 +190,6 @@ public void affirmsValidSignaturesInSignedTxn() throws Exception { } private void givenImpliedSubject(SyncVerifier syncVerifier) { - subject = new PrecheckVerifier(syncVerifier, precheckKeyReqs, provider); + subject = new PrecheckVerifier(syncVerifier, precheckKeyReqs, ignore -> VALID_PROVIDER_FACTORY.get()); } } diff --git a/hedera-node/src/test/java/com/hedera/services/store/tokens/HederaTokenStoreTest.java b/hedera-node/src/test/java/com/hedera/services/store/tokens/HederaTokenStoreTest.java index 881c7c100423..68783b9e415b 100644 --- a/hedera-node/src/test/java/com/hedera/services/store/tokens/HederaTokenStoreTest.java +++ b/hedera-node/src/test/java/com/hedera/services/store/tokens/HederaTokenStoreTest.java @@ -121,55 +121,55 @@ import static org.mockito.Mockito.times; class HederaTokenStoreTest { - EntityIdSource ids; - GlobalDynamicProperties properties; - FCMap tokens; - TransactionalLedger accountsLedger; - TransactionalLedger, TokenRelProperty, MerkleTokenRelStatus> tokenRelsLedger; - HederaLedger hederaLedger; - - MerkleToken token; - MerkleToken modifiableToken; - MerkleAccount account; - - Key newKey = TxnHandlingScenario.TOKEN_REPLACE_KT.asKey(); - JKey newFcKey = TxnHandlingScenario.TOKEN_REPLACE_KT.asJKeyUnchecked(); - Key adminKey, kycKey, freezeKey, supplyKey, wipeKey; - String symbol = "NOTHBAR"; - String newSymbol = "REALLYSOM"; - String newMemo = "NEWMEMO"; - String memo = "TOKENMEMO"; - String name = "TOKENNAME"; - String newName = "NEWNAME"; - long expiry = CONSENSUS_NOW + 1_234_567; - long newExpiry = CONSENSUS_NOW + 1_432_765; - long totalSupply = 1_000_000; - long adjustment = 1; - int decimals = 10; - long treasuryBalance = 50_000, sponsorBalance = 1_000; - TokenID misc = IdUtils.asToken("3.2.1"); - TokenID anotherMisc = IdUtils.asToken("6.4.2"); - boolean freezeDefault = true; - boolean accountsKycGrantedByDefault = false; - long autoRenewPeriod = 500_000; - long newAutoRenewPeriod = 2_000_000; - AccountID autoRenewAccount = IdUtils.asAccount("1.2.5"); - AccountID newAutoRenewAccount = IdUtils.asAccount("1.2.6"); - AccountID treasury = IdUtils.asAccount("1.2.3"); - AccountID newTreasury = IdUtils.asAccount("3.2.1"); - AccountID sponsor = IdUtils.asAccount("1.2.666"); - TokenID created = IdUtils.asToken("1.2.666666"); - TokenID pending = IdUtils.asToken("1.2.555555"); - int MAX_TOKENS_PER_ACCOUNT = 100; - int MAX_TOKEN_SYMBOL_UTF8_BYTES = 10; - int MAX_TOKEN_NAME_UTF8_BYTES = 100; - Pair sponsorMisc = asTokenRel(sponsor, misc); - Pair treasuryMisc = asTokenRel(treasury, misc); - - HederaTokenStore subject; + private EntityIdSource ids; + private GlobalDynamicProperties properties; + private FCMap tokens; + private TransactionalLedger accountsLedger; + private TransactionalLedger, TokenRelProperty, MerkleTokenRelStatus> tokenRelsLedger; + private HederaLedger hederaLedger; + + private MerkleToken token; + private MerkleToken modifiableToken; + private MerkleAccount account; + + private Key newKey = TxnHandlingScenario.TOKEN_REPLACE_KT.asKey(); + private JKey newFcKey = TxnHandlingScenario.TOKEN_REPLACE_KT.asJKeyUnchecked(); + private Key adminKey, kycKey, freezeKey, supplyKey, wipeKey; + private String symbol = "NOTHBAR"; + private String newSymbol = "REALLYSOM"; + private String newMemo = "NEWMEMO"; + private String memo = "TOKENMEMO"; + private String name = "TOKENNAME"; + private String newName = "NEWNAME"; + private long expiry = CONSENSUS_NOW + 1_234_567; + private long newExpiry = CONSENSUS_NOW + 1_432_765; + private long totalSupply = 1_000_000; + private long adjustment = 1; + private int decimals = 10; + private long treasuryBalance = 50_000, sponsorBalance = 1_000; + private TokenID misc = IdUtils.asToken("3.2.1"); + private TokenID anotherMisc = IdUtils.asToken("6.4.2"); + private boolean freezeDefault = true; + private boolean accountsKycGrantedByDefault = false; + private long autoRenewPeriod = 500_000; + private long newAutoRenewPeriod = 2_000_000; + private AccountID autoRenewAccount = IdUtils.asAccount("1.2.5"); + private AccountID newAutoRenewAccount = IdUtils.asAccount("1.2.6"); + private AccountID treasury = IdUtils.asAccount("1.2.3"); + private AccountID newTreasury = IdUtils.asAccount("3.2.1"); + private AccountID sponsor = IdUtils.asAccount("1.2.666"); + private TokenID created = IdUtils.asToken("1.2.666666"); + private TokenID pending = IdUtils.asToken("1.2.555555"); + private int MAX_TOKENS_PER_ACCOUNT = 100; + private int MAX_TOKEN_SYMBOL_UTF8_BYTES = 10; + private int MAX_TOKEN_NAME_UTF8_BYTES = 100; + private Pair sponsorMisc = asTokenRel(sponsor, misc); + private Pair treasuryMisc = asTokenRel(treasury, misc); + + private HederaTokenStore subject; @BeforeEach - public void setup() { + void setup() { adminKey = TOKEN_ADMIN_KT.asKey(); kycKey = TOKEN_KYC_KT.asKey(); freezeKey = TOKEN_FREEZE_KT.asKey(); @@ -256,13 +256,13 @@ void rebuildsAsExpected() { } @Test - public void injectsTokenRelsLedger() { + void injectsTokenRelsLedger() { // expect: verify(hederaLedger).setTokenRelsLedger(tokenRelsLedger); } @Test - public void applicationRejectsMissing() { + void applicationRejectsMissing() { // setup: var change = mock(Consumer.class); @@ -273,7 +273,7 @@ public void applicationRejectsMissing() { } @Test - public void applicationAlwaysReplacesModifiableToken() { + void applicationAlwaysReplacesModifiableToken() { // setup: var change = mock(Consumer.class); var key = fromTokenId(misc); @@ -287,7 +287,7 @@ public void applicationAlwaysReplacesModifiableToken() { } @Test - public void applicationWorks() { + void applicationWorks() { // setup: var change = mock(Consumer.class); // and: @@ -302,7 +302,7 @@ public void applicationWorks() { } @Test - public void deletionWorksAsExpected() { + void deletionWorksAsExpected() { // when: TokenStore.DELETION.accept(token); @@ -311,7 +311,7 @@ public void deletionWorksAsExpected() { } @Test - public void deletesAsExpected() { + void deletesAsExpected() { // given: given(tokens.getForModify(fromTokenId(misc))).willReturn(token); @@ -325,7 +325,7 @@ public void deletesAsExpected() { } @Test - public void rejectsDeletionMissingAdminKey() { + void rejectsDeletionMissingAdminKey() { // given: given(token.adminKey()).willReturn(Optional.empty()); @@ -337,7 +337,7 @@ public void rejectsDeletionMissingAdminKey() { } @Test - public void rejectsDeletionTokenAlreadyDeleted() { + void rejectsDeletionTokenAlreadyDeleted() { // given: given(token.isDeleted()).willReturn(true); @@ -349,7 +349,7 @@ public void rejectsDeletionTokenAlreadyDeleted() { } @Test - public void rejectsMissingDeletion() { + void rejectsMissingDeletion() { // given: var mockSubject = mock(TokenStore.class); @@ -365,13 +365,13 @@ public void rejectsMissingDeletion() { } @Test - public void getDelegates() { + void getDelegates() { // expect: assertSame(token, subject.get(misc)); } @Test - public void getThrowsIseOnMissing() { + void getThrowsIseOnMissing() { given(tokens.containsKey(fromTokenId(misc))).willReturn(false); // expect: @@ -379,7 +379,7 @@ public void getThrowsIseOnMissing() { } @Test - public void getCanReturnPending() { + void getCanReturnPending() { // setup: subject.pendingId = pending; subject.pendingCreation = token; @@ -389,13 +389,13 @@ public void getCanReturnPending() { } @Test - public void existenceCheckUnderstandsPendingIdOnlyAppliesIfCreationPending() { + void existenceCheckUnderstandsPendingIdOnlyAppliesIfCreationPending() { // expect: assertFalse(subject.exists(HederaTokenStore.NO_PENDING_ID)); } @Test - public void existenceCheckIncludesPending() { + void existenceCheckIncludesPending() { // setup: subject.pendingId = pending; @@ -404,7 +404,7 @@ public void existenceCheckIncludesPending() { } @Test - public void freezingRejectsMissingAccount() { + void freezingRejectsMissingAccount() { given(accountsLedger.exists(sponsor)).willReturn(false); // when: @@ -415,7 +415,7 @@ public void freezingRejectsMissingAccount() { } @Test - public void associatingRejectsDeletedTokens() { + void associatingRejectsDeletedTokens() { given(token.isDeleted()).willReturn(true); // when: @@ -426,7 +426,7 @@ public void associatingRejectsDeletedTokens() { } @Test - public void associatingRejectsMissingToken() { + void associatingRejectsMissingToken() { given(tokens.containsKey(fromTokenId(misc))).willReturn(false); // when: @@ -437,7 +437,7 @@ public void associatingRejectsMissingToken() { } @Test - public void associatingRejectsMissingAccounts() { + void associatingRejectsMissingAccounts() { given(accountsLedger.exists(sponsor)).willReturn(false); // when: @@ -448,13 +448,13 @@ public void associatingRejectsMissingAccounts() { } @Test - public void realAssociationsExist() { + void realAssociationsExist() { // expect: assertTrue(subject.associationExists(sponsor, misc)); } @Test - public void noAssociationsWithMissingAccounts() { + void noAssociationsWithMissingAccounts() { given(accountsLedger.exists(sponsor)).willReturn(false); // expect: @@ -462,7 +462,7 @@ public void noAssociationsWithMissingAccounts() { } @Test - public void dissociatingRejectsUnassociatedTokens() { + void dissociatingRejectsUnassociatedTokens() { // setup: var tokens = mock(MerkleAccountTokens.class); given(tokens.includes(misc)).willReturn(false); @@ -476,7 +476,7 @@ public void dissociatingRejectsUnassociatedTokens() { } @Test - public void dissociatingRejectsTreasuryAccount() { + void dissociatingRejectsTreasuryAccount() { // setup: var tokens = mock(MerkleAccountTokens.class); given(tokens.includes(misc)).willReturn(true); @@ -492,7 +492,7 @@ public void dissociatingRejectsTreasuryAccount() { } @Test - public void dissociatingRejectsFrozenAccount() { + void dissociatingRejectsFrozenAccount() { // setup: var tokens = mock(MerkleAccountTokens.class); given(tokens.includes(misc)).willReturn(true); @@ -507,7 +507,7 @@ public void dissociatingRejectsFrozenAccount() { } @Test - public void associatingRejectsAlreadyAssociatedTokens() { + void associatingRejectsAlreadyAssociatedTokens() { // setup: var tokens = mock(MerkleAccountTokens.class); given(tokens.includes(misc)).willReturn(true); @@ -521,7 +521,7 @@ public void associatingRejectsAlreadyAssociatedTokens() { } @Test - public void associatingRejectsIfCappedAssociationsLimit() { + void associatingRejectsIfCappedAssociationsLimit() { // setup: var tokens = mock(MerkleAccountTokens.class); given(tokens.includes(misc)).willReturn(false); @@ -539,7 +539,7 @@ public void associatingRejectsIfCappedAssociationsLimit() { } @Test - public void associatingHappyPathWorks() { + void associatingHappyPathWorks() { // setup: var tokens = mock(MerkleAccountTokens.class); var key = asTokenRel(sponsor, misc); @@ -565,7 +565,7 @@ public void associatingHappyPathWorks() { } @Test - public void dissociatingWorksEvenIfTokenDoesntExistAnymore() { + void dissociatingWorksEvenIfTokenDoesntExistAnymore() { // setup: var accountTokens = mock(MerkleAccountTokens.class); var key = asTokenRel(sponsor, misc); @@ -587,7 +587,7 @@ public void dissociatingWorksEvenIfTokenDoesntExistAnymore() { } @Test - public void dissociatingHappyPathWorks() { + void dissociatingHappyPathWorks() { // setup: var tokens = mock(MerkleAccountTokens.class); var key = asTokenRel(sponsor, misc); @@ -608,7 +608,7 @@ public void dissociatingHappyPathWorks() { } @Test - public void dissociatingFailsIfTokenBalanceIsNonzero() { + void dissociatingFailsIfTokenBalanceIsNonzero() { // setup: var tokens = mock(MerkleAccountTokens.class); var key = asTokenRel(sponsor, misc); @@ -630,7 +630,7 @@ public void dissociatingFailsIfTokenBalanceIsNonzero() { } @Test - public void dissociatingPermitsFrozenRelIfDeleted() { + void dissociatingPermitsFrozenRelIfDeleted() { // setup: var tokens = mock(MerkleAccountTokens.class); var key = asTokenRel(sponsor, misc); @@ -654,7 +654,7 @@ public void dissociatingPermitsFrozenRelIfDeleted() { } @Test - public void dissociatingPermitsNonzeroTokenBalanceIfDeleted() { + void dissociatingPermitsNonzeroTokenBalanceIfDeleted() { // setup: var tokens = mock(MerkleAccountTokens.class); var key = asTokenRel(sponsor, misc); @@ -677,7 +677,7 @@ public void dissociatingPermitsNonzeroTokenBalanceIfDeleted() { } @Test - public void dissociatingPermitsNonzeroTokenBalanceIfExpired() { + void dissociatingPermitsNonzeroTokenBalanceIfExpired() { // setup: long balance = 123L; var tokens = mock(MerkleAccountTokens.class); @@ -702,7 +702,7 @@ public void dissociatingPermitsNonzeroTokenBalanceIfExpired() { } @Test - public void grantingKycRejectsMissingAccount() { + void grantingKycRejectsMissingAccount() { given(accountsLedger.exists(sponsor)).willReturn(false); // when: @@ -713,7 +713,7 @@ public void grantingKycRejectsMissingAccount() { } @Test - public void grantingKycRejectsDetachedAccount() { + void grantingKycRejectsDetachedAccount() { given(accountsLedger.exists(sponsor)).willReturn(true); given(hederaLedger.isDetached(sponsor)).willReturn(true); @@ -725,7 +725,7 @@ public void grantingKycRejectsDetachedAccount() { } @Test - public void grantingKycRejectsDeletedAccount() { + void grantingKycRejectsDeletedAccount() { given(accountsLedger.exists(sponsor)).willReturn(true); given(hederaLedger.isDeleted(sponsor)).willReturn(true); @@ -737,7 +737,7 @@ public void grantingKycRejectsDeletedAccount() { } @Test - public void revokingKycRejectsMissingAccount() { + void revokingKycRejectsMissingAccount() { given(accountsLedger.exists(sponsor)).willReturn(false); // when: @@ -748,7 +748,7 @@ public void revokingKycRejectsMissingAccount() { } @Test - public void wipingRejectsMissingAccount() { + void wipingRejectsMissingAccount() { given(accountsLedger.exists(sponsor)).willReturn(false); // when: @@ -759,7 +759,7 @@ public void wipingRejectsMissingAccount() { } @Test - public void wipingRejectsTokenWithNoWipeKey() { + void wipingRejectsTokenWithNoWipeKey() { // when: given(token.treasury()).willReturn(EntityId.fromGrpcAccountId(treasury)); @@ -771,7 +771,7 @@ public void wipingRejectsTokenWithNoWipeKey() { } @Test - public void wipingRejectsTokenTreasury() { + void wipingRejectsTokenTreasury() { long wiping = 3L; given(token.hasWipeKey()).willReturn(true); @@ -786,7 +786,7 @@ public void wipingRejectsTokenTreasury() { } @Test - public void wipingWithoutTokenRelationshipFails() { + void wipingWithoutTokenRelationshipFails() { // setup: given(token.hasWipeKey()).willReturn(false); given(token.treasury()).willReturn(EntityId.fromGrpcAccountId(treasury)); @@ -802,7 +802,7 @@ public void wipingWithoutTokenRelationshipFails() { } @Test - public void wipingWorksWithoutWipeKeyIfCheckSkipped() { + void wipingWorksWithoutWipeKeyIfCheckSkipped() { // setup: given(token.hasWipeKey()).willReturn(false); given(token.treasury()).willReturn(EntityId.fromGrpcAccountId(treasury)); @@ -823,7 +823,7 @@ public void wipingWorksWithoutWipeKeyIfCheckSkipped() { } @Test - public void wipingUpdatesTokenXfersAsExpected() { + void wipingUpdatesTokenXfersAsExpected() { // setup: given(token.hasWipeKey()).willReturn(true); given(token.treasury()).willReturn(EntityId.fromGrpcAccountId(treasury)); @@ -845,7 +845,7 @@ public void wipingUpdatesTokenXfersAsExpected() { } @Test - public void wipingFailsWithInvalidWipingAmount() { + void wipingFailsWithInvalidWipingAmount() { // setup: long wipe = 1_235L; @@ -861,7 +861,7 @@ public void wipingFailsWithInvalidWipingAmount() { } @Test - public void adjustingRejectsMissingAccount() { + void adjustingRejectsMissingAccount() { given(accountsLedger.exists(sponsor)).willReturn(false); // when: @@ -872,7 +872,7 @@ public void adjustingRejectsMissingAccount() { } @Test - public void updateRejectsInvalidExpiry() { + void updateRejectsInvalidExpiry() { given(tokens.getForModify(fromTokenId(misc))).willReturn(token); // given: var op = updateWith(NO_KEYS, true, true, false); @@ -886,7 +886,7 @@ public void updateRejectsInvalidExpiry() { } @Test - public void updateRejectsImmutableToken() { + void updateRejectsImmutableToken() { given(token.hasAdminKey()).willReturn(false); given(tokens.getForModify(fromTokenId(misc))).willReturn(token); // given: @@ -900,7 +900,7 @@ public void updateRejectsImmutableToken() { } @Test - public void canExtendImmutableExpiry() { + void canExtendImmutableExpiry() { given(token.hasAdminKey()).willReturn(false); given(tokens.getForModify(fromTokenId(misc))).willReturn(token); // given: @@ -915,7 +915,7 @@ public void canExtendImmutableExpiry() { } @Test - public void updateRejectsInvalidNewAutoRenew() { + void updateRejectsInvalidNewAutoRenew() { given(accountsLedger.exists(newAutoRenewAccount)).willReturn(false); // and: var op = updateWith(NO_KEYS, true, true, false, true, false); @@ -928,7 +928,7 @@ public void updateRejectsInvalidNewAutoRenew() { } @Test - public void updateRejectsInvalidNewAutoRenewPeriod() { + void updateRejectsInvalidNewAutoRenewPeriod() { given(tokens.getForModify(fromTokenId(misc))).willReturn(token); // and: var op = updateWith(NO_KEYS, true, true, false, false, false); @@ -942,7 +942,7 @@ public void updateRejectsInvalidNewAutoRenewPeriod() { } @Test - public void updateRejectsMissingToken() { + void updateRejectsMissingToken() { given(tokens.containsKey(fromTokenId(misc))).willReturn(false); // and: givenUpdateTarget(ALL_KEYS); @@ -958,7 +958,7 @@ public void updateRejectsMissingToken() { @Test - public void updateRejectsInappropriateKycKey() { + void updateRejectsInappropriateKycKey() { given(tokens.getForModify(fromTokenId(misc))).willReturn(token); // and: givenUpdateTarget(NO_KEYS); @@ -973,7 +973,7 @@ public void updateRejectsInappropriateKycKey() { } @Test - public void updateRejectsInappropriateFreezeKey() { + void updateRejectsInappropriateFreezeKey() { given(tokens.getForModify(fromTokenId(misc))).willReturn(token); // and: givenUpdateTarget(NO_KEYS); @@ -988,7 +988,7 @@ public void updateRejectsInappropriateFreezeKey() { } @Test - public void updateRejectsInappropriateWipeKey() { + void updateRejectsInappropriateWipeKey() { given(tokens.getForModify(fromTokenId(misc))).willReturn(token); // and: givenUpdateTarget(NO_KEYS); @@ -1003,7 +1003,7 @@ public void updateRejectsInappropriateWipeKey() { } @Test - public void updateRejectsInappropriateSupplyKey() { + void updateRejectsInappropriateSupplyKey() { given(tokens.getForModify(fromTokenId(misc))).willReturn(token); // and: givenUpdateTarget(NO_KEYS); @@ -1018,7 +1018,7 @@ public void updateRejectsInappropriateSupplyKey() { } @Test - public void treasuryRemovalForTokenRemovesKeyWhenEmpty() { + void treasuryRemovalForTokenRemovesKeyWhenEmpty() { Set tokenSet = new HashSet<>(Arrays.asList(misc)); subject.knownTreasuries.put(treasury, tokenSet); @@ -1030,7 +1030,7 @@ public void treasuryRemovalForTokenRemovesKeyWhenEmpty() { } @Test - public void addKnownTreasuryWorks() { + void addKnownTreasuryWorks() { subject.addKnownTreasury(treasury, misc); // expect: @@ -1038,7 +1038,7 @@ public void addKnownTreasuryWorks() { } @Test - public void removeKnownTreasuryWorks() { + void removeKnownTreasuryWorks() { Set tokenSet = new HashSet<>(Arrays.asList(misc, anotherMisc)); subject.knownTreasuries.put(treasury, tokenSet); @@ -1051,7 +1051,7 @@ public void removeKnownTreasuryWorks() { } @Test - public void isKnownTreasuryWorks() { + void isKnownTreasuryWorks() { Set tokenSet = new HashSet<>(Arrays.asList(misc)); subject.knownTreasuries.put(treasury, tokenSet); @@ -1061,7 +1061,7 @@ public void isKnownTreasuryWorks() { } @Test - public void treasuriesServeWorks() { + void treasuriesServeWorks() { Set tokenSet = new HashSet<>(List.of(anotherMisc, misc)); subject.knownTreasuries.put(treasury, tokenSet); @@ -1077,7 +1077,7 @@ public void treasuriesServeWorks() { } @Test - public void isTreasuryForTokenWorks() { + void isTreasuryForTokenWorks() { Set tokenSet = new HashSet<>(Arrays.asList(misc)); subject.knownTreasuries.put(treasury, tokenSet); @@ -1087,7 +1087,7 @@ public void isTreasuryForTokenWorks() { } @Test - public void isTreasuryForTokenReturnsFalse() { + void isTreasuryForTokenReturnsFalse() { // setup: subject.knownTreasuries.clear(); @@ -1096,13 +1096,13 @@ public void isTreasuryForTokenReturnsFalse() { } @Test - public void throwsIfKnownTreasuryIsMissing() { + void throwsIfKnownTreasuryIsMissing() { // expect: assertThrows(IllegalArgumentException.class, () -> subject.removeKnownTreasuryForToken(null, misc)); } @Test - public void throwsIfInvalidTreasury() { + void throwsIfInvalidTreasury() { // setup: subject.knownTreasuries.clear(); @@ -1112,7 +1112,7 @@ public void throwsIfInvalidTreasury() { @Test - public void updateHappyPathIgnoresZeroExpiry() { + void updateHappyPathIgnoresZeroExpiry() { // setup: subject.addKnownTreasury(treasury, misc); Set tokenSet = new HashSet<>(); @@ -1137,7 +1137,7 @@ public void updateHappyPathIgnoresZeroExpiry() { } @Test - public void updateRemovesAdminKeyWhenAppropos() { + void updateRemovesAdminKeyWhenAppropos() { // setup: subject.addKnownTreasury(treasury, misc); @@ -1158,7 +1158,7 @@ public void updateRemovesAdminKeyWhenAppropos() { } @Test - public void updateHappyPathWorksForEverythingWithNewExpiry() { + void updateHappyPathWorksForEverythingWithNewExpiry() { // setup: subject.addKnownTreasury(treasury, misc); @@ -1191,7 +1191,7 @@ public void updateHappyPathWorksForEverythingWithNewExpiry() { } @Test - public void updateHappyPathWorksWithNewMemo() { + void updateHappyPathWorksWithNewMemo() { // setup: subject.addKnownTreasury(treasury, misc); @@ -1217,7 +1217,7 @@ public void updateHappyPathWorksWithNewMemo() { } @Test - public void updateHappyPathWorksWithNewAutoRenewAccount() { + void updateHappyPathWorksWithNewAutoRenewAccount() { // setup: subject.addKnownTreasury(treasury, misc); @@ -1342,7 +1342,7 @@ private void givenUpdateTarget(EnumSet keys) { } @Test - public void understandsPendingCreation() { + void understandsPendingCreation() { // expect: assertFalse(subject.isCreationPending()); @@ -1354,7 +1354,7 @@ public void understandsPendingCreation() { } @Test - public void adjustingRejectsMissingToken() { + void adjustingRejectsMissingToken() { given(tokens.containsKey(fromTokenId(misc))).willReturn(false); // when: @@ -1365,7 +1365,7 @@ public void adjustingRejectsMissingToken() { } @Test - public void freezingRejectsUnfreezableToken() { + void freezingRejectsUnfreezableToken() { given(token.freezeKey()).willReturn(Optional.empty()); // when: @@ -1376,7 +1376,7 @@ public void freezingRejectsUnfreezableToken() { } @Test - public void grantingRejectsUnknowableToken() { + void grantingRejectsUnknowableToken() { given(token.kycKey()).willReturn(Optional.empty()); // when: @@ -1387,7 +1387,7 @@ public void grantingRejectsUnknowableToken() { } @Test - public void mintingRejectsInvalidToken() { + void mintingRejectsInvalidToken() { given(tokens.containsKey(fromTokenId(misc))).willReturn(false); // when: @@ -1398,7 +1398,7 @@ public void mintingRejectsInvalidToken() { } @Test - public void mintingRejectsDetachedTreasury() { + void mintingRejectsDetachedTreasury() { given(token.hasSupplyKey()).willReturn(true); given(hederaLedger.isDetached(treasury)).willReturn(true); @@ -1410,7 +1410,7 @@ public void mintingRejectsDetachedTreasury() { } @Test - public void burningRejectsInvalidToken() { + void burningRejectsInvalidToken() { given(tokens.containsKey(fromTokenId(misc))).willReturn(false); // when: @@ -1421,7 +1421,7 @@ public void burningRejectsInvalidToken() { } @Test - public void mintingRejectsFixedSupplyToken() { + void mintingRejectsFixedSupplyToken() { given(token.hasSupplyKey()).willReturn(false); // when: @@ -1432,7 +1432,7 @@ public void mintingRejectsFixedSupplyToken() { } @Test - public void burningRejectsFixedSupplyToken() { + void burningRejectsFixedSupplyToken() { given(token.hasSupplyKey()).willReturn(false); // when: @@ -1443,7 +1443,7 @@ public void burningRejectsFixedSupplyToken() { } @Test - public void burningRejectsDetachedTreasury() { + void burningRejectsDetachedTreasury() { given(token.hasSupplyKey()).willReturn(true); given(token.totalSupply()).willReturn(treasuryBalance); given(hederaLedger.isDetached(treasury)).willReturn(true); @@ -1456,7 +1456,7 @@ public void burningRejectsDetachedTreasury() { } @Test - public void mintingRejectsNegativeMintAmount() { + void mintingRejectsNegativeMintAmount() { given(token.hasSupplyKey()).willReturn(true); // when: @@ -1467,7 +1467,7 @@ public void mintingRejectsNegativeMintAmount() { } @Test - public void burningRejectsDueToInsufficientFundsInTreasury() { + void burningRejectsDueToInsufficientFundsInTreasury() { given(token.hasSupplyKey()).willReturn(true); given(token.totalSupply()).willReturn(treasuryBalance * 2); given(token.treasury()).willReturn(EntityId.fromGrpcAccountId(treasury)); @@ -1480,7 +1480,7 @@ public void burningRejectsDueToInsufficientFundsInTreasury() { } @Test - public void mintingRejectsInvalidNewSupply() { + void mintingRejectsInvalidNewSupply() { long halfwayToOverflow = ((1L << 63) - 1) / 2; given(token.hasSupplyKey()).willReturn(true); @@ -1494,7 +1494,7 @@ public void mintingRejectsInvalidNewSupply() { } @Test - public void wipingRejectsDeletedToken() { + void wipingRejectsDeletedToken() { given(token.isDeleted()).willReturn(true); // when: @@ -1505,7 +1505,7 @@ public void wipingRejectsDeletedToken() { } @Test - public void mintingRejectsDeletedToken() { + void mintingRejectsDeletedToken() { given(token.isDeleted()).willReturn(true); // when: @@ -1516,7 +1516,7 @@ public void mintingRejectsDeletedToken() { } @Test - public void validBurnChangesTokenSupplyAndAdjustsTreasury() { + void validBurnChangesTokenSupplyAndAdjustsTreasury() { // setup: long oldSupply = 123; @@ -1543,7 +1543,7 @@ public void validBurnChangesTokenSupplyAndAdjustsTreasury() { } @Test - public void validMintChangesTokenSupplyAndAdjustsTreasury() { + void validMintChangesTokenSupplyAndAdjustsTreasury() { // setup: long oldTotalSupply = 1_000; long adjustment = 500; @@ -1572,7 +1572,7 @@ public void validMintChangesTokenSupplyAndAdjustsTreasury() { } @Test - public void burningRejectsAmountMoreThanFound() { + void burningRejectsAmountMoreThanFound() { long amount = 1; given(token.hasSupplyKey()).willReturn(true); @@ -1587,7 +1587,7 @@ public void burningRejectsAmountMoreThanFound() { } @Test - public void freezingRejectsDeletedToken() { + void freezingRejectsDeletedToken() { givenTokenWithFreezeKey(true); given(token.isDeleted()).willReturn(true); @@ -1599,7 +1599,7 @@ public void freezingRejectsDeletedToken() { } @Test - public void unfreezingInvalidWithoutFreezeKey() { + void unfreezingInvalidWithoutFreezeKey() { // when: var status = subject.unfreeze(treasury, misc); @@ -1608,7 +1608,7 @@ public void unfreezingInvalidWithoutFreezeKey() { } @Test - public void performsValidFreeze() { + void performsValidFreeze() { givenTokenWithFreezeKey(false); // when: @@ -1624,7 +1624,7 @@ private void givenTokenWithFreezeKey(boolean freezeDefault) { } @Test - public void adjustingRejectsDeletedToken() { + void adjustingRejectsDeletedToken() { given(token.isDeleted()).willReturn(true); // when: @@ -1635,7 +1635,7 @@ public void adjustingRejectsDeletedToken() { } @Test - public void refusesToAdjustFrozenRelationship() { + void refusesToAdjustFrozenRelationship() { given(tokenRelsLedger.get(treasuryMisc, IS_FROZEN)).willReturn(true); // when: var status = subject.adjustBalance(treasury, misc, -1); @@ -1645,7 +1645,7 @@ public void refusesToAdjustFrozenRelationship() { } @Test - public void refusesToAdjustRevokedKycRelationship() { + void refusesToAdjustRevokedKycRelationship() { given(tokenRelsLedger.get(treasuryMisc, IS_KYC_GRANTED)).willReturn(false); // when: var status = subject.adjustBalance(treasury, misc, -1); @@ -1655,7 +1655,7 @@ public void refusesToAdjustRevokedKycRelationship() { } @Test - public void refusesInvalidAdjustment() { + void refusesInvalidAdjustment() { // when: var status = subject.adjustBalance(treasury, misc, -treasuryBalance - 1); @@ -1664,7 +1664,7 @@ public void refusesInvalidAdjustment() { } @Test - public void performsValidAdjustment() { + void performsValidAdjustment() { given(tokens.get(fromTokenId(misc))).willReturn(token); // when: @@ -1675,7 +1675,7 @@ public void performsValidAdjustment() { } @Test - public void rollbackReclaimsIdAndClears() { + void rollbackReclaimsIdAndClears() { // setup: subject.pendingId = created; subject.pendingCreation = token; @@ -1692,14 +1692,14 @@ public void rollbackReclaimsIdAndClears() { } @Test - public void commitAndRollbackThrowIseIfNoPendingCreation() { + void commitAndRollbackThrowIseIfNoPendingCreation() { // expect: assertThrows(IllegalStateException.class, subject::commitCreation); assertThrows(IllegalStateException.class, subject::rollbackCreation); } @Test - public void commitPutsToMapAndClears() { + void commitPutsToMapAndClears() { // setup: subject.pendingId = created; subject.pendingCreation = token; @@ -1718,7 +1718,7 @@ public void commitPutsToMapAndClears() { } @Test - public void happyPathWorksWithAutoRenew() { + void happyPathWorksWithAutoRenew() { // setup: var expected = new MerkleToken( CONSENSUS_NOW + autoRenewPeriod, @@ -1757,7 +1757,7 @@ public void happyPathWorksWithAutoRenew() { } @Test - public void happyPathWorksWithExplicitExpiry() { + void happyPathWorksWithExplicitExpiry() { // setup: var expected = new MerkleToken( expiry, @@ -1790,7 +1790,7 @@ public void happyPathWorksWithExplicitExpiry() { } @Test - public void rejectsInvalidAutoRenewAccount() { + void rejectsInvalidAutoRenewAccount() { given(accountsLedger.exists(autoRenewAccount)).willReturn(false); // given: @@ -1807,7 +1807,7 @@ public void rejectsInvalidAutoRenewAccount() { } @Test - public void rejectsMissingTreasury() { + void rejectsMissingTreasury() { given(accountsLedger.exists(treasury)).willReturn(false); // and: var req = fullyValidAttempt() @@ -1821,7 +1821,7 @@ public void rejectsMissingTreasury() { } @Test - public void rejectsDeletedTreasuryAccount() { + void rejectsDeletedTreasuryAccount() { given(hederaLedger.isDeleted(treasury)).willReturn(true); // and: @@ -1836,7 +1836,7 @@ public void rejectsDeletedTreasuryAccount() { } @Test - public void allowsZeroInitialSupplyAndDecimals() { + void allowsZeroInitialSupplyAndDecimals() { // given: var req = fullyValidAttempt() .setInitialSupply(0L) @@ -1851,7 +1851,7 @@ public void allowsZeroInitialSupplyAndDecimals() { } @Test - public void allowsToCreateTokenWithTheBiggestAmountInLong() { + void allowsToCreateTokenWithTheBiggestAmountInLong() { // given: var req = fullyValidAttempt() .setInitialSupply(9) @@ -1866,7 +1866,7 @@ public void allowsToCreateTokenWithTheBiggestAmountInLong() { } @Test - public void forcesToTrueAccountsKycGrantedByDefaultWithoutKycKey() { + void forcesToTrueAccountsKycGrantedByDefaultWithoutKycKey() { // given: var req = fullyValidAttempt() .clearKycKey() diff --git a/hedera-node/src/test/java/com/hedera/services/txns/ExpandHandleSpanTest.java b/hedera-node/src/test/java/com/hedera/services/txns/ExpandHandleSpanTest.java index 963537a4f917..be719982eca9 100644 --- a/hedera-node/src/test/java/com/hedera/services/txns/ExpandHandleSpanTest.java +++ b/hedera-node/src/test/java/com/hedera/services/txns/ExpandHandleSpanTest.java @@ -88,7 +88,7 @@ void tracksWithinDuration() throws InterruptedException, InvalidProtocolBufferEx final var startAccessor = subject.track(validTxn); // when: - testUnit.sleep(duration / 2); + testUnit.sleep(duration / 10); // and: final var endAccessor = subject.accessorFor(validTxn); diff --git a/hedera-node/src/test/java/com/hedera/services/utils/PlatformTxnAccessorTest.java b/hedera-node/src/test/java/com/hedera/services/utils/PlatformTxnAccessorTest.java index 6998618c0941..fb6af5980f94 100644 --- a/hedera-node/src/test/java/com/hedera/services/utils/PlatformTxnAccessorTest.java +++ b/hedera-node/src/test/java/com/hedera/services/utils/PlatformTxnAccessorTest.java @@ -46,6 +46,7 @@ import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertSame; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.BDDMockito.any; import static org.mockito.BDDMockito.given; @@ -53,7 +54,7 @@ import static org.mockito.BDDMockito.verify; import static org.mockito.Mockito.mock; -public class PlatformTxnAccessorTest { +class PlatformTxnAccessorTest { private static final byte[] NONSENSE = "Jabberwocky".getBytes(); TransactionBody someTxn = TransactionBody.newBuilder() .setTransactionID(TransactionID.newBuilder().setAccountID(asAccount("0.0.2"))) @@ -61,13 +62,32 @@ public class PlatformTxnAccessorTest { .build(); @Test - public void extractorReturnsNoneWhenExpected() { + void sigMetaGetterSetterCheck() throws InvalidProtocolBufferException { + // setup: + Transaction signedTxnWithBody = Transaction.newBuilder() + .setBodyBytes(someTxn.toByteString()) + .build(); + SwirldTransaction platformTxn = + new SwirldTransaction(signedTxnWithBody.toByteArray()); + + // given: + SignedTxnAccessor subject = new PlatformTxnAccessor(platformTxn); + + // when: + subject.setSigMeta(RationalizedSigMeta.noneAvailable()); + + // then: + assertSame(RationalizedSigMeta.noneAvailable(), subject.getSigMeta()); + } + + @Test + void extractorReturnsNoneWhenExpected() { // expect: assertEquals(HederaFunctionality.NONE, SignedTxnAccessor.functionExtractor.apply(someTxn)); } @Test - public void hasExpectedSignedBytes() throws InvalidProtocolBufferException { + void hasExpectedSignedBytes() throws InvalidProtocolBufferException { // given: Transaction signedTxnWithBody = Transaction.newBuilder() .setBodyBytes(someTxn.toByteString()) @@ -81,7 +101,7 @@ public void hasExpectedSignedBytes() throws InvalidProtocolBufferException { } @Test - public void extractorReturnsExpectedFunction() { + void extractorReturnsExpectedFunction() { // given: someTxn = someTxn.toBuilder() .setConsensusCreateTopic(ConsensusCreateTopicTransactionBody.newBuilder()) @@ -92,7 +112,7 @@ public void extractorReturnsExpectedFunction() { } @Test - public void usesExtractorToGetFunctionAsExpected() { + void usesExtractorToGetFunctionAsExpected() { // setup: var memory = SignedTxnAccessor.functionExtractor; Function mockFn = @@ -124,7 +144,7 @@ public void usesExtractorToGetFunctionAsExpected() { } @Test - public void allowsUncheckedConstruction() { + void allowsUncheckedConstruction() { // setup: Transaction validTxn = Transaction.getDefaultInstance(); @@ -134,14 +154,14 @@ public void allowsUncheckedConstruction() { } @Test - public void failsWithIllegalStateOnUncheckedConstruction() { + void failsWithIllegalStateOnUncheckedConstruction() { // expect: assertThrows(IllegalStateException.class, () -> uncheckedAccessorFor(new SwirldTransaction(NONSENSE))); } @Test - public void failsOnInvalidSignedTxn() { + void failsOnInvalidSignedTxn() { // given: SwirldTransaction platformTxn = new SwirldTransaction(NONSENSE); @@ -150,7 +170,7 @@ public void failsOnInvalidSignedTxn() { } @Test - public void failsOnInvalidTxn() { + void failsOnInvalidTxn() { // given: Transaction signedNonsenseTxn = Transaction.newBuilder() .setBodyBytes(ByteString.copyFrom(NONSENSE)) @@ -164,7 +184,7 @@ public void failsOnInvalidTxn() { } @Test - public void usesBodyBytesCorrectly() throws Exception { + void usesBodyBytesCorrectly() throws Exception { // given: Transaction signedTxnWithBody = Transaction.newBuilder() .setBodyBytes(someTxn.toByteString()) @@ -181,7 +201,7 @@ public void usesBodyBytesCorrectly() throws Exception { } @Test - public void getsCorrectLoggableForm() throws Exception { + void getsCorrectLoggableForm() throws Exception { Transaction signedTxnWithBody = Transaction.newBuilder() .setBodyBytes(someTxn.toByteString()) .setSigMap(SignatureMap.newBuilder().addSigPair( @@ -206,7 +226,7 @@ public void getsCorrectLoggableForm() throws Exception { } @Test - public void getsCorrectLoggableFormWithSignedTransactionBytes() throws Exception { + void getsCorrectLoggableFormWithSignedTransactionBytes() throws Exception { SignedTransaction signedTxn = SignedTransaction.newBuilder(). setBodyBytes(someTxn.toByteString()). setSigMap(SignatureMap.newBuilder().addSigPair(SignaturePair.newBuilder() @@ -235,7 +255,7 @@ public void getsCorrectLoggableFormWithSignedTransactionBytes() throws Exception } @Test - public void getsPayer() throws Exception { + void getsPayer() throws Exception { // given: AccountID payer = asAccount("0.0.2"); Transaction signedTxnWithBody = Transaction.newBuilder() diff --git a/hedera-node/src/test/java/com/hedera/services/utils/RationalizedSigMetaTest.java b/hedera-node/src/test/java/com/hedera/services/utils/RationalizedSigMetaTest.java new file mode 100644 index 000000000000..22395b244569 --- /dev/null +++ b/hedera-node/src/test/java/com/hedera/services/utils/RationalizedSigMetaTest.java @@ -0,0 +1,84 @@ +package com.hedera.services.utils; + +/*- + * ‌ + * Hedera Services Node + * ​ + * Copyright (C) 2018 - 2021 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. + * ‍ + */ + +import com.hedera.services.legacy.core.jproto.JKey; +import com.hedera.test.factories.scenarios.TxnHandlingScenario; +import com.swirlds.common.crypto.TransactionSignature; +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static com.hedera.services.sigs.factories.PlatformSigFactoryTest.EXPECTED_SIG; +import static com.hedera.services.sigs.factories.PlatformSigFactoryTest.pk; +import static org.junit.jupiter.api.Assertions.*; + +class RationalizedSigMetaTest { + private final JKey payerKey = TxnHandlingScenario.MISC_ACCOUNT_KT.asJKeyUnchecked(); + private final List othersKeys = List.of(TxnHandlingScenario.MISC_ADMIN_KT.asJKeyUnchecked()); + private final List rationalizedSigs = List.of(EXPECTED_SIG); + + private RationalizedSigMeta subject; + + @Test + void noneAvailableHasNoInfo() { + // given: + subject = RationalizedSigMeta.noneAvailable(); + + // then: + assertFalse(subject.couldRationalizePayer()); + assertFalse(subject.couldRationalizeOthers()); + // and: + assertThrows(IllegalStateException.class, subject::verifiedSigs); + assertThrows(IllegalStateException.class, subject::payerKey); + assertThrows(IllegalStateException.class, subject::othersReqSigs); + assertThrows(IllegalStateException.class, subject::pkToVerifiedSigFn); + } + + @Test + void payerOnlyHasExpectedInfo() { + // given: + subject = RationalizedSigMeta.forPayerOnly(payerKey, rationalizedSigs); + + // then: + assertTrue(subject.couldRationalizePayer()); + assertFalse(subject.couldRationalizeOthers()); + // and: + assertSame(payerKey, subject.payerKey()); + assertSame(rationalizedSigs, subject.verifiedSigs()); + assertSame(EXPECTED_SIG, subject.pkToVerifiedSigFn().apply(pk)); + } + + @Test + void forBothHaveExpectedInfo() { + // given: + subject = RationalizedSigMeta.forPayerAndOthers(payerKey, othersKeys, rationalizedSigs); + + // then: + assertTrue(subject.couldRationalizePayer()); + assertTrue(subject.couldRationalizeOthers()); + // and: + assertSame(payerKey, subject.payerKey()); + assertSame(othersKeys, subject.othersReqSigs()); + assertSame(rationalizedSigs, subject.verifiedSigs()); + assertSame(EXPECTED_SIG, subject.pkToVerifiedSigFn().apply(pk)); + } +} diff --git a/hedera-node/src/test/java/com/hedera/test/factories/sigs/SigWrappers.java b/hedera-node/src/test/java/com/hedera/test/factories/sigs/SigWrappers.java index ea5fdc1f47b6..1c62671b9f68 100644 --- a/hedera-node/src/test/java/com/hedera/test/factories/sigs/SigWrappers.java +++ b/hedera-node/src/test/java/com/hedera/test/factories/sigs/SigWrappers.java @@ -32,7 +32,9 @@ public class SigWrappers { public static List asValid(List sigs) { - return sigs.stream().map(sig -> new SigWithKnownStatus(sig, VALID)).collect(toList()); + return sigs.stream() + .map(sig -> new SigWithKnownStatus(sig, VALID)) + .collect(toList()); } public static List asInvalid(List sigs) { return sigs.stream().map(sig -> new SigWithKnownStatus(sig, INVALID)).collect(toList()); diff --git a/hedera-node/src/test/java/com/hedera/test/factories/sigs/SyncVerifiers.java b/hedera-node/src/test/java/com/hedera/test/factories/sigs/SyncVerifiers.java index b5623bb63dd3..cfd78ff914e8 100644 --- a/hedera-node/src/test/java/com/hedera/test/factories/sigs/SyncVerifiers.java +++ b/hedera-node/src/test/java/com/hedera/test/factories/sigs/SyncVerifiers.java @@ -9,9 +9,9 @@ * 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. @@ -29,6 +29,15 @@ import static com.hedera.test.factories.sigs.SigWrappers.asValid; public class SyncVerifiers { - public static final SyncVerifier NEVER_VALID = l -> { List lv = asInvalid(l); l.clear(); l.addAll(lv); }; - public static final SyncVerifier ALWAYS_VALID = l -> { List lv = asValid(l); l.clear(); l.addAll(lv); }; + public static final SyncVerifier NEVER_VALID = l -> { + List lv = asInvalid(l); + l.clear(); + l.addAll(lv); + }; + + public static final SyncVerifier ALWAYS_VALID = l -> { + List lv = asValid(l); + l.clear(); + l.addAll(lv); + }; }