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.
- #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.
- #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.