Skip to content

Simplified Validation Model#770

Merged
erikzhang merged 6 commits intomasterfrom
3.0/SVM
May 25, 2019
Merged

Simplified Validation Model#770
erikzhang merged 6 commits intomasterfrom
3.0/SVM

Conversation

@erikzhang
Copy link
Copy Markdown
Member

@erikzhang erikzhang commented May 21, 2019

  1. Only allow one Witness in a Transaction.
  2. Remove Cosigner from Transaction.Attributes.
  3. Modify Wallet.MakeTransaction() to support SVM.

NOTE: Which SYSCALLs can be called by the Validation trigger has been limited by the gas. See #771

@erikzhang erikzhang added this to the NEO 3.0 milestone May 21, 2019
@codecov-io
Copy link
Copy Markdown

codecov-io commented May 21, 2019

Codecov Report

Merging #770 into master will increase coverage by 0.24%.
The diff coverage is 26.94%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #770      +/-   ##
==========================================
+ Coverage   36.58%   36.82%   +0.24%     
==========================================
  Files         175      174       -1     
  Lines       12401    12262     -139     
==========================================
- Hits         4537     4516      -21     
+ Misses       7864     7746     -118
Impacted Files Coverage Δ
neo/SmartContract/Helper.cs 43.5% <0%> (+0.85%) ⬆️
neo/Cryptography/Helper.cs 17.09% <0%> (+0.14%) ⬆️
neo/Network/P2P/Payloads/TransactionAttribute.cs 0% <0%> (ø) ⬆️
neo/Ledger/Blockchain.cs 36.81% <100%> (-0.47%) ⬇️
neo/SmartContract/InteropService.cs 15.49% <100%> (-0.2%) ⬇️
neo/SmartContract/InteropService.NEO.cs 12.78% <14.28%> (+0.04%) ⬆️
neo/SmartContract/ContractParametersContext.cs 33.76% <37.5%> (-2.8%) ⬇️
neo/Network/P2P/Payloads/Transaction.cs 56.83% <38.46%> (-5.04%) ⬇️
neo/Consensus/ConsensusContext.cs 54.77% <50%> (ø) ⬆️
neo/Network/P2P/Payloads/BlockBase.cs 77.04% <57.14%> (+4.74%) ⬆️
... and 6 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 56866f4...b0f7c21. Read the comment docs.

Copy link
Copy Markdown
Member

@vncoelho vncoelho left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like this simplification.
However, are we still going to perform multiple signatures on a transaction, @erikzhang?
I mean, nowdays we can sign an InvocationTx with several signers (singlesig, multisig and special_verification scripts) at the same time.

I saw that the Array of Witness has been simplified.

@erikzhang
Copy link
Copy Markdown
Member Author

You can still use multisig as a Sender, but you can't add any CoSigner.

@vncoelho
Copy link
Copy Markdown
Member

vncoelho commented May 21, 2019

