Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Query contract module #1125

Merged
merged 8 commits into from
Feb 29, 2024
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## Unreleased changes

- Add support for new `invoke` calls from smart contracts in protocol version 7:
- query the contract module reference for a given contract address
- query the contract name for a given contract address

## 6.3.0

- Fix a bug where `GetBlockPendingUpdates` fails to report pending updates to the finalization
Expand Down
84 changes: 83 additions & 1 deletion concordium-consensus/src/Concordium/Scheduler.hs
Original file line number Diff line number Diff line change
Expand Up @@ -1563,6 +1563,87 @@ handleContractUpdateV1 originAddr istance checkAndGetSender transferAmount recei
WasmV1.SignatureCheckFailed
Nothing
)
WasmV1.QueryContractModuleReference{..} -> do
-- Charge for querying the balance of a contract.
tickEnergy Cost.contractInstanceQueryContractModuleReferenceCost
-- Lookup contract balances.
maybeInstanceInfo <- getCurrentContractInstance imqcmrAddress
case maybeInstanceInfo of
Nothing ->
-- The Wasm execution does not reset contract events for queries, hence we do not have to
-- add them here via an interrupt. They will be retained until the next interrupt.
go events
=<< runInterpreter
( return
. WasmV1.resumeReceiveFun
rrdInterruptedConfig
rrdCurrentState
False
entryBalance
(WasmV1.Error $ WasmV1.EnvFailure $ WasmV1.MissingContract imqcmrAddress)
Nothing
)
Just instanceInfo -> do
let modRef = case instanceInfo of
InstanceInfoV0 ii -> GSWasm.miModuleRef $ instanceModuleInterface $ iiParameters ii
InstanceInfoV1 ii -> GSWasm.miModuleRef $ instanceModuleInterface $ iiParameters ii
-- Construct the return value.
let returnValue = WasmV1.byteStringToReturnValue $ S.encode modRef
-- The Wasm execution does not reset contract events for queries, hence we do not have to
-- add them here via an interrupt. They will be retained until the next interrupt.
go events
=<< runInterpreter
( return
. WasmV1.resumeReceiveFun
rrdInterruptedConfig
rrdCurrentState
False
entryBalance
WasmV1.Success
(Just returnValue)
)
WasmV1.QueryContractName{..} -> do
-- Charge for querying the balance of a contract.
tickEnergy Cost.contractInstanceQueryContractNameCost
-- Lookup contract balances.
maybeInstanceInfo <- getCurrentContractInstance imqcnAddress
case maybeInstanceInfo of
Nothing ->
-- The Wasm execution does not reset contract events for queries, hence we do not have to
-- add them here via an interrupt. They will be retained until the next interrupt.
go events
=<< runInterpreter
( return
. WasmV1.resumeReceiveFun
rrdInterruptedConfig
rrdCurrentState
False
entryBalance
(WasmV1.Error $ WasmV1.EnvFailure $ WasmV1.MissingContract imqcnAddress)
Nothing
)
Just instanceInfo -> do
let name = case instanceInfo of
InstanceInfoV0 ii -> instanceInitName $ iiParameters ii
InstanceInfoV1 ii -> instanceInitName $ iiParameters ii
-- Construct the return value.
let returnValue =
WasmV1.byteStringToReturnValue $
GSWasm.initNameBytes name
td202 marked this conversation as resolved.
Show resolved Hide resolved
-- The Wasm execution does not reset contract events for queries, hence we do not have to
-- add them here via an interrupt. They will be retained until the next interrupt.
go events
=<< runInterpreter
( return
. WasmV1.resumeReceiveFun
rrdInterruptedConfig
rrdCurrentState
False
entryBalance
WasmV1.Success
(Just returnValue)
)

-- start contract execution.
-- transfer the amount from the sender to the contract at the start. This is so that the contract may immediately use it
-- for, e.g., forwarding.
Expand All @@ -1578,7 +1659,8 @@ handleContractUpdateV1 originAddr istance checkAndGetSender transferAmount recei
-- Check whether the number of logs and the size of return values are limited in the current protocol version.
rcLimitLogsAndRvs = Wasm.limitLogsAndReturnValues $ protocolVersion @(MPV m),
rcFixRollbacks = demoteProtocolVersion (protocolVersion @(MPV m)) >= P6,
rcSupportAccountSignatureChecks = supportsAccountSignatureChecks $ protocolVersion @(MPV m)
rcSupportAccountSignatureChecks = supportsAccountSignatureChecks $ protocolVersion @(MPV m),
rcSupportContractInspectionQueries = supportsContractInspectionQueries $ protocolVersion @(MPV m)
}
transferAccountSync ::
AccountAddress -> -- The target account address.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,8 @@ foreign import ccall "call_receive_v1"
Word8 ->
-- | Non-zero to enable support for account keys query and signature checks.
Word8 ->
-- | Non-zero to enable support for contract module reference and name queries.
Word8 ->
-- | New state, logs, and actions, if applicable, or null, signalling out-of-energy.
IO (Ptr Word8)

Expand Down Expand Up @@ -424,6 +426,14 @@ data InvokeMethod
QueryAccountKeys
{ imqakAddress :: !AccountAddress
}
| -- | Query the module reference of a contract.
QueryContractModuleReference
{ imqcmrAddress :: !ContractAddress
}
| -- | Query the constructor name of a contract.
QueryContractName
{ imqcnAddress :: !ContractAddress
}

getInvokeMethod :: Get InvokeMethod
getInvokeMethod =
Expand All @@ -436,6 +446,8 @@ getInvokeMethod =
5 -> return QueryExchangeRates
6 -> CheckAccountSignature <$> get <*> getByteStringLen
7 -> QueryAccountKeys <$> get
8 -> QueryContractModuleReference <$> get
9 -> QueryContractName <$> get
n -> fail $ "Unsupported invoke method tag: " ++ show n

-- | Data return from the contract in case of successful initialization.
Expand Down Expand Up @@ -668,7 +680,9 @@ data RuntimeConfig = RuntimeConfig
rcLimitLogsAndRvs :: Bool,
-- | Whether to support account key queries and account signature checks.
-- Supported in P6 onward.
rcSupportAccountSignatureChecks :: Bool
rcSupportAccountSignatureChecks :: Bool,
-- | Whether to support querying smart contract module reference and name.
rcSupportContractInspectionQueries :: Bool
}

-- | Apply a receive function which is assumed to be part of the given module.
Expand Down Expand Up @@ -728,6 +742,7 @@ applyReceiveFun miface cm receiveCtx rName useFallback param amnt initialState R
stateWrittenToPtr
(if rcSupportChainQueries then 1 else 0)
(if rcSupportAccountSignatureChecks then 1 else 0)
(if rcSupportContractInspectionQueries then 1 else 0)
if outPtr == nullPtr
then return (Just (Left Trap, 0)) -- this case should not happen
else do
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,7 @@ data SchedulerResult = SchedulerResult
-- | The total execution energy of the block.
srUsedEnergy :: Types.Energy
}
deriving (Show)

-- | Run the scheduler on transactions in a test environment.
runScheduler ::
Expand Down
Loading
Loading