-
Notifications
You must be signed in to change notification settings - Fork 1k
Enforce NEP-25 extended type validation #4187
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
base: nep-25
Are you sure you want to change the base?
Conversation
256d956
to
1bce361
Compare
NEP-25 adds ExtendedType descriptors to contract manifests, but the branch currently accepts manifests that reference undefined named types, mismatch parameter metadata, or break the base NEP-25 rules. This commit adds ExtendedType validation to ContractAbi, ContractMethodDescriptor, and ContractParameterDefinition so contracts that violate NEP-25 are rejected before deployment.\n\nThe change keeps the detailed FormatException messages recently introduced in dev, ensuring operators get actionable errors while we enforce the extended-type invariants.
1bce361
to
12da30f
Compare
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.
Overall this should work.
ValidateCore(expectedType: null, allowFields: true, knownNamedTypes, allowNamedTypeReference: true); | ||
} | ||
|
||
private void ValidateCore(ContractParameterType? expectedType, bool allowFields, ISet<string>? knownNamedTypes, bool allowNamedTypeReference) |
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.
allowNamedTypeReference is always true
NamedType = json["namedtype"]?.GetString(), | ||
}; | ||
if (!Enum.IsDefined(typeof(ContractParameterType), type.Type)) throw new FormatException(); | ||
if (type.Type == ContractParameterType.Void) throw Nep25Error("Void type is not allowed."); |
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.
Somewhat duplicating ValdateCore
|
||
if (Type == ContractParameterType.Map && !Key.HasValue) | ||
throw Nep25Error("key is required for Map type."); | ||
|
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.
Many of the checks are context-independent (can be performed on a single ExtendedType value), so can be done at ExtendedType.FromJSON/FromStackItem level. But that's just a suggestion, functionally ABI-level checks can be sufficient.
ContractParameterType.String | ||
}; | ||
|
||
private static FormatException Nep25Error(string message) => new($"Invalid NEP-25 extended type: {message}"); |
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 dont like this approach.
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.
But why? And what's the alternative?
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.
There are many alternatives. But the simplest is to just use throw new FormatException($"Invalid NEP-25 extended type: {message}")
instead of a function. But I would prefer to use an exception class with the name Nep25TypeException
. The reason for this is when you throw Nep25Error(message)
you dont know the exception at hand and can make it hard to track down when debugging. Makes you have to look at Call Stack...etc. It just harder to maintain.
interface/key/value/fields/namedtype usage, array element requirements, named type existence).
ContractEventDescriptor, ContractParameterDefinition) for both JSON and stack deserialization,
blocking mismatched parameter/return declarations.
types to ensure invalid manifests are rejected.