services: allow non-empty inv scripts for contract-based notary witness

This commit is contained in:
Anna Shaleva 2021-10-22 16:59:16 +03:00 committed by AnnaShaleva
parent 75d7891ca1
commit 807fa4a720
2 changed files with 12 additions and 5 deletions

View file

@ -376,8 +376,9 @@ the steps to create a signature request:
9. Construct the list of main transactions witnesses (that will be `Scripts` 9. Construct the list of main transactions witnesses (that will be `Scripts`
transaction field). Use the following rules: transaction field). Use the following rules:
- Contract-based witness should have `Invocation` script that pushes arguments - Contract-based witness should have `Invocation` script that pushes arguments
on stack (it may be empty) and empty `Verification` script. Currently, **only on stack (it may be empty) and empty `Verification` script. If multiple notary
empty** `Invocation` scripts are supported for contract-based witnesses. requests provide different `Invocation` scripts then the first one will be used
to construct contract-based witness.
- **Notary contract witness** (which is also a contract-based witness) should - **Notary contract witness** (which is also a contract-based witness) should
have empty `Verification` script. `Invocation` script should be of the form have empty `Verification` script. `Invocation` script should be of the form
[opcode.PUSHDATA1, 64, make([]byte, 64)...], i.e. to be a placeholder for [opcode.PUSHDATA1, 64, make([]byte, 64)...], i.e. to be a placeholder for

View file

@ -220,12 +220,18 @@ func (n *Notary) OnNewRequest(payload *payload.P2PNotaryRequest) {
} }
mainHash := hash.NetSha256(uint32(n.Network), r.main).BytesBE() mainHash := hash.NetSha256(uint32(n.Network), r.main).BytesBE()
for i, w := range payload.MainTransaction.Scripts { for i, w := range payload.MainTransaction.Scripts {
if r.witnessInfo[i].typ == Contract || // check that we need to fill that witness if len(w.InvocationScript) == 0 || // check that signature for this witness was provided
len(w.InvocationScript) == 0 || // check that signature for this witness was provided (r.witnessInfo[i].nSigsLeft == 0 && r.witnessInfo[i].typ != Contract) { // check that signature wasn't yet added (consider receiving the same payload multiple times)
r.witnessInfo[i].nSigsLeft == 0 { // check that signature wasn't yet added (consider receiving the same payload multiple times)
continue continue
} }
switch r.witnessInfo[i].typ { switch r.witnessInfo[i].typ {
case Contract:
// Need to check even if r.main.Scripts[i].InvocationScript is already filled in.
err := n.Config.Chain.VerifyWitness(r.main.Signers[i].Account, r.main, &w, n.Config.Chain.GetPolicer().GetMaxVerificationGAS())
if err != nil {
continue
}
r.main.Scripts[i].InvocationScript = w.InvocationScript
case Signature: case Signature:
if r.witnessInfo[i].pubs[0].Verify(w.InvocationScript[2:], mainHash) { if r.witnessInfo[i].pubs[0].Verify(w.InvocationScript[2:], mainHash) {
r.main.Scripts[i] = w r.main.Scripts[i] = w