From be125d3b7908a95d8a373f30aa5b081cb358267f Mon Sep 17 00:00:00 2001
From: Jason Elie Bou Kheir <5115126+jasonboukheir@users.noreply.github.com>
Date: Wed, 13 Jul 2022 22:42:32 -0700
Subject: [PATCH] fix(abi): fix Tuple not encoding dynamic types correctly
---
.../Experimental/Abi/Values/Array.cs | 20 +++++---
.../Experimental/Abi/Values/Tuple.cs | 47 ++++++++++++++-----
2 files changed, 49 insertions(+), 18 deletions(-)
diff --git a/Runtime/CareBoo.AlgoSdk/Experimental/Abi/Values/Array.cs b/Runtime/CareBoo.AlgoSdk/Experimental/Abi/Values/Array.cs
index 5c0eadbda..0df7104cb 100644
--- a/Runtime/CareBoo.AlgoSdk/Experimental/Abi/Values/Array.cs
+++ b/Runtime/CareBoo.AlgoSdk/Experimental/Abi/Values/Array.cs
@@ -41,13 +41,19 @@ public EncodedAbiArg Encode(IAbiType type, AbiReferences references, Allocator a
if (type.IsFixedArray)
return tupleEncoding;
- var result = new EncodedAbiArg(allocator);
- using var k = new UInt16((ushort)value.Length)
- .Encode(AbiType.UIntN(16), references, Allocator.Persistent);
- result.Bytes.AddRange(k.Bytes);
- result.Bytes.AddRange(tupleEncoding.Bytes);
- tupleEncoding.Dispose();
- return result;
+ try
+ {
+ var result = new EncodedAbiArg(allocator);
+ using var k = new UInt16((ushort)value.Length)
+ .Encode(AbiType.UIntN(16), references, Allocator.Persistent);
+ result.Bytes.AddRange(k.Bytes);
+ result.Bytes.AddRange(tupleEncoding.Bytes);
+ return result;
+ }
+ finally
+ {
+ tupleEncoding.Dispose();
+ }
}
///
diff --git a/Runtime/CareBoo.AlgoSdk/Experimental/Abi/Values/Tuple.cs b/Runtime/CareBoo.AlgoSdk/Experimental/Abi/Values/Tuple.cs
index 4e2daeff0..b16d2be40 100644
--- a/Runtime/CareBoo.AlgoSdk/Experimental/Abi/Values/Tuple.cs
+++ b/Runtime/CareBoo.AlgoSdk/Experimental/Abi/Values/Tuple.cs
@@ -106,6 +106,8 @@ struct Encoder
byte boolShift;
+ Optional headBytesTotalLength;
+
public Encoder(T args, U types, AbiReferences references, Allocator allocator)
{
this.args = args;
@@ -115,6 +117,7 @@ public Encoder(T args, U types, AbiReferences references, Allocator allocator)
this.tailBytes = new NativeList(allocator);
this.result = new EncodedAbiArg(allocator);
this.boolShift = 0;
+ this.headBytesTotalLength = default;
}
public EncodedAbiArg Encode(Allocator allocator)
@@ -183,18 +186,14 @@ void EncodeStaticHead(int t)
void EncodeDynamicHead(int t)
{
- boolShift = 0;
- var offset = headBytes.Length + tailBytes.Length;
- var args = this.args;
- do
+ if (!headBytesTotalLength.HasValue)
{
- var type = types[t];
- offset += type.IsStatic
- ? args.LengthOfCurrent(types[t])
- : 2
- ;
- t++;
- } while (args.TryNext(out args));
+ headBytesTotalLength = CountHeadBytesLength(t);
+ }
+ var ptr = headBytesTotalLength.Value + tailBytes.Length;
+ var offset = headBytes.Length;
+ headBytes.Length += 2;
+ Endianness.CopyToNativeBytesBigEndian((ushort)ptr, ref headBytes, offset);
}
void EncodeBoolHead(int t)
@@ -224,6 +223,32 @@ void EncodeDynamicTail(int t)
using var bytes = args.EncodeCurrent(types[t], references, Allocator.Persistent);
tailBytes.AddRange(bytes.Bytes);
}
+
+ int CountHeadBytesLength(int t)
+ {
+ var totalLength = headBytes.Length;
+ var args = this.args;
+ do
+ {
+ var type = types[t];
+ if (type.Name == "bool")
+ {
+ boolShift %= 8;
+ if (boolShift == 0)
+ totalLength++;
+ boolShift++;
+ }
+ else
+ {
+ boolShift = 0;
+ totalLength += type.IsStatic
+ ? args.LengthOfCurrent(type)
+ : 2;
+ }
+ t++;
+ } while (args.TryNext(out args));
+ return totalLength;
+ }
}
}