public void TestVerifyTransactionHoursSpending() { FullCases2(); for (int i = 0; i < cases.Length; i++) { var tc = cases[i]; var uxIn = new coin_UxOutArray(); var uxOut = new coin_UxOutArray(); uxIn.allocate(tc.inUxs.Length); uxOut.allocate(tc.outUxs.Length); for (int j = 0; j < tc.inUxs.Length; j++) { var ch = tc.inUxs[j]; var puxIn = new coin__UxOut(); puxIn.Body.Coins = ch.coins; puxIn.Body.Hours = ch.hours; uxIn.setAt(j, puxIn); } for (int j = 0; j < tc.outUxs.Length; j++) { var ch = tc.outUxs[j]; var puxOut = new coin__UxOut(); puxOut.Body.Coins = ch.coins; puxOut.Body.Hours = ch.hours; uxOut.setAt(j, puxOut); } Assert.AreEqual(tc.inUxs.Length, uxIn.count); Assert.AreEqual(tc.outUxs.Length, uxOut.count); var err = SKY_coin_VerifyTransactionHoursSpending(tc.headTime, uxIn, uxOut); Assert.AreEqual(err, tc.err); } }
public void TestUxArraySwap() { var uxa = new coin_UxOutArray(); uxa.allocate(2); var uxx = new coin__UxOut(); var uxy = new coin__UxOut(); makeUxOut(uxx); makeUxOut(uxy); uxa.setAt(0, uxx); uxa.setAt(1, uxy); var err = SKY_coin_UxArray_Swap(uxa, 0, 1); Assert.AreEqual(err, SKY_OK); Assert.AreEqual(uxa.getAt(0).isEqual(uxy), 0); Assert.AreEqual(uxa.getAt(1).isEqual(uxx), 0); err = SKY_coin_UxArray_Swap(uxa, 0, 1); Assert.AreEqual(err, SKY_OK); Assert.AreEqual(uxa.getAt(0).isEqual(uxx), 0); Assert.AreEqual(uxa.getAt(1).isEqual(uxy), 0); err = SKY_coin_UxArray_Swap(uxa, 1, 0); Assert.AreEqual(err, SKY_OK); Assert.AreEqual(uxa.getAt(0).isEqual(uxx), 0); Assert.AreEqual(uxa.getAt(1).isEqual(uxy), 0); }
public void makeTransactionFromUxOut(coin__UxOut ux, cipher_SecKey s, SWIGTYPE_p_Transaction__Handle handle, coin__Transaction ptx) { handle = makeEmptyTransaction(); var h = new cipher_SHA256(); Assert.AreEqual(skycoin.skycoin.SKY_cipher_SecKey_Verify(s), skycoin.skycoin.SKY_OK); var err = skycoin.skycoin.SKY_coin_UxOut_Hash(ux, h); Assert.AreEqual(err, skycoin.skycoin.SKY_OK); var r = new uint(); r = skycoin.skycoin.SKY_coin_Transaction_PushInput(handle, h); Assert.AreEqual(err, skycoin.skycoin.SKY_OK); err = skycoin.skycoin.SKY_coin_Transaction_PushOutput(handle, makeAddress(), (ulong)1e6, 50); Assert.AreEqual(err, skycoin.skycoin.SKY_OK); err = skycoin.skycoin.SKY_coin_Transaction_PushOutput(handle, makeAddress(), (ulong)5e6, 50); Assert.AreEqual(err, skycoin.skycoin.SKY_OK); var seckeys = new cipher_SecKeys(); seckeys.allocate(1); seckeys.setAt(0, s); err = skycoin.skycoin.SKY_coin_Transaction_SignInputs(handle, seckeys); Assert.AreEqual(err, skycoin.skycoin.SKY_OK); err = skycoin.skycoin.SKY_coin_Transaction_UpdateHeader(handle); Assert.AreEqual(err, skycoin.skycoin.SKY_OK); err = skycoin.skycoin.SKY_coin_GetTransactionObject(handle, ptx); Assert.AreEqual(err, skycoin.skycoin.SKY_OK); err = skycoin.skycoin.SKY_coin_Transaction_Verify(handle); Assert.AreEqual(err, skycoin.skycoin.SKY_OK); }
public void TestTransactionFee() { FullCases(); var addr = transutils.makeAddress(); for (int i = 0; i < ListCases.Length; i++) { var tc = ListCases[i]; var tx = transutils.makeEmptyTransaction(); for (int j = 0; j < tc.outs.Length; j++) { var h = tc.outs[j]; var err1 = SKY_coin_Transaction_PushOutput(tx, addr, (ulong)0, (ulong)h); Assert.AreEqual(err1, SKY_OK); } var inUxs = transutils.makeUxOutArray(tc.ins.Length); Assert.AreEqual(inUxs.count, tc.ins.Length); for (int j = 0; j < tc.ins.Length; j++) { uxInput b = tc.ins[j]; coin__UxOut ux = new coin__UxOut(); ux.Head.Time = b.time; ux.Body.Coins = b.coins; ux.Body.Hours = b.hours; inUxs.setAt(j, ux); } var fee = new_GoUint64p(); var err = SKY_fee_TransactionFee(tx, tc.headTime, inUxs, fee); Assert.AreEqual(err, tc.err); var fee_v = GoUint64p_value(fee); Assert.AreEqual(fee_v, tc.fee); } }
public coin__UxOut makeUxOut() { var uxb = new coin__UxOut(); var s = new cipher_SecKey(); makeUxOutWithSecret(uxb, s); return(uxb); }
public void makeTransaction(SWIGTYPE_p_Transaction__Handle handle, coin__Transaction ptx) { var s = new cipher_SecKey(); var ux = new coin__UxOut(); makeUxOutWithSecret(ux, s); makeTransactionFromUxOut(ux, s, handle, ptx); }
public void makeUxOutWithSecret(coin__UxOut uxOut, cipher_SecKey secKey) { var uxBody = new coin__UxBody(); makeUxBodyWithSecret(uxBody, secKey); uxOut = new coin__UxOut(); var uxHead = new coin__UxHead(); uxHead.Time = 100; uxHead.BkSeq = 2; uxOut.Body = uxBody; uxOut.Head = uxHead; }
public void TestCreateUnspent() { var p = new cipher_PubKey(); var s = new cipher_SecKey(); var a = new cipher__Address(); var err = SKY_cipher_GenerateKeyPair(p, s); Assert.AreEqual(err, SKY_OK); err = SKY_cipher_AddressFromPubKey(p, a); Assert.AreEqual(err, SKY_OK); var h = new cipher_SHA256(); var handle = new_Transaction__Handlep(); makeEmptyTransaction(handle); err = SKY_coin_Transaction_PushOutput(handle, a, 11000000, 255); Assert.AreEqual(err, SKY_OK); var bh = new coin__BlockHeader(); bh.Time = 0; bh.BkSeq = 1; testcase[] t = new testcase[2]; var tc = new testcase(); tc.index = 0; tc.failure = SKY_OK; t[0] = tc; tc = new testcase(); tc.failure = SKY_ERROR; tc.index = 10; t[1] = tc; var ux = new coin__UxOut(); var tests_count = t.Length; for (int i = 0; i < tests_count; i++) { err = SKY_coin_CreateUnspent(bh, handle, t[i].index, ux); if (t[i].failure == SKY_ERROR) { continue; } Assert.AreEqual(bh.Time, ux.Head.Time); Assert.AreEqual(bh.BkSeq, ux.Head.BkSeq); } }
public void TestTransactionVerifyInput() { // Valid var uxOut = new coin__UxOut(); var seckey = new cipher_SecKey(); var result = (uint)makeUxOutWithSecret(uxOut, seckey); Assert.AreEqual(result, SKY_OK); var handle = new_Transaction__Handlep(); makeEmptyTransaction(handle); var ptx = makeTransactionFromUxOut(uxOut, seckey, handle); Assert.AreEqual(result, SKY_OK); var ux = new coin_UxOutArray(); ux.allocate(0); ux.append(uxOut); result = SKY_coin_VerifyInputSignatures(handle, ux); Assert.AreEqual(result, SKY_OK); }
public void TestTransactionPushInput() { var tx = new_Transaction__Handlep(); makeEmptyTransaction(tx); var ux = new coin__UxOut(); makeUxOut(ux); var sha = new cipher_SHA256(); var err = SKY_coin_UxOut_Hash(ux, sha); Assert.AreEqual(err, SKY_OK); var r = new uint(); r = SKY_coin_Transaction_PushInput(tx, sha); Assert.AreEqual(r, 0); var count = new_Gointp(); err = SKY_coin_Transaction_GetInputsCount(tx, count); Assert.AreEqual(err, SKY_OK); Assert.AreEqual(Gointp_value(count), 1); var sha1 = new cipher_SHA256(); err = SKY_coin_Transaction_GetInputAt(tx, 0, sha1); Assert.AreEqual(err, SKY_OK); Assert.AreEqual(sha.isEqual(sha1), 1); err = SKY_coin_Transaction_ResetInputs(tx, 0); Assert.AreEqual(err, SKY_OK); for (int i = 0; i < short.MaxValue; i++) { r = new uint(); r = SKY_coin_Transaction_PushInput(tx, new cipher_SHA256()); Assert.AreEqual(r, SKY_OK); } makeUxOut(ux); err = SKY_coin_UxOut_Hash(ux, sha); Assert.AreEqual(err, SKY_OK); }
public void TestTransactionHashInner() { var handle = new_Transaction__Handlep(); makeTransaction(handle); var h = new cipher_SHA256(); var err = SKY_coin_Transaction_HashInner(handle, h); Assert.AreEqual(err, SKY_OK); Assert.AreEqual(h.isEqual(new cipher_SHA256()), 0); // If tx.In is changed, hash should change var handle2 = transutils.copyTransaction(handle); Assert.AreEqual(err, SKY_OK); var ux = new coin__UxOut(); makeUxOut(ux); h = new cipher_SHA256(); var h1 = new cipher_SHA256(); err = SKY_coin_UxOut_Hash(ux, h); Assert.AreEqual(err, SKY_OK); err = SKY_coin_Transaction_SetInputAt(handle2, 0, h); Assert.AreEqual(err, SKY_OK); err = SKY_coin_UxOut_Hash(ux, h1); Assert.AreEqual(err, SKY_OK); Assert.AreEqual(h.isEqual(h1), 1); err = SKY_coin_Transaction_HashInner(handle, h); Assert.AreEqual(err, SKY_OK); err = SKY_coin_Transaction_HashInner(handle2, h1); Assert.AreEqual(err, SKY_OK); Assert.AreEqual(h.isEqual(h1), 0); // If tx.Out is changed, hash should change handle2 = transutils.copyTransaction(handle); var a = transutils.makeAddress(); var pOut = new coin__TransactionOutput(); err = SKY_coin_Transaction_GetOutputAt(handle2, 0, pOut); Assert.AreEqual(err, SKY_OK); pOut.Address = a; err = SKY_coin_Transaction_SetOutputAt(handle2, 0, pOut); Assert.AreEqual(err, SKY_OK); var sha1 = new cipher_SHA256(); var sha2 = new cipher_SHA256(); err = SKY_coin_Transaction_HashInner(handle, sha1); Assert.AreEqual(err, SKY_OK); err = SKY_coin_Transaction_HashInner(handle2, sha2); Assert.AreEqual(err, SKY_OK); Assert.AreEqual(sha1.isEqual(sha2), 0); // If tx.Head is changed, hash should not change handle2 = transutils.copyTransaction(handle); var sig = new cipher_Sig(); err = SKY_coin_Transaction_PushSignature(handle, sig); Assert.AreEqual(err, SKY_OK); sha1 = new cipher_SHA256(); sha2 = new cipher_SHA256(); err = SKY_coin_Transaction_HashInner(handle, sha1); Assert.AreEqual(err, SKY_OK); err = SKY_coin_Transaction_HashInner(handle2, sha2); Assert.AreEqual(err, SKY_OK); Assert.AreEqual(sha1.isEqual(sha2), 1); }
public void TestTransactionSignInputs() { var handle = transutils.makeEmptyTransaction(); // Panics if txns already signed var sig = new cipher_Sig(); var err = SKY_coin_Transaction_PushSignature(handle, sig); Assert.AreEqual(err, SKY_OK); var seckeys = new cipher_SecKeys(); seckeys.allocate(1); seckeys.setAt(0, new cipher_SecKey()); // Panics if not enough keys handle = transutils.makeEmptyTransaction(); var s = new cipher_SecKey(); var s2 = new cipher_SecKey(); var ux = new coin__UxOut(); var ux2 = new coin__UxOut(); makeUxOutWithSecret(ux, s); var h = new cipher_SHA256(); err = SKY_coin_UxOut_Hash(ux, h); Assert.AreEqual(err, SKY_OK); var r = new uint(); r = SKY_coin_Transaction_PushInput(handle, h); Assert.AreEqual(r, SKY_OK); makeUxOutWithSecret(ux2, s2); err = SKY_coin_UxOut_Hash(ux2, h); Assert.AreEqual(err, SKY_OK); r = SKY_coin_Transaction_PushInput(handle, h); Assert.AreEqual(r, SKY_OK); err = SKY_coin_Transaction_PushOutput(handle, transutils.makeAddress(), 40, 80); Assert.AreEqual(err, SKY_OK); var count = new_Gointp(); err = SKY_coin_Transaction_GetSignaturesCount(handle, count); Assert.AreEqual(err, SKY_OK); Assert.AreEqual(Gointp_value(count), 0); // Valid signing h = new cipher_SHA256(); SKY_coin_Transaction_HashInner(handle, h); seckeys = new cipher_SecKeys(); seckeys.allocate(2); seckeys.setAt(0, s); seckeys.setAt(1, s2); err = SKY_coin_Transaction_SignInputs(handle, seckeys); Assert.AreEqual(err, SKY_OK); err = SKY_coin_Transaction_GetSignaturesCount(handle, count); Assert.AreEqual(err, SKY_OK); Assert.AreEqual(Gointp_value(count), 2); var h2 = new cipher_SHA256(); err = SKY_coin_Transaction_HashInner(handle, h2); Assert.AreEqual(err, SKY_OK); Assert.AreEqual(h.isEqual(h2), 1); var p = new cipher_PubKey(); err = SKY_cipher_PubKeyFromSecKey(s, p); Assert.AreEqual(err, SKY_OK); var a = new cipher__Address(); var a2 = new cipher__Address(); err = SKY_cipher_AddressFromPubKey(p, a); Assert.AreEqual(err, SKY_OK); err = SKY_cipher_PubKeyFromSecKey(s2, p); Assert.AreEqual(err, SKY_OK); err = SKY_cipher_AddressFromPubKey(p, a2); Assert.AreEqual(err, SKY_OK); var sha1 = new cipher_SHA256(); var sha2 = new cipher_SHA256(); var txin0 = new cipher_SHA256(); var txin1 = new cipher_SHA256(); err = SKY_coin_Transaction_GetInputAt(handle, 0, txin0); Assert.AreEqual(err, SKY_OK); err = SKY_coin_Transaction_GetInputAt(handle, 1, txin1); Assert.AreEqual(err, SKY_OK); err = SKY_cipher_AddSHA256(h, txin0, sha1); Assert.AreEqual(err, SKY_OK); err = SKY_cipher_AddSHA256(h, txin1, sha2); Assert.AreEqual(err, SKY_OK); var txsig0 = new cipher_Sig(); var txsig1 = new cipher_Sig(); err = SKY_coin_Transaction_GetSignatureAt(handle, 0, txsig0); Assert.AreEqual(err, SKY_OK); err = SKY_coin_Transaction_GetSignatureAt(handle, 1, txsig1); Assert.AreEqual(err, SKY_OK); }
public void TestTransactionVerify() { // Mismatch header hash var tx = transutils.makeEmptyTransaction(); var ptx = makeTransaction(tx); ptx.setInnerHash(new cipher_SHA256()); var err = SKY_coin_Transaction_Verify(tx); Assert.AreEqual(err, SKY_ERROR); // No inputs tx = new_Transaction__Handlep(); makeTransaction(tx); err = SKY_coin_Transaction_ResetInputs(tx, 0); Assert.AreEqual(err, SKY_OK); err = SKY_coin_Transaction_UpdateHeader(tx); Assert.AreEqual(err, SKY_OK); err = SKY_coin_Transaction_Verify(tx); Assert.AreEqual(err, SKY_ERROR); // No outputs makeTransaction(tx); err = SKY_coin_Transaction_ResetOutputs(tx, 0); Assert.AreEqual(err, SKY_OK, ""); err = SKY_coin_Transaction_UpdateHeader(tx); Assert.AreEqual(err, SKY_OK); err = SKY_coin_Transaction_Verify(tx); Assert.AreEqual(err, SKY_ERROR); // Invalid number of Sigs makeTransaction(tx); err = SKY_coin_Transaction_ResetSignatures(tx, 0); Assert.AreEqual(err, SKY_OK); err = SKY_coin_Transaction_UpdateHeader(tx); Assert.AreEqual(err, SKY_OK); err = SKY_coin_Transaction_Verify(tx); Assert.AreEqual(err, SKY_ERROR); err = SKY_coin_Transaction_ResetSignatures(tx, 20); Assert.AreEqual(err, SKY_OK); err = SKY_coin_Transaction_UpdateHeader(tx); Assert.AreEqual(err, SKY_OK); err = SKY_coin_Transaction_Verify(tx); Assert.AreEqual(err, SKY_ERROR); // Too many sigs & inputs makeTransaction(tx); err = SKY_coin_Transaction_ResetSignatures(tx, short.MaxValue); Assert.AreEqual(err, SKY_OK); err = SKY_coin_Transaction_ResetInputs(tx, short.MaxValue); Assert.AreEqual(err, SKY_OK); err = SKY_coin_Transaction_UpdateHeader(tx); Assert.AreEqual(err, SKY_OK); err = SKY_coin_Transaction_Verify(tx); Assert.AreEqual(err, SKY_ERROR); // Duplicate inputs var ux = new coin__UxOut(); var s = new cipher_SecKey(); var h = new cipher_SHA256(); makeUxOutWithSecret(ux, s); makeTransactionFromUxOut(ux, s, tx); err = SKY_coin_Transaction_GetInputAt(tx, 0, h); Assert.AreEqual(err, SKY_OK); var r = new uint(); r = SKY_coin_Transaction_PushInput(tx, h); Assert.AreEqual(r, SKY_OK); err = SKY_coin_Transaction_ResetSignatures(tx, 0); Assert.AreEqual(err, SKY_OK); var secKeys = new cipher_SecKeys(); secKeys.allocate(2); secKeys.setAt(0, s); secKeys.setAt(1, s); err = SKY_coin_Transaction_SignInputs(tx, secKeys); Assert.AreEqual(err, SKY_OK); err = SKY_coin_Transaction_UpdateHeader(tx); Assert.AreEqual(err, SKY_OK); err = SKY_coin_Transaction_Verify(tx); Assert.AreEqual(err, SKY_ERROR); // Duplicate outputs makeTransaction(tx); var pOutput = new coin__TransactionOutput(); err = SKY_coin_Transaction_GetOutputAt(tx, 0, pOutput); pOutput.Address = new cipher__Address(); err = SKY_coin_Transaction_ResetOutputs(tx, 0); Assert.AreEqual(err, SKY_OK); err = SKY_coin_Transaction_PushOutput(tx, pOutput.Address, pOutput.Coins, pOutput.Hours); Assert.AreEqual(err, SKY_OK); err = SKY_coin_Transaction_PushOutput(tx, pOutput.Address, pOutput.Coins, pOutput.Hours); Assert.AreEqual(err, SKY_OK); err = SKY_coin_Transaction_UpdateHeader(tx); Assert.AreEqual(err, SKY_OK); err = SKY_coin_Transaction_Verify(tx); Assert.AreEqual(err, SKY_ERROR); // Output coins are 0 makeTransaction(tx); err = SKY_coin_Transaction_GetOutputAt(tx, 0, pOutput); pOutput.Coins = 0; err = SKY_coin_Transaction_ResetOutputs(tx, 0); Assert.AreEqual(err, SKY_OK); err = SKY_coin_Transaction_PushOutput(tx, pOutput.Address, pOutput.Coins, pOutput.Hours); Assert.AreEqual(err, SKY_OK); err = SKY_coin_Transaction_UpdateHeader(tx); Assert.AreEqual(err, SKY_OK); err = SKY_coin_Transaction_Verify(tx); Assert.AreEqual(err, SKY_ERROR); // Output coin overflow makeTransaction(tx); err = SKY_coin_Transaction_GetOutputAt(tx, 0, pOutput); pOutput.Coins = (ulong)(ulong.MaxValue - 3e6); err = SKY_coin_Transaction_PushOutput(tx, pOutput.Address, pOutput.Coins, pOutput.Hours); Assert.AreEqual(err, SKY_OK); err = SKY_coin_Transaction_UpdateHeader(tx); Assert.AreEqual(err, SKY_OK); err = SKY_coin_Transaction_Verify(tx); Assert.AreEqual(err, SKY_ERROR); // Output coins are not multiples of 1e6 (valid, decimal restriction is not enforced here) makeTransaction(tx); err = SKY_coin_Transaction_GetOutputAt(tx, 0, pOutput); Assert.AreEqual(err, SKY_OK); err = SKY_coin_Transaction_ResetOutputs(tx, 0); Assert.AreEqual(err, SKY_OK); pOutput.Coins += 10; err = SKY_coin_Transaction_PushOutput(tx, pOutput.Address, pOutput.Coins, pOutput.Hours); Assert.AreEqual(err, SKY_OK); err = SKY_coin_Transaction_UpdateHeader(tx); Assert.AreEqual(err, SKY_OK); err = SKY_coin_Transaction_ResetSignatures(tx, 0); Assert.AreEqual(err, SKY_OK); var p = new cipher_PubKey(); s = new cipher_SecKey(); err = SKY_cipher_GenerateKeyPair(p, s); Assert.AreEqual(err, SKY_OK); secKeys = new cipher_SecKeys(); secKeys.allocate(1); secKeys.setAt(0, s); err = SKY_coin_Transaction_SignInputs(tx, secKeys); Assert.AreEqual(err, SKY_OK); Assert.IsTrue(pOutput.Coins % 1e6 != 0); err = SKY_coin_Transaction_Verify(tx); Assert.AreEqual(err, SKY_OK); // Valid makeTransaction(tx); err = SKY_coin_Transaction_GetOutputAt(tx, 0, pOutput); Assert.AreEqual(err, SKY_OK); err = SKY_coin_Transaction_ResetOutputs(tx, 0); Assert.AreEqual(err, SKY_OK); err = SKY_coin_Transaction_PushOutput(tx, pOutput.Address, (ulong)(10e6), pOutput.Hours); Assert.AreEqual(err, SKY_OK); err = SKY_coin_Transaction_PushOutput(tx, pOutput.Address, (ulong)(1e6), pOutput.Hours); Assert.AreEqual(err, SKY_OK); err = SKY_coin_Transaction_UpdateHeader(tx); Assert.AreEqual(err, SKY_OK); err = SKY_coin_Transaction_Verify(tx); Assert.AreEqual(err, SKY_OK); }
public void TestUxOutSnapshotHash() { var p = new cipher_PubKey(); var s = new cipher_SecKey(); var err = SKY_cipher_GenerateKeyPair(p, s); Assert.AreEqual(err, SKY_OK); var uxb = new coin__UxBody(); var b = new GoSlice(); err = SKY_cipher_RandByte(128, b); Assert.AreEqual(err, SKY_OK); var h = new cipher_SHA256(); err = SKY_cipher_SumSHA256(b, h); Assert.AreEqual(err, SKY_OK); uxb.SetSrcTransaction(h); var a = new cipher__Address(); err = SKY_cipher_AddressFromPubKey(p, a); Assert.AreEqual(err, SKY_OK); uxb.Address = a; uxb.Coins = (ulong)1e6; uxb.Hours = (ulong)100; var uxo = new coin__UxOut(); var uxh = new coin__UxHead(); uxh.Time = 100; uxh.BkSeq = 2; uxo.Head = uxh; uxo.Body = uxb; var hn = new cipher_SHA256(); err = SKY_coin_UxOut_SnapshotHash(uxo, hn); Assert.AreEqual(err, SKY_OK); // snapshot hash should be dependent on every field in body and head // Head Time var uxo_2 = uxo; uxh.Time = 20; uxo_2.Head = uxh; var hn_2 = new cipher_SHA256(); err = SKY_coin_UxOut_SnapshotHash(uxo_2, hn_2); Assert.AreEqual(err, SKY_OK); Assert.AreEqual(hn.isEqual(hn_2), 0); // Head BkSeq uxo_2 = uxo; uxh.BkSeq = 4; uxo_2.Head = uxh; hn_2 = new cipher_SHA256(); err = SKY_coin_UxOut_SnapshotHash(uxo_2, hn_2); Assert.AreEqual(err, SKY_OK); Assert.AreEqual(hn.isEqual(hn_2), 0); // Body SetSrcTransaction uxo_2 = uxo; uxb = new coin__UxBody(); err = SKY_cipher_RandByte(128, b); Assert.AreEqual(err, SKY_OK); h = new cipher_SHA256(); err = SKY_cipher_SumSHA256(b, h); Assert.AreEqual(err, SKY_OK); uxb.SetSrcTransaction(h); uxo_2.Body = uxb; hn_2 = new cipher_SHA256(); err = SKY_coin_UxOut_SnapshotHash(uxo_2, hn_2); Assert.AreEqual(err, SKY_OK); Assert.AreEqual(hn.isEqual(hn_2), 0); // Body Address var p_2 = new cipher_PubKey(); var s_2 = new cipher_SecKey(); err = SKY_cipher_GenerateKeyPair(p_2, s_2); Assert.AreEqual(err, SKY_OK); var a_2 = new cipher__Address(); err = SKY_cipher_AddressFromPubKey(p_2, a_2); Assert.AreEqual(err, SKY_OK); uxo_2 = uxo; uxb = new coin__UxBody(); uxb.Address = a_2; uxo_2.Body = uxb; hn_2 = new cipher_SHA256(); err = SKY_coin_UxOut_SnapshotHash(uxo_2, hn_2); Assert.AreEqual(err, SKY_OK); Assert.AreEqual(hn.isEqual(hn_2), 0); // Body Coins uxo_2 = uxo; uxb = new coin__UxBody(); uxb.Coins = 2; uxo_2.Body = uxb; hn_2 = new cipher_SHA256(); err = SKY_coin_UxOut_SnapshotHash(uxo_2, hn_2); Assert.AreEqual(err, SKY_OK); Assert.AreEqual(hn.isEqual(hn_2), 0); // Body Hours uxo_2 = uxo; uxb = new coin__UxBody(); uxb.Hours = 2; uxo_2.Body = uxb; hn_2 = new cipher_SHA256(); err = SKY_coin_UxOut_SnapshotHash(uxo_2, hn_2); Assert.AreEqual(err, SKY_OK); Assert.AreEqual(hn.isEqual(hn_2), 0); }
public void TestUxOutCoinHours() { var p = new cipher_PubKey(); var s = new cipher_SecKey(); SKY_cipher_GenerateKeyPair(p, s); var uxb = new coin__UxBody(); var b = new GoSlice(); SKY_cipher_RandByte(128, b); var h = new cipher_SHA256(); var err = SKY_cipher_SumSHA256(b, h); Assert.AreEqual(err, SKY_OK); uxb.SetSrcTransaction(h); var a = new cipher__Address(); SKY_cipher_AddressFromPubKey(p, a); uxb.Address = a; uxb.Coins = (ulong)1e6; uxb.Hours = 100; var uxo = new coin__UxOut(); var uxh = new coin__UxHead(); uxh.Time = 100; uxh.BkSeq = 2; uxo.Head = uxh; uxo.Body = uxb; // Less than an hour passed var now = uxh.Time + 100; var hours = new_GoUint64p(); err = SKY_coin_UxOut_CoinHours(uxo, now, hours); Assert.AreEqual(err, SKY_OK); Assert.AreEqual(uxh.Time, GoUint64p_value(hours), "Less than an hour passed"); // 1 hours passed now = uxh.Time + 3600; err = SKY_coin_UxOut_CoinHours(uxo, now, hours); Assert.AreEqual(err, SKY_OK); Assert.AreEqual(GoUint64p_value(hours), uxh.Time + (uxb.Coins / 1000000), "1 hours passed"); // 6 hours passed now = uxh.Time + 3600 * 6; err = SKY_coin_UxOut_CoinHours(uxo, now, hours); Assert.AreEqual(err, SKY_OK); Assert.AreEqual(GoUint64p_value(hours), uxh.Time + (uxb.Coins / 1000000) * 6, "1 hours passed"); // Time is backwards (treated as no hours passed) now = uxh.Time / 2; err = SKY_coin_UxOut_CoinHours(uxo, now, hours); Assert.AreEqual(err, SKY_OK); Assert.AreEqual(GoUint64p_value(hours), uxh.Time); // 1 hour has passed, output has 1.5 coins, should gain 1 coinhour uxb.Coins = 1500000; now = uxh.Time + 3600; err = SKY_coin_UxOut_CoinHours(uxo, now, hours); Assert.AreEqual(err, SKY_OK); Assert.AreEqual(GoUint64p_value(hours), uxb.Hours + 1); // 2 hours have passed, output has 1.5 coins, should gain 3 coin hours uxb.Coins = 1500000; uxo.Body = uxb; now = uxh.Time + 3600 * 2; err = SKY_coin_UxOut_CoinHours(uxo, now, hours); Assert.AreEqual(err, SKY_OK); // 1 second has passed, output has 3600 coins, should gain 1 coin hour uxb.Coins = 3600000000; uxo.Body = uxb; now = uxh.Time + 1; err = SKY_coin_UxOut_CoinHours(uxo, now, hours); Assert.AreEqual(err, SKY_OK); Assert.AreEqual(GoUint64p_value(hours), uxb.Hours + 1); // 1000000 hours minus 1 second have passed, output has 1 droplet, should gain 0 coin hour uxb.Coins = 1; uxo.Body = uxb; now = (ulong)(uxh.Time + (ulong)Convert.ToInt64(1e6 * 3600) - 1); err = SKY_coin_UxOut_CoinHours(uxo, now, hours); Assert.AreEqual(err, SKY_OK); Assert.AreEqual(GoUint64p_value(hours), uxb.Hours); // 1000000 hours have passed, output has 1 droplet, should gain 1 coin hour uxb.Coins = 1; uxo.Body = uxb; now = uxh.Time + Convert.ToUInt64(10e5 * 3600); err = SKY_coin_UxOut_CoinHours(uxo, now, hours); Assert.AreEqual(err, SKY_OK); Assert.AreEqual(GoUint64p_value(hours), uxb.Hours + 1); // No hours passed, using initial coin hours uxb.Coins = (ulong)10e8; uxb.Hours = 1000 * 1000; uxo.Body = uxb; now = uxh.Time; err = SKY_coin_UxOut_CoinHours(uxo, now, hours); Assert.AreEqual(err, SKY_OK); Assert.AreEqual(GoUint64p_value(hours), uxb.Hours); // One hour passed, using initial coin hours now = uxh.Time + 3600; err = SKY_coin_UxOut_CoinHours(uxo, now, hours); Assert.AreEqual(err, SKY_OK); Assert.AreEqual(GoUint64p_value(hours), uxb.Hours + (10e8 / 10e5)); // No hours passed and no hours to begin with 0 uxb.Hours = 0; uxo.Body = uxb; now = uxh.Time; err = SKY_coin_UxOut_CoinHours(uxo, now, hours); Assert.AreEqual(err, SKY_OK); Assert.AreEqual(GoUint64p_value(hours), 0); // Centuries have passed, time-based calculation overflows uint64 when calculating the whole coin seconds uxb.Coins = (ulong)20e5; uxo.Body = uxb; now = 0xFFFFFFFFFFFFFFFF; err = SKY_coin_UxOut_CoinHours(uxo, now, hours); Assert.AreEqual(err, SKY_ERROR); // Centuries have passed, time-based calculation overflows uint64 when calculating the droplet seconds uxb.Coins = (ulong)15e5; uxo.Body = uxb; now = 0xFFFFFFFFFFFFFFFF; err = SKY_coin_UxOut_CoinHours(uxo, now, hours); Assert.AreEqual(err, SKY_ERROR); // Output would overflow if given more hours, has reached its limit uxb.Coins = (ulong)36e8; uxo.Body = uxb; now = 0xFFFFFFFFFFFFFFFF; err = SKY_coin_UxOut_CoinHours(uxo, now, hours); Assert.AreEqual(err, SKY_ERROR); }