# Party-state-actor

This actor is loaded into the [state\_machine\_replica](https://github.com/tearust/t-rust/blob/master/docs/_gitbook-dev-docs/z_glossary/state_machine_replica.md)'s [mini-runtime](/z_glossary/mini-runtime.md). It is the same concept as stored procedure in traditional cloud computing webapp. There are many pure functions that handle incoming txns and modify the state (including [state](/z_glossary/state.md) and [gluesql](https://github.com/tearust/t-rust/blob/master/docs/_gitbook-dev-docs/z_glossary/gluesql.md) data).

As you already know, every [state\_machine\_replica](https://github.com/tearust/t-rust/blob/master/docs/_gitbook-dev-docs/z_glossary/state_machine_replica.md) runs an instance of this actor. All of them run the same txn at the same sequence and modify the same state to finally get the same new state. This is guaranteed by the [proof of time](/z_glossary/consensus.md#proof-of-time) consensus. As an application developer, you don't need to care too much about how it works. You can simply assume there's only one instance of your function running that updates a single state.

There are two types of requests: [queries](/z_glossary/queries.md) and [commands](/z_glossary/commands.md). Please click the links to get to know more about them. At least you should know that queries execute immediately, but commands need to wait a period of time prior to execution.

## Handling txns

Please go to [lib.rs](https://github.com/tearust/tapp-sample-teaparty/blob/demo-code/party-state-actor/src/lib.rs) and find the function\
fn txn\_exec\_inner(tsid: Tsid, txn\_bytes: &\[u8]) -> HandlerResult<()>. This is where most of the logic lives.

```
let (context_bytes, auth_key): (Vec<u8>, AuthKey) = match sample_txn {
		/// PostMessage, when user post a new message
		TeapartyTxn::PostMessage {
			token_id,
			from,
			ttl,
			auth_b64,
		} => {
			info!("PostMessage => from ttl: {:?},{:?}", &from, &ttl);
			let amt = calculate_fee(ttl);
			let auth_key: AuthKey = bincode::deserialize(&base64::decode(auth_b64)?)?;
			let auth_ops_bytes = actor_statemachine::query_auth_ops_bytes(auth_key)?;
			let ctx = TokenContext::new(tsid, base, token_id, &auth_ops_bytes)?;
			let req = ConsumeFromAccountRequest {
				ctx: bincode::serialize(&ctx)?,
				acct: bincode::serialize(&from)?,
				amt: bincode::serialize(&amt)?,
			};
			(actor_statemachine::consume_from_account(req)?, auth_key)
		}
```

The code above shows how you handle the PostMessage txn.

This txn (sometimes we call it a command) is generated in the [party-actor](/z_glossary/party-actor.md) when user click post message button in [party-fe](/z_glossary/party-fe.md).

The message has been stored to the [orbitdb](https://github.com/tearust/t-rust/blob/master/docs/_gitbook-dev-docs/z_glossary/orbitdb.md) by [back\_end\_actor](/z_glossary/back_end_actor.md), the only thing this actor is supposed to do in the state level is to transfer the gas fee. Gas fee is what the end users supposed to pay for this kind of service, in this case, posting a message.

In this function, the logic determines how much (amt) the user need to pay based on the TTL (time to live), and who should pay (the message sender). Finally, call the `actor_statemachine::consume_from_account` function.

There are a few concepts we'll need to explain here. [authKey](https://github.com/tearust/t-rust/blob/master/docs/_gitbook-dev-docs/z_glossary/authKey.md) and [context](https://github.com/tearust/t-rust/blob/master/docs/_gitbook-dev-docs/z_glossary/context.md). Please click the links for further explanation.

There are other txns this function handles. They are very straightforward from just reading the txn name and code.

## Commit state changes

After the txn has been handled, all changes are not commited yet. they are just saved to [context](https://github.com/tearust/t-rust/blob/master/docs/_gitbook-dev-docs/z_glossary/context.md). So you can see the code after all the txns ahave been handled. This code is used to commit the changes.

```
if context_bytes.is_empty() {
		error!("######### party state actor txn handle returns empty ctx. Cannot commit ######");
		return Ok(());
	}
	let hidden_acct_balance_change_after_commit = actor_statemachine::commit(CommitRequest {
		ctx: context_bytes,
		auth_key: bincode::serialize(&auth_key)?,
	})?;
	if hidden_acct_balance_change_after_commit != (0, 0) {
		warn!("********* party state actor commit succesfully but the hidden account balance changed. make sure a follow up tx is trigger to keey the balance sheet balance. {:?}", &hidden_acct_balance_change_after_commit);
	} else {
		info!("*********  party state actor commit succesfully.");
	}
	Ok(())
}
fn health(_req: codec::core::HealthRequest) -> HandlerResult<()> {
	info!("health call from party-state actor");
	Ok(())
```

The hidden balance is used to verify if the txn made any mistake that caused the state to be unbalanced after the update. If all the code is correct, there shouldn't be any unbalanced state.

After the commit, the state is finally changed. Before the commit, any error causing the function to return early will not affect the state. The state remains as it was before. See [context](https://github.com/tearust/t-rust/blob/master/docs/_gitbook-dev-docs/z_glossary/context.md) for more details about atomic transaction concepts.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://dev.teaproject.org/z_glossary/party-state-actor.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
