Skip to content

Commit

Permalink
feat: consistent transaction abort reason (#1172)
Browse files Browse the repository at this point in the history
Description
---
There was no exact reason when a transaction was aborted, so added all
currently possible abort reasons.

Motivation and Context
---
There was no explicit reason/reason code provided for aborted
transactions.

How Has This Been Tested?
---
- Submitted a transaction with invalid versions of inputs:

![image](https://github.com/user-attachments/assets/d0833408-0176-4623-8876-13b8be75ea8f)

- Submitted 2 concurrent transactions which are causing one an abort
error on locking inputs:

![image](https://github.com/user-attachments/assets/431c5bbe-4731-4a17-b146-953f1c649f95)


What process can a PR reviewer use to test or verify this change?
---


Breaking Changes
---

- [ ] None
- [ ] Requires data directory to be deleted
- [x] Other - Please specify - Since a new data structure is used it can
be inconsistent with older version of code, so a fresh start with
deleted data/processes directory would be needed.
  • Loading branch information
ksrichard authored Oct 18, 2024
1 parent f64bac7 commit 52f00ad
Show file tree
Hide file tree
Showing 45 changed files with 1,126 additions and 894 deletions.
62 changes: 36 additions & 26 deletions Cargo.lock

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

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ borsh = "1.3"
bytes = "1.5"
cacache = "12.0.0"
cargo_metadata = "0.15.3"
cargo_toml = "0.11.5"
cargo_toml = "0.20.5"
ciborium = { git = "https://github.com/enarx/ciborium.git", rev = "114614d2a61102eb2321c68e53799d1e6f087aef", default-features = false }
ciborium-io = { git = "https://github.com/enarx/ciborium.git", rev = "114614d2a61102eb2321c68e53799d1e6f087aef", default-features = false }
clap = "3.2.25"
Expand Down
3 changes: 2 additions & 1 deletion applications/tari_indexer/src/event_scanner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

use std::{collections::HashMap, str::FromStr};

use anyhow::anyhow;
use futures::StreamExt;
use log::*;
use tari_bor::decode;
Expand Down Expand Up @@ -402,7 +403,7 @@ impl EventScanner {

match PayloadResultStatus::try_from(response.status) {
Ok(PayloadResultStatus::Finalized) => {
let proto_decision = tari_dan_p2p::proto::consensus::Decision::try_from(response.final_decision)?;
let proto_decision = response.final_decision.ok_or(anyhow!("Missing final decision!"))?;
let final_decision = proto_decision.try_into()?;
if let Decision::Commit = final_decision {
Ok(Some(response.execution_result)
Expand Down
2 changes: 1 addition & 1 deletion applications/tari_validator_node/src/consensus/metrics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ impl<S: StateStore> ConsensusHooks for PrometheusConsensusMetrics<S> {
Decision::Commit => {
self.transactions_finalized_committed.inc();
},
Decision::Abort => {
Decision::Abort(_) => {
self.transactions_finalized_aborted.inc();
},
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ impl ValidatorNodeRpcService for ValidatorNodeRpcServiceImpl {
Ok(Response::new(GetTransactionResultResponse {
status: PayloadResultStatus::Finalized.into(),

final_decision: proto::consensus::Decision::from(final_decision) as i32,
final_decision: Some(proto::consensus::Decision::from(final_decision)),
execution_time_ms: transaction
.execution_time()
.map(|t| u64::try_from(t.as_millis()).unwrap_or(u64::MAX))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,40 +20,39 @@
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

import { Chip, Avatar } from "@mui/material";
import { IoCheckmarkOutline, IoHourglassOutline, IoCloseOutline, IoBandageOutline } from "react-icons/io5";
import { Decision } from "@tari-project/typescript-bindings";
import {Avatar, Chip} from "@mui/material";
import {IoBandageOutline, IoCheckmarkOutline, IoCloseOutline, IoHourglassOutline} from "react-icons/io5";

interface StatusChipProps {
status: Decision | "Commit" | "Pending" | "Dummy";
showTitle?: boolean;
status: "Commit" | "Abort" | "Pending" | "Dummy";
showTitle?: boolean;
}

const colorList: Record<string, string> = {
Commit: "#5F9C91",
Pending: "#ECA86A",
Abort: "#DB7E7E",
Dummy: "#C0C0C0",
Commit: "#5F9C91",
Pending: "#ECA86A",
Abort: "#DB7E7E",
Dummy: "#C0C0C0",
};

const iconList: Record<string, JSX.Element> = {
Commit: <IoCheckmarkOutline style={{ height: 14, width: 14 }} color="#FFF" />,
Pending: <IoHourglassOutline style={{ height: 14, width: 14 }} color="#FFF" />,
Abort: <IoCloseOutline style={{ height: 14, width: 14 }} color="#FFF" />,
Dummy: <IoBandageOutline style={{ height: 14, width: 14 }} color="#FFF" />,
Commit: <IoCheckmarkOutline style={{height: 14, width: 14}} color="#FFF"/>,
Pending: <IoHourglassOutline style={{height: 14, width: 14}} color="#FFF"/>,
Abort: <IoCloseOutline style={{height: 14, width: 14}} color="#FFF"/>,
Dummy: <IoBandageOutline style={{height: 14, width: 14}} color="#FFF"/>,
};

export default function StatusChip({ status, showTitle = true }: StatusChipProps) {
if (!showTitle) {
return <Avatar sx={{ bgcolor: colorList[status], height: 22, width: 22 }}>{iconList[status]}</Avatar>;
} else {
return (
<Chip
avatar={<Avatar sx={{ bgcolor: colorList[status] }}>{iconList[status]}</Avatar>}
label={status}
style={{ color: colorList[status], borderColor: colorList[status] }}
variant="outlined"
/>
);
}
export default function StatusChip({status, showTitle = true}: StatusChipProps) {
if (!showTitle) {
return <Avatar sx={{bgcolor: colorList[status], height: 22, width: 22}}>{iconList[status]}</Avatar>;
} else {
return (
<Chip
avatar={<Avatar sx={{bgcolor: colorList[status]}}>{iconList[status]}</Avatar>}
label={status}
style={{color: colorList[status], borderColor: colorList[status]}}
variant="outlined"
/>
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,43 +21,44 @@
// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

import React from "react";
import { Table, TableContainer, TableBody, TableHead, TableRow, TableCell } from "@mui/material";
import {Table, TableBody, TableCell, TableContainer, TableHead, TableRow} from "@mui/material";
import StatusChip from "../../Components/StatusChip";
import type { TransactionAtom } from "@tari-project/typescript-bindings";
import type {TransactionAtom} from "@tari-project/typescript-bindings";

function Transaction({ transaction }: { transaction: TransactionAtom }) {
return (
<TableRow>
<TableCell>
<a href={`/transactions/${transaction.id}`}>{transaction.id}</a>
</TableCell>
<TableCell>
<StatusChip status={transaction.decision} />
</TableCell>
<TableCell>{transaction.leader_fee?.fee}</TableCell>
<TableCell>{transaction.transaction_fee}</TableCell>
</TableRow>
);
function Transaction({transaction}: { transaction: TransactionAtom }) {
const decision = typeof transaction.decision === 'object' ? "Abort" : "Commit";
return (
<TableRow>
<TableCell>
<a href={`/transactions/${transaction.id}`}>{transaction.id}</a>
</TableCell>
<TableCell>
<StatusChip status={decision}/>
</TableCell>
<TableCell>{transaction.leader_fee?.fee}</TableCell>
<TableCell>{transaction.transaction_fee}</TableCell>
</TableRow>
);
}

export default function Transactions({ transactions }: { transactions: TransactionAtom[] }) {
return (
<TableContainer>
<Table>
<TableHead>
<TableRow>
<TableCell>Transaction ID</TableCell>
<TableCell>Decision</TableCell>
<TableCell>Leader fee</TableCell>
<TableCell>Transaction fee</TableCell>
</TableRow>
</TableHead>
<TableBody>
{transactions.map((tx: TransactionAtom) => (
<Transaction key={tx.id} transaction={tx} />
))}
</TableBody>
</Table>
</TableContainer>
);
export default function Transactions({transactions}: { transactions: TransactionAtom[] }) {
return (
<TableContainer>
<Table>
<TableHead>
<TableRow>
<TableCell>Transaction ID</TableCell>
<TableCell>Decision</TableCell>
<TableCell>Leader fee</TableCell>
<TableCell>Transaction fee</TableCell>
</TableRow>
</TableHead>
<TableBody>
{transactions.map((tx: TransactionAtom) => (
<Transaction key={tx.id} transaction={tx}/>
))}
</TableBody>
</Table>
</TableContainer>
);
}
Loading

0 comments on commit 52f00ad

Please sign in to comment.