gear_core/message/
init.rs

1// This file is part of Gear.
2
3// Copyright (C) 2022-2025 Gear Technologies Inc.
4// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
5
6// This program is free software: you can redistribute it and/or modify
7// it under the terms of the GNU General Public License as published by
8// the Free Software Foundation, either version 3 of the License, or
9// (at your option) any later version.
10
11// This program is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15
16// You should have received a copy of the GNU General Public License
17// along with this program. If not, see <https://www.gnu.org/licenses/>.
18
19use crate::{
20    buffer::Payload,
21    ids::{ActorId, CodeId, MessageId, prelude::*},
22    message::{
23        Dispatch, DispatchKind, GasLimit, Message, Packet, Salt, StoredDispatch, StoredMessage,
24        Value,
25    },
26};
27
28/// Message for Init entry point.
29/// Used to initiate a newly created program.
30#[derive(Clone, Debug, PartialEq, Eq)]
31pub struct InitMessage {
32    /// Message id.
33    id: MessageId,
34    /// Message destination.
35    destination: ActorId,
36    /// Message payload.
37    payload: Payload,
38    /// Message optional gas limit.
39    gas_limit: Option<GasLimit>,
40    /// Message value.
41    value: Value,
42}
43
44impl InitMessage {
45    /// Create InitMessage from InitPacket.
46    pub fn from_packet(id: MessageId, packet: InitPacket) -> Self {
47        Self {
48            id,
49            destination: packet.program_id,
50            payload: packet.payload,
51            gas_limit: packet.gas_limit,
52            value: packet.value,
53        }
54    }
55
56    /// Convert InitMessage into Message.
57    pub fn into_message(self, source: ActorId) -> Message {
58        Message::new(
59            self.id,
60            source,
61            self.destination,
62            self.payload,
63            self.gas_limit,
64            self.value,
65            None,
66        )
67    }
68
69    /// Convert InitMessage into StoredMessage.
70    pub fn into_stored(self, source: ActorId) -> StoredMessage {
71        self.into_message(source).into_stored()
72    }
73
74    /// Convert InitMessage into Dispatch.
75    pub fn into_dispatch(self, source: ActorId) -> Dispatch {
76        Dispatch::new(DispatchKind::Init, self.into_message(source))
77    }
78
79    /// Convert InitMessage into StoredDispatch.
80    pub fn into_stored_dispatch(self, source: ActorId) -> StoredDispatch {
81        self.into_dispatch(source).into_stored()
82    }
83
84    /// Message id.
85    pub fn id(&self) -> MessageId {
86        self.id
87    }
88
89    /// Message destination.
90    pub fn destination(&self) -> ActorId {
91        self.destination
92    }
93
94    /// Message payload bytes.
95    pub fn payload_bytes(&self) -> &[u8] {
96        &self.payload
97    }
98
99    /// Message optional gas limit.
100    pub fn gas_limit(&self) -> Option<GasLimit> {
101        self.gas_limit
102    }
103
104    /// Message value.
105    pub fn value(&self) -> Value {
106        self.value
107    }
108}
109
110// TODO: #issue 3320
111/// Init message packet.
112///
113/// This structure is preparation for future init message sending. Has no message id.
114#[derive(Clone, Debug, PartialEq, Eq)]
115#[cfg_attr(any(feature = "mock", test), derive(Default))]
116pub struct InitPacket {
117    /// Newly created program id.
118    program_id: ActorId,
119    /// Code id.
120    code_id: CodeId,
121    /// Salt.
122    salt: Salt,
123    /// Message payload.
124    payload: Payload,
125    /// Message optional gas limit.
126    gas_limit: Option<GasLimit>,
127    /// Message value.
128    value: Value,
129}
130
131impl InitPacket {
132    /// Create new InitPacket via user.
133    pub fn new_from_user(
134        code_id: CodeId,
135        salt: Salt,
136        payload: Payload,
137        gas_limit: GasLimit,
138        value: Value,
139    ) -> Self {
140        Self {
141            program_id: ActorId::generate_from_user(code_id, &salt),
142            code_id,
143            salt,
144            payload,
145            gas_limit: Some(gas_limit),
146            value,
147        }
148    }
149
150    /// Create new InitPacket via program.
151    pub fn new_from_program(
152        code_id: CodeId,
153        salt: Salt,
154        payload: Payload,
155        message_id: MessageId,
156        gas_limit: Option<GasLimit>,
157        value: Value,
158    ) -> Self {
159        Self {
160            program_id: ActorId::generate_from_program(message_id, code_id, &salt),
161            code_id,
162            salt,
163            payload,
164            gas_limit,
165            value,
166        }
167    }
168
169    /// Packet destination (newly created program id).
170    pub fn destination(&self) -> ActorId {
171        self.program_id
172    }
173
174    /// Code id.
175    pub fn code_id(&self) -> CodeId {
176        self.code_id
177    }
178
179    /// Salt.
180    pub fn salt(&self) -> &[u8] {
181        &self.salt
182    }
183}
184
185impl Packet for InitPacket {
186    fn payload_bytes(&self) -> &[u8] {
187        &self.payload
188    }
189
190    fn payload_len(&self) -> u32 {
191        self.payload.len_u32()
192    }
193
194    fn gas_limit(&self) -> Option<GasLimit> {
195        self.gas_limit
196    }
197
198    fn value(&self) -> Value {
199        self.value
200    }
201
202    fn kind() -> DispatchKind {
203        DispatchKind::Init
204    }
205}