Skip to content

Commit

Permalink
Refactors proposal execution
Browse files Browse the repository at this point in the history
  • Loading branch information
grarco committed Feb 17, 2023
1 parent 5322ed8 commit d32c4e4
Show file tree
Hide file tree
Showing 2 changed files with 138 additions and 182 deletions.
319 changes: 137 additions & 182 deletions apps/src/lib/node/ledger/shell/governance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use namada::ledger::storage::{DBIter, StorageHasher, DB};
use namada::ledger::storage_api::{token, StorageWrite};
use namada::proof_of_stake::read_total_stake;
use namada::types::address::Address;
use namada::types::governance::{Tally, TallyResult, VotePower};
use namada::types::governance::{Council, Tally, TallyResult, VotePower};
use namada::types::storage::Epoch;

use super::*;
Expand Down Expand Up @@ -75,192 +75,31 @@ where
// Execute proposal if succesful
let transfer_address = match tally_result {
TallyResult::Passed(tally) => {
match tally {
Tally::Default => {
let proposal_author_key =
gov_storage::get_author_key(id);
let proposal_author = shell
.read_storage_key::<Address>(&proposal_author_key)
.ok_or_else(|| {
Error::BadProposal(
id,
"Invalid proposal author.".to_string(),
)
})?;

let proposal_code_key =
gov_storage::get_proposal_code_key(id);
let proposal_code =
shell.read_storage_key_bytes(&proposal_code_key);
match proposal_code {
Some(proposal_code) => {
let tx =
Tx::new(proposal_code, Some(encode(&id)));
let tx_type =
TxType::Decrypted(DecryptedTx::Decrypted {
tx,
#[cfg(not(feature = "mainnet"))]
has_valid_pow: false,
});
let pending_execution_key =
gov_storage::get_proposal_execution_key(id);
shell
.wl_storage
.write(&pending_execution_key, ())
.expect(
"Should be able to write to storage.",
);
let tx_result = protocol::apply_tx(
tx_type,
0, /* this is used to compute the fee
* based on the code size. We dont
* need it here. */
TxIndex::default(),
&mut BlockGasMeter::default(),
&mut shell.wl_storage.write_log,
&shell.wl_storage.storage,
&mut shell.vp_wasm_cache,
&mut shell.tx_wasm_cache,
);
shell
.wl_storage
.storage
.delete(&pending_execution_key)
.expect(
"Should be able to delete the storage.",
);
match tx_result {
Ok(tx_result) => {
if tx_result.is_accepted() {
shell.wl_storage.commit_tx();
let proposal_event: Event =
ProposalEvent::new(
EventType::Proposal
.to_string(),
TallyResult::Passed(
Tally::Default,
),
id,
true,
true,
)
.into();
response
.events
.push(proposal_event);
proposals_result.passed.push(id);

proposal_author
} else {
shell.wl_storage.drop_tx();
let proposal_event: Event =
ProposalEvent::new(
EventType::Proposal
.to_string(),
TallyResult::Passed(
Tally::Default,
),
id,
true,
false,
)
.into();
response
.events
.push(proposal_event);
proposals_result.rejected.push(id);

slash_fund_address
}
}
Err(_e) => {
shell.wl_storage.drop_tx();
let proposal_event: Event =
ProposalEvent::new(
EventType::Proposal.to_string(),
TallyResult::Passed(
Tally::Default,
),
id,
true,
false,
)
.into();
response.events.push(proposal_event);
proposals_result.rejected.push(id);

slash_fund_address
}
}
}
None => {
let proposal_event: Event = ProposalEvent::new(
EventType::Proposal.to_string(),
TallyResult::Passed(Tally::Default),
id,
false,
false,
)
.into();
response.events.push(proposal_event);
proposals_result.passed.push(id);

proposal_author
}
}
}
Tally::PGFCouncil(council) => {
// TODO: implement when PGF is in place, update the PGF
// council in storage
let proposal_event: Event = ProposalEvent::new(
EventType::Proposal.to_string(),
TallyResult::Passed(Tally::PGFCouncil(council)),
let proposal_author_key = gov_storage::get_author_key(id);
let proposal_author = shell
.read_storage_key::<Address>(&proposal_author_key)
.ok_or_else(|| {
Error::BadProposal(
id,
false,
false,
"Invalid proposal author.".to_string(),
)
.into();
response.events.push(proposal_event);
proposals_result.passed.push(id);
})?;

let proposal_author_key =
gov_storage::get_author_key(id);

shell
.read_storage_key::<Address>(&proposal_author_key)
.ok_or_else(|| {
Error::BadProposal(
id,
"Invalid proposal author.".to_string(),
)
})?
let (successful_execution, proposal_event) = match tally {
Tally::Default => execute_default_proposal(shell, id),
Tally::PGFCouncil(council) => {
execute_pgf_proposal(id, council)
}
Tally::ETHBridge => {
// TODO: implement when ETH Bridge. Apply the
// modification requested by the proposal
let proposal_event: Event = ProposalEvent::new(
EventType::Proposal.to_string(),
TallyResult::Passed(Tally::ETHBridge),
id,
false,
false,
)
.into();
response.events.push(proposal_event);
proposals_result.passed.push(id);

let proposal_author_key =
gov_storage::get_author_key(id);
Tally::ETHBridge => execute_eth_proposal(id),
};

shell
.read_storage_key::<Address>(&proposal_author_key)
.ok_or_else(|| {
Error::BadProposal(
id,
"Invalid proposal author.".to_string(),
)
})?
}
response.events.push(proposal_event);
if successful_execution {
proposals_result.passed.push(id);
proposal_author
} else {
proposals_result.rejected.push(id);
slash_fund_address
}
}
TallyResult::Rejected => {
Expand Down Expand Up @@ -296,3 +135,119 @@ where

Ok(proposals_result)
}

fn execute_default_proposal<D, H>(
shell: &mut Shell<D, H>,
id: u64,
) -> (bool, Event)
where
D: DB + for<'iter> DBIter<'iter> + Sync + 'static,
H: StorageHasher + Sync + 'static,
{
let proposal_code_key = gov_storage::get_proposal_code_key(id);
let proposal_code = shell.read_storage_key_bytes(&proposal_code_key);
match proposal_code {
Some(proposal_code) => {
let tx = Tx::new(proposal_code, Some(encode(&id)));
let tx_type = TxType::Decrypted(DecryptedTx::Decrypted {
tx,
#[cfg(not(feature = "mainnet"))]
has_valid_pow: false,
});
let pending_execution_key =
gov_storage::get_proposal_execution_key(id);
shell
.wl_storage
.write(&pending_execution_key, ())
.expect("Should be able to write to storage.");
let tx_result = protocol::apply_tx(
tx_type,
0, /* this is used to compute the fee
* based on the code size. We dont
* need it here. */
TxIndex::default(),
&mut BlockGasMeter::default(),
&mut shell.wl_storage.write_log,
&shell.wl_storage.storage,
&mut shell.vp_wasm_cache,
&mut shell.tx_wasm_cache,
);
shell
.wl_storage
.storage
.delete(&pending_execution_key)
.expect("Should be able to delete the storage.");
match tx_result {
Ok(tx_result) if tx_result.is_accepted() => (
tx_result.is_accepted(),
ProposalEvent::new(
EventType::Proposal.to_string(),
TallyResult::Passed(Tally::Default),
id,
true,
tx_result.is_accepted(),
)
.into(),
),
_ => {
shell.wl_storage.drop_tx();
(
false,
ProposalEvent::new(
EventType::Proposal.to_string(),
TallyResult::Passed(Tally::Default),
id,
true,
false,
)
.into(),
)
}
}
}
None => (
true,
ProposalEvent::new(
EventType::Proposal.to_string(),
TallyResult::Passed(Tally::Default),
id,
false,
false,
)
.into(),
),
}
}

fn execute_pgf_proposal(id: u64, council: Council) -> (bool, Event) {
// TODO: implement when PGF is in place, update the PGF
// council in storage
(
true,
ProposalEvent::new(
EventType::Proposal.to_string(),
TallyResult::Passed(Tally::PGFCouncil(council)),
id,
false,
false,
)
.into(),
)
}

fn execute_eth_proposal(id: u64) -> (bool, Event) {
// TODO: implement when ETH Bridge. Apply the
// modification requested by the proposal
// <https://github.com/anoma/namada/issues/1166>
(
true,
ProposalEvent::new(
EventType::Proposal.to_string(),
TallyResult::Passed(Tally::ETHBridge),
id,
false,
false,
)
.into(),
)
}
1 change: 1 addition & 0 deletions shared/src/ledger/native_vp/governance/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,7 @@ where
} else if let VoteType::ETHBridge(_sig) = vote_type {
// TODO: Check the validity of the signature with the
// governance ETH key in storage for the given validator
// <https://github.com/anoma/namada/issues/1166>
}
}

Expand Down

0 comments on commit d32c4e4

Please sign in to comment.