Skip to content

Commit 2cb3e25

Browse files
committed
Add Privora [VORA]
1 parent db051ab commit 2cb3e25

File tree

5 files changed

+222
-19
lines changed

5 files changed

+222
-19
lines changed

src/Miningcore/Blockchain/Bitcoin/BitcoinJob.cs

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -753,16 +753,13 @@ protected virtual Money CreateFounderOutputs(Transaction tx, Money reward)
753753

754754
protected virtual Money CreateMinerFundOutputs(Transaction tx, Money reward)
755755
{
756-
var payeeReward = minerFundParameters.MinimumValue;
757-
758756
if (!string.IsNullOrEmpty(minerFundParameters.Addresses?.FirstOrDefault()))
759757
{
760758
var payeeAddress = BitcoinUtils.AddressToDestination(minerFundParameters.Addresses[0], network);
759+
var payeeReward = minerFundParameters.MinimumValue;
761760
tx.Outputs.Add(payeeReward, payeeAddress);
761+
reward -= payeeReward;
762762
}
763-
764-
reward -= payeeReward;
765-
766763
return reward;
767764
}
768765

@@ -775,16 +772,13 @@ protected virtual Money CreateMinerFundOutputs(Transaction tx, Money reward)
775772

776773
protected virtual Money CreateMinerDevFundOutputs(Transaction tx, Money reward)
777774
{
778-
var payeeReward = minerDevFundParameters.MinimumValue;
779-
780775
if (!string.IsNullOrEmpty(minerDevFundParameters.Addresses?.FirstOrDefault()))
781776
{
782777
var payeeAddress = BitcoinUtils.AddressToDestination(minerDevFundParameters.Addresses[0], network);
778+
var payeeReward = minerDevFundParameters.MinimumValue;
783779
tx.Outputs.Add(payeeReward, payeeAddress);
780+
reward -= payeeReward;
784781
}
785-
786-
reward -= payeeReward;
787-
788782
return reward;
789783
}
790784

