From e2a3c743d5ff87d93fe29c14f10c336565fa52cc Mon Sep 17 00:00:00 2001 From: cyl19970726 <15258378443@163.com> Date: Mon, 27 Feb 2023 18:24:53 +0800 Subject: [PATCH] support uploadChunk on ETHStorage --- src/storage/ETHStorage.ts | 63 ++++++++++++++++++++++++++++++++++----- 1 file changed, 56 insertions(+), 7 deletions(-) diff --git a/src/storage/ETHStorage.ts b/src/storage/ETHStorage.ts index d9e01b3..925565b 100644 --- a/src/storage/ETHStorage.ts +++ b/src/storage/ETHStorage.ts @@ -2,7 +2,9 @@ import { Ref, Status, Storage } from "./storage.js" import { ethers } from "ethers" import { TxManager } from "../common/tx-manager.js" import { Git3Protocol } from "../common/git3-protocol.js" +import { buffer } from "stream/consumers" + export class ETHStorage implements Storage { repoName: string wallet: ethers.Signer @@ -39,14 +41,61 @@ export class ETHStorage implements Storage { async upload(path: string, file: Buffer): Promise { try { - console.error(`=== uploading file ${path} ===`) - await this.txManager.SendCall("upload", [ - Buffer.from(this.repoName), - Buffer.from(path), - file, - ]) - console.error(`=== upload ${path} succeed ===`) + let chunks: Buffer[] = []; + let costs:number[] = []; + const FileChunkSize = 475 * 1024 + const perEthPayStorageSize = 24 * 1024 + const initCodeLen = 280; + if (file.length > FileChunkSize) { + let uploadedSize = 0; + let nouploadfileSize = file.length; + for (uploadedSize = 0; uploadedSize < file.length; uploadedSize += FileChunkSize) { + let newchunk:Buffer; + let cost:number; + if (file.length != nouploadfileSize + uploadedSize){ + throw new Error(`file.length${file.length} != nouploadfileSize${nouploadfileSize} + uploadedSize${uploadedSize}`) + } + if (nouploadfileSize < FileChunkSize){ + newchunk = Buffer.alloc(nouploadfileSize) + file.copy(newchunk, 0,uploadedSize,file.length) + cost = Math.ceil((nouploadfileSize+ initCodeLen) / perEthPayStorageSize) + }else{ + newchunk = Buffer.alloc(FileChunkSize) + file.copy(newchunk, 0,uploadedSize,uploadedSize+FileChunkSize) + cost = Math.ceil((FileChunkSize+initCodeLen) / perEthPayStorageSize) + nouploadfileSize -= FileChunkSize; + } + chunks.push(newchunk); + costs.push(cost); + } + + chunks.forEach(async (context,index) => { + console.error(`=== uploading file chunk ${path} chunkId-${index} chunk_size:${context.length} storage_cost:${costs[index]}-token===`) + await this.txManager.SendCall("uploadChunk", [ + Buffer.from(this.repoName), + Buffer.from(path), + index, + context, + {value:ethers.utils.parseEther(costs[index].toString())}, + ]); + console.error(`=== upload file chunk ${path} chunkId-${index} chunk_size:${context.length} storage_cost:${costs[index]}-token Succeed===`) + }) + + } else { + let cost:number = 0; + if (file.length > perEthPayStorageSize){ + cost = Math.ceil(file.length / perEthPayStorageSize); + } + console.error(`=== uploading file ${path} file_size ${file.length} storage_cost:${cost}-token===`) + await this.txManager.SendCall("upload", [ + Buffer.from(this.repoName), + Buffer.from(path), + file, + {value:ethers.utils.parseEther(cost.toString())}, + ]) + console.error(`=== upload ${path} file_size ${file.length} storage_cost:${cost}-token succeed ===`) + } return Status.SUCCEED } catch (error: any) { this.txManager.CancelAll()