public static extern void Sort(GoSlice a);
static void Main(string[] args) { // CGO checks // Go code may not store a Go pointer in C memory. // C code may store Go pointers in C memory, // subject to the rule above: it must stop storing the Go pointer when // the C function returns. Environment.SetEnvironmentVariable("GODEBUG", "cgocheck=2"); // define parameters int a = 10; int b = 2; double x = 100; Int64[] t = new Int64[] { 35, 56, 1, 3, 2, 88, 14 }; // Allocate unmanaged memory for // the GoSlice int n = t.Length; GCHandle h = GCHandle.Alloc(t, GCHandleType.Pinned); GoSlice gs = new GoSlice { data = h.AddrOfPinnedObject(), cap = n, len = n }; // Allocate unmanaged memory for the // GoString string msg = "I am the Hal 9000"; GoString s = new GoString { p = Marshal.StringToHGlobalAnsi(msg), n = msg.Length }; // call the external functions int addResult = GoMath.Add(a, b); int subResult = GoMath.Sub(a, b); double cosineResult = GoMath.Cosine(x); int sumResult = GoMath.Sum(gs); var helloResult = GoHello.HelloWorld(s); GoMath.Sort(gs); // Read the Sorted GoSlice n = (int)gs.len; Int64[] arr = new Int64[n]; for (int i = 0; i < n; i++) { arr[i] = Marshal.ReadInt64(gs.data, i * Marshal.SizeOf(typeof(Int64))); } // Read the size of the data returned by HelloWorld // The size is an int32, so we read 4 bytes byte *buf = (byte *)helloResult; byte[] lenBytes = new byte[4]; for (int i = 0; i < 4; i++) { lenBytes[i] = *buf++; } // Read the result itself n = BitConverter.ToInt32(lenBytes, 0); int j = 0; byte[] bytes = new byte[n]; for (int i = 0; i < n; i++) { // Skip the first 4 bytes because // they hold the size if (i < 4) { *buf++ = 0; } else { bytes[j] = *buf++; j++; } } // Print results Console.WriteLine( "#########################################" + "\n### .NET Calling Shared-C Golang .dll ###" + "\n#########################################\n" ); Console.WriteLine($"HelloWorld: {Encoding.UTF8.GetString(bytes)}"); Console.WriteLine($"Add: {addResult}"); Console.WriteLine($"Sub: {subResult}"); Console.WriteLine($"Cos: {cosineResult}"); Console.WriteLine($"Sum: {sumResult}"); Console.WriteLine(Int64ArrayToString(arr)); // free up allocated unmanaged memory if (h.IsAllocated) { h.Free(); } }
internal static global::System.Runtime.InteropServices.HandleRef getCPtr(GoSlice obj) { return((obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr); }
public static extern int Sum(GoSlice vals);
public static extern void Sort(GoSlice vals);
public void TestDistributionAddressArrays() { var addrs = new GoSlice(); var unlocked = new GoSlice(); var locked = new GoSlice(); SKY_params_GetDistributionAddresses(addrs); Assert.AreEqual(addrs.len, 100); SKY_params_GetUnlockedDistributionAddresses(unlocked); Assert.AreEqual(unlocked.len, 25); SKY_params_GetLockedDistributionAddresses(locked); Assert.AreEqual(locked.len, 75); for (int i = 0; i < addrs.len; i++) { var iStr = new _GoString_(); addrs.getAtString(i, iStr); for (int j = 0; j < i + 1; j++) { if (j < addrs.len) { break; } var jStr = new _GoString_(); addrs.getAtString(i + 1, jStr); Assert.AreEqual(iStr.isEqual(jStr), 0); } } for (int i = 0; i < unlocked.len; i++) { var iStr = new _GoString_(); unlocked.getAtString(i, iStr); for (int j = 0; j < i + 1; j++) { if (j < unlocked.len) { break; } var jStr = new _GoString_(); unlocked.getAtString(i + 1, jStr); Assert.AreEqual(iStr.isEqual(jStr), 0); } } for (int i = 0; i < locked.len; i++) { var iStr = new _GoString_(); locked.getAtString(i, iStr); for (int j = 0; j < i + 1; j++) { if (j < locked.len) { break; } var jStr = new _GoString_(); locked.getAtString(i + 1, jStr); Assert.AreEqual(iStr.isEqual(jStr), 0); } } }
void freshSumSHA256(GoSlice bytes, cipher_SHA256 sha256) { SKY_cipher_SumSHA256(bytes, sha256); }
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); }
private static extern GoSlice NativeGenerateVerifier(GoString password, GoString signedModulus, GoSlice rawSalt, int bits);