@@ -915,7 +909,7 @@ public void Init(BlockTemplate blockTemplate, string jobId,
915909
if(coin.HasMasterNodes)
916910
{
917911
masterNodeParameters = BlockTemplate.Extra.SafeExtensionDataAs<MasterNodeBlockTemplateExtra>();
918-
912+
919913
if(coin.HasSmartNodes)
920914
{
921915
if(masterNodeParameters.Extra?.ContainsKey("smartnode") == true)
@@ -1061,4 +1055,4 @@ public virtual (Share Share, string BlockHex) ProcessShare(StratumConnection wor
10611055
}
10621056

10631057
#endregion // API-Surface
1064-
}
1058+
}
Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
using System.Globalization;
2+
using System.Text;
3+
using Miningcore.Blockchain.Bitcoin;
4+
using Miningcore.Blockchain.Bitcoin.DaemonResponses;
5+
using Miningcore.Crypto;
6+
using Miningcore.Crypto.Hashing.Progpow;
7+
using Miningcore.Extensions;
8+
using Miningcore.Stratum;
9+
using Miningcore.Time;
10+
using Miningcore.Util;
11+
using NBitcoin;
12+
using NBitcoin.DataEncoders;
13+
using Newtonsoft.Json.Linq;
14+
using NLog;
15+
using Transaction = NBitcoin.Transaction;
16+
17+
namespace Miningcore.Blockchain.Progpow.Custom.Privora;
18+
19+
public class PrivoraJob : ProgpowJob
20+
{
21+
public override (Share Share, string BlockHex) ProcessShareInternal(ILogger logger, StratumConnection worker, ulong nonce, string inputHeaderHash, string mixHash)
22+
{
23+
var context = worker.ContextAs<ProgpowWorkerContext>();
24+
var extraNonce1 = context.ExtraNonce1;
25+
26+
// build coinbase
27+
var coinbase = SerializeCoinbase(extraNonce1);
28+
Span<byte> coinbaseHash = stackalloc byte[32];
29+
coinbaseHasher.Digest(coinbase, coinbaseHash);
30+
31+
// hash block-header
32+
var headerBytes = SerializeHeader(coinbaseHash);
33+
Span<byte> headerHash = stackalloc byte[32];
34+
headerHasher.Digest(headerBytes, headerHash);
35+
headerHash.Reverse();
36+
37+
var headerHashHex = headerHash.ToHexString();
38+
39+
if(headerHashHex != inputHeaderHash)
40+
throw new StratumException(StratumError.MinusOne, $"bad header-hash");
41+
42+
if(!progpowHasher.Compute(logger, (int) BlockTemplate.Height, headerHash.ToArray(), nonce, out var mixHashOut, out var resultBytes))
43+
throw new StratumException(StratumError.MinusOne, "bad hash");
44+
45+
if(mixHash != mixHashOut.ToHexString())
46+
throw new StratumException(StratumError.MinusOne, $"bad mix-hash");
47+
48+
resultBytes.ReverseInPlace();
49+
mixHashOut.ReverseInPlace();
50+
51+
var resultValue = new uint256(resultBytes);
52+
var resultValueBig = resultBytes.AsSpan().ToBigInteger();
53+
54+
// calc share-diff
55+
var shareDiff = (double) new BigRational(FiroConstants.Diff1, resultValueBig) * shareMultiplier;
56+
var stratumDifficulty = context.Difficulty;
57+
var ratio = shareDiff / stratumDifficulty;
58+
59+
// check if the share meets the much harder block difficulty (block candidate)
60+
var isBlockCandidate = resultValue <= blockTargetValue;
61+
62+
// test if share meets at least workers current difficulty
63+
if(!isBlockCandidate && ratio < 0.99)
64+
{
65+
// check if share matched the previous difficulty from before a vardiff retarget
66+
if(context.VarDiff?.LastUpdate != null && context.PreviousDifficulty.HasValue)
67+
{
68+
ratio = shareDiff / context.PreviousDifficulty.Value;
69+
70+
if(ratio < 0.99)
71+
throw new StratumException(StratumError.LowDifficultyShare, $"low difficulty share ({shareDiff})");
72+
73+
// use previous difficulty
74+
stratumDifficulty = context.PreviousDifficulty.Value;
75+
}
76+
else
77+
{
78+
throw new StratumException(StratumError.LowDifficultyShare, $"low difficulty share ({shareDiff})");
79+
}
80+
}
81+
82+
var result = new Share
83+
{
84+
BlockHeight = BlockTemplate.Height,
85+
NetworkDifficulty = Difficulty,
86+
Difficulty = stratumDifficulty / shareMultiplier,
87+
};
88+
89+
if(!isBlockCandidate)
90+
{
91+
return (result, null);
92+
}
93+
94+
result.IsBlockCandidate = true;
95+
result.BlockHash = resultBytes.ReverseInPlace().ToHexString();
96+
97+
var blockBytes = SerializeBlock(headerBytes, coinbase, nonce, mixHashOut);
98+
var blockHex = blockBytes.ToHexString();
99+
100+
return (result, blockHex);
101+
}
102+
103+
#region Masternodes
104+
105+
protected override Money CreateMasternodeOutputs(Transaction tx, Money reward)
106+
{
107+
if(masterNodeParameters.Masternode != null)
108+
{
109+
Masternode[] masternodes;
110+
111+
// Dash v13 Multi-Master-Nodes
112+
if(masterNodeParameters.Masternode.Type == JTokenType.Array)
113+
masternodes = masterNodeParameters.Masternode.ToObject<Masternode[]>();
114+
else
115+
masternodes = new[] { masterNodeParameters.Masternode.ToObject<Masternode>() };
116+
117+
if(masternodes != null)
118+
{
119+
foreach(var masterNode in masternodes)
120+
{
121+
if(!string.IsNullOrEmpty(masterNode.Payee))
122+
{
123+
var payeeDestination = BitcoinUtils.AddressToDestination(masterNode.Payee, network);
124+
var payeeReward = masterNode.Amount;
125+
126+
tx.Outputs.Add(payeeReward, payeeDestination);
127+
//reward -= payeeReward; // VORA does not deduct payeeReward from coinbasevalue (reward) since it's the amount which goes to miners
128+
}
129+
}
130+
}
131+
}
132+
133+
return reward;
134+
}
135+
136+
#endregion // Masternodes
137+
138+
#region Founder
139+
140+
protected override Money CreateFounderOutputs(Transaction tx, Money reward)
141+
{
142+
if (coin.HasFounderFee)
143+
{
144+
Founder[] founders;
145+
146+
if(network.Name.ToLower() == "testnet")
147+
{
148+
founders = new[] { new Founder{ Payee = "TwnodAoZDovgCPq14Qif3EzeYj7FEF4vqf", Amount = 1000000000 } };
149+
}
150+
else
151+
{
152+
founders = new[] { new Founder{ Payee = "PfadcTvPhr8L9k6jaRbXT1mwgp8U8jXcp1", Amount = 1000000000 } };
153+
}
154+
155+
156+
foreach(var Founder in founders)
157+
{
158+
if(!string.IsNullOrEmpty(Founder.Payee))
159+
{
160+
var payeeAddress = BitcoinUtils.AddressToDestination(Founder.Payee, network);
161+
var payeeReward = Founder.Amount;
162+
tx.Outputs.Add(payeeReward, payeeAddress);
163+
//reward -= payeeReward; // VORA does not deduct payeeReward from coinbasevalue (reward) since it's the amount which goes to miners
164+
}
165+
}
166+
}
167+
168+
return reward;
169+
}
170+
171+
#endregion // Founder
172+
}

src/Miningcore/Blockchain/Progpow/ProgpowJob.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -206,12 +206,12 @@ public virtual void Init(BlockTemplate blockTemplate, string jobId,
206206

207207
this.extraNoncePlaceHolderLength = RavencoinConstants.ExtranoncePlaceHolderLength;
208208
this.shareMultiplier = shareMultiplier;
209-
209+
210210
if(coin.HasMasterNodes)
211211
{
212212
masterNodeParameters = BlockTemplate.Extra.SafeExtensionDataAs<MasterNodeBlockTemplateExtra>();
213213

214-
if(coin.Symbol == "FIRO" || coin.Symbol == "KIIRO" || coin.Symbol == "REALI")
214+
if(coin.Symbol == "FIRO" || coin.Symbol == "KIIRO" || coin.Symbol == "REALI" || coin.Symbol == "VORA")
215215
{
216216
if(masterNodeParameters.Extra?.ContainsKey("znode") == true)
217217
{
@@ -234,7 +234,7 @@ public virtual void Init(BlockTemplate blockTemplate, string jobId,
234234
txVersion += txType << 16;
235235
}
236236
}
237-
237+
238238
if(coin.HasPayee)
239239
payeeParameters = BlockTemplate.Extra.SafeExtensionDataAs<PayeeBlockTemplateExtra>();
240240

@@ -270,7 +270,7 @@ public virtual void Init(BlockTemplate blockTemplate, string jobId,
270270
this.headerHasher = headerHasher;
271271
this.blockHasher = blockHasher;
272272
this.progpowHasher = progpowHasher;
273-
273+
274274
if(!string.IsNullOrEmpty(BlockTemplate.Target))
275275
this.blockTargetValue = new uint256(BlockTemplate.Target);
276276
else
@@ -324,4 +324,4 @@ private string CreateHeaderHash(ProgpowWorkerJob workerJob)
324324

325325

326326
#endregion // API-Surface
327-
}
327+
}

src/Miningcore/Blockchain/Progpow/ProgpowJobManager.cs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using Miningcore.Blockchain.Bitcoin.DaemonResponses;
55
using Miningcore.Blockchain.Progpow.Custom.Firo;
66
using Miningcore.Blockchain.Progpow.Custom.Kiiro;
7+
using Miningcore.Blockchain.Progpow.Custom.Privora;
78
using Miningcore.Blockchain.Progpow.Custom.Realichain;
89
using Miningcore.Blockchain.Progpow.Custom.Telestai;
910
using Miningcore.Configuration;
@@ -63,8 +64,12 @@ private ProgpowJob CreateJob()
6364

6465
case "TLS":
6566
return new TelestaiJob();
67+
68+
case "VORA":
69+
return new PrivoraJob();
70+
6671
}
67-
72+
6873
return new ProgpowJob();
6974
}
7075

@@ -329,4 +334,4 @@ public async ValueTask<Share> SubmitShareAsync(StratumConnection worker, object
329334
}
330335

331336
#endregion // API-Surface
332-
}
337+
}

