Skip to content

Commit

Permalink
Add Telestai
Browse files Browse the repository at this point in the history
  • Loading branch information
xiaolin1579 committed Aug 7, 2024
1 parent 0519af2 commit a270a58
Show file tree
Hide file tree
Showing 3 changed files with 170 additions and 0 deletions.
136 changes: 136 additions & 0 deletions src/Miningcore/Blockchain/Progpow/Custom/Telestai/TelestaiJob.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
using System.Globalization;
using System.Text;
using Miningcore.Blockchain.Bitcoin;
using Miningcore.Blockchain.Bitcoin.DaemonResponses;
using Miningcore.Crypto;
using Miningcore.Crypto.Hashing.Progpow;
using Miningcore.Extensions;
using Miningcore.Stratum;
using Miningcore.Time;
using Miningcore.Util;
using NBitcoin;
using NBitcoin.DataEncoders;
using Newtonsoft.Json.Linq;
using NLog;
using Transaction = NBitcoin.Transaction;

namespace Miningcore.Blockchain.Progpow.Custom.Telestai;

public class TelestaiJob : ProgpowJob
{
public override (Share Share, string BlockHex) ProcessShareInternal(ILogger logger,
StratumConnection worker, ulong nonce, string inputHeaderHash, string mixHash)
{
var context = worker.ContextAs<ProgpowWorkerContext>();
var extraNonce1 = context.ExtraNonce1;

// build coinbase
var coinbase = SerializeCoinbase(extraNonce1);
Span<byte> coinbaseHash = stackalloc byte[32];
coinbaseHasher.Digest(coinbase, coinbaseHash);

// hash block-header
var headerBytes = SerializeHeader(coinbaseHash);
Span<byte> headerHash = stackalloc byte[32];
headerHasher.Digest(headerBytes, headerHash);
headerHash.Reverse();

var headerHashHex = headerHash.ToHexString();

if(headerHashHex != inputHeaderHash)
throw new StratumException(StratumError.MinusOne, $"bad header-hash");

if(!progpowHasher.Compute(logger, (int) BlockTemplate.Height, headerHash.ToArray(), nonce, out var mixHashOut, out var resultBytes))
throw new StratumException(StratumError.MinusOne, "bad hash");

if(mixHash != mixHashOut.ToHexString())
throw new StratumException(StratumError.MinusOne, $"bad mix-hash");

resultBytes.ReverseInPlace();
mixHashOut.ReverseInPlace();

var resultValue = new uint256(resultBytes);
var resultValueBig = resultBytes.AsSpan().ToBigInteger();
// calc share-diff
var shareDiff = (double) new BigRational(TelestaiConstants.Diff1, resultValueBig) * shareMultiplier;
var stratumDifficulty = context.Difficulty;
var ratio = shareDiff / stratumDifficulty;

// check if the share meets the much harder block difficulty (block candidate)
var isBlockCandidate = resultValue <= blockTargetValue;

// test if share meets at least workers current difficulty
if(!isBlockCandidate && ratio < 0.99)
{
// check if share matched the previous difficulty from before a vardiff retarget
if(context.VarDiff?.LastUpdate != null && context.PreviousDifficulty.HasValue)
{
ratio = shareDiff / context.PreviousDifficulty.Value;

if(ratio < 0.99)
throw new StratumException(StratumError.LowDifficultyShare, $"low difficulty share ({shareDiff})");

// use previous difficulty
stratumDifficulty = context.PreviousDifficulty.Value;
}

else
throw new StratumException(StratumError.LowDifficultyShare, $"low difficulty share ({shareDiff})");
}

var result = new Share
{
BlockHeight = BlockTemplate.Height,
NetworkDifficulty = Difficulty,
Difficulty = stratumDifficulty / shareMultiplier,
};

if(!isBlockCandidate)
{
return (result, null);
}

result.IsBlockCandidate = true;
result.BlockHash = resultBytes.ReverseInPlace().ToHexString();

var blockBytes = SerializeBlock(headerBytes, coinbase, nonce, mixHashOut);
var blockHex = blockBytes.ToHexString();

return (result, blockHex);
}

#region Founder

protected override Money CreateFounderOutputs(Transaction tx, Money reward)
{
if (coin.HasFounderFee)
{
Founder[] founders;

if(network.Name.ToLower() == "testnet")
{
founders = new[] { new Founder{ Payee = "nVG96MbaKEDFzzj9NzbAuxkDt86KAm2Qj5", Amount = 11700000000 } };
}
else
{
founders = new[] { new Founder{ Payee = "TesBmcgLQsowvYEYPXpSHkkapoTbVV7Xfe", Amount = 11700000000 } };
}

foreach(var Founder in founders)
{
if(!string.IsNullOrEmpty(Founder.Payee))
{
var payeeAddress = BitcoinUtils.AddressToDestination(Founder.Payee, network);
var payeeReward = Founder.Amount;

tx.Outputs.Add(payeeReward, payeeAddress);
reward -= payeeReward;
}
}
}

return reward;
}

#endregion // Founder
}
4 changes: 4 additions & 0 deletions src/Miningcore/Blockchain/Progpow/ProgpowJobManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using Miningcore.Blockchain.Bitcoin.Configuration;
using Miningcore.Blockchain.Bitcoin.DaemonResponses;
using Miningcore.Blockchain.Progpow.Custom.Firo;
using Miningcore.Blockchain.Progpow.Custom.Telestai;
using Miningcore.Configuration;
using Miningcore.Contracts;
using Miningcore.Crypto;
Expand Down Expand Up @@ -51,6 +52,9 @@ private ProgpowJob CreateJob()
{
case "FIRO":
return new FiroJob();

case "TLS":
return new TelestaiJob();
}

return new ProgpowJob();
Expand Down
30 changes: 30 additions & 0 deletions src/Miningcore/coins.json
Original file line number Diff line number Diff line change
Expand Up @@ -2693,6 +2693,36 @@
"explorerTxLink": "https://mewc.cryptoscope.io/tx/?txid={0}",
"explorerAccountLink": "https://mewc.cryptoscope.io/address/?address={0}"
},
"telestai": {
"name": "Telestai",
"symbol": "TLS",
"family": "progpow",
"progpower": "meraki",
"website": "https://www.telestai.io/",
"market": "",
"twitter": "https://x.com/Telestai_io",
"telegram": "",
"discord": "https://discord.gg/VmFXfHnZE5",
"coinbaseHasher": {
"hash": "sha256d"
},
"headerHasher": {
"hash": "sha256d"
},
"blockHasher": {
"hash": "reverse",
"args": [
{
"hash": "sha256d"
}
]
},
"hasFounderFee": true,
"shareMultiplier": 1,
"explorerBlockLink": "https://telestai.cryptoscope.io/block/?blockhash=$hash$",
"explorerTxLink": "https://telestai.cryptoscope.io/tx/?txid={0}",
"explorerAccountLink": "https://telestai.cryptoscope.io/address/?address={0}"
},
"joss": {
"name": "Joss Network",
"symbol": "JOSS",
Expand Down

0 comments on commit a270a58

Please sign in to comment.