From 24f1ffe4595d7638344370a6bd9a9d1fcfcd5e57 Mon Sep 17 00:00:00 2001 From: Ross Nicoll Date: Mon, 28 Dec 2015 21:17:47 +0000 Subject: [PATCH] Clean up network parameters Correct block subsidy calculations for Dogecoin and Litecoin and add test coverage for both networks. Change Litecoin block version check parameters to match Litecoin Core. Add checkpoints for Dogecoin main and test, and Litecoin main network. --- .../java/org/bitcoinj/core/AltcoinBlock.java | 7 +++ .../core/AltcoinNetworkParameters.java | 7 +++ .../params/AbstractDogecoinParams.java | 18 +++++++ .../params/AbstractLitecoinParams.java | 10 +++- .../libdohj/params/LitecoinMainNetParams.java | 17 +++---- .../params/LitecoinTestNet3Params.java | 9 ++-- .../org.dogecoin.production.checkpoints | Bin 0 -> 19509 bytes .../resources/org.dogecoin.test.checkpoints | Bin 0 -> 14805 bytes .../org.litecoin.production.checkpoints | Bin 0 -> 21237 bytes .../params/AbstractDogecoinParamsTest.java | 26 +++++++++- .../params/AbstractLitecoinParamsTest.java | 46 ++++++++++++++++++ .../params/LitecoinTestNet3ParamsTest.java | 42 ++++++++++++++++ 12 files changed, 166 insertions(+), 16 deletions(-) create mode 100644 src/main/resources/org.dogecoin.production.checkpoints create mode 100644 src/main/resources/org.dogecoin.test.checkpoints create mode 100644 src/main/resources/org.litecoin.production.checkpoints create mode 100644 src/test/java/org/libdohj/params/AbstractLitecoinParamsTest.java create mode 100644 src/test/java/org/libdohj/params/LitecoinTestNet3ParamsTest.java diff --git a/src/main/java/org/bitcoinj/core/AltcoinBlock.java b/src/main/java/org/bitcoinj/core/AltcoinBlock.java index 496576d3..62e320cf 100644 --- a/src/main/java/org/bitcoinj/core/AltcoinBlock.java +++ b/src/main/java/org/bitcoinj/core/AltcoinBlock.java @@ -28,6 +28,7 @@ import java.math.BigInteger; import java.security.GeneralSecurityException; import java.util.BitSet; import java.util.List; +import static org.bitcoinj.core.Coin.FIFTY_COINS; import org.libdohj.core.ScryptHash; import static org.libdohj.core.Utils.scryptDigest; @@ -149,6 +150,12 @@ public class AltcoinBlock extends org.bitcoinj.core.Block { return getScryptHash().toString(); } + @Override + public Coin getBlockInflation(int height) { + final AltcoinNetworkParameters altParams = (AltcoinNetworkParameters) params; + return altParams.getBlockSubsidy(height); + } + /** * Get the chain ID (upper 16 bits) from an AuxPoW version number. */ diff --git a/src/main/java/org/libdohj/core/AltcoinNetworkParameters.java b/src/main/java/org/libdohj/core/AltcoinNetworkParameters.java index 384cb0f1..980df013 100644 --- a/src/main/java/org/libdohj/core/AltcoinNetworkParameters.java +++ b/src/main/java/org/libdohj/core/AltcoinNetworkParameters.java @@ -16,6 +16,7 @@ package org.libdohj.core; import org.bitcoinj.core.Block; +import org.bitcoinj.core.Coin; import org.bitcoinj.core.Sha256Hash; /** @@ -31,4 +32,10 @@ public interface AltcoinNetworkParameters { Sha256Hash getBlockDifficultyHash(Block block); public boolean isTestNet(); + + /** + * Get the subsidy (i.e. maximum number of coins that can be generated + * by the coinbase transaction) for a block at the given height. + */ + public Coin getBlockSubsidy(final int height); } diff --git a/src/main/java/org/libdohj/params/AbstractDogecoinParams.java b/src/main/java/org/libdohj/params/AbstractDogecoinParams.java index 4975f620..6127ba6d 100644 --- a/src/main/java/org/libdohj/params/AbstractDogecoinParams.java +++ b/src/main/java/org/libdohj/params/AbstractDogecoinParams.java @@ -94,6 +94,9 @@ public abstract class AbstractDogecoinParams extends NetworkParameters implement public static final int DOGECOIN_PROTOCOL_VERSION_AUXPOW = 70003; public static final int DOGECOIN_PROTOCOL_VERSION_CURRENT = 70004; + private static final Coin BASE_SUBSIDY = COIN.multiply(500000); + private static final Coin STABLE_SUBSIDY = COIN.multiply(10000); + public AbstractDogecoinParams(final int setDiffChangeTarget) { super(); genesisBlock = createGenesis(this); @@ -129,6 +132,21 @@ public abstract class AbstractDogecoinParams extends NetworkParameters implement return genesisBlock; } + @Override + public Coin getBlockSubsidy(final int height) { + if (height < DIGISHIELD_BLOCK_HEIGHT) { + // Up until the Digishield hard fork, subsidy was based on the + // previous block hash. Rather than actually recalculating that, we + // simply use the maximum possible here, and let checkpoints enforce + // that new blocks with different values can't be mined + return BASE_SUBSIDY.shiftRight(height / getSubsidyDecreaseBlockCount()).multiply(2); + } else if (height < 600000) { + return BASE_SUBSIDY.shiftRight(height / getSubsidyDecreaseBlockCount()); + } else { + return STABLE_SUBSIDY; + } + } + /** How many blocks pass between difficulty adjustment periods. After new diff algo. */ public int getNewInterval() { return newInterval; diff --git a/src/main/java/org/libdohj/params/AbstractLitecoinParams.java b/src/main/java/org/libdohj/params/AbstractLitecoinParams.java index 01a3e5c2..bb41f23e 100644 --- a/src/main/java/org/libdohj/params/AbstractLitecoinParams.java +++ b/src/main/java/org/libdohj/params/AbstractLitecoinParams.java @@ -83,10 +83,13 @@ public abstract class AbstractLitecoinParams extends NetworkParameters implement /** The string returned by getId() for the testnet. */ public static final String ID_LITE_TESTNET = "org.litecoin.test"; - protected Logger log = LoggerFactory.getLogger(AbstractLitecoinParams.class); public static final int LITECOIN_PROTOCOL_VERSION_MINIMUM = 70002; public static final int LITECOIN_PROTOCOL_VERSION_CURRENT = 70003; + private static final Coin BASE_SUBSIDY = COIN.multiply(50); + + protected Logger log = LoggerFactory.getLogger(AbstractLitecoinParams.class); + public AbstractLitecoinParams() { super(); interval = LITE_INTERVAL; @@ -98,6 +101,11 @@ public abstract class AbstractLitecoinParams extends NetworkParameters implement bip32HeaderPriv = 0x0488E1F4; //The 4 byte header that serializes in base58 to "xprv" (?) } + @Override + public Coin getBlockSubsidy(final int height) { + return BASE_SUBSIDY.shiftRight(height / getSubsidyDecreaseBlockCount()); + } + /** * Get the hash to use for a block. */ diff --git a/src/main/java/org/libdohj/params/LitecoinMainNetParams.java b/src/main/java/org/libdohj/params/LitecoinMainNetParams.java index 542b8a41..35b05228 100644 --- a/src/main/java/org/libdohj/params/LitecoinMainNetParams.java +++ b/src/main/java/org/libdohj/params/LitecoinMainNetParams.java @@ -29,6 +29,7 @@ import org.bitcoinj.core.NetworkParameters; import org.bitcoinj.core.Transaction; import org.bitcoinj.core.TransactionInput; import org.bitcoinj.core.TransactionOutput; +import org.bitcoinj.params.MainNetParams; import org.bitcoinj.script.Script; import org.bitcoinj.script.ScriptOpCodes; @@ -37,9 +38,9 @@ import org.bitcoinj.script.ScriptOpCodes; * goods and services. */ public class LitecoinMainNetParams extends AbstractLitecoinParams { - public static final int MAINNET_MAJORITY_WINDOW = 1000; - public static final int MAINNET_MAJORITY_REJECT_BLOCK_OUTDATED = 950; - public static final int MAINNET_MAJORITY_ENFORCE_BLOCK_UPGRADE = 750; + public static final int MAINNET_MAJORITY_WINDOW = MainNetParams.MAINNET_MAJORITY_WINDOW; + public static final int MAINNET_MAJORITY_REJECT_BLOCK_OUTDATED = MainNetParams.MAINNET_MAJORITY_REJECT_BLOCK_OUTDATED; + public static final int MAINNET_MAJORITY_ENFORCE_BLOCK_UPGRADE = MainNetParams.MAINNET_MAJORITY_ENFORCE_BLOCK_UPGRADE; public LitecoinMainNetParams() { super(); @@ -55,8 +56,8 @@ public class LitecoinMainNetParams extends AbstractLitecoinParams { dumpedPrivateKeyHeader = 176; this.genesisBlock = createGenesis(this); - spendableCoinbaseDepth = 30; - subsidyDecreaseBlockCount = 100000; + spendableCoinbaseDepth = 100; + subsidyDecreaseBlockCount = 840000; String genesisHash = genesisBlock.getHashAsString(); checkState(genesisHash.equals("12a765e31ffd4059bada1e25190f6e98c99d9714d334efa41a195a7e7e04bfe2")); @@ -73,10 +74,8 @@ public class LitecoinMainNetParams extends AbstractLitecoinParams { "dnsseed.koin-project.com", "dnsseed.weminemnc.com" }; - // Note this is the same as the BIP32 testnet, as BIP44 makes HD wallets - // chain agnostic. Litecoin mainnet has its own headers for legacy reasons. - bip32HeaderPub = 0x043587CF; - bip32HeaderPriv = 0x04358394; + bip32HeaderPub = 0x0488B21E; + bip32HeaderPriv = 0x0488ADE4; } private static AltcoinBlock createGenesis(NetworkParameters params) { diff --git a/src/main/java/org/libdohj/params/LitecoinTestNet3Params.java b/src/main/java/org/libdohj/params/LitecoinTestNet3Params.java index 3de4fa9d..e9b8dc7e 100644 --- a/src/main/java/org/libdohj/params/LitecoinTestNet3Params.java +++ b/src/main/java/org/libdohj/params/LitecoinTestNet3Params.java @@ -38,9 +38,9 @@ import org.bitcoinj.script.ScriptOpCodes; * Litecoin versions. */ public class LitecoinTestNet3Params extends AbstractLitecoinParams { - public static final int TESTNET_MAJORITY_WINDOW = 1000; - public static final int TESTNET_MAJORITY_REJECT_BLOCK_OUTDATED = 750; - public static final int TESTNET_MAJORITY_ENFORCE_BLOCK_UPGRADE = 501; + public static final int TESTNET_MAJORITY_WINDOW = 100; + public static final int TESTNET_MAJORITY_REJECT_BLOCK_OUTDATED = 75; + public static final int TESTNET_MAJORITY_ENFORCE_BLOCK_UPGRADE = 51; public LitecoinTestNet3Params() { super(); @@ -72,8 +72,7 @@ public class LitecoinTestNet3Params extends AbstractLitecoinParams { "testnet-seed.ltc.xurious.com", "dnsseed.wemine-testnet.com" }; - // Note this is the same as the BIP32 testnet, as BIP44 makes HD wallets - // chain agnostic. Litecoin mainnet has its own headers for legacy reasons. + bip32HeaderPub = 0x043587CF; bip32HeaderPriv = 0x04358394; } diff --git a/src/main/resources/org.dogecoin.production.checkpoints b/src/main/resources/org.dogecoin.production.checkpoints new file mode 100644 index 0000000000000000000000000000000000000000..19a3fee977744d9e89cb6c659881520a12a07118 GIT binary patch literal 19509 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/org.dogecoin.test.checkpoints b/src/main/resources/org.dogecoin.test.checkpoints new file mode 100644 index 0000000000000000000000000000000000000000..45fbc6d22d439bc23a8869264065c3436f2158e1 GIT binary patch literal 14805 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 >>l|I8( z_atwdJH$dQg5aUgoBFS>Dz4hugEe;9834VdjlIS!Fs(Yn9Gb??XfUMa|f4bDMLndFBr3aY{5M2Lw z?>spstx_y=7=nA)KenPrL?$ec(@TYg1G|MWrP!^2t$k$EK)jqd>gOBiEpoL?_lLp( z)YE(IGdC#VxP$zkKwq`ul!v}%+#uM`Z(`?>wafw#wgp}$j6p!r_!G>bA$sSYTJ?7i(UzmZg%QSfFb26I{SW_Pxa4tLNK-KmDF zNfkfzl|264foV5NElvp10TA>-|C%r#8uj$ZB~!af^Unu!XSsz2EV=9UqX|dabCX{A z?kUD_r#A6iY5X<`!XLeT7+p`$9leFu->Z(w1^#jUt1j|APR)M!6$}vR__zIB(=TJ( zeGLT=>_PvPJYKapJe?LHtBT!=a3R!ySK~~cSUNIFUDi?Oe*0R^4wC}MXR%qWjAGRs zRC)Yb$T%)0ST3csQBtXwKdu{?h|<(v2RXt3xft|E9|(M(BvQ2cZvepyT>q%Nzcjoy zsnSPi^*>8^C39F$KAl)ul$d%k#QR4owYHtZQm$jel-Mb8be_vJz$X1Desfbo^hL@X zM{r%8{}O(^TAo@V!b2bVq7Ljc=G1JG?cynZnai#+bs&onRmg4J zf~retc8%L^40kWJA8)(sTL1aJmMdv!Q5Fk-!_C%vX=hO}Ip9Nv>2%EvmTtM)F{2#} zV4DNCZx9uW>}MGsNB}|x=Gz&`0(1OXD_ZB;XE{3R{b!q|y)-XUfKM$PW1I^PifPxS} zCQx#? zR*wpmIO~4gct)u~?AI2$&fTVFzGDCbXl=mbD@dN#jaEnmLB6Lmm^_W{mUluqS8>QTs^*EI_VD>` zra$(fkX2yXs8ta_m;?Q%>jrpLy!nuaau_ts?!K5$*GMe68yl2ZEQygvIc*ax-qK@f zY7LwtnX@jfE!ap?rdI|uxi)67EmL)0!k%Y*SpTkOjx7hPfzuoY`~2;?@TUdy0KyLN zxP6v5w5X*BG@BneB>ufmK~2Nu6$vSM>X%SL-MszGa=pU2=S6pBd9AM~$8-Of23;TC zq~h++w57q+PoDh}Qm!Ip!CXhJ7 z3VU(qD81hG8*TM7W)t&6&BBrIvR3c5mJJk|+=d#rX=znh6s>Ay9I5>pcn*WWCvk)Q z)v2Cu4LZmGB7yj$PYma#J=%o=AsV{58C|e-jpfTm@fJ5mq-N>7@cqp%3)Ci~6s3lO z&nF~vH)6>LjRIWuW5lmz0wEI9mp^e__D@B0cDT zdK;W(X@S_T=uBe-A?9M6G5OYm5h1SO1}jg@L&o&D`q=h4;)FT)nb!{NL_> zR}pSkeJ)$(kb2?~U>6gc_ZlvQn`I|lrqb&BxQM4D%ZF5_`UCo=s2FE4{^N{{@s$)+ z4E2qk=P=-qJ^<_oyc?+`EOG-7WkG)oQORKo?41Jl*_rLbXpE>65?+HLwp8Ryp6`7~ z@7DU)zK8X#yNd(&k)n7Qby9p7^?pMXPdq}$(o?fH(PXqtCGpi8E+k>V#T0mc0oNAP zX59bH13=UU{h#8LmF~{;=_Zn(OPZL_Gep1+Yos*uLo-4kl!+g_7uHFxOSf3RIg;L z68|23;mV{IiBX+?SOx}3T}68A!wY=*I{60^4M2PY`fo2cD;F2=Nnn)i!r_*#nS*{80har?dY$vk|uG}qAfNQF86WBMO3p2Z-VNCK7ud^KspchKUMy&usLT3 z5K}<^3pZcmqgc_zC$;InG7cImyZm08J?Yxd>9_2!T21h#fx{$bXE@L~&{+(%SdQ3< z4HjEa-$FTxjINN$XmS%jie8ga$3x(U!G&HKgZ+D}zo=P7sQ_Xz=uZ;qZ$IU_jDAMh zVBwd~%!>rQT+_Np{Eqw1{E8W0)tIXc5B_pXoxWm>q`fNjGGBfVo^7|}eK!+qjFTwi zDdlvEk~&Yn2n;BuDSzxEh-0Gj@tTbRhz+2BI2CqDiOE}JJPvC0Tpu%RwqrY+v@b3 z_p8^FMB0^@TwfuF2H0Z6AVpEtAJQe~$4+R$7slCp` zm)BRy@Hbd0dg|k1(RS*YiV`qDMNjatj|iw0q-ehJ2M{+ve;G_&>4=He`&<>RZwte- zzwWHwozDgIS3O_KFf^ou=SaNIc3}RAAX3zILsMT-<;Lc;_}XoPm-5Z{q&n2tZ7K(S|pt7fNMQgKL3(BI)(k5`L$y?3DD# z8!tgbJ47;s$tVizu8pIk#Jc?tss8$*>N^MAFrbgp2<*=XvY@5pDg#J3pns0yjh14) zhE}DfMv`OhP3E2*my^ci?9Z|AzjqSh6Y@$>xbpH6DoQ;@e$=YXUN}i+*dBswi(uvm zKi7=VD~sZzSao2D1qK{M2|xCcxLCe9Hl;`cNYtP|6~zLxx1e3-XPYndb34*1{_W=R zA+Ra`DCbXhRcEZ4m4ctgab?MkWL~{h+O)luy+SzYQ(=5KveWY%;$vU7$oiS0o`}i> zgM5J&g8eiT$gnQYG=Rhj`rEwj?(JmR?oCVknQ)&?_O_A%8F9{O`)h`E6q_ph=v@*D zWjhjo#BZL)uN&Ju&UKBV{8F8TIibEpPa;$8fsHTF9QAB{N*Ewf4xYat6XNmIOz$uP zNRptxT$a`?kDcjsPpHFJxo{2oUBck(f$wXH!HQ32zCGNJHMcY3C=$?aA7K)9sIBLj zy&b@ay1L23qKV(TrE@ThVAw2H|DpD9?F1{t<8glEerN&wqQwn>qz?L1u2L0_rxYwZ z(Kj%Q42#&E8d#_iBcJ8fNZIvg6ivlzKe5djU>`lsB0{}nAjf@;6@tu=`<2gTww#7g zgQ6ZIBDhLDlLZe3B$tEFSD-{>aN^k;^#Vxdp#Rq>`oH_T1YMgzC{OkJ{@_EgyDr=z-$4YoP^U`JO)z#Y9AyYg$NdyG`{3T#cx;Hsrp(4C zp70QAIYZUTw=)c}Js}gE3_pg{`8;r7ke4&y^;NX_&m~DI`hm@d zQGn^u9x@nmt~GjTWO8vu$(8G1V1Q>!qd#Ni^}7wP#MiatXcHsnwRYdo$X`XS!bF5p z^1YM$H&f~cvrk|EeL?P{5BgWDLZ5rlEC4AV^e04u@u{7s5KhS+$KE(+dej^AN2T{E zuy)u?jAwnIP%y=?)Pbe%VZ6wTB{svjKdSYhT_foY5%%D*IZ8`n5pqggREJqUfk9rc zG(Pq*ic1#-T5QSzq#DpaSf{(z6Fp4PUyZ5c5P2!?{!=P|X%0k>Q$8vv;b z^jE~@W4)Xs*IyZFS`BCmJmt%Ys@Ssj+bdK zq!?C4p@yfUnLmR&hnQFn)tiM0U;tABxc$T;@;I?ooPU^q0`zxeo@MOeS>pCBv;B=I z+Nk^ecq`WPt%?@w+2Ak8M(1gsP)tGai))udduwx%$eQEhNpTdk_K0i4#%!fs(=PLw zgTLw$K@ZtvP6admH=wIX^Q;~>l)`wm5@~8h*LUsu%&Z0E2>)ZH) zUEzSj6vVK0I|DVoE?13uB1bBZEPjbRp2MQckQwWUa4gi&^WlkYI^P_6gl(UT z9(>X`{+@|3mNCBrTBCyi1k-9F(w>wh4HAW>k=Kd?1FY7>ANxpS_n?17 zYd!nR1>&Putpmr*3BgZYM@-)`;L~I=(1-Dd$NF-Ud`3GaotGEy{3hILXY^HRBX3}< zT=wJAYMIfz45hcOyEU$c2LkqkzZSUuu^CQ=5fXGZ0c0%Dzgo3~NuEx@i7+@%e#b}k z$QP&i5|JV0DI6o(awcbv?d~iM@vJB^`d)kHu@8g8pXouagt5IM`IJ-B?48$$(=LG| z8i?O9U;qX>cz%kb@Uuv+CP)}SCI|g3!i2^cU+UPP?7<7tF?oF+&q@63QrmHpE=$DI zf~gTX&S1@NHvays*xu;!%vY2>qyT~v_LCqavNl4~!u|+NLYG!!wif;2{85na(FZq+ zuD}(;S`0vD1^uxVJF|Y>c?ndE3}evHC!A`cNC@rhG5#U8;9d-U;T<0IqLhOAPXpPn z-`R5|r|=PTu4W$bdZ%JM{l+xupY?hPP*^n(h0tI?tlYyh&kwhc&K#Q1{N#=SWKq!n zUZL{ErE`@GJyae=n*zJN>bY{1%$&eU5~_I;TK$&<5B+EBYkGcY+(svp@mOyyS)p}j zAKr~hRh$AZ5!tThMQr&rL}DKLXadh4`vjUZ^cQ`4e*k1<(EqHuVRrq^ZR&@T;pcLU z9ve~oUwzkJ?tC|*Vf$7|_T=Rj(JC_28?V~>I6v%Ff92NYs{sJn5A=VX z`O-09>xlw~+~N4nfwZf`9robg=L9M6Vb?(uDT3!e+LjFKgu>qT_@%z0$>jFG6?;~o z!EMmgwssHny~7PtqcGGU`;H0&jIVJX`=n63o@izTbpSaI^tb7JS71@fa{togiVuH4 z*yU$tKh>QP3*s$~u7B%A=#pff^peclG3#$6yivg}gTl~GBo{gIsd)eISxncNB06{B zmKuBq$S?qg_TsTm)`?=$d(oK)AZLUAGl5Zrn%w?duV0E`Qkx7OK}$jwjQ`|fG5)=K zsokus^xhic2_d9~@7)Pav-!oJ8l_V7-sSV!-@ALcUz<}tn(V}m8e`cgFt7amt;arv zGa?f^DXbYl{s8(xcQ`V z%vx&sjz!(y{G@iyof+`Msh|CbsXMM{8kVioOrwFZ`8DEi9#g~HjNWJqz z=c@t=^slSz=vpzmj(+gQtZHBIS-gQgH#oM5m_W&E=;i)JO{}+>NFOqewTOjt`y)3} zyCx^tYm2BYPunx(5}X!o*X+&kyz^G*L%~s54UE+dHQZb?PdpMU6;9!wxfX z2N$B~L`5PS@1sXJ`AjZ+MXIKr{PuOu)Ocrr2uoHd(R}PPxmfF!N2a3z$k(8M3OX^x zrixO9qJ1^?mVe|+ou=Zia(mygB)7y6`-KP5-m!98UU+}}CK7FnA9eoz-sL1p#x0=z z!|rc&23th|;pK}04GISY*k|CH=&{dgy+X6|5=#z1K?D7Z!|2%>Xm=Ri$BH}?ig8L4 z=@O+a%U7S?nEZ5|A)?S@g|lN)aIaZ*_Vt^XeKwAjY`Mcirm*$87lHytTX=5Ilc`FL zkXv}z_*+uj$390((^F4(r+okg2KpzWtl2haOf*Mp?S0Y3U}DSuHbrA9rkec@!HAE# zq~T@M=qly3#b)8$MZ*EMEB5Z^ohrXqN&G8R{^ZYD$wdvYUpHuQ>A}OKpa`aqeV*{Q z;paPJeE`Zc(0^iNYVEV>yYzwrL_rxk@~PrE&W|tCc~Eu6D&Eq=;(*UjFi+yOG8jok zjcx`R_e|EvJG=Q`D)Cz8&e%77K>cO-pRY;8hfy1;9U3^Np;cP`P_oeuZCE=FJS-T~ z$i;_)C3;z%J^Dyz`7YyU&o2Tf509`u{Qc{%L=>-4l&J6%ev19|8MnF#Bi!oTKhRCD z3Z#bc;-C55)UxEwEta$DL=Ru+Kco)h2!ub$iTl%&W0~ppjLfqoW;G0Jp|EKY7plj; zd}JIWZdlV4fMN&wkX=rSg4icvQ*o? zb})O-+I4yH@W9Ug4URs)`Ep?BUI%k+=bgu@#%dMx;okBS(Z{}OEqQ&K1|~Cr;syGn zbS+oQrLv54&zk1{5?_O&*lpV-^D4hKEX@!q^_b)QHlusdrKo=~Nf?Ms&vem>w$3^v z8A~7WV~?K_b56j-iEvkANe2pR_c(my0Ce7lbxSVLBm*c>p#Ne$GY3L}l*``gC-T3` zxUqy{7R3o4_nf>ZRD;cGztE|YaB&;$ySJ?mx?Hg+tuECY_07BX>ZUf0lPDOjPGrAS zJ=S2+g2KFGoWZ`aCOMDK_wyA1B?I)oFMavtB^q@GCqu2q#wxPdr8GsRKJzJN3qeVJ zuP#mLn(d5iY@pyf$(=^>x@AraF{To&x^ZTi(|i;!03hy~GlDeqlu( zOG_I$l?R}df&QjDcRg-RqiqYCrjd#Z`uTIeHhXy3J~S=`h6i)j>Xvu=re(vf#FZ`W zLKSe)1)L|_zOv(#k96}Bm`VVG1uNvI@R}1Zp|EPvC2)R+CXBXw42K2)r3Lhl6j_I` zj|iQidRo0xGB)KQRu=j&3d|vR!;A`$* zLtwd3QN+i-w;N;-m$l?!{yETJh+lB_z%%&Ob3+ovX$!jJE<*{F*Xc@8Pk1Jb&YXuY zr%WYyeBwth3z7!6p#9%#y`%T<_D57MibSI*J&|!GlDEh;pP)iv=LfZLkNsf(j&TAn zOML)k8}xs89%-p9?=Nbvu$HLhTvzpPTP|b~aoGy&$+vUIBzK7G8#G^%CQLNBtIfae zu}q`ScqPPD!ORUlyi{bnpw2LR;)^oLvdzN3Aq zWRk%?H>p4(B*Zo;EhnFRlCm2a=Tp3P+ST*7s3E0jJDv=YSC-xR<~5t5T08U1gtX*o z)m~#lLk(jKho(Y51hxXLAb9L2_Y(n?l0)tQDiY|=`9#(3xJ26Kn^!gy*3F+Wv{Al? zUjxP@`IdgUj=WGGpb~)oXI=%nEQ`cv1)RX!9A?4o4_eK~#YE5ay(@9tdon3d zKMvb>N=kk*NT)P&xAN$1`0?Y6s z(QyDO9q50UOQGj$=*x*uKv`FA%W}p;dn+xTEIHSkIdAV6W6}ad-Y(i#rYqWfYIuVf zayE6V=rLwDxEhEsh3aW$RMp0+rKGvr4uPFXZh^<2RXGhx?}s`R090Pkf2bY4wbyx% zL~K5l^F(A$c(jdW8DXA+luH%iVP68#nK12GQ+|5u+bx6GK+#~fwo}MSuEn%hZrRTK{hN4TK4QqNUgYz2sU8*rx)G&`iKf^)2<+o8 z?4OT5J;%~8H;iEC{lxP^EqT9%B0%GLK%6D}v2PCDk* z+J!3We1T^QKGgfK+u`&*m!Qs?y{Zscu=tn!$Ns!QgwsSpkq&_R2K3+7VY~`fde)np zclM(oUq@t8E-!c%NpIXmH`79Xi)d@>yCKG!5S-f`v` z=Tl4WX8CFvJf?U3^51c+(b|WVO*(Rt&QtbjC0WlU6U~gMc z_8#Xy9_&ZqF!VbIP*XtvnX-NgsH<7N&HAg9=P4@-r2~Tj*%ys#eBs!1xEPRgZeR3< z0MoylBMC_d=$Q;svZSk<%+G^7mz0*x6TzdwA?Tagad&olo6P($;&aig? zY7yvns9<3li*7@tqmm68Fd4WNIgzMQ>m!bGnk z_JaONw#AsB8WnBax&dm1{GaC=fgON(H7PFxd|7)S>vf$;&B`QONNec|akUGlEQy@8 z`_~Orw;at-5(rF-$MF4QpLkMFWUAC57C`L-{nd=N6B!S%=mw1^N6^n z9=AUbdImEJIq_s=Sz*H~v?x=9CEpX1g-^<+0BxJ(>kzaH9gK z>!5$)3n#;moM;fKy;%Kcw@Eux<3lm_PevCiFVbUkQ7Ofg|CG8N%R+!R0RLp7;5$Y8r*BSBF%+y*MIQumS!;#G1RF} zG&}OS>C;4rfAHz9efU2C0EjHbrg*X6I4^((2l}%FeUh8`i!)q}7ZT+?tF#>Y^cjiq z#+wN1{NA|(UXxWVh7Vl?Puy;769}ka?v;Q1(oE*-U33E$su)e_EjwsE(o4cya3Q}K>txIv^!a$`+<^7Ma>=ye4&?1FHh7$mp_Nb3XJrr zmT)@jM63YgW@Z5dzB#mX&$z>uV&399bG9 z187vB{}*K!BKN-(F@_@>%2&TOWlB#F1t9v>TSXc3D>W;nu(<4P?Guc)FNjB8fl^fK zw&Zit$ssvnh^;Ct&J@KTYP=g(H6aiErhU7|?LWj)`baJ#bifWk;{^Tdg9PG$+l1nR zgl#r8uJ7Mc|9t*&fDwEpqdS|3SBfp0d-FzDsi`{Fl-cJ);8w*-ZBH}%+WIzD>4vB$ zk5-N0h=nbGrg8pnBRxy>_^9?&4R~$-Ff)G18<2VKH z%@jq?bo2D8!j|;yoN@!hmiNecA0p;X8ILG$3cRJ+<-~rI7kF9bGTFb?JJAf!gTUTZ z39mo)J&HcMF<=?!185JwLiO;*DBg44**EHQ6zQ)=!ajMM9I9b&VM$|0D(Z7|A%>E% zq%=fq?9|RA^w46*X0fCOc$B!W_frjxb(aLXb{IVMY45(#G_QfcJQ*!Z9{WM6#>(+> zLjeGq8R-9BOeG^rG@y?CP+gyrAys$ zDf6lWls~F4V2bj8aCpZVoU;jT6LytC%zwCdEjU;Ea@|pSjMz5C08NukcVdKE<0%l> zOUR4L$A0$5;f#iBx=sKs3H1NeyZ&>7?dT0Kq(y*4{(l{ui9b}|8^`aR$TlNcO2!hA z60+~I6|zR%v1Aa+J|rzfgpw^HLiT;%cd|4g+4+@ikhLrsrZ0{CH+TMl_v^gg=iGD8 z`8@ZzQrA~@V_1rMZ!)k{JC25h%7uAaI*n!+4)-(%GD|cylwrmiDkJr+>YW*X+__nP-SPs%9-m@=sTXPF+71FOAiEWT!Fr6{t?NgRO*PUrP; z|0cNOw$)ccy0i!^dH$@AvlZs1s|<)(#2^cbIdjCPyF{ovbR${_Q6U1^#DQp3^lk;r zul$PI78_T)4=`0w{cl}1kMm8bzC25qLR5;dYexyN`PM75n~nDrM&@Q@PrR#lFSoUw zYO+3T(hX$(=mL;h|Hu_q_ZIDkNUj7{u-|5ofuhqu^vvj{70hogPsj8e)K2w} z5#nLEJ|s1Jpzt}_eFZV$)UYK@4!gY0lUSO@`I@z!tI~3z2}Q=0b&E0AF*j{=HB0Jm zin=|^^uTJ!5y{@Z+N#hxg-@z4f$P^`r{DBE($V%Wz%)el56O#nkP*8pzfvoDFtX43 zs%TZ8)#)VgBq4sw43%Po-M&wh;GIU-b_yO81U#6|_rysV=wI?;4YZl&_8a5m-b&Dh zwDLgoxRoHBUx5Sbdd$v094Y{&S*m}=huJ-fY5Y*$KB^2)68{{VK7#!4KC%8(DC@On z*>>KC2k}M$4nejf-~`8yR|ts_G_2^j*2xp%NR+_iEe@#(Q zR=DIkZknV}Qf0d9q22d{wYSu%ZztQQawNmX&EYFZxZfO)jge%g(JRC~p!;CazBps6 zSAQ)dBi@7v<{@!kS7qzU$>OQ>^l-Ca_ z;%06;Uewea`Q&H)&bC8Z#;nX*GtH;3weFZxwIn-Loxf1py~-PEqU@g>Ird{P|0tdK zaQSt36Mz&Cgb$3n;k(y`q5|deQym$09gQK?vpce<1mb)IyxN9Y2iI=Z*Wjgv$E0x`%0|l^@@TH=3%`I?Yd|zXMx8>Vbd7gUup4MI=L5)V>M;Mc zZ=zaU)ZKABjscS}_tgHRG|8!Wt$yQWvuiWS0crj5TkvW~^RJgTg1hK+rII`N3_o1J znyFSa6qJf)M`Rh#sD(lx#sA0my^Apav?11_i$jc3h%}=5Pb>B_$mZ2Z=#W_O`)fzv zDzHcf#TW7U&{eCuw&@qlYHQo%=L%g!r%qmWbdhQzo!>99>-xo>7jH+d_nA37+EIyt zoMJ&V_CI_K%ty<z6Oxkc6j`+rnc;Dt5)iv>&H%v;g;RV;mlh#U*>=-W56s{ z+U1azCx$a{g(#}AobTyXxMWCHO}o=z#9cO>qbaRUE28gzCkYC81)_Z?#av;&5Xn38 z>Isuh0O?Nkzin0Y{g6lTc>Clh!?7th$?k}y(>bl=K?h0Swf)&XI}FWHp5YcCbhhw& z0hi>>=;4D|O-<4SF4`+nRFeKNqTpT@#7nuqNZUBPhxrn#|Ms|id$s_iKh^)<{P$Rk zQ{_8tswMnte_f0$7bGd2mH?Nc4%XE;aHulzbq@+T&UO`2csSD1;k1pN$_W43rze;H zhc|cc2Id`mOEJV40HPU-`QiK@q3nNd?)GYh5`c^XU_WN@;U^ZyM_R(3lKZuHWCnZ` zeys~LG)`&@hdu0g^@vxfbx-DJP*KiD!Cp>d<`Ub6xx>NnjMW6w`#_&wV*w$jy9T=D z38HBkott33c4)+8%*;+IfJ~wKA9NHoawPr`_AEMMt8(@v;Mf)>`7~c-oWWmw=kxS8 zx%he2N#R_9+dIj@y)1J2%=c2CJgtu7Y~kN<%55WfX;}XG1SL6x=%R0vaDIp|`4Q@r z+fEb)kR??ADF@P;-xRI$Au)OZ!$$kG4{lt1*x(oVz0*r3&-BIy2O>y19d%;%&nF^T zQiF~Nnj^cnKdWlsOk(P;3H-;Ge#qYqr8`piw7jqmgw=l}(DrGd0)T9x`Zr9OtTow6 zGNEy>v8D;AJacdDg%vHn2Pl_o5;GpD^wypQ-kPre%f9Q?|2HbMjX2G*e@^cCYS8E4 zhpm~1-P}JThai5+{06?{(SrGo1EFlIyt)+tvXAOtkvD*^nAY2J_P~m3ZmDc1@2$I% z&CIWn$-1i4TAiZ^%e?Md3mk2V9BT1O(k5q+`9HVWI=Zj>_nx}ym$VtQMKw=AdtM;A zaMJ~@k087>S6UvC@;(8`DXRZH6ZznrTsK22^>obzBE}rNFUBRi&Du#uKf;U62Y;-# z{a^Bsxaxm1fHssau%SXVi2ub>cj=}{ebrbSM%8^ z0J%o>Kbl6yQ$7}y>8tlu&xmEMiFN-yAElBt&!g;N?QZ7y_#A1}RCh4;*SrX7PnHmU zS359=sOKKtQ})CA60}Slo%C6UvO_`iPTFtk{JzfeebL^6tOk(#RR0$Yf=8@8r-qdi zw#`(0g`e%8z|-T>lP=k0Al}ert2{iw`gB;oei1%hDG+8FPw(n7oj-g*jD>-)P!1&W z_Zcj|+=d(|{_VhUJ9zx>O7CC6v2kz%C?=|Z-F7Lt2C1;ksOQ68^zMyAIm&aq4DNdF zF`a1{-T%(Nb2Fi#5%%u)pXRvyVB(}ka1DPUbSam{tR}r~YNlqT{2lHH+Qw4uk9%Hl zeuzkA!E`#A61M;p7uA1?-yH6r8V4V_{nN2N_C_*$)7aE23pD+!;b~f{f(WfsgGYYKlvI0@$0h!>2U4R47CP)bz)4kfV)U&9(6F!`IZ z%G~_PQLy=OjL!My&kNjRaf>gPM!`frd98@IaUpzrrnq=fXx}TqL#!~C`-@8bZDTRH$rkLo|5-c-x;+&7Hevum_^MV=(bvP#K6<49e3 zsli1FjprxvT^>R|EX*>L=)!ac7>oLwMV`ljO$TdTM=a>^a0E`$;{xWdJ&11b%O8OG zyWqoLA)7|uHScs+esJR) zxyvC}HS-t3#yH*8pj5GUx!|n8=5E8sES20RqL|`4Ao`kaGF%@=j5%w9jH0W2vLu-$(nQL(b$K#BpSZd`qPB9yz#)2e({Us_=w7v}Z~Lq76CT=h z5mx}*3*SBV?Gx(N&F$)qvKRt}ay}{0hx?Zi3rhDQm)^Vm15iFx|1Tp9&y? literal 0 HcmV?d00001 diff --git a/src/test/java/org/libdohj/params/AbstractDogecoinParamsTest.java b/src/test/java/org/libdohj/params/AbstractDogecoinParamsTest.java index eb14143b..444e259c 100644 --- a/src/test/java/org/libdohj/params/AbstractDogecoinParamsTest.java +++ b/src/test/java/org/libdohj/params/AbstractDogecoinParamsTest.java @@ -17,6 +17,7 @@ package org.libdohj.params; import java.io.IOException; import org.bitcoinj.core.AltcoinBlock; +import org.bitcoinj.core.Coin; import org.bitcoinj.core.Context; import org.bitcoinj.core.Sha256Hash; import org.bitcoinj.core.Util; @@ -27,7 +28,7 @@ import org.libdohj.core.AltcoinSerializer; /** * - * @author jrn + * @author Ross Nicoll */ public class AbstractDogecoinParamsTest { private static final AbstractDogecoinParams params = DogecoinMainNetParams.get(); @@ -136,6 +137,29 @@ public class AbstractDogecoinParamsTest { assertEquals(block720.getDifficultyTarget(), params.calculateNewDifficultyTargetInner(719, block719, block720, block479)); } + /** + * Confirm subsidy rules follow Dogecoin pattern. + */ + @Test + public void shouldCalculateSubsidy() { + assertEquals(Coin.COIN.multiply(1000000), params.getBlockSubsidy(0)); + assertEquals(Coin.COIN.multiply(1000000), params.getBlockSubsidy(99999)); + assertEquals(Coin.COIN.multiply(500000), params.getBlockSubsidy(100000)); + assertEquals(Coin.COIN.multiply(500000), params.getBlockSubsidy(144999)); + assertEquals(Coin.COIN.multiply(250000), params.getBlockSubsidy(145000)); + assertEquals(Coin.COIN.multiply(250000), params.getBlockSubsidy(199999)); + assertEquals(Coin.COIN.multiply(125000), params.getBlockSubsidy(200000)); + assertEquals(Coin.COIN.multiply(125000), params.getBlockSubsidy(299999)); + assertEquals(Coin.COIN.multiply(62500), params.getBlockSubsidy(300000)); + assertEquals(Coin.COIN.multiply(62500), params.getBlockSubsidy(399999)); + assertEquals(Coin.COIN.multiply(31250), params.getBlockSubsidy(400000)); + assertEquals(Coin.COIN.multiply(31250), params.getBlockSubsidy(499999)); + assertEquals(Coin.COIN.multiply(15625), params.getBlockSubsidy(500000)); + assertEquals(Coin.COIN.multiply(15625), params.getBlockSubsidy(599999)); + assertEquals(Coin.COIN.multiply(10000), params.getBlockSubsidy(600000)); + assertEquals(Coin.COIN.multiply(10000), params.getBlockSubsidy(699999)); + } + @Test public void targetSpacingShouldBe60() { // The getTargetSpacing() method only really exists for future expansion, diff --git a/src/test/java/org/libdohj/params/AbstractLitecoinParamsTest.java b/src/test/java/org/libdohj/params/AbstractLitecoinParamsTest.java new file mode 100644 index 00000000..3f71928b --- /dev/null +++ b/src/test/java/org/libdohj/params/AbstractLitecoinParamsTest.java @@ -0,0 +1,46 @@ +/* + * Copyright 2015 J. Ross Nicoll + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.libdohj.params; + +import org.bitcoinj.core.Coin; +import org.bitcoinj.core.Context; +import static org.junit.Assert.assertEquals; +import org.junit.Before; +import org.junit.Test; + +/** + * + * @author Ross Nicoll + */ +public class AbstractLitecoinParamsTest { + private static final AbstractLitecoinParams params = LitecoinMainNetParams.get(); + + @Before + public void setUp() throws Exception { + Context context = new Context(params); + } + + /** + * Confirm subsidy rules follow Litecoin pattern. + */ + @Test + public void shouldCalculateSubsidy() { + assertEquals(Coin.COIN.multiply(50), params.getBlockSubsidy(0)); + assertEquals(Coin.COIN.multiply(50), params.getBlockSubsidy(839999)); + assertEquals(Coin.COIN.multiply(25), params.getBlockSubsidy(840000)); + assertEquals(Coin.COIN.multiply(25), params.getBlockSubsidy(1679999)); + } +} diff --git a/src/test/java/org/libdohj/params/LitecoinTestNet3ParamsTest.java b/src/test/java/org/libdohj/params/LitecoinTestNet3ParamsTest.java new file mode 100644 index 00000000..fefc877f --- /dev/null +++ b/src/test/java/org/libdohj/params/LitecoinTestNet3ParamsTest.java @@ -0,0 +1,42 @@ +/* + * Copyright 2015 J. Ross Nicoll + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.libdohj.params; + +import org.bitcoinj.core.Context; +import static org.junit.Assert.assertEquals; +import org.junit.Before; +import org.junit.Test; + +/** + * + * @author Ross Nicoll + */ +public class LitecoinTestNet3ParamsTest { + private static final LitecoinTestNet3Params params = LitecoinTestNet3Params.get(); + + @Before + public void setUp() throws Exception { + Context context = new Context(params); + } + + // Confirm subsidy rules follow Dogecoin pattern + @Test + public void shouldHaveCorrectValues() { + assertEquals(100, params.getMajorityWindow()); + assertEquals(51, params.getMajorityEnforceBlockUpgrade()); + assertEquals(75, params.getMajorityRejectBlockOutdated()); + } +}