From c541fc9c4d7a298e8d70fed1a2ee338b43c2dd4b Mon Sep 17 00:00:00 2001 From: Michael Kim Date: Wed, 2 Oct 2024 17:44:22 +0900 Subject: [PATCH] Eliminate the possibility of overlapping hash --- packages/contracts/package.json | 2 +- packages/sdk/package.json | 2 +- .../modules/blockchain/data/BlockHeader.ts | 15 ++++++++++-- .../sdk/src/modules/utils/JSONValidator.ts | 5 +++- packages/server/package.json | 2 +- packages/server/scripts/getS3.ts | 18 +++++++++++---- .../server/src/service/network/IPFSManager.ts | 4 ++++ .../src/service/network/IStorageManager.ts | 1 + .../server/src/service/network/S3Manager.ts | 23 ++++++++++++++++++- packages/server/src/service/scheduler/Node.ts | 8 ++++++- 10 files changed, 67 insertions(+), 13 deletions(-) diff --git a/packages/contracts/package.json b/packages/contracts/package.json index 170d70f..f2ef3bf 100644 --- a/packages/contracts/package.json +++ b/packages/contracts/package.json @@ -33,7 +33,7 @@ "@types/chai": "^4.3.5", "@types/mocha": "^10.0.0", "@types/node": "^12.20.43", - "acc-save-purchase-sdk": "~2.2.0", + "acc-save-purchase-sdk": "~2.3.0", "assert": "^2.0.0", "chai": "^4.3.7", "chai-http": "^4.3.7", diff --git a/packages/sdk/package.json b/packages/sdk/package.json index 51c325d..818fec4 100644 --- a/packages/sdk/package.json +++ b/packages/sdk/package.json @@ -1,6 +1,6 @@ { "name": "acc-save-purchase-sdk", - "version": "2.2.0", + "version": "2.3.0", "description": "The TypeScript DMS Store Purchase SDK library", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/packages/sdk/src/modules/blockchain/data/BlockHeader.ts b/packages/sdk/src/modules/blockchain/data/BlockHeader.ts index 0081eb4..baef617 100644 --- a/packages/sdk/src/modules/blockchain/data/BlockHeader.ts +++ b/packages/sdk/src/modules/blockchain/data/BlockHeader.ts @@ -38,18 +38,22 @@ export class BlockHeader { */ public timestamp: bigint; + public nonce: bigint; + /** * Constructor * @param prevBlock The Hash of the previous block in the chain of blocks * @param merkleRoot The hash of the merkle root of the transactions * @param height The block height * @param timestamp + * @param nonce */ - constructor(prevBlock: Hash, merkleRoot: Hash, height: bigint, timestamp: bigint) { + constructor(prevBlock: Hash, merkleRoot: Hash, height: bigint, timestamp: bigint, nonce: bigint = 0n) { this.prevBlock = prevBlock; this.merkleRoot = merkleRoot; this.height = height; this.timestamp = timestamp; + this.nonce = nonce; } /** @@ -71,7 +75,8 @@ export class BlockHeader { new Hash(value.prevBlock), new Hash(value.merkleRoot), BigInt(value.height), - BigInt(value.timestamp) + BigInt(value.timestamp), + BigInt(value.nonce) ); } @@ -84,6 +89,7 @@ export class BlockHeader { merkleRoot: this.merkleRoot, height: this.height.toString(), timestamp: this.timestamp.toString(), + nonce: this.nonce.toString(), }; } @@ -96,5 +102,10 @@ export class BlockHeader { this.merkleRoot.computeHash(buffer); buffer.writeBigUInt64LE(this.height); buffer.writeBigUInt64LE(this.timestamp); + buffer.writeBigUInt64LE(this.nonce); + } + + public increaseNonce(): void { + this.nonce++; } } diff --git a/packages/sdk/src/modules/utils/JSONValidator.ts b/packages/sdk/src/modules/utils/JSONValidator.ts index f49be17..39cea18 100644 --- a/packages/sdk/src/modules/utils/JSONValidator.ts +++ b/packages/sdk/src/modules/utils/JSONValidator.ts @@ -68,9 +68,12 @@ export class JSONValidator { timestamp: { type: "string", }, + nonce: { + type: "string", + }, }, additionalProperties: false, - required: ["prevBlock", "merkleRoot", "height", "timestamp"], + required: ["prevBlock", "merkleRoot", "height", "timestamp", "nonce"], }, ], [ diff --git a/packages/server/package.json b/packages/server/package.json index 300f778..a02de06 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -68,7 +68,7 @@ "dependencies": { "@aws-sdk/client-s3": "^3.658.1", "acc-save-purchase-contracts": "~1.0.2", - "acc-save-purchase-sdk": "~2.2.0", + "acc-save-purchase-sdk": "~2.3.0", "argparse": "^2.0.1", "assert": "^2.0.0", "axios": "^1.6.7", diff --git a/packages/server/scripts/getS3.ts b/packages/server/scripts/getS3.ts index a35ecb4..c42d388 100644 --- a/packages/server/scripts/getS3.ts +++ b/packages/server/scripts/getS3.ts @@ -4,20 +4,28 @@ import { HTTPClient } from "../src/service/utils/HTTPClient"; import URI from "urijs"; +import axios from "axios"; + dotenv.config({ path: "env/.env" }); async function main() { const PURCHASE_STORAGE_ENDPOINT = `https://${process.env.NODE_S3_BUCKET}.s3.${process.env.NODE_S3_REGION}.amazonaws.com`; console.log(`STORE_PURCHASE_ENDPOINT : ${PURCHASE_STORAGE_ENDPOINT}`); - const client = new HTTPClient({}); + const client = axios.create(); const url = URI(PURCHASE_STORAGE_ENDPOINT) - .filename("0x1035197ef87cdef2ffce17acf76e8745de9d521a47893e5df341dc02306fcab2") + .filename("0x1035197ef87cdef2ffce17acf76e8745de9d521a47893e5df341dc02306fcab23") .toString(); console.log(`URL : ${url}`); - const response = await client.get(url); - - console.log(`RESULT: ${JSON.stringify(response.data)}`); + try { + const response = await client.get(url); + console.log(`status: ${JSON.stringify(response.status)}`); + console.log(`RESULT: ${JSON.stringify(response.data)}`); + } catch (reason: any) { + if (reason.response !== undefined && reason.response.status !== undefined) { + console.log(reason.response.status); + } + } await ContractUtils.delay(500); } diff --git a/packages/server/src/service/network/IPFSManager.ts b/packages/server/src/service/network/IPFSManager.ts index 7e4843a..0e253ae 100644 --- a/packages/server/src/service/network/IPFSManager.ts +++ b/packages/server/src/service/network/IPFSManager.ts @@ -63,4 +63,8 @@ export class IPFSManager implements IStorageManager { }); }); } + + public exists(cid: string): Promise { + return Promise.resolve(false); + } } diff --git a/packages/server/src/service/network/IStorageManager.ts b/packages/server/src/service/network/IStorageManager.ts index 019113b..2c10dcc 100644 --- a/packages/server/src/service/network/IStorageManager.ts +++ b/packages/server/src/service/network/IStorageManager.ts @@ -1,4 +1,5 @@ export interface IStorageManager { setTest(value: boolean): any; add(data: string | Buffer, cid: string): Promise; + exists(cid: string): Promise; } diff --git a/packages/server/src/service/network/S3Manager.ts b/packages/server/src/service/network/S3Manager.ts index c97d356..7037418 100644 --- a/packages/server/src/service/network/S3Manager.ts +++ b/packages/server/src/service/network/S3Manager.ts @@ -3,6 +3,8 @@ import { IStorageManager } from "./IStorageManager"; import { PutObjectCommand, S3Client } from "@aws-sdk/client-s3"; +import axios, { AxiosInstance } from "axios"; + /** * Store data in IPFS. */ @@ -10,6 +12,7 @@ export class S3Manager implements IStorageManager { private test: boolean; private config: Config; private s3_client: S3Client; + private axios_client: AxiosInstance; /** * Constructor @@ -23,6 +26,9 @@ export class S3Manager implements IStorageManager { secretAccessKey: this.config.node.s3_secret_key, }, }); + this.axios_client = axios.create({ + baseURL: `https://${this.config.node.s3_bucket}.s3.${this.config.node.s3_region}.amazonaws.com`, + }); this.test = false; } @@ -53,9 +59,24 @@ export class S3Manager implements IStorageManager { return resolve(cid); }) .catch((reason) => { - console.error(reason); return reject(new Error(reason)); }); }); } + + public exists(cid: string): Promise { + return new Promise((resolve, reject) => { + this.axios_client + .get(cid) + .then((response) => { + return resolve(true); + }) + .catch((reason) => { + if (reason.response !== undefined && reason.response.status !== undefined) { + if (reason.response.status === 404) return resolve(false); + else return reject(reason); + } else return reject(reason); + }); + }); + } } diff --git a/packages/server/src/service/scheduler/Node.ts b/packages/server/src/service/scheduler/Node.ts index 68fc3ce..87f57f3 100644 --- a/packages/server/src/service/scheduler/Node.ts +++ b/packages/server/src/service/scheduler/Node.ts @@ -237,13 +237,19 @@ export class Node extends Scheduler { const txList = DBTransaction.converterTxArray(txs); const block = Block.createBlock(this.prev_hash, this.prev_height, txList); + let blockHash: string; + while (true) { + blockHash = hashFull(block).toString(); + if (!(await this.blockStorage.exists(blockHash))) break; + else block.header.increaseNonce(); + } let cid: string = ""; let success: boolean = true; try { // Save block - cid = await this.blockStorage.add(JSON.stringify(block), hashFull(block).toString()); + cid = await this.blockStorage.add(JSON.stringify(block), blockHash); logger.info(`Saved block to IPFS - height: ${block.header.height.toString()}, CID: ${cid}`); } catch { success = false;