src/Miningcore/coins.json

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6772,5 +6772,37 @@
67726772
"explorerBlockLink": "https://explorer.lightningcash-reborn.space/block/$height$",
67736773
"explorerTxLink": "https://explorer.lightningcash-reborn.space/tx/{0}",
67746774
"explorerAccountLink": "https://explorer.lightningcash-reborn.space/address/{0}"
6775+
},
6776+
"privora": {
6777+
"name": "Privora",
6778+
"symbol": "VORA",
6779+
"family": "progpow",
6780+
"progpower": "firopow",
6781+
"website": "https://privora.org/",
6782+
"github": "https://github.com/PrivoraCore/Privora",
6783+
"market": "",
6784+
"twitter": "",
6785+
"telegram": "https://t.me/PrivoraTM",
6786+
"discord": "https://discord.gg/4AM5SUVzgs",
6787+
"coinbaseHasher": {
6788+
"hash": "sha256d"
6789+
},
6790+
"headerHasher": {
6791+
"hash": "sha256d"
6792+
},
6793+
"blockHasher": {
6794+
"hash": "reverse",
6795+
"args": [
6796+
{
6797+
"hash": "sha256d"
6798+
}
6799+
]
6800+
},
6801+
"hasFounderFee": true,
6802+
"hasMasterNodes": true,
6803+
"shareMultiplier": 1,
6804+
"explorerBlockLink": "https://explorer.privora.org/block/$hash$",
6805+
"explorerTxLink": "https://explorer.privora.org/tx/{0}",
6806+
"explorerAccountLink": "https://explorer.privora.org/address/{0}"
67756807
}
67766808
}

0 commit comments

Comments
 (0)