我正在从头开始进行区块链项目,似乎在我的 adjustDifficulty(...)函数遇到问题。在测试中,用于正确提高块的挖掘难度的测试用例将失败。尽管难度调整似乎在应用程序运行时有效,但在测试中仍然失败。该函数位于Block.js文件的底部,并具有相应的笑话测试。任何帮助都将不胜感激!
p.s。我知道将GENESIS设置为Date.now()会破坏对等2对等并进行同步。只是忽略它。
Block.js:
const SHA256 = require('crypto-js/sha256');
const { DIFFICULTY, MINE_RATE, GENESIS} = require('../config');
class Block {
constructor (timestamp, lastHash, hash, data, nonce, difficulty) {
this.timestamp = timestamp;
this.lastHash = lastHash;
this.hash = hash;
this.data = data;
this.nonce = nonce;
this.difficulty = difficulty || DIFFICULTY;
}
toString() { // diagonal ticks, template string
return `Block -
Timestamp : ${this.timestamp}
Last Hash : ${this.lastHash.substring(1, 10)}
Hash : ${this.hash.substring(0, 10)}
Nonce : ${this.nonce}
Difficulty: ${this.difficulty}
Data : ${this.data}`;
}
static genesis() { // creates genesis (origin) block
return new this(GENESIS, '-----', 'f1r57-h45h', [], 0, DIFFICULTY);
}
static mineBlock(lastBlock, data) { // adds (Mines) new block
let hash, timestamp;
timestamp = Date.now();
const lastHash = lastBlock.hash;
let { difficulty } = lastBlock;
let nonce = 0;
do {
nonce++;
timestamp = Date.now();
difficulty = Block.adjustDifficulty(lastBlock, timestamp);
hash = Block.hash(timestamp, lastHash, data, nonce, difficulty);
} while(hash.substring(0,difficulty) !== '0'.repeat(difficulty));
return new this(timestamp, lastHash, hash, data, nonce, difficulty);
}
static hash(timestamp, lastHash, data, nonce, difficulty) { // generates new hash
return SHA256(`${timestamp}${lastHash}${data}${nonce}${difficulty}`).toString();
}
static blockHash(block) { // checks has validity
const { timestamp, lastHash, data, nonce, difficulty} = block;
return Block.hash(timestamp, lastHash, data, nonce, difficulty);
}
static adjustDifficulty(lastBlock, currentTime) { // adjusts mining difficulty
let { difficulty } = lastBlock;
// if(lastBlock.timestamp + MINE_RATE > currentTime){
// difficulty+=1
// }
// else{
// difficulty-=1;
// }
difficulty = MINE_RATE >= currentTime - lastBlock.timestamp ? difficulty + 1 : difficulty - 1;
return difficulty;
}
}
module.exports = Block;
block.test.js
const Block = require('./Block');
describe('Block', () => {
let data, lastblock, block;
beforeEach(() => {
data = 'bar';
lastBlock = Block.genesis();
block = Block.mineBlock(lastBlock, data);
});
it('sets the `data` to match the input', () => {
expect(block.data).toEqual(data);
});
it('sets the `lastHash` to match the hash of the last block', () => {
expect(block.lastHash).toEqual(lastBlock.hash);
});
it('generates hash that matches difficulty', () => {
expect(block.hash.substring(0, block.difficulty)).toEqual('0'.repeat(block.difficulty));
});
it('lowers the difficulty for slowly mined blocks', () => {
expect(Block.adjustDifficulty(block, block.timeStamp+360000)).toEqual(block.difficulty - 1);
});
it('raises the difficulty for quickly mined block', () => {
expect(Block.adjustDifficulty(block, block.timeStamp+1)).toEqual(block.difficulty + 1);
});
});
config.js:
const DIFFICULTY = 3; // difficulty of mining a block
const MINE_RATE = 3000; // mine rate definition
const GENESIS = Date.now(); // setting date of first block (genesis block)
module.exports = { DIFFICULTY, MINE_RATE, GENESIS };