Repository: ergoplatform/sigma-rust (language: rust)

Issue:
[200 SigmaUSD] Implement `groupGenerator` global var

- Add enum variant `GroupGenerator` to `ergotree-ir::mir::global_vars::GlobalVars`;
- Write serialization roundtrip tests for all `GlobalVars` variants (PBT will be suffice, see `serialization::expr::tests::ser_roundtrip`);
- Add `GlobalGenerator` enum variant handling in `ergotree-interpreter::eval::global_vars`;

Reference Scala version:
IR node and eval - https://github.com/ScorexFoundation/sigmastate-interpreter/blob/b60edae20f2af3352e4064d139d45a15fc507f7d/sigmastate/src/main/scala/sigmastate/Values.scala#L691-L701




Discussion / hints:

Fix patch:
diff --git a/ergotree-interpreter/src/eval/global_vars.rs b/ergotree-interpreter/src/eval/global_vars.rs
index 97540fbc9..28fc0f3b5 100644
--- a/ergotree-interpreter/src/eval/global_vars.rs
+++ b/ergotree-interpreter/src/eval/global_vars.rs
@@ -1,11 +1,12 @@
 use crate::eval::Env;
 use ergotree_ir::mir::global_vars::GlobalVars;
 use ergotree_ir::mir::value::Value;
+use ergotree_ir::serialization::SigmaSerializable;
+use ergotree_ir::sigma_protocol::dlog_group;
 
 use super::EvalContext;
 use super::EvalError;
 use super::Evaluable;
-use ergotree_ir::serialization::SigmaSerializable;
 
 impl Evaluable for GlobalVars {
     fn eval(&self, _env: &Env, ectx: &mut EvalContext) -> Result<Value, EvalError> {
@@ -17,6 +18,7 @@ impl Evaluable for GlobalVars {
             GlobalVars::MinerPubKey => {
                 Ok(ectx.ctx.pre_header.miner_pk.sigma_serialize_bytes().into())
             }
+            GlobalVars::GroupGenerator => Ok(dlog_group::generator().into()),
         }
     }
 }
@@ -31,6 +33,7 @@ mod tests {
     use ergoscript_compiler::compiler::compile_expr;
     use ergoscript_compiler::script_env::ScriptEnv;
     use ergotree_ir::ir_ergo_box::IrBoxId;
+    use ergotree_ir::sigma_protocol::dlog_group::EcPoint;
     use sigma_test_util::force_any_val;
 
     use super::*;
@@ -68,4 +71,13 @@ mod tests {
             ctx.inputs
         );
     }
+
+    #[test]
+    fn eval_group_generator() {
+        let ctx = Rc::new(force_any_val::<Context>());
+        assert_eq!(
+            eval_out::<EcPoint>(&GlobalVars::GroupGenerator.into(), ctx.clone()),
+            dlog_group::generator()
+        );
+    }
 }
diff --git a/ergotree-ir/src/mir/global_vars.rs b/ergotree-ir/src/mir/global_vars.rs
index 20576dc7e..b2b40c196 100644
--- a/ergotree-ir/src/mir/global_vars.rs
+++ b/ergotree-ir/src/mir/global_vars.rs
@@ -17,6 +17,8 @@ pub enum GlobalVars {
     SelfBox,
     /// When interpreted evaluates to a ByteArrayConstant built from Context.minerPubkey
     MinerPubKey,
+    /// GroupElement (EcPoint) generator
+    GroupGenerator,
 }
 
 impl GlobalVars {
@@ -28,6 +30,7 @@ impl GlobalVars {
             GlobalVars::Height => SType::SInt,
             GlobalVars::SelfBox => SType::SBox,
             GlobalVars::MinerPubKey => SType::SColl(Box::new(SType::SByte)),
+            GlobalVars::GroupGenerator => SType::SGroupElement,
         }
     }
 }
@@ -41,6 +44,7 @@ impl HasOpCode for GlobalVars {
             GlobalVars::Outputs => OpCode::OUTPUTS,
             GlobalVars::Height => OpCode::HEIGHT,
             GlobalVars::MinerPubKey => OpCode::MINER_PUBKEY,
+            GlobalVars::GroupGenerator => OpCode::GROUP_GENERATOR,
         }
     }
 }
@@ -62,7 +66,8 @@ mod tests {
                 Just(Outputs),
                 Just(Height),
                 Just(SelfBox),
-                Just(MinerPubKey)
+                Just(MinerPubKey),
+                Just(GroupGenerator)
             ]
             .boxed()
         }
diff --git a/ergotree-ir/src/serialization/expr.rs b/ergotree-ir/src/serialization/expr.rs
index 4c652b99a..41548b353 100644
--- a/ergotree-ir/src/serialization/expr.rs
+++ b/ergotree-ir/src/serialization/expr.rs
@@ -103,6 +103,7 @@ impl Expr {
                 OpCode::INPUTS => Ok(Expr::GlobalVars(GlobalVars::Inputs)),
                 OpCode::OUTPUTS => Ok(Expr::GlobalVars(GlobalVars::Outputs)),
                 OpCode::MINER_PUBKEY => Ok(Expr::GlobalVars(GlobalVars::MinerPubKey)),
+                OpCode::GROUP_GENERATOR => Ok(Expr::GlobalVars(GlobalVars::GroupGenerator)),
                 OpCode::GLOBAL => Ok(Expr::Global),
                 OpCode::PROPERTY_CALL => Ok(Expr::ProperyCall(PropertyCall::sigma_parse(r)?)),
                 OpCode::METHOD_CALL => Ok(Expr::MethodCall(MethodCall::sigma_parse(r)?)),


Test patch: