Skip to content

Commit

Permalink
Enhance upload preparation task to include metadata changes and cost …
Browse files Browse the repository at this point in the history
…estimation
  • Loading branch information
thomas-senechal committed Jan 13, 2025
1 parent 930c8d4 commit da6ed19
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 21 deletions.
53 changes: 43 additions & 10 deletions cli/src/lib/website/filesInit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,26 @@ import {
strToBytes,
U32,
} from '@massalabs/massa-web3'

import {
CallManager,
CallStatus,
CallUpdate,
FunctionCall,
} from '../utils/callManager'
import { storageCostForEntry } from '../utils/storage'
import { maxBigInt } from '../utils/utils'
import { FileDelete } from './models/FileDelete'

import { FileInit } from './models/FileInit'
import { Metadata } from './models/Metadata'

import {
FILE_TAG,
fileChunkCountKey,
fileLocationKey,
globalMetadataKey,
} from './storageKeys'
import { FileDelete } from './models/FileDelete'
import { maxBigInt } from '../utils/utils'
import {
FunctionCall,
CallManager,
CallUpdate,
CallStatus,
} from '../utils/callManager'

const functionName = 'filesInit'
export const batchSize = 32
Expand Down Expand Up @@ -154,13 +157,19 @@ export async function sendFilesInits(

// TODO: Improve estimation
// - If a file is already stored, we don't need to send coins for its hash storage
export async function filesInitCost(
export async function prepareCost(
_: SmartContract,
files: FileInit[],
filesToDelete: FileDelete[],
metadatas: Metadata[],
metadatasToDelete: Metadata[]
): Promise<bigint> {
): Promise<{
filePathListCost: bigint
storageCost: bigint
filesToDeleteCost: bigint
metadatasCost: bigint
metadatasToDeleteCost: bigint
}> {
const filePathListCost = files.reduce((acc, chunk) => {
return (
acc +
Expand Down Expand Up @@ -211,6 +220,30 @@ export async function filesInitCost(
)
}, 0n)

return {
filePathListCost,
storageCost,
filesToDeleteCost,
metadatasCost,
metadatasToDeleteCost,
}
}

export async function filesInitCost(
_sc: SmartContract,
files: FileInit[],
filesToDelete: FileDelete[],
metadatas: Metadata[],
metadatasToDelete: Metadata[]
): Promise<bigint> {
const {
filePathListCost,
storageCost,
filesToDeleteCost,
metadatasCost,
metadatasToDeleteCost,
} = await prepareCost(_sc, files, filesToDelete, metadatas, metadatasToDelete)

return BigInt(
filePathListCost +
storageCost +
Expand Down
60 changes: 49 additions & 11 deletions cli/src/tasks/prepareUpload.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { ListrTask } from 'listr2'
import {
batchSize,
filesInitCost,

Check failure on line 7 in cli/src/tasks/prepareUpload.ts

View workflow job for this annotation

GitHub Actions / lint-cli

'filesInitCost' is defined but never used
prepareCost,
sendFilesInits,
} from '../lib/website/filesInit'
import { LAST_UPDATE_KEY } from '../lib/website/metadata'
Expand All @@ -20,8 +21,13 @@ export function prepareUploadTask(): ListrTask {
return {
title: 'Prepare upload',
task: (ctx: UploadCtx, task) => {
if (ctx.fileInits.length === 0 && ctx.filesToDelete.length === 0) {
task.skip('All files are ready for upload')
if (
ctx.fileInits.length === 0 &&
ctx.filesToDelete.length === 0 &&
ctx.metadatas.length === 0 &&
ctx.metadatasToDelete.length === 0
) {
task.skip('All files are ready for upload, and no metadata changes')
return
}

Expand All @@ -34,22 +40,54 @@ export function prepareUploadTask(): ListrTask {
{
title: 'Confirm SC preparation',
task: async (ctx, subTask) => {
if (
ctx.fileInits.length !== 0 ||
ctx.filesToDelete.length !== 0
) {
subTask.output = 'Files changes detected'
}
if (
ctx.metadatas.length !== 0 ||
ctx.metadatasToDelete.length !== 0
) {
subTask.output = 'Metadata changes detected'
}

const totalChanges =
ctx.fileInits.length +
ctx.filesToDelete.length +
ctx.metadatas.length +
ctx.metadatasToDelete.length
const estimatedOperations = Math.ceil(totalChanges / batchSize)
const minimalFees = ctx.minimalFees * BigInt(estimatedOperations)
const cost =
(await filesInitCost(
ctx.sc,
ctx.fileInits,
ctx.filesToDelete,
ctx.metadatas,
ctx.metadatasToDelete
)) + minimalFees
subTask.output = `SC preparation costs ${formatMas(cost)} MAS (including ${formatMas(minimalFees)} MAS of minimal fees)`
const {
filePathListCost,
storageCost,
filesToDeleteCost,
metadatasCost,
metadatasToDeleteCost,
} = await prepareCost(
ctx.sc,
ctx.fileInits,
ctx.filesToDelete,
ctx.metadatas,
ctx.metadatasToDelete
)

const totalCost =
filePathListCost +
storageCost -
filesToDeleteCost +
metadatasCost -
metadatasToDeleteCost

subTask.output = `Estimated cost of SC preparation:`
subTask.output = ` + Files init: ${formatMas(filePathListCost)} MAS`
subTask.output = ` + Storage: ${formatMas(storageCost)} MAS`
subTask.output = ` - Files to delete: ${formatMas(filesToDeleteCost)} MAS`
subTask.output = ` + Metadatas: ${formatMas(metadatasCost)} MAS`
subTask.output = ` - Metadatas to delete: ${formatMas(metadatasToDeleteCost)} MAS`
subTask.output = `SC preparation costs ${formatMas(totalCost + minimalFees)} MAS (including ${formatMas(minimalFees)} MAS of minimal fees)`

if (!ctx.skipConfirm) {
const answer = await subTask
Expand Down

0 comments on commit da6ed19

Please sign in to comment.