Skip to content

Commit f9adcf4

Browse files
authored
Merge pull request #2993 from ProvableHQ/feat/finalize-timestamp
[Feature] Add `block.timestamp` operand to finalize
2 parents 6ef4e61 + d47040b commit f9adcf4

File tree

28 files changed

+270
-42
lines changed

28 files changed

+270
-42
lines changed

ledger/src/advance.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,10 +345,14 @@ impl<N: Network, C: ConsensusStorage<N>> Ledger<N, C> {
345345
latest_coinbase_target,
346346
)?;
347347

348+
// Determine if the block timestamp should be included.
349+
let next_block_timestamp =
350+
(next_height >= N::CONSENSUS_HEIGHT(ConsensusVersion::V12).unwrap_or_default()).then_some(next_timestamp);
348351
// Construct the finalize state.
349352
let state = FinalizeGlobalState::new::<N>(
350353
next_round,
351354
next_height,
355+
next_block_timestamp,
352356
next_cumulative_weight,
353357
next_cumulative_proof_target,
354358
previous_block.hash(),

ledger/src/check_next_block.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,14 @@ impl<N: Network, C: ConsensusStorage<N>> Ledger<N, C> {
4242
}
4343
}
4444

45+
// Determine if the block timestamp should be included.
46+
let block_timestamp = (block.height() >= N::CONSENSUS_HEIGHT(ConsensusVersion::V12).unwrap_or_default())
47+
.then_some(block.timestamp());
4548
// Construct the finalize state.
4649
let state = FinalizeGlobalState::new::<N>(
4750
block.round(),
4851
block.height(),
52+
block_timestamp,
4953
block.cumulative_weight(),
5054
block.cumulative_proof_target(),
5155
block.previous_hash(),

synthesizer/process/src/stack/evaluate.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,8 @@ impl<N: Network> Stack<N> {
8383
Operand::Caller => Ok(Value::Plaintext(Plaintext::from(Literal::Address(registers.caller()?)))),
8484
// If the operand is the block height, throw an error.
8585
Operand::BlockHeight => bail!("Cannot retrieve the block height from a closure scope."),
86+
// If the operand is the block timestamp, throw an error.
87+
Operand::BlockTimestamp => bail!("Cannot retrieve the block timestamp from a closure scope."),
8688
// If the operand is the network id, throw an error.
8789
Operand::NetworkID => bail!("Cannot retrieve the network ID from a closure scope."),
8890
// If the operand is the program checksum, throw an error.
@@ -237,6 +239,8 @@ impl<N: Network> Stack<N> {
237239
Operand::Caller => Ok(Value::Plaintext(Plaintext::from(Literal::Address(registers.caller()?)))),
238240
// If the operand is the block height, throw an error.
239241
Operand::BlockHeight => bail!("Cannot retrieve the block height from a function scope."),
242+
// If the operand is the block timestamp, throw an error.
243+
Operand::BlockTimestamp => bail!("Cannot retrieve the block timestamp from a function scope."),
240244
// If the operand is the network id, throw an error.
241245
Operand::NetworkID => bail!("Cannot retrieve the network ID from a function scope."),
242246
// If the operand is the program checksum, throw an error.

synthesizer/process/src/stack/execute.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,10 @@ impl<N: Network> Stack<N> {
115115
Operand::BlockHeight => {
116116
bail!("Illegal operation: cannot retrieve the block height in a closure scope")
117117
}
118+
// If the operand is the block timestamp, throw an error.
119+
Operand::BlockTimestamp => {
120+
bail!("Illegal operation: cannot retrieve the block timestamp in a closure scope")
121+
}
118122
// If the operand is the network id, throw an error.
119123
Operand::NetworkID => {
120124
bail!("Illegal operation: cannot retrieve the network id in a closure scope")
@@ -365,6 +369,10 @@ impl<N: Network> Stack<N> {
365369
Operand::BlockHeight => {
366370
bail!("Illegal operation: cannot retrieve the block height in a function scope")
367371
}
372+
// If the operand is the block timestamp, throw an error.
373+
Operand::BlockTimestamp => {
374+
bail!("Illegal operation: cannot retrieve the block timestamp in a function scope")
375+
}
368376
// If the operand is the network id, throw an error.
369377
Operand::NetworkID => {
370378
bail!("Illegal operation: cannot retrieve the network id in a function scope")

synthesizer/process/src/stack/finalize_registers/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use crate::FinalizeTypes;
1919
use console::{
2020
network::prelude::*,
2121
program::{Identifier, Literal, Plaintext, Register, Value},
22-
types::{U16, U32},
22+
types::{I64, U16, U32},
2323
};
2424
use snarkvm_synthesizer_program::{FinalizeGlobalState, FinalizeRegistersState, Operand, RegistersTrait, StackTrait};
2525

synthesizer/process/src/stack/finalize_registers/registers_trait.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,13 @@ impl<N: Network> RegistersTrait<N> for FinalizeRegisters<N> {
4141
Operand::BlockHeight => {
4242
return Ok(Value::Plaintext(Plaintext::from(Literal::U32(U32::new(self.state.block_height())))));
4343
}
44+
// If the operand is the block timestamp, load the block timestamp.
45+
Operand::BlockTimestamp => match self.state.block_timestamp() {
46+
Some(timestamp) => {
47+
return Ok(Value::Plaintext(Plaintext::from(Literal::I64(I64::new(timestamp)))));
48+
}
49+
None => bail!("The block timestamp is not available until ConsensusVersion::V12"),
50+
},
4451
// If the operand is the network ID, load the network ID.
4552
Operand::NetworkID => {
4653
return Ok(Value::Plaintext(Plaintext::from(Literal::U16(U16::new(N::ID)))));

synthesizer/process/src/stack/finalize_types/matches.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,10 @@ impl<N: Network> FinalizeTypes<N> {
6464
"Struct member '{struct_name}.{member_name}' expects {member_type}, but found '{plaintext_type}' in the operand '{operand}'.",
6565
)
6666
}
67-
// Ensure the program ID, block height, network ID, checksum, edition, and program owner types matches the member type.
67+
// Ensure the program ID, block height, block timestamp, network ID, checksum, edition, and program owner types matches the member type.
6868
Operand::ProgramID(..)
6969
| Operand::BlockHeight
70+
| Operand::BlockTimestamp
7071
| Operand::NetworkID
7172
| Operand::Checksum(_)
7273
| Operand::Edition(_)
@@ -144,6 +145,7 @@ impl<N: Network> FinalizeTypes<N> {
144145
// Ensure the program ID, block height, network ID, checksum, edition, and program owner types matches the element type.
145146
Operand::ProgramID(..)
146147
| Operand::BlockHeight
148+
| Operand::BlockTimestamp
147149
| Operand::NetworkID
148150
| Operand::Checksum(_)
149151
| Operand::Edition(_)

synthesizer/process/src/stack/finalize_types/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ impl<N: Network> FinalizeTypes<N> {
106106
Operand::Signer => bail!("'self.signer' is not a valid operand in a finalize context."),
107107
Operand::Caller => bail!("'self.caller' is not a valid operand in a finalize context."),
108108
Operand::BlockHeight => FinalizeType::Plaintext(PlaintextType::Literal(LiteralType::U32)),
109+
Operand::BlockTimestamp => FinalizeType::Plaintext(PlaintextType::Literal(LiteralType::I64)),
109110
Operand::NetworkID => FinalizeType::Plaintext(PlaintextType::Literal(LiteralType::U16)),
110111
Operand::Checksum(_) => FinalizeType::Plaintext(PlaintextType::Array(ArrayType::new(
111112
PlaintextType::Literal(LiteralType::U8),

synthesizer/process/src/stack/register_types/matches.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,10 @@ impl<N: Network> RegisterTypes<N> {
8888
Operand::BlockHeight => bail!(
8989
"Struct member '{struct_name}.{member_name}' cannot be from a block height in a non-finalize scope"
9090
),
91+
// If the operand is a block timestamp type, throw an error.
92+
Operand::BlockTimestamp => bail!(
93+
"Struct member '{struct_name}.{member_name}' cannot be from a block timestamp in a non-finalize scope"
94+
),
9195
// If the operand is a network ID type, throw an error.
9296
Operand::NetworkID => bail!(
9397
"Struct member '{struct_name}.{member_name}' cannot be from a network ID in a non-finalize scope"
@@ -181,6 +185,10 @@ impl<N: Network> RegisterTypes<N> {
181185
}
182186
// If the operand is a block height type, throw an error.
183187
Operand::BlockHeight => bail!("Array element cannot be from a block height in a non-finalize scope"),
188+
// If the operand is a block timestamp type, throw an error.
189+
Operand::BlockTimestamp => {
190+
bail!("Array element cannot be from a block timestamp in a non-finalize scope")
191+
}
184192
// If the operand is a network ID type, throw an error.
185193
Operand::NetworkID => bail!("Array element cannot be from a network ID in a non-finalize scope"),
186194
// If the operand is a checksum type, throw an error.
@@ -252,6 +260,9 @@ impl<N: Network> RegisterTypes<N> {
252260
Operand::BlockHeight => {
253261
bail!("Forbidden operation: Cannot cast a block height as a record owner")
254262
}
263+
Operand::BlockTimestamp => {
264+
bail!("Forbidden operation: Cannot cast a block timestamp as a record owner")
265+
}
255266
Operand::NetworkID => {
256267
bail!("Forbidden operation: Cannot cast a network ID as a record owner")
257268
}
@@ -324,6 +335,12 @@ impl<N: Network> RegisterTypes<N> {
324335
"Record entry '{record_name}.{entry_name}' expects a '{plaintext_type}', but found a block height in the operand '{operand}'."
325336
)
326337
}
338+
// Fail if the operand is a block timestamp.
339+
Operand::BlockTimestamp => {
340+
bail!(
341+
"Record entry '{record_name}.{entry_name}' expects a '{plaintext_type}', but found a block timestamp in the operand '{operand}'."
342+
)
343+
}
327344
// Fail if the operand is a network ID.
328345
Operand::NetworkID => {
329346
bail!(

synthesizer/process/src/stack/register_types/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,9 @@ impl<N: Network> RegisterTypes<N> {
9797
RegisterType::Plaintext(PlaintextType::Literal(LiteralType::Address))
9898
}
9999
Operand::BlockHeight => bail!("'block.height' is not a valid operand in a non-finalize context."),
100+
Operand::BlockTimestamp => {
101+
bail!("'block.timestamp' is not a valid operand in a non-finalize context.")
102+
}
100103
Operand::NetworkID => bail!("'network.id' is not a valid operand in a non-finalize context."),
101104
Operand::Checksum(_) => bail!("'checksum' is not a valid operand in a non-finalize context."),
102105
Operand::Edition(_) => bail!("'edition' is not a valid operand in a non-finalize context."),

0 commit comments

Comments
 (0)