-
Notifications
You must be signed in to change notification settings - Fork 0
/
P5.txt
173 lines (143 loc) · 8.57 KB
/
P5.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
Protocol update
Protocol Version: 5
Builds on Protocol Version: 4
Abstract
This document describes the changes in Concordium protocol version 5
compared to protocol version 4.
The protocol change adds support for upgradable smart contracts and
allows smart contracts to query additional data from the chain. The
protocol update also allows smart contracts to use more resources and
introduces a major reorganization of the account storage. The
reorganization allows for more efficient account retrieval and updates.
Background
Protocol version 5 changes protocol version 4 in three areas: making
smart contracts more usable, making account storage and operations more
efficient, and simplifying the hashing of transaction outcomes.
With regards to smart contracts, there are the following limitations in
previous protocol versions.
In previous protocol versions smart contract instances are immutable.
Once instantiated, there is no way to change the code that is executed
for each entrypoint. The instance can still change behaviour based on
the state of course, however any bugs in the contract are permanent.
Since the state of the contract instance may change, a workaround to
this limitation is to introduce an indirection in terms of a proxy
contract that dispatches calls to other implementation contracts. This
works, but is complex and error-prone. In protocol version 5 smart
contracts can invoke a special operation to upgrade themselves. Whether
they make use of this or not is entirely up to the smart contract
writer, and it is clear from the contract whether it will potentially
make use of the upgrade or not. This makes writing and testing
upgradable contracts substantially simpler.
Smart contracts also get very limited information about the chain. In
particular they can manipulate their own state, invoke other contracts,
and transfer CCD to other accounts. They cannot get balances of accounts
or other contracts on the chain, nor values of any chain parameters.
Protocol version 5 adds additional query capabilities to smart
contracts.
Finally, there are some hard limits enforced on smart contracts, and
these limits are needlessly restrictive. These are the limit on
parameter (or message) size, which limits how much data can be
transferred to the smart contract invocation; the limit on the number of
logs that a smart contract can produce; and the limit on how much data a
contract can return. This latter limit restricts the usability of
so-called view functions, since they can only return 16kB of data. These
limits are lifted in protocol version 5.
With regards to accounts, the changes are internal to the node, and the
only protocol visible effect is that the hash of the accounts, and
therefore the hash of the entire state is computed differently. The node
maintains the current state of each account. This state contains the
public, encrypted, and locked balances; the credentials that currently
belong to the account; information about whether the account is a baker
or delegator; and any release schedule. All this data is hashed and the
hash is part of the block hash and is in turn part of validity criteria
for blocks. The current account storage has inefficiencies that make
loading of accounts slower than it needs to be, and some common
operations require loading more data than is required. Additionally,
account hash has to be recomputed after each update. This currently
involves loading most of the account data, which is inefficient.
The rationale for making this change is to optimize the common account
operations.
With regards to transaction outcome hashing, the change there is to not
assign protocol relevant meaning to all the outcome data. In protocol
versions 1-4 the entire transaction outcome is hashed, even if the
transaction was rejected because, for example, the receiver account did
not exist. If a transaction was rejected then there is no effect on the
chain other than payment. Having the exact rejection reason as part of
the protocol defined data means that the logic of transaction checking
must keep all the checks in the exact same order.
Changes
The following behaviours are changed in protocol version 5.
1. The transactions `InitContract` and `Update`
can take a parameter of size `65535B` in contrast to a parameter of
size `1024B` previously.
2. When a V0 or V1 contract sends a message, or invokes a contract,
respectively, they may now send a parameter of size `65535B`, in
contrast to the previous limit of `1024B`.
3. When a V1 contract returns a value as a result of either the init
function execution, or entrypoint execution, the return value is now
limited to `4294967295B`, up from the previous limit of `16384B`.
4. V1 contracts may now use an additional host function `upgrade`. This
takes a pointer to a new smart contract module reference. From that
point onward new entrypoint executions will use the new code.
The new module has to exist on the chain at the time of the
execution, and it must be a V1 module. The upgrade function returns
whether the upgrade succeeded or not, and if not the reason why in
the form of a status code.
5. The `invoke` host function for V1 contracts is extended with 3 new
operations for querying account balance, contract balance, and
EUR/NRG and CCD/EUR exchange rates. These operations have operation
tags `2`, `3`, and `4`, respectively.
- The account balance query takes an account address and returns
either an error if the account does not exist, or a tuple of 3
balances (as 64-bit integers)
- current total balance (accounting for changes in the current
transaction)
- staked balance (0 if account is not delegating or baking)
- balance locked in scheduled transfers
- The contract balance query takes a contract instance address and
returns the current CCD balance of the contract instance,
accounting for changes in the current transaction, if the contract
exists, and an error code otherwise.
- The exchange rate query always returns a pair of exchange rates in
the form of 4 64-bit integers. The first two represent the EUR/NRG
exchange rate (as numerator/denominator in reduced form) and the
last two represent CCD/EUR, in the same form.
6. The hash for accounts is computed in a different way now, but this
has no other visible effects.
7. For transactions that have been rejected, the hash no longer reflects
the exact reason why they were rejected. Instead only a tag `1u8` is
retained.
Effects
1. The account hash changes have no visible effects on the chain apart
from the computation of the block hash.
2. Transaction outcome hashing changes also have no visible effect apart
from the computation of the block hash.
3. The addition of upgradability changes the behaviour of `DeployModule`
transactions. Previously, deploying a module that used the `upgrade`
host function would have failed with "module not well-formed" error.
4. Behaviour of existing contract instances may be affected in the
following scenarios
- the contract previously tried to invoke another contract (for V1
contracts) or send a message (V0 contracts) with a parameter larger
than `1024B`. The contract invocation would have failed with a
runtime exception. Now it will succeed if the size is no more than
`65535B`.
- A V1 contract attempted to write to the return value starting
beyond `16384B`. This would have failed with a runtime error, and
will now succeed.
- A V1 contract attempted to write to the return value such that it
would extend it beyond `1024B`. Previously the response would the
be the number of bytes written, which would be less than the amount
that the contract attempted to write. Now the entire value will be
written, and correspondingly the return value will reflect that.
- A V1 contract attempted to invoke to invoke an operation with tags
2, 3, or 4. That would have led to a runtime error, but will now
succeed and return control to the smart contract.
- If a V0 or V1 smart contract attempted to log more than 64 items,
the call to the `log_event` host function would have returned `0`
to indicate the fact that too many logs were produced. The event
would not be emitted. It will now return `1` and the event will
be recorded in the transaction outcome.
Protocol update instruction
The protocol update instruction is identified by the SHA256 hash of this
file. The instruction needs no auxiliary data.