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; + } } }