-
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
[Neo Rpc Methods] fix contract rpc methods parameters #3485
Conversation
/// <param name="useDiagnostic">Optional. Flag to enable diagnostic information.</param> | ||
/// <returns>A JToken containing the result of the invocation.</returns> | ||
[RpcMethodWithParams] | ||
protected internal virtual JToken InvokeFunction(string scriptHash, string operation, ContractParameter[] args = null, Signer[] signers = null, bool useDiagnostic = false) |
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.
This behaviour diverges from an old one. This method should accept the list of signers with witnesses as the fourth parameter, not only the list of signers.
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.
It never worked. And not bing of any use at anywhere.
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.
And not bing of any use at anywhere.
You don't know that. It's an external API and it's a very widely used one. Your changes can easily break real applications. Refactorings must not break compatibility.
|
||
namespace Neo.Plugins.RpcServer.Model; | ||
|
||
public class SignerOrWitness |
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.
Why not make a base
class for common stuff? Than two different classes one, being Signer
and other being Witness
. This way we can get Signer
attributes like Rules
or other properties that separate the two classes.
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.
make it work first, optimize it later. I think you are better than me to make the code more elegent.
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.
You may take a look at https://github.com/nspcc-dev/neo-go/blob/e1d5ac8557d7e087158e6a766d059913a56df79f/pkg/neorpc/types.go#L75 and https://github.com/nspcc-dev/neo-go/blob/e1d5ac8557d7e087158e6a766d059913a56df79f/pkg/neorpc/types.go#L83 as a reference, both Signer and Witness should be accepted at the same time.
@AnnaShaleva please check latest update to make it |
throw new RpcException(CreateInvalidParamError<Signer>(token)); | ||
} | ||
} | ||
throw new RpcException(CreateInvalidParamError<Signer>(token)); |
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.
Would adding an else
statement here make it clearer?
AllowedContracts = ((JArray)jObject["allowedcontracts"])?.Select(p => UInt160.Parse(p.AsString())).ToArray() ?? Array.Empty<UInt160>(), | ||
AllowedGroups = ((JArray)jObject["allowedgroups"])?.Select(p => ECPoint.Parse(p.AsString(), ECCurve.Secp256r1)).ToArray() ?? Array.Empty<ECPoint>(), | ||
Rules = ((JArray)jObject["rules"])?.Select(r => WitnessRule.FromJson((JObject)r)).ToArray() ?? Array.Empty<WitnessRule>() | ||
}; |
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 also need a check against the maximum number of parsed contracts, rules and groups, it's 16.
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.
You may serialize and deserialize parsed items to ensure validity, exactly how the old code does it.
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.
Still not resolved, we need validation.
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.
this is already copied from the original code, if its still not working, i would say it has never worked, and should not be a concern of this pr.
return new[] { signerOrWitness }; | ||
} | ||
} | ||
throw new RpcException(RpcError.InvalidParams.WithData($"Invalid SignerOrWitness format: {token}")); |
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.
Ditto.
@AnnaShaleva updated this pr to mock the complete http request process, now should be able to work without miss any detail. |
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.
testes some methods and they are working as expected
However, maybe @superboyiii should do a more extensive tests, these changes affects various methods |
I have updated to make it use existing unit test, without updating the unit test logic makes sure that changes in this pr follows the old processing logic. |
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.
This is probably a breaking change to several dapps.
InvokeFunction is a methods that probably many services use.
Perhaps its parameters will now face this modification from array.
var signers = signerWithWitnesses?.Where(u => u.Signer != null).Select(u => u.Signer).ToArray() ?? []; | ||
var witnesses = signerWithWitnesses?.Where(u => u.Witness != null).Select(u => u.Witness).ToArray() ?? []; |
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.
Checks .Where(u => u.Signer != null)
and .Where(u => u.Witness != null)
are not quite correct because it may lead to unexpected result if e.g. some witness is missing for a signer. These checks may lead to the situation when signers
and witnesses
have different length.
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 think we have properly defined the behavior of when signers and witnesses have different length. we dont have any logic to process it in previous code.
AllowedContracts = ((JArray)jObject["allowedcontracts"])?.Select(p => UInt160.Parse(p.AsString())).ToArray() ?? Array.Empty<UInt160>(), | ||
AllowedGroups = ((JArray)jObject["allowedgroups"])?.Select(p => ECPoint.Parse(p.AsString(), ECCurve.Secp256r1)).ToArray() ?? Array.Empty<ECPoint>(), | ||
Rules = ((JArray)jObject["rules"])?.Select(r => WitnessRule.FromJson((JObject)r)).ToArray() ?? Array.Empty<WitnessRule>() | ||
}; |
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.
Still not resolved, we need validation.
Signer[] signers = _params.Count >= 3 ? SignersFromJson((JArray)_params[2], system.Settings) : null; | ||
Witness[] witnesses = _params.Count >= 3 ? WitnessesFromJson((JArray)_params[2]) : null; | ||
Signer[] signers = _params.Count >= 3 ? SignerWithWitness.ParseArray((JArray)_params[2], system.Settings).Where(u => u.Signer != null).Select(u => u.Signer).ToArray() : null; | ||
Witness[] witnesses = _params.Count >= 3 ? SignerWithWitness.ParseArray((JArray)_params[2], system.Settings).Where(u => u.Witness != null).Select(u => u.Witness).ToArray() : null; |
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.
Ditto.
If it's a breaking change, it MUST NOT be merged. We have exactly zero reasons to break these interfaces. Any refactorings MUST keep compatibility. |
|
||
namespace Neo.Plugins.RpcServer.Model; | ||
|
||
public class SignerWithWitness(Signer? signer, Witness? witness) |
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.
SignerWithWitness
?
May be WitnessSigner
is better?
{ | ||
signer = SignerFromJson(jObject, settings); | ||
} | ||
if (jObject.ContainsProperty("invocation") || jObject.ContainsProperty("verification")) |
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.
"invocation"
and "verification"
defined as constant values is better?
Why it was closed @Jim8y ? |
Srry i should have mentioned, i am working a new pr to replace this one that introduces minumum change to the existing code base such that it can be easier to review. This pr has made many changes that is not relavent to this pr. |
Description
This pr updates the rpc plugin contract related methods.
Fixes # (issue)
Type of change
How Has This Been Tested?
Test Configuration:
Checklist: