Skip to content

Commit

Permalink
Add event to veto and dissolve hooks (#6)
Browse files Browse the repository at this point in the history
* add events

* add tests

* Update astra/src/events.rs

Co-authored-by: Robert Zaremba <robert@zaremba.ch>

---------

Co-authored-by: Robert Zaremba <robert@zaremba.ch>
  • Loading branch information
amityadav0 and robert-zaremba authored Sep 21, 2023
1 parent c5fac1d commit bf7b322
Show file tree
Hide file tree
Showing 8 changed files with 165 additions and 3 deletions.
15 changes: 13 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions astra/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ crate-type = ["cdylib", "rlib"]
near-sdk.workspace = true
near-contract-standards.workspace = true
hex.workspace = true
serde_json.workspace = true

common = { path = "../common" }

[dependencies.serde_with]
version = "1.4.0"
Expand Down
44 changes: 44 additions & 0 deletions astra/src/events.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
use near_sdk::serde::Serialize;
use serde_json::json;

use common::{EventPayload, NearEvent};

fn emit_event<T: Serialize>(event: EventPayload<T>) {
NearEvent {
standard: "astra++",
version: "1.0.0",
event,
}
.emit();
}

pub(crate) fn emit_veto(prop_id: u64) {
emit_event(EventPayload {
event: "veto",
data: json!({ "prop_id": prop_id }),
});
}

pub(crate) fn emit_dissolve() {
emit_event(EventPayload {
event: "dissolve",
data: "",
})
}

#[cfg(test)]
mod unit_tests {
use near_sdk::{test_utils};

use super::*;

#[test]
fn log_hooks() {
let expected1 = r#"EVENT_JSON:{"standard":"astra++","version":"1.0.0","event":"veto","data":{"prop_id":21}}"#;
let expected2 = r#"EVENT_JSON:{"standard":"astra++","version":"1.0.0","event":"dissolve","data":"dao is dissolved"}"#;
emit_veto(21);
assert_eq!(vec![expected1], test_utils::get_logs());
emit_dissolve();
assert_eq!(vec![expected1, expected2], test_utils::get_logs());
}
}
13 changes: 12 additions & 1 deletion astra/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,15 @@ pub use crate::proposals::{Proposal, ProposalInput, ProposalKind, ProposalStatus
pub use crate::types::{Action, Config, OldAccountId, OLD_BASE_TOKEN};
use crate::upgrade::{internal_get_factory_info, internal_set_factory_info, FactoryInfo};
pub use crate::views::{BountyOutput, ProposalOutput};
use events::{emit_dissolve, emit_veto};

mod bounties;
mod delegation;
mod policy;
mod proposals;
mod types;
mod upgrade;
mod events;
pub mod views;
#[cfg(test)]
pub mod test_utils;
Expand Down Expand Up @@ -171,6 +173,7 @@ impl Contract {
panic!("Proposal finalized");
}
}
emit_veto(id)
}

/// Dissolves the DAO by removing all members, closing all active proposals and returning bonds.
Expand All @@ -190,6 +193,7 @@ impl Contract {

let funds = env::account_balance() - self.locked_amount;
Promise::new(self.trust.clone()).transfer(funds);
emit_dissolve();
}

pub fn finalize_dissolve(&mut self, from_prop: u64, limit: u64) {
Expand Down Expand Up @@ -257,7 +261,7 @@ mod tests {
use std::collections::{HashMap};

use near_sdk::json_types::U64;
use near_sdk::test_utils::{accounts, VMContextBuilder};
use near_sdk::test_utils::{accounts, VMContextBuilder, get_logs};
use near_sdk::{testing_env, VMContext};
use near_units::parse_near;

Expand Down Expand Up @@ -499,6 +503,9 @@ mod tests {
testing_env!(context);
contract.veto_hook(id);

let expected = r#"EVENT_JSON:{"standard":"astra++","version":"1.0.0","event":"veto","data":{"prop_id":4}}"#;
assert_eq!(vec![expected], get_logs());

contract.get_proposal(id);
// TODO: this should not panic, instead return NONE
}
Expand All @@ -523,6 +530,10 @@ mod tests {
context.predecessor_account_id = acc_voting_body();
testing_env!(context.clone());
contract.dissolve_hook();

let expected = r#"EVENT_JSON:{"standard":"astra++","version":"1.0.0","event":"dissolve","data":"dao is dissolved"}"#;
assert_eq!(vec![expected], get_logs());

res = contract.policy.get().unwrap().to_policy();
assert!(res.roles.is_empty());

Expand Down
12 changes: 12 additions & 0 deletions common/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[package]
name = "common"
version = "1.0.0"
authors = { workspace = true }
edition = { workspace = true }
repository = { workspace = true }
license = { workspace = true }

[dependencies]
uint.workspace = true
near-sdk.workspace = true
serde_json.workspace = true
3 changes: 3 additions & 0 deletions common/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Set of common functions and structures

- event handling
75 changes: 75 additions & 0 deletions common/src/events.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
use near_sdk::env;
use near_sdk::serde::Serialize;

/// Helper struct to create Standard NEAR Event JSON.
/// Arguments:
/// * `standard`: name of standard e.g. nep171
/// * `version`: e.g. 1.0.0
/// * `event`: associate event data
#[derive(Serialize)]
#[serde(crate = "near_sdk::serde")]
pub struct NearEvent<T: Serialize> {
pub standard: &'static str,
pub version: &'static str,

// `flatten` to not have "event": {<EventVariant>} in the JSON, just have the contents of {<EventVariant>}.
#[serde(flatten)]
pub event: T,
}

impl<T: Serialize> NearEvent<T> {
pub fn to_json_event_string(&self) -> String {
let s = serde_json::to_string(&self)
.ok()
.unwrap_or_else(|| env::abort());
format!("EVENT_JSON:{}", s)
}

pub fn emit(self) {
env::log_str(&self.to_json_event_string());
}
}

/// Helper struct to be used in `NearEvent.event` to construct NEAR Event compatible payload
#[derive(Serialize)]
#[serde(crate = "near_sdk::serde")]
pub struct EventPayload<T: Serialize> {
/// event name
pub event: &'static str,
/// event payload
pub data: T,
}

impl<T: Serialize> EventPayload<T> {
pub fn emit(self, standard: &'static str, version: &'static str) {
NearEvent {
standard,
version,
event: self,
}
.emit()
}
}

#[cfg(test)]
mod tests {
use near_sdk::{test_utils, AccountId};

use super::*;

fn alice() -> AccountId {
AccountId::new_unchecked("alice.near".to_string())
}

#[test]
fn emit_event_payload() {
let expected = r#"EVENT_JSON:{"standard":"nepXYZ","version":"1.0.1","event":"mint","data":["alice.near",[821,10,44]]}"#;
let tokens = vec![821, 10, 44];
let event = EventPayload {
event: "mint",
data: (alice(), tokens),
};
event.emit("nepXYZ", "1.0.1");
assert_eq!(vec![expected], test_utils::get_logs());
}
}
3 changes: 3 additions & 0 deletions common/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
mod events;

pub use events::*;

0 comments on commit bf7b322

Please sign in to comment.