@@ -7,35 +7,47 @@ import "../src/core/Coordinator.sol";
77import "../src/core/TxManagerBase.sol " ;
88import "../src/core/TxAuthManagerBase.sol " ;
99import {ICrossError} from "../src/core/ICrossError.sol " ;
10+ import {ICrossEvent} from "../src/core/ICrossEvent.sol " ;
1011import {
1112 QueryCoordinatorStateRequest,
1213 QueryCoordinatorStateResponse,
1314 CoordinatorState
1415} from "../src/proto/cross/core/atomic/simple/AtomicSimple.sol " ;
15- import {MsgInitiateTx} from "../src/proto/cross/core/initiator/Initiator.sol " ;
16+ import {MsgInitiateTx, ContractTransaction } from "../src/proto/cross/core/initiator/Initiator.sol " ;
1617import {Tx} from "../src/proto/cross/core/tx/Tx.sol " ;
18+ import {Account as AuthAccount} from "../src/proto/cross/core/auth/Auth.sol " ;
19+ import {IbcCoreClientV1Height} from "../src/proto/ibc/core/client/v1/client.sol " ;
1720
1821contract MockTxManager is TxManagerBase , ICrossError {
1922 mapping (bytes32 => CoordinatorState.Data) internal mockStates;
20- mapping (bytes32 => bool ) internal exists;
23+ mapping (bytes32 => bool ) internal recordedTxs;
24+ mapping (bytes32 => bool ) internal stateExists;
25+ uint256 public runCount;
2126
2227 function setCoordinatorState (bytes32 txID , CoordinatorState.Data memory data ) public {
2328 mockStates[txID] = data;
24- exists[txID] = true ;
29+ stateExists[txID] = true ;
30+ }
31+
32+ function setTxRecorded (bytes32 txID , bool recorded ) public {
33+ recordedTxs[txID] = recorded;
2534 }
2635
2736 function _getCoordinatorState (bytes32 txID ) internal view virtual override returns (CoordinatorState.Data memory ) {
28- if (! exists [txID]) {
37+ if (! stateExists [txID]) {
2938 revert CoordinatorStateNotFound (txID);
3039 }
3140 return mockStates[txID];
3241 }
3342
3443 function _createTx (bytes32 , MsgInitiateTx.Data calldata ) internal virtual override {}
35- function _runTxIfCompleted (MsgInitiateTx.Data calldata ) internal virtual override {}
3644
37- function _isTxRecorded (bytes32 ) internal view virtual override returns (bool ) {
38- return false ;
45+ function _runTxIfCompleted (MsgInitiateTx.Data calldata ) internal virtual override {
46+ ++ runCount;
47+ }
48+
49+ function _isTxRecorded (bytes32 txID ) internal view virtual override returns (bool ) {
50+ return recordedTxs[txID];
3951 }
4052}
4153
@@ -65,12 +77,71 @@ contract MockTxAuthManager is TxAuthManagerBase {
6577
6678contract CoordinatorHarness is Coordinator , MockTxManager , MockTxAuthManager {}
6779
68- contract CoordinatorTest is Test , ICrossError {
80+ contract CoordinatorTest is Test , ICrossError , ICrossEvent {
6981 CoordinatorHarness private harness;
70- bytes32 private txID = keccak256 ("test_tx_id " );
82+ MsgInitiateTx.Data private dummyMsg;
83+ bytes32 private txID;
7184
7285 function setUp () public {
7386 harness = new CoordinatorHarness ();
87+
88+ dummyMsg = MsgInitiateTx.Data ({
89+ chain_id: "test-chain " ,
90+ nonce: 1 ,
91+ commit_protocol: Tx.CommitProtocol.COMMIT_PROTOCOL_SIMPLE,
92+ timeout_height: IbcCoreClientV1Height.Data (0 , 0 ),
93+ timeout_timestamp: 0 ,
94+ signers: new AuthAccount.Data [](0 ),
95+ contract_transactions: new ContractTransaction.Data [](0 )
96+ });
97+
98+ txID = sha256 (MsgInitiateTx.encode (dummyMsg));
99+ }
100+
101+ function test_executeTx_Succeeds () public {
102+ harness.setTxRecorded (txID, true );
103+ harness.setCompletedAuth (txID, true );
104+
105+ vm.expectEmit (address (harness));
106+ emit TxExecuted (abi.encodePacked (txID), address (this ));
107+
108+ harness.executeTx (dummyMsg);
109+
110+ assertEq (harness.runCount (), 1 , "runTxIfCompleted should be called " );
111+ }
112+
113+ function test_executeTx_RevertIf_TimeoutHeight () public {
114+ dummyMsg.timeout_height.revision_height = uint64 (block .number );
115+
116+ vm.expectRevert (
117+ abi.encodeWithSelector (MessageTimeoutHeight.selector , block .number , dummyMsg.timeout_height.revision_height)
118+ );
119+ harness.executeTx (dummyMsg);
120+ }
121+
122+ function test_executeTx_RevertIf_TimeoutTimestamp () public {
123+ dummyMsg.timeout_timestamp = uint64 (block .timestamp );
124+
125+ vm.expectRevert (
126+ abi.encodeWithSelector (MessageTimeoutTimestamp.selector , block .timestamp , dummyMsg.timeout_timestamp)
127+ );
128+ harness.executeTx (dummyMsg);
129+ }
130+
131+ function test_executeTx_RevertIf_TxNotRecorded () public {
132+ harness.setTxRecorded (txID, false );
133+ harness.setCompletedAuth (txID, true );
134+
135+ vm.expectRevert (abi.encodeWithSelector (TxIDNotFound.selector , txID));
136+ harness.executeTx (dummyMsg);
137+ }
138+
139+ function test_executeTx_RevertIf_AuthNotCompleted () public {
140+ harness.setTxRecorded (txID, true );
141+ harness.setCompletedAuth (txID, false );
142+
143+ vm.expectRevert (abi.encodeWithSelector (AuthNotCompleted.selector , txID));
144+ harness.executeTx (dummyMsg);
74145 }
75146
76147 function test_coordinatorState_ReturnsCorrectState () public {
0 commit comments