Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simplify fee charging #1516

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
262bd58
Save record to state outside user transaction
May 22, 2021
bbe5d74
Purge expired records/short-lived entities from state before beginnin…
May 22, 2021
98ac4e9
Add license header; fix typo in unit test
May 22, 2021
139efd2
Remove unused stats tracker
May 22, 2021
f82dd05
Rename RecordsHistorian.addNewEntities() to noteNewExpirationEvents()
May 22, 2021
e2d8529
Create NodeInfo and InvariantChecks to simplify unit-test of AwarePro…
May 23, 2021
97e9eac
Add AwareProcessLogic unit tests
May 23, 2021
66f826c
Extract node accounts from NodeInfo when context is available
May 23, 2021
f967383
Fix unit test
May 23, 2021
e63a4fc
Confirm RecordCreationSuite runs in CI
May 23, 2021
5f29cc6
Implement TxnFeeChargingPolicy in terms of injected StagedCharging; d…
May 24, 2021
9945c49
Begin implementation of NarratedCharging
May 25, 2021
2aff08c
Merge remote-tracking branch 'origin/master' into 01459-01422-IncAcco…
May 25, 2021
90ababb
Fix unit test
May 25, 2021
f5ca711
Merge branch '01459-01422-IncAccountsInNodeInfo' into 01461-01459-Sim…
May 25, 2021
c75e262
Remove ItemizableFeeCharging and collaborators
May 25, 2021
28c3e5c
Reenable CI
May 25, 2021
bbfea9f
And include fee exemptions
May 26, 2021
e11d777
Merge remote-tracking branch 'origin/master' into 01461-M-SimplifyFee…
May 27, 2021
882187a
Use isIndexOutOfBounds
May 27, 2021
f68af8c
Introduce TxnChargingPolicyAgent
May 27, 2021
08db8c8
Need more collaborators
May 28, 2021
176f87a
Extract ChargingPolicyAgent
May 29, 2021
d69077f
Merge branch 'master-plus-sdk-0.15.0-alpha.1' into 01461-M0150-Simpli…
May 29, 2021
2b8fe3b
Address reviewer comments
Jun 2, 2021
ab8449c
Address Sonar cloud flags
Jun 2, 2021
34f9beb
updated unit test to increase test coverage
anighanta Jun 2, 2021
b7a82dc
fix unit test for a triggered transaction
anighanta Jun 2, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,25 @@
package com.hedera.services.legacy.proto.utils;

/*-
* ‌
* Hedera Services API Utilities
* ​
* 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 org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

Expand All @@ -10,4 +30,4 @@ void rejectsNonEddsaKeys() {
IllegalArgumentException.class,
() -> SignatureGenerator.signBytes(new byte[0], null));
}
}
}
1 change: 1 addition & 0 deletions hedera-node/configuration/dev/api-permission.properties
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,4 @@ getVersionInfo=0-*
systemDelete=2-59
systemUndelete=2-60
freeze=2-58
uncheckedSubmit=2-50
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
import com.hedera.services.state.expiry.ExpiringEntity;
import com.hedera.services.state.merkle.MerkleTopic;
import com.hedera.services.utils.TxnAccessor;
import com.hederahashgraph.api.proto.java.AccountAmount;
import com.hederahashgraph.api.proto.java.AccountID;
import com.hederahashgraph.api.proto.java.ContractFunctionResult;
import com.hederahashgraph.api.proto.java.ContractID;
Expand All @@ -40,8 +39,6 @@
import com.hederahashgraph.api.proto.java.TransactionID;
import com.hederahashgraph.api.proto.java.TransactionReceipt;
import com.hederahashgraph.api.proto.java.TransactionRecord;
import com.hederahashgraph.api.proto.java.TransferList;
import com.swirlds.common.Address;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

Expand All @@ -54,8 +51,6 @@
import static com.hedera.services.state.merkle.MerkleEntityId.fromAccountId;
import static com.hedera.services.utils.MiscUtils.asFcKeyUnchecked;
import static com.hedera.services.utils.MiscUtils.asTimestamp;
import static com.hedera.services.utils.MiscUtils.canonicalDiffRepr;
import static com.hedera.services.utils.MiscUtils.readableTransferList;
import static com.hederahashgraph.api.proto.java.ResponseCodeEnum.UNKNOWN;

/**
Expand Down Expand Up @@ -118,7 +113,8 @@ public void resetFor(TxnAccessor accessor, Instant consensusTime, long submittin
isPayerSigKnownActive = false;
hasComputedRecordSoFar = false;

ctx.charging().resetFor(accessor, submittingNodeAccount());
ctx.narratedCharging().resetForTxn(accessor, submittingMember);

recordSoFar.clear();
}

Expand Down Expand Up @@ -154,17 +150,14 @@ public long submittingSwirldsMember() {

@Override
public TransactionRecord recordSoFar() {
long amount = ctx.charging().totalFeesChargedToPayer() + otherNonThresholdFees;
final long feesCharged = ctx.narratedCharging().totalFeesChargedToPayer() + otherNonThresholdFees;

if (log.isDebugEnabled()) {
logItemized();
}
recordSoFar
.setMemo(accessor.getTxn().getMemo())
.setReceipt(receiptSoFar())
.setTransferList(ctx.ledger().netTransfersInTxn())
.setTransactionID(accessor.getTxnId())
.setTransactionFee(amount)
.setTransactionFee(feesCharged)
.setTransactionHash(hash)
.setConsensusTimestamp(consensusTimestamp)
.addAllTokenTransferLists(ctx.ledger().netTokenTransfersInTxn());
Expand All @@ -178,39 +171,6 @@ public TransactionRecord recordSoFar() {
return recordSoFar.build();
}

@Override
public TransactionRecord updatedRecordGiven(TransferList listWithNewFees) {
if (!hasComputedRecordSoFar) {
throw new IllegalStateException(String.format(
"No record exists to be updated with '%s'!",
readableTransferList(listWithNewFees)));
}

long amount = ctx.charging().totalFeesChargedToPayer() + otherNonThresholdFees;
recordSoFar.setTransferList(listWithNewFees).setTransactionFee(amount);

return recordSoFar.build();
}

private void logItemized() {
String readableTransferList = readableTransferList(itemizedRepresentation());
log.debug(
"Transfer list with itemized fees for {} is {}",
accessor().getSignedTxn4Log(),
readableTransferList);
}

TransferList itemizedRepresentation() {
TransferList canonicalRepr = ctx.ledger().netTransfersInTxn();
TransferList itemizedFees = ctx.charging().itemizedFees();

List<AccountAmount> nonFeeAdjustments =
canonicalDiffRepr(canonicalRepr.getAccountAmountsList(), itemizedFees.getAccountAmountsList());
return itemizedFees.toBuilder()
.addAllAccountAmounts(nonFeeAdjustments)
.build();
}

private TransactionReceipt.Builder receiptSoFar() {
TransactionReceipt.Builder receipt = TransactionReceipt.newBuilder()
.setExchangeRate(ctx.exchange().activeRates())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
* ‍
*/

import com.hedera.services.state.merkle.MerkleEntityId;
import com.swirlds.common.AddressBook;

import java.util.function.Supplier;
Expand All @@ -43,6 +44,7 @@ public class NodeInfo {
private int numberOfNodes;
private boolean[] isZeroStake;
private AccountID[] accounts;
private MerkleEntityId[] accountKeys;
qnswirlds marked this conversation as resolved.
Show resolved Hide resolved

private final long selfId;
private final Supplier<AddressBook> book;
Expand Down Expand Up @@ -86,6 +88,18 @@ public boolean isSelfZeroStake() {
* @throws IllegalArgumentException if the book did not contain the id, or was missing an account for the id
*/
public AccountID accountOf(long nodeId) {
final int index = validatedIndexFor(nodeId);

return accounts[index];
}

public MerkleEntityId accountKeyOf(long nodeId) {
final int index = validatedIndexFor(nodeId);

return accountKeys[index];
}

private int validatedIndexFor(long nodeId) {
if (!bookIsRead) {
readBook();
}
Expand All @@ -94,11 +108,10 @@ public AccountID accountOf(long nodeId) {
if (isIndexOutOfBounds(index)) {
throw new IllegalArgumentException("No node with id " + nodeId + " was in the address book!");
}
final var account = accounts[index];
if (account == null) {
if (accounts[index] == null) {
throw new IllegalArgumentException("The address book did not have an account for node id " + nodeId + "!");
}
return account;
return index;
}

/**
Expand Down Expand Up @@ -131,13 +144,15 @@ void readBook() {

numberOfNodes = staticBook.getSize();
accounts = new AccountID[numberOfNodes];
accountKeys = new MerkleEntityId[numberOfNodes];
isZeroStake = new boolean[numberOfNodes];

for (int i = 0; i < numberOfNodes; i++) {
final var address = staticBook.getAddress(i);
isZeroStake[i] = address.getStake() <= 0;
try {
accounts[i] = parseAccount(address.getMemo());
accountKeys[i] = MerkleEntityId.fromAccountId(accounts[i]);
} catch (IllegalArgumentException e) {
if (!isZeroStake[i]) {
log.error("Cannot parse account for staked node id {}, potentially fatal!", i, e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,10 @@
import com.hedera.services.fees.calculation.token.txns.TokenUnfreezeResourceUsage;
import com.hedera.services.fees.calculation.token.txns.TokenUpdateResourceUsage;
import com.hedera.services.fees.calculation.token.txns.TokenWipeResourceUsage;
import com.hedera.services.fees.charging.ItemizableFeeCharging;
import com.hedera.services.fees.charging.TxnFeeChargingPolicy;
import com.hedera.services.fees.charging.NarratedCharging;
import com.hedera.services.fees.charging.NarratedLedgerCharging;
import com.hedera.services.fees.charging.FeeChargingPolicy;
import com.hedera.services.fees.charging.TxnChargingPolicyAgent;
import com.hedera.services.files.DataMapFactory;
import com.hedera.services.files.EntityExpiryMapFactory;
import com.hedera.services.files.FileUpdateInterceptor;
Expand Down Expand Up @@ -305,7 +307,6 @@
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.EntityIdUtils;
import com.hedera.services.utils.JvmSystemExits;
import com.hedera.services.utils.MiscUtils;
import com.hedera.services.utils.Pause;
Expand Down Expand Up @@ -491,6 +492,7 @@ public class ServicesContext {
private FreezeController freezeGrpc;
private BalancesExporter balancesExporter;
private SysFileCallbacks sysFileCallbacks;
private NarratedCharging narratedCharging;
private NetworkCtxManager networkCtxManager;
private SolidityLifecycle solidityLifecycle;
private ExpiringCreations creator;
Expand Down Expand Up @@ -521,7 +523,7 @@ public class ServicesContext {
private TransactionPrecheck transactionPrecheck;
private FeeMultiplierSource feeMultiplierSource;
private NodeLocalProperties nodeLocalProperties;
private TxnFeeChargingPolicy txnChargingPolicy;
private FeeChargingPolicy txnChargingPolicy;
private TxnAwareRatesManager exchangeRatesManager;
private ServicesStatsManager statsManager;
private LedgerAccountsSource accountSource;
Expand All @@ -532,7 +534,7 @@ public class ServicesContext {
private HfsSystemFilesManager systemFilesManager;
private CurrentPlatformStatus platformStatus;
private SystemAccountsCreator systemAccountsCreator;
private ItemizableFeeCharging itemizableFeeCharging;
private TxnChargingPolicyAgent chargingPolicyAgent;
private ServicesRepositoryRoot repository;
private CharacteristicsFactory characteristics;
private AccountRecordsHistorian recordsHistorian;
Expand Down Expand Up @@ -850,16 +852,6 @@ public TransactionThrottling txnThrottling() {
return txnThrottling;
}

public ItemizableFeeCharging charging() {
if (itemizableFeeCharging == null) {
itemizableFeeCharging = new ItemizableFeeCharging(
ledger(),
exemptions(),
globalDynamicProperties());
}
return itemizableFeeCharging;
}

public SubmissionFlow submissionFlow() {
if (submissionFlow == null) {
submissionFlow = new BasicSubmissionFlow(nodeType(), transactionPrecheck(), submissionManager());
Expand Down Expand Up @@ -1522,6 +1514,14 @@ public EntityAutoRenewal entityAutoRenewal() {
return entityAutoRenewal;
}

public NarratedCharging narratedCharging() {
if (narratedCharging == null) {
narratedCharging = new NarratedLedgerCharging(
nodeInfo(), ledger(), exemptions(), globalDynamicProperties(), this::accounts);
}
return narratedCharging;
}

public ExpiryManager expiries() {
if (expiries == null) {
var histories = txnHistories();
Expand Down Expand Up @@ -1926,13 +1926,21 @@ public UsagePricesProvider usagePrices() {
return usagePrices;
}

public TxnFeeChargingPolicy txnChargingPolicy() {
public FeeChargingPolicy txnChargingPolicy() {
if (txnChargingPolicy == null) {
txnChargingPolicy = new TxnFeeChargingPolicy();
txnChargingPolicy = new FeeChargingPolicy(narratedCharging());
}
return txnChargingPolicy;
}

public TxnChargingPolicyAgent chargingPolicyAgent() {
if (chargingPolicyAgent == null) {
chargingPolicyAgent = new TxnChargingPolicyAgent(
fees(), txnChargingPolicy(), txnCtx(), this::currentView, nodeDiligenceScreen(), txnHistories());
}
return chargingPolicyAgent;
}

public SystemAccountsCreator systemAccountsCreator() {
if (systemAccountsCreator == null) {
systemAccountsCreator = new BackedSystemAccountsCreator(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@
import com.hederahashgraph.api.proto.java.TopicID;
import com.hederahashgraph.api.proto.java.TransactionID;
import com.hederahashgraph.api.proto.java.TransactionRecord;
import com.hederahashgraph.api.proto.java.TransferList;

import java.time.Instant;
import java.util.Collection;
Expand Down Expand Up @@ -123,16 +122,6 @@ default AccountID effectivePayer() {
*/
TransactionRecord recordSoFar();

/**
* Returns the last record created by {@link TransactionContext#recordSoFar()},
* with the transfer list and fees updated.
*
* @param listWithNewFees the new transfer list to use in the record.
* @return the updated historical record of processing the current txn thus far.
* @throws IllegalStateException if {@code recordSoFar} has not been called for the active txn.
*/
TransactionRecord updatedRecordGiven(TransferList listWithNewFees);

/**
* Gets an accessor to the defined type {@link TxnAccessor}
* currently being processed.
Expand Down
Loading