github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/fvm/blueprints/fees.go (about)

     1  package blueprints
     2  
     3  import (
     4  	_ "embed"
     5  	"encoding/hex"
     6  	"fmt"
     7  
     8  	"github.com/onflow/cadence"
     9  	jsoncdc "github.com/onflow/cadence/encoding/json"
    10  	"github.com/onflow/cadence/runtime/common"
    11  	"github.com/onflow/flow-core-contracts/lib/go/templates"
    12  
    13  	"github.com/onflow/flow-go/model/flow"
    14  )
    15  
    16  var TransactionFeesExecutionEffortWeightsPath = cadence.Path{
    17  	Domain:     common.PathDomainStorage,
    18  	Identifier: "executionEffortWeights",
    19  }
    20  var TransactionFeesExecutionMemoryWeightsPath = cadence.Path{
    21  	Domain:     common.PathDomainStorage,
    22  	Identifier: "executionMemoryWeights",
    23  }
    24  var TransactionFeesExecutionMemoryLimitPath = cadence.Path{
    25  	Domain:     common.PathDomainStorage,
    26  	Identifier: "executionMemoryLimit",
    27  }
    28  
    29  //go:embed scripts/deployTxFeesTransactionTemplate.cdc
    30  var deployTxFeesTransactionTemplate string
    31  
    32  //go:embed scripts/setupParametersTransactionTemplate.cdc
    33  var setupParametersTransactionTemplate string
    34  
    35  //go:embed scripts/setupStorageForServiceAccountsTemplate.cdc
    36  var setupStorageForServiceAccountsTemplate string
    37  
    38  //go:embed scripts/setupStorageForAccount.cdc
    39  var setupStorageForAccountTemplate string
    40  
    41  //go:embed scripts/setupFeesTransactionTemplate.cdc
    42  var setupFeesTransactionTemplate string
    43  
    44  //go:embed scripts/setExecutionMemoryLimit.cdc
    45  var setExecutionMemoryLimit string
    46  
    47  func DeployTxFeesContractTransaction(flowFees, service flow.Address, contract []byte) *flow.TransactionBody {
    48  
    49  	return flow.NewTransactionBody().
    50  		SetScript([]byte(deployTxFeesTransactionTemplate)).
    51  		AddArgument(jsoncdc.MustEncode(cadence.String(hex.EncodeToString(contract)))).
    52  		AddAuthorizer(flowFees).
    53  		AddAuthorizer(service)
    54  }
    55  
    56  func DeployStorageFeesContractTransaction(service flow.Address, contract []byte) *flow.TransactionBody {
    57  	return DeployContractTransaction(service, contract, "FlowStorageFees")
    58  }
    59  
    60  func SetupParametersTransaction(
    61  	service flow.Address,
    62  	addressCreationFee,
    63  	minimumStorageReservation,
    64  	storagePerFlow cadence.UFix64,
    65  	restrictedAccountCreationEnabled cadence.Bool,
    66  ) *flow.TransactionBody {
    67  	addressCreationFeeArg, err := jsoncdc.Encode(addressCreationFee)
    68  	if err != nil {
    69  		panic(fmt.Sprintf("failed to encode address creation fee: %s", err.Error()))
    70  	}
    71  	minimumStorageReservationArg, err := jsoncdc.Encode(minimumStorageReservation)
    72  	if err != nil {
    73  		panic(fmt.Sprintf("failed to encode minimum storage reservation: %s", err.Error()))
    74  	}
    75  	storagePerFlowArg, err := jsoncdc.Encode(storagePerFlow)
    76  	if err != nil {
    77  		panic(fmt.Sprintf("failed to encode storage ratio: %s", err.Error()))
    78  	}
    79  	restrictedAccountCreationEnabledArg, err := jsoncdc.Encode(restrictedAccountCreationEnabled)
    80  	if err != nil {
    81  		panic(fmt.Sprintf("failed to encode restrictedAccountCreationEnabled: %s", err.Error()))
    82  	}
    83  
    84  	return flow.NewTransactionBody().
    85  		SetScript([]byte(templates.ReplaceAddresses(setupParametersTransactionTemplate,
    86  			templates.Environment{
    87  				StorageFeesAddress:    service.Hex(),
    88  				ServiceAccountAddress: service.Hex(),
    89  			})),
    90  		).
    91  		AddArgument(addressCreationFeeArg).
    92  		AddArgument(minimumStorageReservationArg).
    93  		AddArgument(storagePerFlowArg).
    94  		AddArgument(restrictedAccountCreationEnabledArg).
    95  		AddAuthorizer(service)
    96  }
    97  
    98  func SetupStorageForServiceAccountsTransaction(
    99  	service, fungibleToken, flowToken, feeContract flow.Address,
   100  ) *flow.TransactionBody {
   101  	return flow.NewTransactionBody().
   102  		SetScript([]byte(templates.ReplaceAddresses(setupStorageForServiceAccountsTemplate,
   103  			templates.Environment{
   104  				ServiceAccountAddress: service.Hex(),
   105  				StorageFeesAddress:    service.Hex(),
   106  				FungibleTokenAddress:  fungibleToken.Hex(),
   107  				FlowTokenAddress:      flowToken.Hex(),
   108  			})),
   109  		).
   110  		AddAuthorizer(service).
   111  		AddAuthorizer(fungibleToken).
   112  		AddAuthorizer(flowToken).
   113  		AddAuthorizer(feeContract)
   114  }
   115  
   116  func SetupStorageForAccountTransaction(
   117  	account, service, fungibleToken, flowToken flow.Address,
   118  ) *flow.TransactionBody {
   119  	return flow.NewTransactionBody().
   120  		SetScript([]byte(templates.ReplaceAddresses(setupStorageForAccountTemplate,
   121  			templates.Environment{
   122  				ServiceAccountAddress: service.Hex(),
   123  				StorageFeesAddress:    service.Hex(),
   124  				FungibleTokenAddress:  fungibleToken.Hex(),
   125  				FlowTokenAddress:      flowToken.Hex(),
   126  			})),
   127  		).
   128  		AddAuthorizer(account).
   129  		AddAuthorizer(service)
   130  }
   131  
   132  func SetupFeesTransaction(
   133  	service flow.Address,
   134  	flowFees flow.Address,
   135  	surgeFactor,
   136  	inclusionEffortCost,
   137  	executionEffortCost cadence.UFix64,
   138  ) *flow.TransactionBody {
   139  	surgeFactorArg, err := jsoncdc.Encode(surgeFactor)
   140  	if err != nil {
   141  		panic(fmt.Sprintf("failed to encode surge factor: %s", err.Error()))
   142  	}
   143  	inclusionEffortCostArg, err := jsoncdc.Encode(inclusionEffortCost)
   144  	if err != nil {
   145  		panic(fmt.Sprintf("failed to encode inclusion effort cost: %s", err.Error()))
   146  	}
   147  	executionEffortCostArg, err := jsoncdc.Encode(executionEffortCost)
   148  	if err != nil {
   149  		panic(fmt.Sprintf("failed to encode execution effort cost: %s", err.Error()))
   150  	}
   151  
   152  	return flow.NewTransactionBody().
   153  		SetScript([]byte(templates.ReplaceAddresses(setupFeesTransactionTemplate,
   154  			templates.Environment{
   155  				FlowFeesAddress: flowFees.Hex(),
   156  			})),
   157  		).
   158  		AddArgument(surgeFactorArg).
   159  		AddArgument(inclusionEffortCostArg).
   160  		AddArgument(executionEffortCostArg).
   161  		AddAuthorizer(service)
   162  }
   163  
   164  // SetExecutionEffortWeightsTransaction creates a transaction that sets up weights for the weighted Meter.
   165  func SetExecutionEffortWeightsTransaction(
   166  	service flow.Address,
   167  	weights map[uint]uint64,
   168  ) (*flow.TransactionBody, error) {
   169  	return setExecutionWeightsTransaction(
   170  		service,
   171  		weights,
   172  		TransactionFeesExecutionEffortWeightsPath,
   173  	)
   174  }
   175  
   176  // SetExecutionMemoryWeightsTransaction creates a transaction that sets up weights for the weighted Meter.
   177  func SetExecutionMemoryWeightsTransaction(
   178  	service flow.Address,
   179  	weights map[uint]uint64,
   180  ) (*flow.TransactionBody, error) {
   181  	return setExecutionWeightsTransaction(
   182  		service,
   183  		weights,
   184  		TransactionFeesExecutionMemoryWeightsPath,
   185  	)
   186  }
   187  
   188  func setExecutionWeightsTransaction(
   189  	service flow.Address,
   190  	weights map[uint]uint64,
   191  	path cadence.Path,
   192  ) (*flow.TransactionBody, error) {
   193  	newWeightsKeyValuePairs := make([]cadence.KeyValuePair, len(weights))
   194  	i := 0
   195  	for k, w := range weights {
   196  		newWeightsKeyValuePairs[i] = cadence.KeyValuePair{
   197  			Key:   cadence.UInt64(k),
   198  			Value: cadence.UInt64(w),
   199  		}
   200  		i += 1
   201  	}
   202  	newWeights, err := jsoncdc.Encode(cadence.NewDictionary(newWeightsKeyValuePairs))
   203  	if err != nil {
   204  		return nil, err
   205  	}
   206  
   207  	storagePath, err := jsoncdc.Encode(path)
   208  	if err != nil {
   209  		return nil, err
   210  	}
   211  
   212  	tx := flow.NewTransactionBody().
   213  		SetScript([]byte(setExecutionWeightsScript)).
   214  		AddArgument(newWeights).
   215  		AddArgument(storagePath).
   216  		AddAuthorizer(service)
   217  
   218  	return tx, nil
   219  }
   220  
   221  //go:embed scripts/setExecutionWeightsScript.cdc
   222  var setExecutionWeightsScript string
   223  
   224  func SetExecutionMemoryLimitTransaction(
   225  	service flow.Address,
   226  	limit uint64,
   227  ) (*flow.TransactionBody, error) {
   228  	newLimit, err := jsoncdc.Encode(cadence.UInt64(limit))
   229  	if err != nil {
   230  		return nil, err
   231  	}
   232  
   233  	storagePath, err := jsoncdc.Encode(TransactionFeesExecutionMemoryLimitPath)
   234  	if err != nil {
   235  		return nil, err
   236  	}
   237  
   238  	tx := flow.NewTransactionBody().
   239  		SetScript([]byte(setExecutionMemoryLimit)).
   240  		AddArgument(newLimit).
   241  		AddArgument(storagePath).
   242  		AddAuthorizer(service)
   243  
   244  	return tx, nil
   245  }