neo: Storage.Find duplicate values
The Neo.Storage.Find SYSCALL returns duplicate results causing the invoker to be charged for unnecessary extra Neo.Iterator.Key and Neo.Iterator.Next calls.
Take this contract
using Neo.SmartContract.Framework;
using Neo.SmartContract.Framework.Services.Neo;
namespace NeoContract1
{
public class Contract1 : SmartContract
{
public static void Main(int op)
{
if (op == 1)
{
Storage.Put(Storage.CurrentContext, "AA_1", "1");
Storage.Put(Storage.CurrentContext, "AA_2", "2");
Storage.Put(Storage.CurrentContext, "AA_3", "3");
} else if (op == 2)
{
Iterator<string, byte[]> si = Storage.Find(Storage.CurrentContext, "AA_");
notify_results(si);
}
else if (op == 3)
{
Storage.Get(Storage.CurrentContext, "AA_1");
Iterator<string, byte[]> si = Storage.Find(Storage.CurrentContext, "AA_");
notify_results(si);
}
}
private static void notify_results(Iterator<string, byte[]> si)
{
Runtime.Notify("Starting");
while (si.Next())
{
Runtime.Notify(si.Key);
}
Runtime.Notify("Done");
}
}
}
Invoke the contract once with the contract op argument being 1 to persist the contents to the DB. Next invoke the contract with op being 2 and 3.
2gives the expected:AA_1,AA_2,AA_3,3however gives:AA_1,AA_2,AA_3,AA_1,AA_1The last 2 values should not be there. I believe this is a caching issue.
Take a secondary contract that allows us to call Contract 1 multiple times in a single DB snapshot
using Neo.SmartContract.Framework;
using Neo.SmartContract.Framework.Services.Neo;
using System;
using System.Numerics;
namespace NeoContract2
{
public class Contract2 : SmartContract
{
[Appcall("f4032cfb5505c05d935db8bd41b608005eca0b00")]
public static extern void OtherContract(int op);
public static void Main(int op)
{
if (op == 1)
{
OtherContract(2);
OtherContract(2);
}
else if (op == 2)
{
OtherContract(2);
OtherContract(3);
}
else
{
OtherContract(3);
OtherContract(2);
}
}
}
}
opis1is still correct and produces:AA_1,AA_2,AA_3followed by anotherAA_1,AA_2,AA_3opis2is wrong in the same way it was wrong when calling contract 1 directly. We first getAA_1,AA_2,AA_3followed byAA_1,AA_2,AA_3,AA_1,AA_1opis3is where it gets really interesting. Given the previous results you’d expect:AA_1,AA_2,AA_3,AA_1,AA_1followed byAA_1,AA_2,AA_3. Instead you now get 2 times the sequenceAA_1,AA_2,AA_3,AA_1,AA_1
Contract AVM files included in the zip file for easy deploy/reproducing contracts.zip
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Comments: 15 (15 by maintainers)
I should not report issues after an extra long day of debugging. Made a rookie mistake by looking at neo-python’s interpretation 😅
Ricarrrdo, @lock9, here is our flag! 🗡️
But all issues need to be tagged, it has been like this since the old days. We have 96 issues open, 95 have tags, why this one is different? I just didn’t use the “discussion” tag, because this doesn’t look like a discussion. This looks more like a “support request”, I agree that bug may not be the best tag, but we need to tag it.