Skip to content

Commit

Permalink
Add transaction proof of work
Browse files Browse the repository at this point in the history
  • Loading branch information
zpalmtree committed May 21, 2020
1 parent 46036a1 commit 02b5ce8
Show file tree
Hide file tree
Showing 7 changed files with 120 additions and 16 deletions.
2 changes: 1 addition & 1 deletion config.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"maximumOutputAmount": 100000000000,
"maximumOutputsPerTransaction": 90,
"maximumExtraSize": 1024,
"activateFeePerByteTransactions": true,
"activateFeePerByteTransactions": false,
"feePerByte": 1.953125,
"feePerByteChunkSize": 256
}
23 changes: 11 additions & 12 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
"numeral": "^2.0.6",
"secure-random-string": "^1.1.3",
"turtlecoin-base58": "^0.0.6",
"turtlecoin-crypto": "^4.0.9",
"turtlecoin-crypto": "https://github.com/derogold/turtlecoin-crypto.git",
"turtlecoin-mnemonics": "^0.0.6"
},
"devDependencies": {
Expand Down
3 changes: 3 additions & 0 deletions src/CryptoNote.ts
Original file line number Diff line number Diff line change
Expand Up @@ -476,6 +476,7 @@ export class CryptoNote {

for (let i = 0; i < prepared.inputs.length; i++) {
const input = prepared.inputs[i];

const srcKeys: string[] = [];

if (!input.input.privateEphemeral) {
Expand Down Expand Up @@ -673,6 +674,8 @@ export class CryptoNote {
tx.outputs.push(new TransactionOutputs.KeyOutput(output.amount, output.key));
}

await tx.generateTxProofOfWork();

if (tx.extra.length > (this.config.maximumExtraSize || Config.maximumExtraSize)) {
throw new Error('Transaction extra exceeds the limit of [' +
(this.config.maximumExtraSize || Config.maximumExtraSize) + '] bytes');
Expand Down
48 changes: 47 additions & 1 deletion src/Transaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,7 @@ export class Transaction {
protected m_unlockTime: BigInteger.BigInteger = BigInteger.zero;
protected m_rawExtra: Buffer = Buffer.alloc(0);
protected m_readonly: boolean = false;
protected m_extra: ExtraTag.IExtraTag[] = [];
public m_extra: ExtraTag.IExtraTag[] = [];
protected m_cached: Cache = {prefix: '', prefixHash: '', blob: '', hash: ''};

/** @ignore */
Expand Down Expand Up @@ -484,6 +484,52 @@ export class Transaction {
this.transactionKeys.publicKey = publicKey;
}

public async generateTxProofOfWork() {
if (this.readonly) {
throw new Error('Transaction is read-only');
}

let nonceTag = new ExtraTag.ExtraPowNonce(BigInteger(0));

let result: ExtraTag.IExtraTag[] = [];

for (const tag of this.m_extra) {
if (tag.tag !== nonceTag.tag) {
result.push(tag);
}
}

this.m_extra = result;
this.m_extra.push(nonceTag);

const prefix = this.prefix;

/* Find the pow nonce tag and nonce hole */
const tagOffset = prefix.indexOf("040000000000000000");

/* Then add 2 to skip the tag. */
const nonceOffset = tagOffset + 2;

/* Actual offset is half the nonce offset, since this is hex, but it
* will be deserialized into bytes taking up half the space */
const unserializedOffset = nonceOffset / 2;

const nonce = TurtleCoinCrypto.generateTransactionPow(prefix, unserializedOffset);

nonceTag = new ExtraTag.ExtraPowNonce(BigInteger(nonce));

result = [];

for (const tag of this.m_extra) {
if (tag.tag !== nonceTag.tag) {
result.push(tag);
}
}

this.m_extra = result;
this.m_extra.push(nonceTag);
}

/**
* Returns a buffer representation of the transaction object
* @param [headerOnly] whether we should return just the prefix or not
Expand Down
56 changes: 56 additions & 0 deletions src/Types/IExtraTag.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import {Reader, Writer} from 'bytestream-helper';
import {ExtraNonceTag, TurtleCoinCrypto} from '../Types';
import {Common} from '../Common';
import {BigInteger} from 'big-integer';

/** @ignore */
enum SIZES {
Expand All @@ -23,6 +24,7 @@ export namespace ExtraTag {
PUBKEY,
NONCE,
MERGED_MINING,
POW_NONCE
}

/**
Expand Down Expand Up @@ -52,6 +54,60 @@ export namespace ExtraTag {
public abstract toString(): string;
}

export class ExtraPowNonce implements IExtraTag {
public get tag(): ExtraTagType {
return this.m_tag;
}

public get size(): number {
return 9;
}

public static from(data: Buffer | string): ExtraPowNonce {
const reader = new Reader(data);

if (reader.varint().toJSNumber() !== ExtraTagType.POW_NONCE) {
throw new Error('Not a pow nonce field');
}

if (reader.unreadBytes !== SIZES.KEY) {
throw new RangeError('Not enough data available for reading');
}

const nonce = reader.uint64_t();

return new ExtraPowNonce(nonce);
}

private readonly m_tag: ExtraTagType = ExtraTagType.POW_NONCE;
private m_nonce: BigInteger;

constructor(nonce: BigInteger) {
this.m_nonce = nonce;
}

/**
* Represents the field as a Buffer
* @returns the Buffer representation of the object
*/
public toBuffer(): Buffer {
const writer = new Writer();

writer.varint(this.tag);
writer.uint64_t(this.m_nonce);

return writer.buffer;
}

/**
* Represents the field as a hexadecimal string (blob)
* @returns the hexadecimal (blob) representation of the object
*/
public toString(): string {
return this.toBuffer().toString('hex');
}
}

/**
* Represents a structured padding field used in the transaction extra field
*/
Expand Down
2 changes: 1 addition & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@
"strict": true,
"downlevelIteration": true
}
}
}

0 comments on commit 02b5ce8

Please sign in to comment.