#![allow(dead_code)]
use std::collections::HashMap;
use massa_hash::Hash;
use massa_models::async_msg_id::AsyncMessageId;
use massa_models::block_id::BlockId;
use massa_models::config::{GENESIS_TIMESTAMP, T0, THREAD_COUNT};
use massa_models::deferred_calls::DeferredCallId;
use massa_models::denunciation::DenunciationIndex;
use massa_models::operation::OperationId;
use massa_time::MassaTime;
use massa_deferred_calls::DeferredCall;
use massa_models::address::Address;
use massa_models::amount::Amount;
use massa_models::slot::Slot;
use serde::Serialize;
use crate::types_trace_info::ExecutionResult;
#[derive(Debug, Clone)]
pub enum RollOperationInfo {
RollBuy(Address, u64),
RollSell(Address, u64),
}
#[derive(Debug, Clone, Serialize)]
pub enum TransferValue {
Rolls(u64),
DeferredCredits(Amount),
Coins(Amount),
}
#[derive(Clone, Debug, Serialize)]
pub struct TransferInfo {
pub from: Option<Address>,
pub to: Option<Address>,
pub context: TransferContext,
pub id: Option<String>,
pub value: TransferValue,
}
impl TransferInfo {
pub fn new(
value: TransferValue,
context: TransferContext,
from: Option<Address>,
to: Option<Address>,
) -> Self {
Self {
from,
to,
context,
value,
id: None,
}
}
}
#[derive(Debug, Default, Clone, Serialize)]
pub struct OriginTransferContext {
pub operation_id: Option<OperationId>,
pub deferred_call_id: Option<DeferredCallId>,
pub async_message_id: Option<AsyncMessageId>,
pub async_message_id_str: Option<String>,
pub denunciation_index: Option<DenunciationIndex>,
}
#[allow(missing_docs)]
#[derive(Debug, Clone, Serialize)]
pub enum TransferContext {
TransactionCoins(OriginTransferContext),
AyncMsgCancel(OriginTransferContext),
DeferredCredits(OriginTransferContext),
DeferredCallFail(OriginTransferContext),
DeferredCallCancel(OriginTransferContext),
DeferredCallCoins(OriginTransferContext),
DeferredCallRegister(OriginTransferContext),
DeferredCallStorageRefund(OriginTransferContext),
OperationFee(OriginTransferContext),
RollBuy(OriginTransferContext),
RollSell(OriginTransferContext),
RollSlash,
CreateSCStorage,
DatastoreStorage,
CallSCCoins(OriginTransferContext),
AsyncMsgCoins(OriginTransferContext),
EndorsementCreatorReward,
EndorsementTargetReward,
BlockCreatorReward,
ReadOnlyBytecodeExecutionFee,
ReadOnlyFunctionCallFee,
ReadOnlyFunctionCallCoins,
SetBytecodeStorage,
AbiCallCoins,
AbiTransferCoins,
AbiTransferForCoins,
AbiSendMsgCoins,
AbiSendMsgFee,
}
#[derive(Debug, Clone)]
pub struct ExecutionInfoForSlot {
pub slot: Slot,
pub timestamp: MassaTime,
pub block_producer_reward: Option<(Address, Amount)>,
pub endorsement_creator_rewards: HashMap<Address, Amount>,
pub endorsement_target_reward: Option<(Address, Amount)>,
pub denunciations: Vec<Result<DenunciationResult, String>>,
pub roll_operations: Vec<RollOperationInfo>,
pub async_messages: Vec<Result<AsyncMessageExecutionResult, String>>,
pub deferred_calls_messages: Vec<Result<DeferredCallExecutionResult, String>>,
pub deferred_credits_execution: Vec<(Address, Result<Amount, String>)>,
pub cancel_async_message_execution: Vec<(Address, Result<Amount, String>)>,
pub auto_sell_execution: Vec<(Address, Amount)>,
pub execution_trail_hash: Hash,
pub opt_block_id: Option<String>,
pub transfers: Vec<TransferInfo>,
}
impl ExecutionInfoForSlot {
pub fn new(slot: Slot, execution_trail_hash: Hash, block_id: Option<BlockId>) -> Self {
let timestamp = massa_models::timeslots::get_block_slot_timestamp(
THREAD_COUNT,
T0,
*GENESIS_TIMESTAMP,
slot,
)
.expect("Error getting timestamp for slot in ExecutionInfoForSlot");
Self {
slot,
timestamp,
block_producer_reward: None,
endorsement_creator_rewards: Default::default(),
endorsement_target_reward: None,
denunciations: Default::default(),
roll_operations: Default::default(),
async_messages: Default::default(),
deferred_calls_messages: Default::default(),
deferred_credits_execution: vec![],
cancel_async_message_execution: vec![],
auto_sell_execution: vec![],
opt_block_id: block_id.map(|b| b.to_string()),
transfers: vec![],
execution_trail_hash,
}
}
pub fn build_transfer_list(&mut self) {
#[cfg(feature = "execution-info")]
{
use massa_models::async_msg_id::AsyncMessageIdSerializer;
use massa_serialization::Serializer;
use tracing::error;
let msg_id_serializer = AsyncMessageIdSerializer::new();
self.transfers
.iter_mut()
.enumerate()
.for_each(|(index, transfer)| {
let id = format!("{}:{}", self.execution_trail_hash, index);
transfer.id = Some(id);
match &transfer.context {
TransferContext::AsyncMsgCoins(ctx)
| TransferContext::AyncMsgCancel(ctx) => {
if let Some(id) = ctx.async_message_id {
let mut buf = Vec::new();
let str_opt: Option<String> =
match msg_id_serializer.serialize(&id, &mut buf) {
Ok(_) => String::from_utf8(buf).ok(),
Err(er) => {
error!("Error serializing async_msg_id: {:?}", er);
None
}
};
transfer.context = match transfer.context {
TransferContext::AsyncMsgCoins(_) => {
TransferContext::AsyncMsgCoins(OriginTransferContext {
async_message_id_str: str_opt,
..Default::default()
})
}
TransferContext::AyncMsgCancel(_) => {
TransferContext::AyncMsgCancel(OriginTransferContext {
async_message_id_str: str_opt,
..Default::default()
})
}
_ => transfer.context.clone(),
};
}
}
_ => {}
}
});
}
}
}
#[derive(Debug, Clone)]
pub struct DenunciationResult {
pub address_denounced: Address,
pub slot: Slot,
pub slashed: Amount,
}
#[derive(Debug, Clone)]
pub struct AsyncMessageExecutionResult {
pub success: bool,
pub sender: Option<Address>,
pub destination: Option<Address>,
pub coins: Option<Amount>,
pub traces: Option<ExecutionResult>,
}
impl AsyncMessageExecutionResult {
pub fn new() -> Self {
Self {
success: false,
sender: None,
destination: None,
coins: None,
traces: None,
}
}
}
impl Default for AsyncMessageExecutionResult {
fn default() -> Self {
Self::new()
}
}
#[derive(Debug, Clone)]
pub struct DeferredCallExecutionResult {
pub success: bool,
pub sender: Address,
pub target_address: Address,
pub(crate) target_function: String,
pub coins: Amount,
pub fee: Amount,
pub traces: Option<ExecutionResult>,
}
impl DeferredCallExecutionResult {
pub fn new(call: &DeferredCall) -> Self {
Self {
success: false,
sender: call.sender_address,
target_address: call.target_address,
target_function: call.target_function.clone(),
coins: call.coins,
fee: call.fee,
traces: None,
}
}
}