Skip to content

Commit

Permalink
add while loop from Riley's Fortuna miner
Browse files Browse the repository at this point in the history
  • Loading branch information
MicroProofs committed Aug 27, 2023
1 parent adf7205 commit 721cc8a
Showing 1 changed file with 169 additions and 115 deletions.
284 changes: 169 additions & 115 deletions miner/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,161 +34,215 @@ type Genesis = {
outRef: { txHash: string; index: number };
};

const delay = (ms: number | undefined) =>
new Promise((res) => setTimeout(res, ms));

const mine = new Command()
.description("Start the miner")
.env("KUPO_URL=<value:string>", "Kupo URL", { required: true })
.env("OGMIOS_URL=<value:string>", "Ogmios URL", { required: true })
.option("-p, --preview", "Use testnet")
.action(async ({ preview, ogmiosUrl, kupoUrl }) => {
const genesisFile = Deno.readTextFileSync(
`genesis/${preview ? "preview" : "mainnet"}.json`,
);
while (true) {
const genesisFile = Deno.readTextFileSync(
`genesis/${preview ? "preview" : "mainnet"}.json`,
);

const { validatorHash, validatorAddress }: Genesis = JSON.parse(
genesisFile,
);
const { validatorHash, validatorAddress }: Genesis = JSON
.parse(
genesisFile,
);

const provider = new Kupmios(kupoUrl, ogmiosUrl);
const lucid = await Lucid.new(provider, preview ? "Preview" : "Mainnet");
const provider = new Kupmios(kupoUrl, ogmiosUrl);
const lucid = await Lucid.new(provider, preview ? "Preview" : "Mainnet");

lucid.selectWalletFromSeed(Deno.readTextFileSync("seed.txt"));
lucid.selectWalletFromSeed(Deno.readTextFileSync("seed.txt"));

const validatorUTXOs = await lucid.utxosAt(validatorAddress);
let validatorUTXOs = await lucid.utxosAt(validatorAddress);

const validatorOutRef = validatorUTXOs.find(
(u) => u.assets[validatorHash + fromText("lord tuna")],
)!;
let validatorOutRef = validatorUTXOs.find(
(u) => u.assets[validatorHash + fromText("lord tuna")],
)!;

const validatorState = validatorOutRef.datum!;
let validatorState = validatorOutRef.datum!;

const state = Data.from(validatorState) as Constr<
string | bigint | string[]
>;
let state = Data.from(validatorState) as Constr<
string | bigint | string[]
>;

const nonce = new Uint8Array(16);
let nonce = new Uint8Array(16);

crypto.getRandomValues(nonce);
crypto.getRandomValues(nonce);

const targetState = new Constr(0, [
// nonce: ByteArray
toHex(nonce),
// block_number: Int
state.fields[0] as bigint,
// current_hash: ByteArray
state.fields[1] as bigint,
// leading_zeros: Int
state.fields[2] as bigint,
// difficulty_number: Int
state.fields[3] as bigint,
//epoch_time: Int
state.fields[4] as bigint,
]);
let targetState = new Constr(0, [
// nonce: ByteArray
toHex(nonce),
// block_number: Int
state.fields[0] as bigint,
// current_hash: ByteArray
state.fields[1] as bigint,
// leading_zeros: Int
state.fields[2] as bigint,
// difficulty_number: Int
state.fields[3] as bigint,
//epoch_time: Int
state.fields[4] as bigint,
]);

let targetHash: Uint8Array;
let targetHash: Uint8Array;

let difficulty: {
leadingZeros: bigint;
difficulty_number: bigint;
};
let difficulty: {
leadingZeros: bigint;
difficulty_number: bigint;
};

console.log("Mining...");
while (true) {
targetHash = sha256(sha256(fromHex(Data.to(targetState))));
console.log("Mining...");
let timer = new Date().valueOf();
while (true) {
if (new Date().valueOf() - timer > 30000) {
console.log("New block not found in 30 seconds, updating state");
timer = new Date().valueOf();
validatorUTXOs = await lucid.utxosAt(validatorAddress);

difficulty = getDifficulty(targetHash);
validatorOutRef = validatorUTXOs.find(
(u) => u.assets[validatorHash + fromText("lord tuna")],
)!;

const { leadingZeros, difficulty_number } = difficulty;
validatorState = validatorOutRef.datum!;

if (
leadingZeros > (state.fields[2] as bigint) ||
(leadingZeros == (state.fields[2] as bigint) &&
difficulty_number < (state.fields[3] as bigint))
) {
break;
}

incrementU8Array(nonce);
state = Data.from(validatorState) as Constr<
string | bigint | string[]
>;

targetState.fields[0] = toHex(nonce);
}
nonce = new Uint8Array(16);

const realTimeNow = Number((Date.now() / 1000).toFixed(0)) * 1000 - 60000;
crypto.getRandomValues(nonce);

const interlink = calculateInterlink(toHex(targetHash), difficulty, {
leadingZeros: state.fields[2] as bigint,
difficulty_number: state.fields[3] as bigint,
}, state.fields[7] as string[]);
targetState = new Constr(0, [
// nonce: ByteArray
toHex(nonce),
// block_number: Int
state.fields[0] as bigint,
// current_hash: ByteArray
state.fields[1] as bigint,
// leading_zeros: Int
state.fields[2] as bigint,
// difficulty_number: Int
state.fields[3] as bigint,
//epoch_time: Int
state.fields[4] as bigint,
]);
}

let epoch_time = (state.fields[4] as bigint) + BigInt(90000 + realTimeNow) -
(state.fields[5] as bigint);
targetHash = sha256(sha256(fromHex(Data.to(targetState))));

let difficulty_number = state.fields[3] as bigint;
let leading_zeros = state.fields[2] as bigint;
difficulty = getDifficulty(targetHash);

if (
state.fields[0] as bigint % 2016n === 0n && state.fields[0] as bigint > 0
) {
const adjustment = getDifficultyAdjustement(epoch_time, 1_209_600_000n);
const { leadingZeros, difficulty_number } = difficulty;

epoch_time = 0n;

const new_difficulty = calculateDifficultyNumber(
{
leadingZeros: state.fields[2] as bigint,
difficulty_number: state.fields[3] as bigint,
},
adjustment.numerator,
adjustment.denominator,
);
if (
leadingZeros > (state.fields[2] as bigint) ||
(leadingZeros == (state.fields[2] as bigint) &&
difficulty_number < (state.fields[3] as bigint))
) {
break;
}

difficulty_number = new_difficulty.difficulty_number;
leading_zeros = new_difficulty.leadingZeros;
}
incrementU8Array(nonce);

// calculateDifficultyNumber();
targetState.fields[0] = toHex(nonce);
}

const postDatum = new Constr(0, [
(state.fields[0] as bigint) + 1n,
toHex(targetHash),
leading_zeros,
difficulty_number,
epoch_time,
BigInt(90000 + realTimeNow),
0n,
interlink,
]);
const realTimeNow = Number((Date.now() / 1000).toFixed(0)) * 1000 - 60000;

const outDat = Data.to(postDatum);
const interlink = calculateInterlink(toHex(targetHash), difficulty, {
leadingZeros: state.fields[2] as bigint,
difficulty_number: state.fields[3] as bigint,
}, state.fields[7] as string[]);

console.log(`Found next datum: ${outDat}`);
let epoch_time = (state.fields[4] as bigint) +
BigInt(90000 + realTimeNow) -
(state.fields[5] as bigint);

const mintTokens = { [validatorHash + fromText("TUNA")]: 5000000000n };
const masterToken = { [validatorHash + fromText("lord tuna")]: 1n };
let difficulty_number = state.fields[3] as bigint;
let leading_zeros = state.fields[2] as bigint;

const readUtxo = await lucid.utxosByOutRef([{
txHash:
"01751095ea408a3ebe6083b4de4de8a24b635085183ab8a2ac76273ef8fff5dd",
outputIndex: 0,
}]);

const txMine = await lucid
.newTx()
.collectFrom([validatorOutRef], Data.to(new Constr(1, [toHex(nonce)])))
.payToAddressWithData(validatorAddress, { inline: outDat }, masterToken)
.mintAssets(mintTokens, Data.to(new Constr(0, [])))
.readFrom(readUtxo)
.validTo(realTimeNow + 180000)
.validFrom(realTimeNow)
.complete();
if (
state.fields[0] as bigint % 2016n === 0n &&
state.fields[0] as bigint > 0
) {
const adjustment = getDifficultyAdjustement(epoch_time, 1_209_600_000n);

const signed = await txMine.sign().complete();
epoch_time = 0n;

await signed.submit();
const new_difficulty = calculateDifficultyNumber(
{
leadingZeros: state.fields[2] as bigint,
difficulty_number: state.fields[3] as bigint,
},
adjustment.numerator,
adjustment.denominator,
);

console.log(`TX HASH: ${signed.toHash()}`);
console.log("Waiting for confirmation...");
difficulty_number = new_difficulty.difficulty_number;
leading_zeros = new_difficulty.leadingZeros;
}

await lucid.awaitTx(signed.toHash());
// calculateDifficultyNumber();

const postDatum = new Constr(0, [
(state.fields[0] as bigint) + 1n,
toHex(targetHash),
leading_zeros,
difficulty_number,
epoch_time,
BigInt(90000 + realTimeNow),
fromText("AlL HaIl tUnA"),
interlink,
]);

const outDat = Data.to(postDatum);

console.log(`Found next datum: ${outDat}`);

const mintTokens = { [validatorHash + fromText("TUNA")]: 5000000000n };
const masterToken = { [validatorHash + fromText("lord tuna")]: 1n };
try {
const readUtxo = await lucid.utxosByOutRef([{
txHash:
"01751095ea408a3ebe6083b4de4de8a24b635085183ab8a2ac76273ef8fff5dd",
outputIndex: 0,
}]);
const txMine = await lucid
.newTx()
.collectFrom(
[validatorOutRef],
Data.to(new Constr(1, [toHex(nonce)])),
)
.payToAddressWithData(
validatorAddress,
{ inline: outDat },
masterToken,
)
.mintAssets(mintTokens, Data.to(new Constr(0, [])))
.readFrom(readUtxo)
.validTo(realTimeNow + 180000)
.validFrom(realTimeNow)
.complete();

const signed = await txMine.sign().complete();

await signed.submit();

console.log(`TX HASH: ${signed.toHash()}`);
console.log("Waiting for confirmation...");

// // await lucid.awaitTx(signed.toHash());
await delay(5000);
} catch (e) {
console.log(e);
}
}
});

const genesis = new Command()
Expand Down

0 comments on commit 721cc8a

Please sign in to comment.