diff --git a/CHANGELOG.md b/CHANGELOG.md index 5c59b9b..94f8430 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,13 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. +### [0.0.1-alpha.24](https://github.com/DIG-Network/dig-chia-sdk/compare/v0.0.1-alpha.23...v0.0.1-alpha.24) (2024-09-17) + + +### Bug Fixes + +* address bulk payment fee, better store validation ([76d1dd0](https://github.com/DIG-Network/dig-chia-sdk/commit/76d1dd0c0f9a6a165599e06fc1ef01652a98f882)) + ### [0.0.1-alpha.23](https://github.com/DIG-Network/dig-chia-sdk/compare/v0.0.1-alpha.22...v0.0.1-alpha.23) (2024-09-17) diff --git a/package-lock.json b/package-lock.json index a6bb3ec..3ad89d7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@dignetwork/dig-sdk", - "version": "0.0.1-alpha.23", + "version": "0.0.1-alpha.24", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@dignetwork/dig-sdk", - "version": "0.0.1-alpha.23", + "version": "0.0.1-alpha.24", "license": "ISC", "dependencies": { "bip39": "^3.1.0", diff --git a/package.json b/package.json index b4e8233..f1d7145 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@dignetwork/dig-sdk", - "version": "0.0.1-alpha.23", + "version": "0.0.1-alpha.24", "description": "", "type": "commonjs", "main": "./dist/index.js", diff --git a/src/DigNetwork/DigPeer.ts b/src/DigNetwork/DigPeer.ts index 84268e2..9cf14a0 100644 --- a/src/DigNetwork/DigPeer.ts +++ b/src/DigNetwork/DigPeer.ts @@ -224,7 +224,8 @@ export class DigPeer { walletName: string, outputs: { puzzleHash: Buffer; amount: bigint }[] ): Promise { - const fee = BigInt(1000); + const feePerCondition = BigInt(1000); + const totalFee = feePerCondition * BigInt(outputs.length); const wallet = await Wallet.load(walletName); const publicSyntheticKey = await wallet.getPublicSyntheticKey(); const peer = await FullNodePeer.connect(); @@ -235,12 +236,12 @@ export class DigPeer { const coins = await selectUnspentCoins( peer, totalAmount, - fee, + totalFee, [], walletName ); - const coinSpends = await sendXch(publicSyntheticKey, coins, outputs, fee); + const coinSpends = await sendXch(publicSyntheticKey, coins, outputs, totalFee); const sig = signCoinSpends( coinSpends, diff --git a/src/DigNetwork/PropagationServer.ts b/src/DigNetwork/PropagationServer.ts index 5b17ff0..e0f1c71 100644 --- a/src/DigNetwork/PropagationServer.ts +++ b/src/DigNetwork/PropagationServer.ts @@ -178,70 +178,64 @@ export class PropagationServer { { nonce: string; lastUploadedHash: string; generationIndex: number } | false > { const remote = `https://${this.ipAddress}:${PropagationServer.port}/${this.storeId}`; - return waitForPromise( - () => { - return new Promise< - | { nonce: string; lastUploadedHash: string; generationIndex: number } - | false - >((resolve, reject) => { - const url = new URL(remote); - - const options = { - hostname: url.hostname, - port: url.port, - path: url.pathname, - method: "HEAD", - headers: { - Authorization: `Basic ${Buffer.from( - `${username}:${password}` - ).toString("base64")}`, - }, - key: fs.readFileSync(PropagationServer.keyPath), - cert: fs.readFileSync(PropagationServer.certPath), - rejectUnauthorized: false, // Allow self-signed certificates - }; - - const req = https.request(options, (res) => { - if (res.statusCode === 200) { - // Check if the headers are present and valid - const nonce = res.headers["x-nonce"]; - const lastUploadedHash = - res.headers?.["x-last-uploaded-hash"] || - "0000000000000000000000000000000000000000000000000000000000000000"; - const generationIndex = res.headers?.["x-generation-index"] || 0; - - console.log({ nonce, lastUploadedHash, generationIndex }); - - if (nonce) { - resolve({ - nonce: nonce as string, - lastUploadedHash: lastUploadedHash as string, - generationIndex: Number(generationIndex), - }); - } else { - reject(new Error("Missing required headers in the response.")); - } - } else { - reject( - new Error( - `Failed to perform preflight check: ${res.statusCode} ${res.statusMessage}` - ) - ); - } - }); - req.on("error", (err) => { - console.error(err.message); - resolve(false); // Resolve to false if there is an error - }); + return new Promise< + | { nonce: string; lastUploadedHash: string; generationIndex: number } + | false + >((resolve, reject) => { + const url = new URL(remote); - req.end(); - }); - }, - "Performing remote preflight", - "Preflight succeeded.", - "Error on preflight." - ); + const options = { + hostname: url.hostname, + port: url.port, + path: url.pathname, + method: "HEAD", + headers: { + Authorization: `Basic ${Buffer.from( + `${username}:${password}` + ).toString("base64")}`, + }, + key: fs.readFileSync(PropagationServer.keyPath), + cert: fs.readFileSync(PropagationServer.certPath), + rejectUnauthorized: false, // Allow self-signed certificates + }; + + const req = https.request(options, (res) => { + if (res.statusCode === 200) { + // Check if the headers are present and valid + const nonce = res.headers["x-nonce"]; + const lastUploadedHash = + res.headers?.["x-last-uploaded-hash"] || + "0000000000000000000000000000000000000000000000000000000000000000"; + const generationIndex = res.headers?.["x-generation-index"] || 0; + + console.log({ nonce, lastUploadedHash, generationIndex }); + + if (nonce) { + resolve({ + nonce: nonce as string, + lastUploadedHash: lastUploadedHash as string, + generationIndex: Number(generationIndex), + }); + } else { + reject(new Error("Missing required headers in the response.")); + } + } else { + reject( + new Error( + `Failed to perform preflight check: ${res.statusCode} ${res.statusMessage}` + ) + ); + } + }); + + req.on("error", (err) => { + console.error(err.message); + resolve(false); // Resolve to false if there is an error + }); + + req.end(); + }); } // Core method to upload a file directly to the server using a stream diff --git a/src/blockchain/DataStore.ts b/src/blockchain/DataStore.ts index ce0af0b..27831c2 100644 --- a/src/blockchain/DataStore.ts +++ b/src/blockchain/DataStore.ts @@ -523,6 +523,8 @@ export class DataStore { } let filesIntegrityIntact = true; + + // At this point we have verified that the root history and manifest file match for (const rootHash of manifestHashes) { const datFilePath = path.join( STORE_PATH, @@ -546,11 +548,14 @@ export class DataStore { } for (const [fileKey, fileData] of Object.entries(datFileContent.files)) { - const integrityCheck = validateFileSha256( + // We are going to check if the sha256 belongs to the tree, and then we are going to make sure + // that the file is in the data folder and that the sha256 of the file matches the one in the dat file + const belongsInTree = await this.Tree.verifyKeyIntegrity(fileData.sha256, rootHash); + const fileIntegrityCheck = validateFileSha256( fileData.sha256, path.join(STORE_PATH, this.storeId, "data") ); - if (!integrityCheck) { + if (!fileIntegrityCheck || !belongsInTree) { filesIntegrityIntact = false; } }