Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimized StorageMap #89

Merged
merged 15 commits into from
Aug 27, 2019
9 changes: 8 additions & 1 deletion src/Neo.SmartContract.Framework/Helper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ namespace Neo.SmartContract.Framework
public static class Helper
{
/// <summary>
/// Converts byte to byte[].
/// Converts byte to byte[] considering the byte as a BigInteger (0x00 at the end)
/// </summary>
[Script]
shargon marked this conversation as resolved.
Show resolved Hide resolved
public extern static byte[] AsByteArray(this byte source);
shargon marked this conversation as resolved.
Show resolved Hide resolved
Expand Down Expand Up @@ -132,6 +132,13 @@ public static class Helper
// return (byte) source;
//}

/// <summary>
/// Converts byte to byte[].
/// </summary>
[OpCode(OpCode.PUSH1)]
[OpCode(OpCode.LEFT)]
public extern static byte[] ToByteArray(this byte source);

/// <summary>
/// Converts parameter to sbyte from (big)integer range -128-255; faults if out-of-range.
/// Examples: 256 -> fault; -1 -> -1 [0xff]; 255 -> -1 [0xff]; 0 -> 0 [0x00]; 10 -> 10 [0x0a]; 127 -> 127 [0x7f]; 128 -> -128 [0x80]
Expand Down
38 changes: 28 additions & 10 deletions src/Neo.SmartContract.Framework/Services/Neo/Helper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,15 @@ namespace Neo.SmartContract.Framework.Services.Neo
public static class Helper
{
public static StorageMap CreateMap(this StorageContext context, string prefix)
{
return new StorageMap
{
Context = context,
Prefix = prefix.AsByteArray()
};
}

public static StorageMap CreateMap(this StorageContext context, byte[] prefix)
{
return new StorageMap
{
Expand All @@ -13,63 +22,72 @@ public static StorageMap CreateMap(this StorageContext context, string prefix)
};
}

public static StorageMap CreateMap(this StorageContext context, byte prefix)
Copy link
Member Author

@shargon shargon Aug 26, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't find an optimized version of the conversion from byte to byte array inside the VM, should we remove this method?

{
return new StorageMap
{
Context = context,
Prefix = prefix.ToByteArray()
};
}

public static void Delete(this StorageMap map, byte[] key)
{
byte[] k = map.Prefix.AsByteArray().Concat(new byte[] { 0 }).Concat(key);
byte[] k = map.Prefix.Concat(key);
Storage.Delete(map.Context, k);
}

public static void Delete(this StorageMap map, string key)
{
byte[] k = map.Prefix.AsByteArray().Concat(new byte[] { 0 }).Concat(key.AsByteArray());
byte[] k = map.Prefix.Concat(key.AsByteArray());
Storage.Delete(map.Context, k);
}

public static byte[] Get(this StorageMap map, byte[] key)
{
byte[] k = map.Prefix.AsByteArray().Concat(new byte[] { 0 }).Concat(key);
byte[] k = map.Prefix.Concat(key);
return Storage.Get(map.Context, k);
}

public static byte[] Get(this StorageMap map, string key)
{
byte[] k = map.Prefix.AsByteArray().Concat(new byte[] { 0 }).Concat(key.AsByteArray());
byte[] k = map.Prefix.Concat(key.AsByteArray());
return Storage.Get(map.Context, k);
}

public static void Put(this StorageMap map, byte[] key, byte[] value)
{
byte[] k = map.Prefix.AsByteArray().Concat(new byte[] { 0 }).Concat(key);
byte[] k = map.Prefix.Concat(key);
Storage.Put(map.Context, k, value);
}

public static void Put(this StorageMap map, byte[] key, BigInteger value)
{
byte[] k = map.Prefix.AsByteArray().Concat(new byte[] { 0 }).Concat(key);
byte[] k = map.Prefix.Concat(key);
Storage.Put(map.Context, k, value);
}

public static void Put(this StorageMap map, byte[] key, string value)
{
byte[] k = map.Prefix.AsByteArray().Concat(new byte[] { 0 }).Concat(key);
byte[] k = map.Prefix.Concat(key);
Storage.Put(map.Context, k, value);
}

public static void Put(this StorageMap map, string key, byte[] value)
{
byte[] k = map.Prefix.AsByteArray().Concat(new byte[] { 0 }).Concat(key.AsByteArray());
byte[] k = map.Prefix.Concat(key.AsByteArray());
Storage.Put(map.Context, k, value);
}

public static void Put(this StorageMap map, string key, BigInteger value)
{
byte[] k = map.Prefix.AsByteArray().Concat(new byte[] { 0 }).Concat(key.AsByteArray());
byte[] k = map.Prefix.Concat(key.AsByteArray());
Storage.Put(map.Context, k, value);
}

public static void Put(this StorageMap map, string key, string value)
{
byte[] k = map.Prefix.AsByteArray().Concat(new byte[] { 0 }).Concat(key.AsByteArray());
byte[] k = map.Prefix.Concat(key.AsByteArray());
Storage.Put(map.Context, k, value);
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/Neo.SmartContract.Framework/Services/Neo/StorageMap.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ namespace Neo.SmartContract.Framework.Services.Neo
public class StorageMap
{
internal StorageContext Context;
internal string Prefix;
internal byte[] Prefix;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
using Neo.SmartContract.Framework.Services.Neo;

namespace Neo.Compiler.MSIL.TestClasses
{
class Contract_StorageMap : SmartContract.Framework.SmartContract
{
// There is no main here, it can be auto generation.

#region Byte

public static bool TestPutByte(byte[] key, byte[] value)
{
var storage = Storage.CurrentContext.CreateMap(0xAA);
storage.Put(key, value);
return true;
}

public static bool TestDeleteByte(byte[] key)
{
var storage = Storage.CurrentContext.CreateMap(0xAA);
var value = storage.Get(key);
var exists = value.Length > 0;
storage.Delete(key);
return exists;
}

public static byte[] TestGetByte(byte[] key)
{
var storage = Storage.CurrentContext.CreateMap(0xAA);
var value = storage.Get(key);
return value;
}

#endregion

#region String

public static bool TestPutString(byte[] key, byte[] value)
{
var prefix = "aa";
var storage = Storage.CurrentContext.CreateMap(prefix);
storage.Put(key, value);
return true;
}

public static bool TestDeleteString(byte[] key)
{
var prefix = "aa";
var storage = Storage.CurrentContext.CreateMap(prefix);
var value = storage.Get(key);
var exists = value.Length > 0;
storage.Delete(key);
return exists;
}

public static byte[] TestGetString(byte[] key)
{
var prefix = "aa";
var storage = Storage.CurrentContext.CreateMap(prefix);
var value = storage.Get(key);
return value;
}

#endregion

#region ByteArray

public static bool TestPutByteArray(byte[] key, byte[] value)
{
var prefix = new byte[] { 0x00, 0xFF };
var storage = Storage.CurrentContext.CreateMap(prefix);
storage.Put(key, value);
return true;
}

public static bool TestDeleteByteArray(byte[] key)
{
var prefix = new byte[] { 0x00, 0xFF };
var storage = Storage.CurrentContext.CreateMap(prefix);
var value = storage.Get(key);
var exists = value.Length > 0;
storage.Delete(key);
return exists;
}

public static byte[] TestGetByteArray(byte[] key)
{
var prefix = new byte[] { 0x00, 0xFF };
var storage = Storage.CurrentContext.CreateMap(prefix);
var value = storage.Get(key);
return value;
}

#endregion
}
}
2 changes: 1 addition & 1 deletion tests/Neo.Compiler.MSIL.UnitTests/UnitTest_ABI_Event.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public void Test_ABI_Event()
{
var testengine = new TestEngine();
testengine.AddEntryScript("./TestClasses/Contract_Event.cs");
var abi = testengine.scriptEntry.finialABI;
var abi = testengine.ScriptEntry.finialABI;
Console.WriteLine("abi=" + abi.ToString());
var events = abi["events"].AsList()[0].ToString();
Console.WriteLine("event abi info =" + events);
Expand Down
6 changes: 3 additions & 3 deletions tests/Neo.Compiler.MSIL.UnitTests/UnitTest_AutoEntrypoint.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public void Test_AutoEntry()
var testengine = new TestEngine();
testengine.AddEntryScript("./TestClasses/Contract_autoentrypoint.cs");

testengine.scriptEntry.DumpAVM();
testengine.ScriptEntry.DumpAVM();

var result = testengine.GetMethod("call01").Run();//new test method01
StackItem wantresult = new byte[] { 1, 2, 3, 4 };
Expand All @@ -28,7 +28,7 @@ public void Test_AutoEntry_private()
var testengine = new TestEngine();
testengine.AddEntryScript("./TestClasses/Contract_autoentrypoint.cs");

testengine.scriptEntry.DumpAVM();
testengine.ScriptEntry.DumpAVM();
StackItem[] _params = new StackItem[] { "privateMethod", new StackItem[0] };
var result = testengine.ExecuteTestCase(_params);//new test method02

Expand All @@ -43,7 +43,7 @@ public void Test_AutoEntry_call02()
var testengine = new TestEngine();
testengine.AddEntryScript("./TestClasses/Contract_autoentrypoint.cs");

testengine.scriptEntry.DumpAVM();
testengine.ScriptEntry.DumpAVM();

var result = testengine.ExecuteTestCaseStandard("call02", "hello", 33);//old test method
StackItem wantresult = new byte[0];
Expand Down
4 changes: 2 additions & 2 deletions tests/Neo.Compiler.MSIL.UnitTests/UnitTest_Shift.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public void Test_Shift()
var testengine = new TestEngine();
testengine.AddEntryScript("./TestClasses/Contract_shift.cs");

testengine.scriptEntry.DumpAVM();
testengine.ScriptEntry.DumpAVM();

var result = testengine.ExecuteTestCaseStandard("testfunc");
}
Expand All @@ -26,7 +26,7 @@ public void Test_Shift_BigInteger()
var testengine = new TestEngine();
testengine.AddEntryScript("./TestClasses/Contract_shift_bigint.cs");

testengine.scriptEntry.DumpAVM();
testengine.ScriptEntry.DumpAVM();

StackItem[] _params = new StackItem[] { "testfunc", new StackItem[0] };
var result = testengine.ExecuteTestCase(_params);
Expand Down
Loading