All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog and this project adheres to Semantic Versioning.
- 860: Fixed missing fuzzing coverage report in CI.
- #854: Fixed a bug where LDC mode 2 padding bytes would be copied from memory instead of using zeroes.
- #852: Fixed incorrect predicate estimation when max predicate gas is less than max tx gas.
- #849: Add a new mode
2
to the LDC that allows to use the memory as a source for code. - #848: Allow usage of the blob opcode
BSIZ
,BLDD
, andLDC
with mode1
in the predicates. - #838: Implemented
AsRef<[u8]>
andTryFrom<&[u8]>
for DA compression types: ScriptCode, PredicateCode, RegistryKey. - #820: Add fuzzing in CI with ClusterFuzzLite.
- #848: All estimation and verification of predicate functionality is reworked and now requires the instance of the storage with predicates.
- #843: Remove
serde
feature from thefuel-tx
crate. It is default behaviour now if you enablealloc
feature. - #766: Use correct gas price when validating native signatures
- #829: Updated
add_random_fee_input()
to accept anrng
for true randomization. Introducedadd_fee_input()
to retain the previous behavior ofadd_random_fee_input()
. - #845: Removed
Default
implementation ofSecretKey
. - #844:
WDCM
andWQCM
reset$of
and$err
.
- #835: Fixing WASM-NPM packaging and publishing
- #670: Add DA compression functionality to
Transaction
and any types within - #733: Add LibAFL based fuzzer and update
secp256k1
version to 0.29.1. - #825: Avoid leaking partially allocated memory when array deserialization fails
- #824: Use
self
instead of&self
during decompression. - #823: Returned the old behaviour of the json serialization for policies.
- #826: Skip the panic reason from canonical serialization of the panic receipt.
- #821: Added
block_transaction_size_limit
toConsensusParameters
. It adds a newConensusParametersV2
as a variant of theConsensusParameters
. - #670: The
predicate
field offuel_tx::input::Coin
is now a wrapper structPredicateCode
.
- #822: Return recipient as an owner for the message inputs.
- #796: Added implementation of the
MerkleRootStorage
for references.
- #806: Update MSRV to 1.79.0.
- #780: Added
Blob
transaction, andBSIZ
andBLDD
instructions. Also allowsLDC
to load blobs. - #795: Fixed
ed19
instruction to take variable length message instead of a fixed-length one. Changed the gas cost to beDependentCost
.
- #781: Added
base_asset_id
to checked metadata.
- #784: Avoid storage lookups for side nodes in the SMT.
- #787: Fixed charge functions to profile cost before charging.
- #783: Remove unnecessary look up for old values by adding new methods to the
StorageMutate
trait. The oldinsert
andremove
are nowreplace
andtake
. The newinsert
andremove
don't return a value. - #783: Renamed methods of
StorageWrite
trait fromwrite
,replace
,take
towrite_bytes
,replace_bytes
,take_bytes
. - #788: Fix truncating
sp
toMEM_SIZE
ingrow_stack
, and allow empty writes to zero-length ranges at$hp
.
- #789: Avoid conversion into
usize
type and useu32
oru64
instead. The change is breaking since could return other errors for 32-bit systems. - #786: Fixed the CCP opcode to charge for the length from the input arguments.
- #785: Require
ContractCreated
output in theCreate
transaction. TheTransactionBuilder<Create>
has aadd_contract_created
method to simplify the creation of theContractCreated
output for tests.
- #776: Charge for max length in LDC opcode.
- #770: Cache contract inputs in the VM.
-
#768: Charge for LDC opcode before loading the contract into memory.
-
#771: Take into account spent gas during synchronous predicates estimation.
- #769: Use
DependentCost
forCFE
andCFEI
opcodes. - #767: Fixed no zeroing malleable fields for
Create
transaction. - #765: Corrected the gas units for WDOP and WQOP.
- #772: Removed redundant
self.receipts.root()
call.
- #751: Improve test coverage.
- #753: Fix an ownership check bug in
CCP
instruction.
- #748: Make
VmMemoryPool::get_new
async. - #747: Use
DependentCost
foraloc
opcode. The cost of thealoc
opcode is now dependent on the size of the allocation.
- #732: Adds
reset
method to VM memory.
- #732: Makes the VM generic over the memory type, allowing reuse of relatively expensive-to-allocate VM memories through
VmMemoryPool
. Functions and traits which require VM initalization such asestimate_predicates
now take either the memory orVmMemoryPool
as an argument. TheInterpterter::eq
method now only compares accessible memory regions.Memory
was renamed intoMemoryInstance
andMemory
is a trait now.
- #743: Zeroes
$flag
onCALL
, so that contracts can assume clean$flag
state. - #737: Panic on instructions with non-zero reserved part.
- #725: Adds more clippy lints to catch possible integer overflow and casting bugs on compile time.
- #729: Adds more clippy lints to
fuel-merkle
to catch possible integer overflow and casting bugs on compile time. It also does some internal refactoring.
- #725:
UtxoId::from_str
now rejects inputs with multiple0x
prefixes. Many::from_str
implementations also reject extra data in the end of the input, instead of silently ignoring it.UtxoId::from_str
allows a single:
between the fields. UnusedGasUnit
struct removed. - #726: Removed code related to Binary Merkle Sum Trees (BMSTs). The BMST is deprecated and not used in production environments.
- #729: Removed default implementation of
Node::key_size_bits
, implementors must now define it themselves. Also some helper traits have been merged together, or their types changed.
- #736: LDC instruction now works in internal contexts as well. Call frames use code size padded to word alignment.
- #721: Added additional logic to the BMT proof verification algorithm to check the length of the provided proof set against the index provided in the proof.
-
#719: Fix overflow in
LDC
instruction when contract size with padding would overflow. -
#715: The
Interpreter
supports the processing of theUpload
transaction. The change affectsInterpreterStorage
, addingStorageMutate<UploadedBytes>
constrain. -
#714: The change adds a new
Upload
transaction that allows uploading huge byte code on chain subsection by subsection. This transaction is chargeable and is twice as expensive as theCreate
transaction. Anyone can submit this transaction. -
#712: The
Interpreter
supports the processing of theUpgrade
transaction. The change affectsInterpreterStorage
, adding 5 new methods that must be implemented. -
#707: The change adds a new
Upgrade
transaction that allows upgrading either consensus parameters or state transition function used by the network to produce future blocks. The purpose of the upgrade is defined by theUpgrade Purpose
type:pub enum UpgradePurpose { /// The upgrade is performed to change the consensus parameters. ConsensusParameters { /// The index of the witness in the [`Witnesses`] field that contains /// the serialized consensus parameters. witness_index: u16, /// The hash of the serialized consensus parameters. /// Since the serialized consensus parameters live inside witnesses(malleable /// data), any party can override them. The `checksum` is used to verify that the /// data was not modified. checksum: Bytes32, }, /// The upgrade is performed to change the state transition function. StateTransition { /// The Merkle root of the new bytecode of the state transition function. /// The bytecode must be present on the blockchain(should be known by the /// network) at the moment of inclusion of this transaction. root: Bytes32, }, }
The
Upgrade
transaction is chargeable, and the sender should pay for it. Transaction inputs should contain only base assets.Only the privileged address can upgrade the network. The privileged address can be either a real account or a predicate.
Since serialized consensus parameters are small(< 2kb), they can be part of the upgrade transaction and live inside of witness data. The bytecode of the blockchain state transition function is huge ~1.6MB(relative to consensus parameters), and it is impossible to fit it into one transaction. So when we perform the upgrade of the state transition function, it should already be available on the blockchain. The transaction to actually upload the bytecode(
Upload
transaction) will implemented in the FuelLabs/fuel-core#1754.
-
#707: Used the same pattern everywhere in the codebase:
Self::Script(tx) => tx.encode_static(buffer), Self::Create(tx) => tx.encode_static(buffer), Self::Mint(tx) => tx.encode_static(buffer), Self::Upgrade(tx) => tx.encode_static(buffer),
Instead of:
Transaction::Script(script) => script.encode_static(buffer), Transaction::Create(create) => create.encode_static(buffer), Transaction::Mint(mint) => mint.encode_static(buffer), Transaction::Upgrade(upgrade) => upgrade.encode_static(buffer),
-
#714: Added
max_bytecode_subsections
field to theTxParameters
to limit the number of subsections that can be uploaded. -
#707: Side small breaking for tests changes from the
Upgrade
transaction:- Moved
fuel-tx-test-helpers
logic into thefuel_tx::test_helpers
module. - Added a new rule for
Create
transaction: all inputs should use base asset otherwise it returnsTransactionInputContainsNonBaseAssetId
error. - Renamed some errors because now they are used for several transactions(
Upgrade
uses some errors fromCreate
and some fromScript
transactions):TransactionScriptOutputContractCreated
->TransactionOutputContainsContractCreated
.TransactionCreateOutputContract
->TransactionOutputContainsContract
.TransactionCreateOutputVariable
->TransactionOutputContainsVariable
.TransactionCreateOutputChangeNotBaseAsset
->TransactionChangeChangeUsesNotBaseAsset
.TransactionCreateInputContract
->TransactionInputContainsContract
.TransactionCreateMessageData
->TransactionInputContainsMessageData
.
- The combination of
serde
andpostcard
is used to serialize and deserializeConsensusParameters
during the upgrade. This means the protocol and state transition function requires theserde
feature by default forConsensusParameters
andfuel-types
.
- Moved
-
#697: Changed the VM to internally use separate buffers for the stack and the heap to improve startup time. After this change, memory that was never part of the stack or the heap cannot be accessed, even for reading. Also, even if the whole memory is allocated, accesses spanning from the stack to the heap are not allowed. This PR also fixes a bug that required one-byte gap between the stack and the heap. Multiple errors have been changed to be more sensible ones, and sometimes the order of which error is returned has changed.
ALOC
opcode now zeroes the newly allocated memory.
- #705: Added
privileged_address
to theConsensusParameters
for permissioned operations(like upgrade of the network). - #648: Added support for generating proofs for Sparse Merkle Trees (SMTs) and proof verification. Proofs can be used to attest to the inclusion or exclusion of data from the set.
- #709: Removed
bytecode_length
from theCreate
transaction. - #706: Unified
Create
andScript
logic viaChargeableTransaction
. The change is breaking because affects JSON serialization and deserialization. NowScript
andCreate
transactions havebody
fields that include unique transactions. - #703: Reshuffled fields
Script
andCreate
transactions to unify part used by all chargeable transactions. It breaks the serialization and deserialization and requires adoption on the SDK side. - #708: Hidden
Default
params under the "test-helper" feature to avoid accidental use in production code. It is a huge breaking change for any code that has used them before in production, and instead, it should be fetched from the network. In the case of tests simply use the "test-helper" feature in your[dev-dependencies]
section. - #702: Wrapped
FeeParameters
,PredicateParameters
,TxParameters
,ScriptParameters
andContractParameters
into an enum to support versioning. - #701: Wrapped
ConsensusParameters
andGasCosts
into an enum to support versioning. Movedblock_gas_limit
fromfuel_core_chain_config::ChainConfig
toConsensusPataremeters
. Reduced defaultMAX_SIZE
to be 110kb andMAX_CONTRACT_SIZE
to be 100kb. - #692: Add GTF getters for tx size and address.
- #698: Store input, output and witness limits to u16, while keeping the values limited to 255.
- #689: Re-add fields to the checked tx
Metadata
for min and max gas. - #689: Add test helpers and additional getters.
- #686: Implement
serde
forInterpreterError
.
- #685:
The
MaxFee
is a mandatory policy to set. TheMaxFee
policy is used to check that the transaction is valid. Added a new stage for theChecked
transaction -Ready
. This type can be constructed with thegas_price
before being transacted by theInterpreter
. - #671: Support dynamically sized values in the ContractsState table by
using a vector data type (
Vec<u8>
). - #682: Include
Tip
policy in fee calculation - #683: Simplify
InterpreterStorage
by removing dependency onMerkleRootStorage
and removingmerkle_
prefix from method names. - #678: Zero malleable fields before execution. Remove some now-obsolete
GTF getters. Don't update
tx.receiptsRoot
after pushing receipts, and do it after execution instead. - #672: Remove
GasPrice
policy - #672: Add
gas_price
field to transaction execution - #684: Remove
maturity
field fromInput
coin types. Also remove relatedGTF
getter. - #675: Add
GTF
access forasset_id
andto
fields forChange
outputs.
- #679: Require less restricted constraint on
MerkleRootStorage
trait. Now it requiresStorageInspect
instead of theStorageMutate
. - #673: Removed
ContractsInfo
table. Contract salts and roots are no longer stored in on-chain data. - #673: Opcode
CROO
now calculates the given contract's root on demand.CROO
has therefore been changed to aDependentCost
gas cost.
- #672: Add
Tip
policy
- #668: Remove
non_exhaustive
from versionable types for security reasons
- #653:
ECAL
opcode handler can now hold internal state. - #657: Add debugger methods to remove or replace all breakpoints at once.
- #654: Make public types versionable by making non-exhaustive.
- #658: Make
key!
-generated types likeAddress
,AssetId
,ContractId
andBytes32
consume one less byte when serialized with a binary serde serializer like postcard.
- #645: Add wasm support for
fuel-tx
crate.
- #643: Fixed json deserialization of array fuel types from the file.
- #640: Update VM initialization cost to dependent cost; this is required because the time it takes to initialize the VM depends on the size of the transaction.
- #637: Charge for the actual size of the contract in
ccp
opcode.
-
#676 Add
gas_price
toMint
transaction -
#629: Charge the user for VM initialization.
-
#628: Renamed
transaction::CheckError
totransaction::ValidityError
. Created a newchecked_transaction::CheckError
that combinesValidityError
andPredicateVerificationFailed
errors into one. It allows the return of thePredicateVerificationFailed
to the end user instead of losing the reason why predicate verification failed. -
#625: Use
ArithmeticError
only for arithmetic operations, and introduce new errors likeBalanceOverflow
for others. Whenever an error is internally caused by a type conversion tousize
, so that an overflowing value wouldn't map to a valid index anyway, return the missing item error instead. -
#623: Added support for transaction policies. The
Script
andCreate
transactions received a new field,policies
. Policies allow the addition of some limits to the transaction to protect the user or specify some details regarding execution. This change makes theGasPrice
andMaturity
fields optional, allowing to save space in the future. Also, this will enable us to support multidimensional prices later.GasLimit
was renamed toScriptGasLimit
.Along with this change, we introduced two new policies:
WitnessLimit
- allows the limitation of the maximum size of witnesses in bytes for the contract. Because of the changes in the gas calculation model(the blockchain also charges the user for the witness data), the user should protect himself from the block producer or third parties blowing up witness data and draining the user's funds.MaxFee
- allows the upper bound for the maximum fee that users agree to pay for the transaction.
This change brings the following modification to the gas model:
- The
ScriptGasLimit
only limits script execution. Previously, theScriptGasLimit
also limited the predicate execution time, instead predicate gas is now directly included intomin_fee
. So, it is not possible to use theScriptGasLimit
for transaction cost limitations. A newMaxFee
policy is a way to do that. TheGasLimit
field was removed from theCreate
transaction because it only relates to the script execution (which theCreate
transaction doesn't have). - The blockchain charges the user for the size of witness data (before it was free). There is no separate price for
the storage, so it uses gas to charge the user. This change affects
min_gas
andmin_fee
calculation. - A new policy called
WitnessLimit
also impacts themax_gas
andmax_fee
calculation in addition toScriptGasLimit
(in the case ofCreate
transaction onlyWitnessLimit
affects themax_gas
andmax_fee
). - The minimal gas also charges the user for transaction ID calculation.
The change has the following modification to the transaction layout:
- The
Create
transaction doesn't have theScriptGasLimit
field anymore. Because theCreate
transaction doesn't have any script to execute - The
Create
andScript
transactions don't have explicitmaturity
andgas_price
fields. Instead, these fields can be set via a newpolicies
field. - The
Create
andScript
transactions have a newpolicies
field with a unique canonical serialization and deserialization for optimal space consumption.
Other breaking changes caused by the change:
- Each transaction requires setting the
GasPrice
policy. - Previously,
ScriptGasLimit
should be less than theMAX_GAS_PER_TX
constant. After removing this field from theCreate
transaction, it is impossible to require it. Instead, it requires thatmax_gas <= MAX_GAS_PER_TX
for any transaction. Consequently, anyScript
transaction that usesMAX_GAS_PER_TX
as aScriptGasLimit
will always fail because of a new rule. Setting the estimated gas usage instead solves the problem. - If the
max_fee > policies.max_fee
, then transaction will be rejected. - If the
witnessses_size > policies.witness_limit
, then transaction will be rejected. - GTF opcode changed its hardcoded constants for fields. It should be updated according to the values from the specification on the Sway side.
-
#633: Limit receipt count to
u16::MAX
. -
#634: Charge for storage per new byte written. Write opcodes now return the number of new storage slots created, instead of just a boolean on whether the value existed before.
- #627: Added removal of obsolete SMT nodes along the path
during
update
anddelete
operations.
- #622: Divide
DependentCost
into "light" and "heavy" operations: Light operations consume0 < x < 1
gas per unit, while heavy operations consumex
gas per unit. This distinction provides more precision when calculating dependent costs.
- #607: Added
ECAL
instruction support.
- #612: Reduced the memory consumption in all places where we calculate BMT root.
- #615: Made
ReceiptsCtx
of the VM modifiable withtest-helpers
feature.
- #618: Transaction fees for
Create
now include the cost of metadata calculations, including: contract root calculation, state root calculation, and contract id calculation. - #613: Transaction fees now include the cost of signature verification for each input. For signed inputs, the cost of an EC recovery is charged. For predicate inputs, the cost of a BMT root of bytecode is charged.
- #607: The
Interpreter
expects the third generic argument during type definition that specifies the implementer of theEcalHandler
trait forecal
opcode. - #609: Checked transactions (
Create
,Script
, andMint
) now enforce a maximum size. The maximum size is specified byMAX_TRANSACTION_SIZE
in the transaction parameters, under consensus parameters. Checking a transaction above this size raisesCheckError::TransactionSizeLimitExceeded
. - #617: Makes memory outside
$is..$ssp
range not executable. SeparatesErrorFlag
intoInvalidFlags
,MemoryNotExecutable
andInvalidInstruction
. Fixes related tests. - #619: Avoid possible truncation of higher bits. It may invalidate the code that truncated higher bits causing different behavior on 32-bit vs. 64-bit systems.
- #603: Added
MerkleRootCalculator
for efficient in-memory Merkle root calculation. - #603: Added Serialization and Deserialization support
to
MerkleRootCalculator
.
- #595: Removed
wee_alloc
dependency fromfuel-asm
. It now uses the builtin allocator on web targets as well.
- #598: Update cost model for
ldc
opcode to take into account contract size. - #604: Removed
ChainId
fromPredicateId
calculation. It changes the generated address of the predicates and may break tests or logic that uses hard-coded predicate IDs. - #594: Add new predicate input validation tests. Also improves error propagation so that predicate error message better reflects the reason for invalidity.
- #596: Remove
core::ops::{Add, Sub}
impls fromBlockHeight
. Usesucc
andpred
to access adjacent blocks, or perform arithmetic directly on the wrapped integer instead. - #593: Reworked
Mint
transaction to work withInput::Contract
andOutput::Contract
instead ofOutput::Coin
. It allows account-based fee collection for the block producer.
- #586: Added
default_asset
method to theContractIdExt
trait implementation, to mirror thedefault
method on AssetId in the Sway std lib.
- #578: Support
no_std
environments forfuel-crypto
, falling back to a pure-Rust crypto implementation. - #582: Make
fuel-vm
andfuel-tx
crates compatible withno_std
+alloc
. This includes reworking all error handling that usedstd::io::Error
, replacing somestd::collection::{HashMap, HashSet}
withhashbrown::{HashMap, HashSet}
and many changes to feature-gating of APIs. - #587: Replace
thiserror
dependency withderive_more
, so thatcore::fmt::Display
is implemented without thestd
feature. Removesstd::io::Error
trait impls from the affected types. - #588: Re-worked the size calculation of the canonical serialization/deserialization.
- #700: Add
BASE_ASSET_ID
toGM
instruction.
- #588: Removed
SerializedSize
andSerializedFixedSize
traits. Removed support forSIZE_NO_DYNAMIC
andSIZE_STATIC
. Removed enum attributes from derive macro forSerialize
andDeserialize
traits.
- #573: Added
base_asset_id
as a required field toFeeParameters
.base_asset_id
is used to supply the ID of the base asset. - #554: Removed
debug
feature from thefuel-vm
. The debugger is always available and becomes active after calling anyset_*
method. - #537: Use dependent cost for
k256
,s256
,mcpi
,scwq
,swwq
opcodes. These opcodes charged inadequately low costs in comparison to the amount of work. This change should make all transactions that used these opcodes much more expensive than before. - #533: Use custom serialization for fuel-types to allow no_std compilation.
- #546: Improve debug formatting of instruction in panic receipts.
- #574: Enforce fixed 32-byte input length for LHS and RHS inputs to the BMT's internal node sum.
- #547: Bump
ed25519-dalek
to2.0.0
to deal with RustSec Advisory.
- #524: Fix a crash in
CCP
instruction when overflowing contract bounds. Fix a bug inCCP
where overflowing contract bounds in a different way would not actually copy the contract bytes, but just zeroes out the section. Fix a bug inLDC
where it would revert the transaction when the contract bounds were exceeded, when it's just supposed to fill the rest of the bytes with zeroes.
- #525: The
$hp
register is no longer restored to it's previous value when returning from a call, making it possible to return heap-allocated types fromCALL
. - #535: Add better test coverage for TR and TRO.
- #514: Add
ChainId
andGasCosts
toConsensusParameters
. Break downConsensusParameters
into sub-structs to match usage. Change signatures of functions to ask for necessary fields only. - #532: The
TRO
instruction now reverts when attempting to send zero coins to an output. Panic reason of thisTransferZeroCoins
, andTR
was changed to use the same panic reason as well.
-
#511: Changes multiple panic reasons to be more accurate, and internally refactors instruction fetch logic to be less error-prone.
-
#529 #534: Enforcing async WASM initialization for all NPM wrapper packages.
-
#531: UtxoId::from_str and TxPointer::from_str no longer crash on invalid input with multibyte characters. Also adds clippy lints to prevent future issues.
- #527: The balances are empty during predicate estimation/verification.
- #542: Make the
fuel-tx
WASM compatible withserde
feature enabled.
- #539: Rollbacked the change for the gas charging formula. Actualized the gas prices for opcodes.
- #499: The
wasm_bindgen
support offuel-asm
andfuel-types
. Each new release also publish a typescript analog of thefuel-asm
andfuel-types
crates to the npm.
The release mostly fixes funding during the audit and integration with the bridge. But the release also contains some new features like:
- Asynchronous predicate estimation/verification.
- Multi-asset support per contract.
- Support Secp256r1 signature recovery and Ed25519 verificaiton.
-
#486: Adds
ed25519
signature verification andsecp256r1
signature recovery tofuel-crypto
, and corresponding opcodesED19
andECR1
tofuel-vm
. -
#486: Adds
PSHL
,PSHH
,POPH
andPOPL
instructions, which allow cheap push and pop stack operations with multiple registers. -
#500: Introduced
ParallelExecutor
trait and made available async versions of verify and estimate predicates. Updated tests to test for both parallel and sequential execution. Fixed a bug intransaction/check_predicate_owners
.
- #506: Added new
Mint
andBurn
variants toReceipt
enum. It affects serialization and deserialization with new variants.
-
#506: The
mint
andburn
opcodes accept a new$rB
register. It is a sub-identifier used to generate anAssetId
by this rule. This feature allows having multi-asset per one contract. It is a huge breaking change, and after this point,ContractId
can't be equal toAssetId
.The conversion like
AssetId::from(*contract_id)
is no longer valid. Instead, theContractId
implements theContractIdExt
trait:/// Trait extends the functionality of the `ContractId` type. pub trait ContractIdExt { /// Creates an `AssetId` from the `ContractId` and `sub_id`. fn asset_id(&self, sub_id: &Bytes32) -> AssetId; }
-
#506: The
mint
andburn
opcodes affect thereceipts_root
of theScript
transaction.
- #486: Removes apparently unused
Keystore
andSigner
traits fromfuel-crypto
. Also renamesECR
opcode toECK1
.
- #500: Fixed a bug where
MessageCoinPredicate
wasn't checked for incheck_predicate_owners
.
-
#502: The algorithm used by the binary Merkle tree for generating Merkle proofs has been updated to remove the leaf data from the proof set. This change allows BMT proofs to conform to the format expected by the Solidity contracts used for verifying proofs.
-
#503: Use correct amount of gas in call receipts when limited by cgas. Before this change, the
Receipt::Call
could show an incorrect value for the gas limit. -
#504: The
CROO
andCSIZ
opcodes require the existence of correspondingContractId
in the transaction's inputs(the same behavior as for theCROO
opcode). -
#504: The size of the contract was incorrectly padded. It affects the end of the call frame in the memory, making it not 8 bytes align. Also, it affects the cost of the contract call(in some cases, we charged less in some more).
-
#504: The charging for
DependentCost
was done incorrectly, devaluing thedep_per_unit
part. After the fixing of this, the execution should become much more expensive. -
#505: The
data
field of theReceipt
is not part of the canonical serialization and deserialization anymore. The SDK should use theReceipt
type instead ofOpaqueReceipt
. TheReceipt.raw_payload
will be removed for thefuel-core 0.20
. Thedata
field is optional now. The SDK should update serialization and deserialization forMessageOut
,LogData
, andReturnData
receipts. -
#505: The
len
field of theReceipt
is not padded anymore and represents an initial value.
Mainly new opcodes prices and small performance improvements in the BinaryMerkleTree
.
- #492: Minor improvements to BMT
internals, including a reduction in usage of
Box
, usingexpect(...)
overunwrap()
, and additional comments.
- #493: The default
GasCostsValues
is updated according to the benches withfuel-core 0.19
. It may break some unit tests that compare actual gas usage with expected.
This release contains fixes for critical issues that we found before the audit. Mainly, these changes pertain to the Sparse Merkle Tree (SMT) and related code. The SMT API was extended to provide more flexibility and to allow users to select the most appropriate method for their performance needs. Where possible, sequential SMT updates were replaced with constructors that take in a complete data set.
-
#476: The
fuel_vm::Call
supportsFrom<[u8; Self::LEN]>
andInto<[u8; Self::LEN]>
. -
#484: The
sparse::in_memory::MerkleTree
got new methodsfrom_set
,root_from_set
, andnodes_from_set
methods. These methods allow a more optimal way to build and calculate the SMT when you know all leaves. TheContract::initial_state_root
is much faster now (by ~15 times).
- #478: The
CheckedMemRange
is replaced by theMemoryRange
.
-
#477: The
PanicReason::UnknownPanicReason
is0x00
. ThePanicReason
now implementsFrom<u8>
instead ofTryFrom<u8>
and can't return an error anymore. -
#478: The
memcopy
method is updated and returnsMemoryWriteOverlap
instead ofMemoryOverflow
.
-
#482: This PR address a security issue where updates to a Sparse Merkle Tree could deliberately overwrite existing leaves by setting the leaf key to the hash of an existing leaf or node. This is done by removing the insertion of the leaf using the leaf key.
-
#484: Fixed bug with not-working
CreateMetadata
.
-
#473: CFS and CFSI were not validating that the new
$sp
value isn't below$ssp
, allowing write access to non-owned memory. This is now fixed, and attempting to set an incorrect$sp
value panics. -
#485: This PR addresses a security issue where the user may manipulate the structure of the Sparse Merkle Tree. SMT expects hashed storage key wrapped into a
MerkleTreeKey
structure. The change is breaking because it changes thestate_root
generated by the SMT and may change theContractId
if theCreate
transaction has non-emptyStoargeSlot
s.
The release contains a lot of breaking changes. Most of them are audit blockers and affect the protocol itself. Starting this release we plan to maintain the changelog file and describe all minor and major changes that make sense.
-
#386: The coin and message inputs got a new field -
predicate_gas_used
. So it breaks the constructor API of these inputs.The value of this field is zero for non-predicate inputs, but for the predicates, it indicates the exact amount of gas used by the predicate to execute. If after the execution of the predicate remaining gas is not zero, then the predicate execution failed.
This field is malleable but will be used by the VM, and each predicate should be estimated before performing the verification logic. The
Transaction
,Create
, andScript
types implement theEstimatePredicates
for these purposes./// Provides predicate estimation functionality for the transaction. pub trait EstimatePredicates: Sized { /// Estimates predicates of the transaction. fn estimate_predicates(&mut self, params: &ConsensusParameters, gas_costs: &GasCosts) -> Result<(), CheckError>; }
During the creation of the
Input
, the best strategy is to use a default value like0
and call theestimate_predicates
method to actualize thepredicate_gas_used
after. -
#454: VM native array-backed types
Address
,AssetId
,ContractId
,Bytes4
,Bytes8
,Bytes20
,Bytes32
,Nonce
,MessageId
,Salt
now use more compact representation instead of hex-encoded string when serialized using serde format that setsis_human_readable
to false. -
#456: Added a new type -
ChainId
to represent the identifier of the chain. It is a wrapper around theu64
, so anyu64
can be converted into this type via.into()
orChainId::new(...)
. -
#459 Require witness index to be specified when adding an unsigned coin to a transaction. This allows for better reuse of witness data when using the transaction builder and helper methods to make transactions compact.
-
#462: Adds a
cache
parameter toInput::check
andInput::check_signature
. This is used to avoid redundant signature recovery when multiple inputs share the same witness index.
- #458: Automatically sort storage slots for creation transactions.
-
#386: Several methods of the
TransactionFee
are renamedtotal
->max_fee
andbytes
->min_fee
. TheTransactionFee::min_fee
take into account the gas used by predicates. -
#450: The Merkle root of a contract's code is now calculated by partitioning the code into chunks of 16 KiB, instead of 8 bytes. If the last leaf is does not a full 16 KiB, it is padded with
0
up to the nearest multiple of 8 bytes. This affects theContractId
andPredicateId
calculations, breaking all code that used hardcoded values. -
#456: The basic methods
UniqueIdentifier::id
,Signable::sign_inputs
, andInput::predicate_owner
useChainId
instead of theConsensusParameters
. It is a less strict requirement than before because you can getChainId
fromConsensusParameters.chain_id
, and it makes the API cleaner. It affects all downstream functions that use listed methods. -
#463: Moves verification that the
Output::ContractCreated
output contains validcontract_id
andstate_root
(the values from theOutput
match with calculated values from the bytecode, storage slots, and salt) fromfuel-vm
tofuel-tx
. It means the end-user will receive this error earlier on the SDK side beforedry_run
instead of after.
-
#457: Transactions got one more validity rule: Each
Script
orCreate
transaction requires at least one input coin or message to be spendable. It may break code/tests that previously didn't set any spendable inputs. Note:Message
with non-emptydata
field is not spendable. -
#458: The storage slots with the same key inside the
Create
transaction are forbidden.