Skip to content

Commit 564cb45

Browse files
committed
Refactor parser
1 parent a64aac7 commit 564cb45

File tree

8 files changed

+478
-462
lines changed

8 files changed

+478
-462
lines changed

explorer/src/lib/parser/coin.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { Coin, toHex } from 'chia-wallet-sdk-wasm';
2+
3+
export interface ParsedCoin {
4+
coinId: string;
5+
parentCoinInfo: string;
6+
puzzleHash: string;
7+
amount: string;
8+
}
9+
10+
export function parseCoin(coin: Coin): ParsedCoin {
11+
return {
12+
coinId: `0x${toHex(coin.coinId())}`,
13+
parentCoinInfo: `0x${toHex(coin.parentCoinInfo)}`,
14+
puzzleHash: `0x${toHex(coin.puzzleHash)}`,
15+
amount: coin.amount.toString(),
16+
};
17+
}
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
import { bytesEqual, Constants, toHex } from 'chia-wallet-sdk-wasm';
2+
import { parseCoin, ParsedCoin } from './coin';
3+
import { parseCondition, ParsedCondition } from './conditions';
4+
import { ParserContext } from './context';
5+
import { DeserializedCoinSpend } from './deserializedCoinSpend';
6+
import { MessageSide, parseMessageFlags } from './messages';
7+
8+
export interface ParsedCoinSpend {
9+
coin: ParsedCoin;
10+
puzzleReveal: string;
11+
solution: string;
12+
cost: string;
13+
conditions: ParsedCondition[];
14+
}
15+
16+
export function parseCoinSpend(
17+
{ coinSpend, cost, puzzle, conditions }: DeserializedCoinSpend,
18+
ctx: ParserContext,
19+
): ParsedCoinSpend {
20+
const coinId = coinSpend.coin.coinId();
21+
22+
let isFastForwardable =
23+
bytesEqual(puzzle.modHash, Constants.singletonTopLayerV11Hash()) &&
24+
coinSpend.coin.amount % 2n === 1n &&
25+
!ctx.createdCoinIds.has(toHex(coinId)) &&
26+
!ctx.assertedCoinIds.has(toHex(coinId));
27+
28+
if (isFastForwardable) {
29+
let hasIdenticalOutput = false;
30+
31+
for (const condition of conditions.slice(2)) {
32+
const disqualifyingCondition =
33+
condition.parseAssertMyCoinId() ??
34+
condition.parseAssertMyParentId() ??
35+
condition.parseAssertHeightRelative() ??
36+
condition.parseAssertSecondsRelative() ??
37+
condition.parseAssertBeforeHeightRelative() ??
38+
condition.parseAssertBeforeSecondsRelative() ??
39+
condition.parseAssertMyBirthHeight() ??
40+
condition.parseAssertMyBirthSeconds() ??
41+
condition.parseAssertEphemeral() ??
42+
condition.parseAggSigPuzzle() ??
43+
condition.parseAggSigParent() ??
44+
condition.parseAggSigParentAmount() ??
45+
condition.parseAggSigParentPuzzle() ??
46+
condition.parseCreateCoinAnnouncement();
47+
48+
if (disqualifyingCondition) {
49+
isFastForwardable = false;
50+
}
51+
52+
const sendMessage = condition.parseSendMessage();
53+
if (sendMessage) {
54+
const sender = parseMessageFlags(sendMessage.mode, MessageSide.Sender);
55+
56+
if (sender.parent) {
57+
isFastForwardable = false;
58+
}
59+
}
60+
61+
const receiveMessage = condition.parseReceiveMessage();
62+
if (receiveMessage) {
63+
const receiver = parseMessageFlags(
64+
receiveMessage.mode,
65+
MessageSide.Receiver,
66+
);
67+
68+
if (receiver.parent) {
69+
isFastForwardable = false;
70+
}
71+
}
72+
73+
const createCoin = condition.parseCreateCoin();
74+
if (createCoin) {
75+
if (
76+
bytesEqual(createCoin.puzzleHash, coinSpend.coin.puzzleHash) &&
77+
createCoin.amount === coinSpend.coin.amount
78+
) {
79+
hasIdenticalOutput = true;
80+
}
81+
}
82+
}
83+
84+
if (!hasIdenticalOutput) {
85+
isFastForwardable = false;
86+
}
87+
}
88+
89+
return {
90+
coin: parseCoin(coinSpend.coin),
91+
puzzleReveal: toHex(coinSpend.puzzleReveal),
92+
solution: toHex(coinSpend.solution),
93+
cost: cost.toLocaleString(),
94+
conditions: conditions.map((condition) =>
95+
parseCondition(coinSpend.coin, condition, ctx, isFastForwardable),
96+
),
97+
};
98+
}

0 commit comments

Comments
 (0)