The ideia is Multiple Signers (`CoSigner), @erikzhang.
It is usefull for distinct applications.

Sometimes we want to merge SingleSig with a MultiSig or a Single Sig with a special verification script.

This enables interesting scenarios, in which we can even take funds for all of them together in a smart contract.

@erikzhang
Copy link
Copy Markdown
Member Author

The Sender of a Transaction is to pay for the fees. Other signature verification logic should be moved into Application trigger.

@igormcoelho
Copy link
Copy Markdown
Contributor

igormcoelho commented May 21, 2019

This change is very important for TPS (and to prevent attacks), let's think carefully on what can be cut (and how). Having undefinite number of attributes and witnesses is bad, I agree.

The Sender of a Transaction is to pay for the fees.

Ok, I get it now. So this is only for "Input" validation. Perhaps Inputs won't exist, so we will have an "invoker" or "sender" here? The one who pays fees.

Other signature verification logic should be moved into Application trigger.

Ok, so witnesses will be passed for internal contract processing. User signature is passed as argument on contract invocation, correct? This effectively simplifies a lot the architecture, and witness system can be considered effectively gone.
Example:

bool Main(string op, object args[]) {
   ...
   if ! CheckSignature((pubkey)args[0], (signature)args[1]) return false; // or FAULT
}

Perhaps we should rename this single witness to something else, like invoker or sender, since the usage will be very different from Neo 2.0 (so we don't make confusion). We should then abolish Runtime_CheckWitness and leave all work to CheckSignature.

@igormcoelho
Copy link
Copy Markdown
Contributor

igormcoelho commented May 21, 2019

@erikzhang
if somehow VerificationScript is not a necessary part of transaction (only its hash, perhaps), nodes would be able to optimize this by caching known scripts in a map scripthash -> script (like for deployed nodes).
This would drastically reduce blockchain size when exporting it for others (because each used script would need a single mention).
On the other hard, I think it's important not to keep this mandatory, because people could "attack" the network by simply creating random huge scripts with very little value on it (so it would be still necessary for users to attach their verification script during tx submission, and sometimes it would be cached, sometimes not). Same could be done perhaps for InvocationScript (although less likely to be repeated I think).

Example:
TX HEADER
sender hash
invocation scripthash
verification/sender scripthash

REST
invocation script (sometimes cached, sometimes not)
sender script (sometimes cached, sometimes not)

Even on Neo 2.0 we could benefit of such strategies I guess, because at least some scripts aren't part of tx header, as far as I remember (or was it all of them already?) 🤔

@erikzhang
Copy link
Copy Markdown
Member Author

erikzhang commented May 21, 2019

if (verification.Length == 0)
{
verification = snapshot.Contracts.TryGet(hash)?.Script;
if (verification is null) return false;
}

If it's a deployed contract, the VerificationScript can be empty.

@igormcoelho
Copy link
Copy Markdown
Contributor

igormcoelho commented May 21, 2019

Yes, I know that for deployed contracts, but I mean, even for regular contracts we can do that too if it's repeated in the past already. This saves a lot of space when exporting the chain (repeating over and over the VerificationScripts). We can do this on Neo 2.0 as well.
But I'm just emphasizing that if we manage to keep VerificationScript out of header hash (just register its scripthash), we have more options to cache it for the future, or not cache it. I need to check the newest SerializeUnsigned to be sure.

What I mean is:

  1. user submits complete tx to node1 (full node receives the verificationscript, and network fee price is calculated including it)
  2. node1 realizes this contract was used "recently" (according to some future established rule), so it only relays the header and invocation (no verificationscript, because it knows others know that script too). Example, just used it 5 blocks ago.
  3. before arriving to consensus nodes, some p2p node may have "restored" that information and "reappended" it to the tx (without affecting tx hash). This allows consensus node to not need to cache any undeployed script, and still this tx can be easily routed in incomplete form. So, it's important that verification script does not affect tx hash (but its hash is appended to headers anyway).

Another possibility is:

  1. user submits full tx to node1
  2. this verification script was never used, or used "very long time ago" (several thousand blocks). So node1 decides to relay complete tx, to make sure others have complete info. Other nodes may follow the same idea, and only reduce network p2p load when deemed necessary.

Nevermind, I checked and it can work already, since it's still out of SerializeUnsigned. I can leave this proposal for later:

void IVerifiable.SerializeUnsigned(BinaryWriter writer)
{
writer.Write(Version);
writer.Write(Nonce);
writer.WriteVarBytes(Script);
writer.Write(Sender);
writer.Write(Gas);
writer.Write(NetworkFee);
writer.Write(ValidUntilBlock);
writer.Write(Attributes);
}

@shargon
Copy link
Copy Markdown
Member

shargon commented May 21, 2019

Even on Neo 2.0 we could benefit of such strategies I guess, because at least some scripts aren't part of tx header, as far as I remember (or was it all of them already?) 🤔

Don't touch neo 2.0, just for bugs please 📦

@shargon
Copy link
Copy Markdown
Member

shargon commented May 22, 2019

I am scary about how this could affect some projects, for multisig wallets and check owners without multisig wallets... Every time that we want to change one of the owners, we will need to create a new multisign wallet? maybe is a good move, but we should provide a easy method for create this multisign wallet in neo-cli.

@erikzhang
Copy link
Copy Markdown
Member Author

https://github.com/neo-project/neo-cli/blob/5403d5375d295c0b0ccc4569e22a87f205f89f2e/neo-cli/Shell/MainService.cs#L609-L640

There is a command in CLI: import multisigaddress.

@igormcoelho
Copy link
Copy Markdown
Contributor

Don't touch neo 2.0, just for bugs please

It's a plugin shargon, no core change. I can explain better later. Result of a brainstorming here.

Im scary of...

I dont see how this can affect multisig.. its usually one witness, right ?

@shargon
Copy link
Copy Markdown
Member

shargon commented May 24, 2019

Not multisign wallet, multi signatures for owners, without a multign wallet

@erikzhang erikzhang marked this pull request as ready for review May 25, 2019 10:21
{
engine.LoadScript(verification);
engine.LoadScript(verifiable.Witness.InvocationScript);
if (engine.Execute().HasFlag(VMState.FAULT)) return false;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that we shouldn't deal with VMState as a flag

@erikzhang erikzhang merged commit 2401a11 into master May 25, 2019
@erikzhang erikzhang deleted the 3.0/SVM branch May 25, 2019 11:29
Copy link
Copy Markdown
Member

@vncoelho vncoelho left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was a great PR and simplification, Erik. Nice job!
I still wonder about cosigners...however, we check it later.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants