All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.hedera.node.app.hapi.fees.pricing.ScheduleGenerator Maven / Gradle / Ivy

There is a newer version: 0.57.2
Show newest version
/*
 * Copyright (C) 2021-2024 Hedera Hashgraph, LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.hedera.node.app.hapi.fees.pricing;

import static com.hederahashgraph.api.proto.java.HederaFunctionality.ConsensusSubmitMessage;
import static com.hederahashgraph.api.proto.java.HederaFunctionality.ContractAutoRenew;
import static com.hederahashgraph.api.proto.java.HederaFunctionality.CryptoApproveAllowance;
import static com.hederahashgraph.api.proto.java.HederaFunctionality.CryptoCreate;
import static com.hederahashgraph.api.proto.java.HederaFunctionality.CryptoDeleteAllowance;
import static com.hederahashgraph.api.proto.java.HederaFunctionality.CryptoTransfer;
import static com.hederahashgraph.api.proto.java.HederaFunctionality.CryptoUpdate;
import static com.hederahashgraph.api.proto.java.HederaFunctionality.FileAppend;
import static com.hederahashgraph.api.proto.java.HederaFunctionality.ScheduleCreate;
import static com.hederahashgraph.api.proto.java.HederaFunctionality.TokenAccountWipe;
import static com.hederahashgraph.api.proto.java.HederaFunctionality.TokenBurn;
import static com.hederahashgraph.api.proto.java.HederaFunctionality.TokenCreate;
import static com.hederahashgraph.api.proto.java.HederaFunctionality.TokenFeeScheduleUpdate;
import static com.hederahashgraph.api.proto.java.HederaFunctionality.TokenFreezeAccount;
import static com.hederahashgraph.api.proto.java.HederaFunctionality.TokenMint;
import static com.hederahashgraph.api.proto.java.HederaFunctionality.TokenPause;
import static com.hederahashgraph.api.proto.java.HederaFunctionality.TokenUnfreezeAccount;
import static com.hederahashgraph.api.proto.java.HederaFunctionality.TokenUnpause;
import static com.hederahashgraph.api.proto.java.HederaFunctionality.UtilPrng;
import static com.hederahashgraph.api.proto.java.SubType.DEFAULT;
import static com.hederahashgraph.api.proto.java.SubType.SCHEDULE_CREATE_CONTRACT_CALL;
import static com.hederahashgraph.api.proto.java.SubType.TOKEN_FUNGIBLE_COMMON;
import static com.hederahashgraph.api.proto.java.SubType.TOKEN_FUNGIBLE_COMMON_WITH_CUSTOM_FEES;
import static com.hederahashgraph.api.proto.java.SubType.TOKEN_NON_FUNGIBLE_UNIQUE;
import static com.hederahashgraph.api.proto.java.SubType.TOKEN_NON_FUNGIBLE_UNIQUE_WITH_CUSTOM_FEES;
import static java.time.Month.SEPTEMBER;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.hederahashgraph.api.proto.java.HederaFunctionality;
import com.hederahashgraph.api.proto.java.SubType;
import java.io.IOException;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang3.tuple.Pair;

public class ScheduleGenerator {
    private static final String FEE_SCHEDULE_FEES_KEY = "fees";
    private static final String FEE_SCHEDULE_TYPE_KEY = "subType";
    private static final String FEE_SCHEDULE_ENTRY_KEY = "transactionFeeSchedule";
    private static final String FEE_SCHEDULE_FUNCTION_KEY = "hederaFunctionality";

    private static final Instant CURRENT_SCHEDULE_EXPIRY =
            LocalDateTime.of(2021, SEPTEMBER, 2, 0, 0).plusMonths(1).toInstant(ZoneOffset.UTC);
    private static final Instant NEXT_SCHEDULE_EXPIRY =
            LocalDateTime.of(2021, SEPTEMBER, 2, 0, 0).plusMonths(2).toInstant(ZoneOffset.UTC);

    private static final FeeSchedules feeSchedules = new FeeSchedules();

    String feeSchedulesFor(final List>> data) throws IOException {
        final List> currentFeeSchedules = new ArrayList<>();
        final List> nextFeeSchedules = new ArrayList<>();

        for (final var datum : data) {
            final var function = datum.getKey();
            final var subTypes = datum.getValue();
            final var tfs = pricesAsTfs(function, subTypes);
            currentFeeSchedules.add(tfs);
            nextFeeSchedules.add(tfs);
        }
        currentFeeSchedules.add(Map.of("expiryTime", CURRENT_SCHEDULE_EXPIRY.getEpochSecond()));
        nextFeeSchedules.add(Map.of("expiryTime", NEXT_SCHEDULE_EXPIRY.getEpochSecond()));

        final List> everything =
                List.of(Map.of("currentFeeSchedule", currentFeeSchedules), Map.of("nextFeeSchedule", nextFeeSchedules));
        return new ObjectMapper().writerWithDefaultPrettyPrinter().writeValueAsString(everything);
    }

    private Map pricesAsTfs(final HederaFunctionality function, final List subTypes)
            throws IOException {
        final Map transactionFeeSchedule = new HashMap<>();

        final Map details = new LinkedHashMap<>();
        details.put(FEE_SCHEDULE_FUNCTION_KEY, function.toString());

        final List> allTypedPrices = new ArrayList<>();
        for (final var subType : subTypes) {
            final Map typedPrices = new LinkedHashMap<>();
            typedPrices.put(FEE_SCHEDULE_TYPE_KEY, subType.toString());

            final Map> prices =
                    feeSchedules.canonicalPricesFor(function, subType);
            for (final var provider : ResourceProvider.class.getEnumConstants()) {
                final Map constrainedPrices = new LinkedHashMap<>();
                final var providerPrices = prices.get(provider);
                for (final var resource : UsableResource.class.getEnumConstants()) {
                    final var price = providerPrices.get(resource);
                    constrainedPrices.put(resource.toString().toLowerCase(), price);
                }
                constrainedPrices.put("min", 0L);
                constrainedPrices.put("max", 1000000000000000L);
                typedPrices.put(provider.jsonKey(), constrainedPrices);
            }

            allTypedPrices.add(typedPrices);
        }
        details.put(FEE_SCHEDULE_FEES_KEY, allTypedPrices);
        transactionFeeSchedule.put(FEE_SCHEDULE_ENTRY_KEY, details);
        return transactionFeeSchedule;
    }

    @SuppressWarnings("unchecked")
    static final List>> SUPPORTED_FUNCTIONS = List.of(
            Pair.of(ContractAutoRenew, List.of(DEFAULT)),
            /* Crypto */
            Pair.of(
                    CryptoTransfer,
                    List.of(
                            DEFAULT,
                            TOKEN_FUNGIBLE_COMMON,
                            TOKEN_FUNGIBLE_COMMON_WITH_CUSTOM_FEES,
                            TOKEN_NON_FUNGIBLE_UNIQUE,
                            TOKEN_NON_FUNGIBLE_UNIQUE_WITH_CUSTOM_FEES)),
            Pair.of(CryptoCreate, List.of(DEFAULT)),
            Pair.of(CryptoUpdate, List.of(DEFAULT)),
            Pair.of(CryptoApproveAllowance, List.of(DEFAULT)),
            Pair.of(CryptoDeleteAllowance, List.of(DEFAULT)),
            /* File */
            Pair.of(FileAppend, List.of(DEFAULT)),
            /* Token */
            Pair.of(
                    TokenCreate,
                    List.of(
                            TOKEN_FUNGIBLE_COMMON,
                            TOKEN_FUNGIBLE_COMMON_WITH_CUSTOM_FEES,
                            TOKEN_NON_FUNGIBLE_UNIQUE,
                            TOKEN_NON_FUNGIBLE_UNIQUE_WITH_CUSTOM_FEES)),
            Pair.of(TokenMint, List.of(TOKEN_FUNGIBLE_COMMON, TOKEN_NON_FUNGIBLE_UNIQUE)),
            Pair.of(TokenBurn, List.of(TOKEN_FUNGIBLE_COMMON, TOKEN_NON_FUNGIBLE_UNIQUE)),
            Pair.of(TokenAccountWipe, List.of(TOKEN_FUNGIBLE_COMMON, TOKEN_NON_FUNGIBLE_UNIQUE)),
            Pair.of(TokenFeeScheduleUpdate, List.of(DEFAULT)),
            Pair.of(TokenFreezeAccount, List.of(DEFAULT)),
            Pair.of(TokenUnfreezeAccount, List.of(DEFAULT)),
            Pair.of(TokenPause, List.of(DEFAULT)),
            Pair.of(TokenUnpause, List.of(DEFAULT)),
            /* Consensus */
            Pair.of(ConsensusSubmitMessage, List.of(DEFAULT)),
            /* Schedule */
            Pair.of(ScheduleCreate, List.of(DEFAULT, SCHEDULE_CREATE_CONTRACT_CALL)),
            Pair.of(UtilPrng, List.of(DEFAULT)));
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy