-
-
Couldn't load subscription status.
- Fork 106
Description
Bug Description
GET operations fail when attempting to cache contracts that implement version-based state validation (like web-container-contract), if the contract is already cached locally with the same version.
Steps to Reproduce
- Publish a contract using web-container-contract (which implements version checking in its
update_state()method) - Contract gets cached locally via PUT operation
- Perform a GET operation for the same contract
- GET retrieves contract from network successfully
- GET attempts to cache it locally via PutQuery
- Fails with:
invalid contract update, reason: New state version X must be higher than current version X
Root Cause
In crates/core/src/operations/get.rs:970-1046, when GET receives a contract from the network, it determines if it should cache locally:
let should_put = if is_original_requester && subscribe_requested {
true
} else {
op_manager.ring.should_seed(&key)
};If caching is needed, it calls PutQuery which triggers the contract's update_state() method. For contracts like web-container-contract that enforce strict version ordering:
if metadata.version <= current_version {
return Err(ContractError::InvalidUpdateWithInfo {
reason: format!(
"New state version {} must be higher than current version {}",
metadata.version, current_version
),
});
}This rejects the update because the network version equals the local cached version.
Error Log
ERROR freenet::server::path_handlers: error getting contract: client error:
error while executing operation in the network: update error for contract U6odK7aUsr9QXM9oQrUMuyUEyqDBzYBsFmYbLcQSwgY,
reason: execution error: invalid contract update, reason:
New state version 29361237 must be higher than current version 29361237
Context
This bug was exposed after PR #1996 fixed state persistence after PUT merge. Previously, the local cache might have been stale, so the version conflict didn't occur as frequently.
Note: "version" is not a Freenet protocol concept - it's implemented by individual contracts (like web-container-contract) in their state and validation logic.
Proposed Solutions
- GET operation check: Before attempting PutQuery, check if local cached state matches network state (skip caching if identical)
- Contract-side fix: Modify contracts to allow idempotent updates (equal versions accepted if state is identical)
- Alternative caching mechanism: GET should use a different method that doesn't trigger
update_state()validation for simple caching
Version
Freenet v0.1.35
Related Issues/PRs
- Contract state not persisted after PUT merge in network mode #1995 - State persistence issue (fixed by fix: persist contract state after PUT merge in upsert_contract_state #1996)
- fix: persist contract state after PUT merge in upsert_contract_state #1996 - Fix persist contract state after PUT merge
Metadata
Metadata
Assignees
Labels
Type
Projects
Status