-
Notifications
You must be signed in to change notification settings - Fork 1k
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
Read only methods #1052
Read only methods #1052
Changes from 17 commits
ea39390
86aff3e
fa580d2
1e0496a
6759e5a
be5d7a1
aa3dce2
6c6ab1a
3bc6e80
cab7f01
fe0986a
dd65378
288c9ff
a7e4485
6107a8d
049b485
a2e48d2
1095106
d010c54
38e2a10
1ea1538
e8ab57d
6e54e04
c2722ce
c8cd016
fca0844
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -55,8 +55,8 @@ public static partial class InteropService | |
public static readonly uint System_Block_GetTransaction = Register("System.Block.GetTransaction", Block_GetTransaction, 0_00000400, TriggerType.Application); | ||
public static readonly uint System_Transaction_GetHash = Register("System.Transaction.GetHash", Transaction_GetHash, 0_00000400, TriggerType.All); | ||
public static readonly uint System_Contract_Call = Register("System.Contract.Call", Contract_Call, 0_01000000, TriggerType.System | TriggerType.Application); | ||
public static readonly uint System_Contract_Destroy = Register("System.Contract.Destroy", Contract_Destroy, 0_01000000, TriggerType.Application); | ||
public static readonly uint System_Storage_GetContext = Register("System.Storage.GetContext", Storage_GetContext, 0_00000400, TriggerType.Application); | ||
public static readonly uint System_Contract_Destroy = Register("System.Contract.Destroy", Contract_Destroy, 0_01000000, TriggerType.Application, true); | ||
public static readonly uint System_Storage_GetContext = Register("System.Storage.GetContext", Storage_GetContext, 0_00000400, TriggerType.Application, true); | ||
public static readonly uint System_Storage_GetReadOnlyContext = Register("System.Storage.GetReadOnlyContext", Storage_GetReadOnlyContext, 0_00000400, TriggerType.Application); | ||
public static readonly uint System_Storage_Get = Register("System.Storage.Get", Storage_Get, 0_01000000, TriggerType.Application); | ||
public static readonly uint System_Storage_Put = Register("System.Storage.Put", Storage_Put, GetStoragePrice, TriggerType.Application); | ||
|
@@ -88,19 +88,21 @@ internal static bool Invoke(ApplicationEngine engine, uint method) | |
return false; | ||
if (!descriptor.AllowedTriggers.HasFlag(engine.Trigger)) | ||
return false; | ||
if (descriptor.RequireWriteAccess && engine.CurrentContext.GetState<ExecutionContextState>().ReadOnly) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No need to check this @shargon... if something really needs write access, you can invoke it, and let it fail naturally when it tries to access something that requires writing. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I want to ban more syscalls like destroy and create, i think thats is better with this flag |
||
return false; | ||
return descriptor.Handler(engine); | ||
} | ||
|
||
private static uint Register(string method, Func<ApplicationEngine, bool> handler, long price, TriggerType allowedTriggers) | ||
private static uint Register(string method, Func<ApplicationEngine, bool> handler, long price, TriggerType allowedTriggers, bool requireWriteAccess = false) | ||
{ | ||
InteropDescriptor descriptor = new InteropDescriptor(method, handler, price, allowedTriggers); | ||
InteropDescriptor descriptor = new InteropDescriptor(method, handler, price, allowedTriggers, requireWriteAccess); | ||
methods.Add(descriptor.Hash, descriptor); | ||
return descriptor.Hash; | ||
} | ||
|
||
private static uint Register(string method, Func<ApplicationEngine, bool> handler, Func<RandomAccessStack<StackItem>, long> priceCalculator, TriggerType allowedTriggers) | ||
private static uint Register(string method, Func<ApplicationEngine, bool> handler, Func<RandomAccessStack<StackItem>, long> priceCalculator, TriggerType allowedTriggers, bool requireWriteAccess = false) | ||
{ | ||
InteropDescriptor descriptor = new InteropDescriptor(method, handler, priceCalculator, allowedTriggers); | ||
InteropDescriptor descriptor = new InteropDescriptor(method, handler, priceCalculator, allowedTriggers, requireWriteAccess); | ||
methods.Add(descriptor.Hash, descriptor); | ||
return descriptor.Hash; | ||
} | ||
|
@@ -537,9 +539,10 @@ private static bool Contract_Call(ApplicationEngine engine) | |
|
||
StackItem method = engine.CurrentContext.EvaluationStack.Pop(); | ||
StackItem args = engine.CurrentContext.EvaluationStack.Pop(); | ||
string methodStr = method.GetString(); | ||
ContractManifest currentManifest = engine.Snapshot.Contracts.TryGet(engine.CurrentScriptHash)?.Manifest; | ||
|
||
if (currentManifest != null && !currentManifest.CanCall(contract.Manifest, method.GetString())) | ||
if (currentManifest != null && !currentManifest.CanCall(contract.Manifest, methodStr)) | ||
shargon marked this conversation as resolved.
Show resolved
Hide resolved
|
||
return false; | ||
|
||
if (engine.InvocationCounter.TryGetValue(contract.ScriptHash, out var counter)) | ||
|
@@ -552,6 +555,9 @@ private static bool Contract_Call(ApplicationEngine engine) | |
} | ||
|
||
ExecutionContext context_new = engine.LoadScript(contract.Script, 1); | ||
context_new.GetState<ExecutionContextState>().ReadOnly = currentManifest != null && | ||
(currentManifest.ReadOnlyMethods.IsWildcard || currentManifest.ReadOnlyMethods.Contains(methodStr)); | ||
shargon marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
context_new.EvaluationStack.Push(args); | ||
context_new.EvaluationStack.Push(method); | ||
return true; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this is a good idea @shargon... what is
RequireWriteAccess
? To Storage?Could we remove this?
I thought that, if current ExecutionContextState is running on ReadOnly, then methods that require write access could simply fail (example: Storage.GetCurrentContext`).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can rename the var, but not remove it, because is used for ban the syscall when is in readOnly mode