digraph G {

	send [
		label = "transfer";
		shape = "ellipse";
	];

	params [
		label = "get token, value, sender, recipient";
		shape = "parallelogram";
	];

	token_lookup [
		label = "token known?";
		shape = "diamond";	
	];

	token_lookup_x [
		xlabel = "UnknownTokenError";
		shape = "point";
	];

	nonce [
		label = "get sender nonce";
		shape = "box";
		style = "dashed";
	];

	sign_tx [
		label = "sign tx";
		shape = "box";
	];

	sign_tx_x [
		xlabel = "SignerError";
		shape = "point";
	];

	cache [
		label = "queue signed tx";
		shape = "cylinder";
	];

	gas [
		label = "safe sender balance for gas?";
		shape = "diamond";
	];

	gas_rq_exists [
		label = "gas request already pending?"
		shape = "diamond";
	];

	gas_rq [
		label = "queue request for gas";
		shape = "parallelogram";
	];

	gas_tx [
		label = "enough gas for this tx?";
		shape = "diamond";
	];

	cache_waitforgas [
		label = "set status to WAITFORGAS";
		shape = "parallelogram";
	];

	gas_tx_x [
		xlabel = "OutOfGasError";
		shape = "point";
	];

	tx_fail [
		label = "temporary error?"
		shape = "diamond"
	];

	tx_fail_known [
		label = "known error?"
		shape = "diamond"
	];

	cache_sent [
		label = "set tx status to SENT";
		shape = "cylinder";	
	];

	cache_unsent [
		label = "set tx status to SENDFAIL";
		shape = "cylinder";	
	];

	cache_revert [
		label = "set tx status to REVERTED";
		shape = "cylinder";	
	];

	cache_fubar [
		label = "set tx status to FUBAR";
		shape = "cylinder";	
	];

	send_tx_x_tmp [
		xlabel = "TemporaryTxError";
		shape = "point";
	];

	send_tx_x_final [
		xlabel = "PermanentTxError";
		shape = "point";
	];

	ok [
		shape = "point";
	];
	

	send -> params -> token_lookup;
	
	token_lookup -> token_lookup_x [ label = "no"; ];

	token_lookup -> nonce [ label = "yes"; ];
	nonce -> sign_tx;

	sign_tx -> sign_tx_x [ label = "fail"; ];

	sign_tx -> cache [ label = "ok"; ];
	cache -> gas;

	gas -> gas_rq_exists [ label = "no"; ];
	gas_rq_exists -> gas_rq [ label = "no"; ];
	gas_rq_exists -> gas_tx [ label = "yes"; ];
	gas_rq -> gas_tx;

	gas -> send_tx [ label = "yes"; ];	

	gas_tx -> cache_waitforgas -> gas_tx_x [ label = "no"; ];

	gas_tx -> send_tx [ label = "yes"; ];

	send_tx -> tx_fail [ label = "fail"; ];

	tx_fail -> cache_unsent [ label = "yes"; ];
	cache_unsent -> send_tx_x_tmp;

	tx_fail -> tx_fail_known [ label = "no"; ];

	tx_fail_known -> cache_fubar [ label = "no"; ];

	cache_fubar -> send_tx_x_final;

	tx_fail_known -> cache_revert [ label = "yes"; ];
	cache_revert -> send_tx_x_final;

	send_tx -> cache_sent [ label = "ok"; ];
	cache_sent -> ok;

}