This repository has been archived by the owner on Aug 2, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 3.6k
/
transaction_context.hpp
160 lines (114 loc) · 6.77 KB
/
transaction_context.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
#pragma once
#include <eosio/chain/controller.hpp>
#include <eosio/chain/trace.hpp>
#include <eosio/chain/platform_timer.hpp>
#include <signal.h>
namespace eosio { namespace chain {
struct transaction_checktime_timer {
public:
transaction_checktime_timer() = delete;
transaction_checktime_timer(const transaction_checktime_timer&) = delete;
transaction_checktime_timer(transaction_checktime_timer&&) = default;
~transaction_checktime_timer();
void start(fc::time_point tp);
void stop();
/* Sets a callback for when timer expires. Be aware this could might fire from a signal handling context and/or
on any particular thread. Only a single callback can be registered at once; trying to register more will
result in an exception. Use nullptr to disable a previously set callback. */
void set_expiration_callback(void(*func)(void*), void* user);
std::atomic_bool& expired;
private:
platform_timer& _timer;
transaction_checktime_timer(platform_timer& timer);
friend controller_impl;
};
class transaction_context {
private:
void init( uint64_t initial_net_usage);
public:
transaction_context( controller& c,
const signed_transaction& t,
const transaction_id_type& trx_id,
transaction_checktime_timer&& timer,
fc::time_point start = fc::time_point::now() );
void init_for_implicit_trx( uint64_t initial_net_usage = 0 );
void init_for_input_trx( uint64_t packed_trx_unprunable_size,
uint64_t packed_trx_prunable_size,
bool skip_recording);
void init_for_deferred_trx( fc::time_point published );
void exec();
void finalize();
void squash();
void undo();
inline void add_net_usage( uint64_t u ) { net_usage += u; check_net_usage(); }
void check_net_usage()const;
void checktime()const;
void pause_billing_timer();
void resume_billing_timer();
uint32_t update_billed_cpu_time( fc::time_point now );
std::tuple<int64_t, int64_t, bool, bool> max_bandwidth_billed_accounts_can_pay( bool force_elastic_limits = false )const;
void validate_referenced_accounts( const transaction& trx, bool enforce_actor_whitelist_blacklist )const;
private:
friend struct controller_impl;
friend class apply_context;
void add_ram_usage( account_name account, int64_t ram_delta );
action_trace& get_action_trace( uint32_t action_ordinal );
const action_trace& get_action_trace( uint32_t action_ordinal )const;
/** invalidates any action_trace references returned by get_action_trace */
uint32_t schedule_action( const action& act, account_name receiver, bool context_free,
uint32_t creator_action_ordinal, uint32_t closest_unnotified_ancestor_action_ordinal );
/** invalidates any action_trace references returned by get_action_trace */
uint32_t schedule_action( action&& act, account_name receiver, bool context_free,
uint32_t creator_action_ordinal, uint32_t closest_unnotified_ancestor_action_ordinal );
/** invalidates any action_trace references returned by get_action_trace */
uint32_t schedule_action( uint32_t action_ordinal, account_name receiver, bool context_free,
uint32_t creator_action_ordinal, uint32_t closest_unnotified_ancestor_action_ordinal );
void execute_action( uint32_t action_ordinal, uint32_t recurse_depth );
void schedule_transaction();
void record_transaction( const transaction_id_type& id, fc::time_point_sec expire );
void validate_cpu_usage_to_bill( int64_t billed_us, int64_t account_cpu_limit, bool check_minimum )const;
void validate_account_cpu_usage( int64_t billed_us, int64_t account_cpu_limit )const;
void validate_account_cpu_usage_estimate( int64_t billed_us, int64_t account_cpu_limit )const;
void disallow_transaction_extensions( const char* error_msg )const;
/// Fields:
public:
controller& control;
const signed_transaction& trx;
transaction_id_type id;
optional<chainbase::database::session> undo_session;
transaction_trace_ptr trace;
fc::time_point start;
fc::time_point published;
vector<action_receipt> executed;
flat_set<account_name> bill_to_accounts;
flat_set<account_name> validate_ram_usage;
/// the maximum number of virtual CPU instructions of the transaction that can be safely billed to the billable accounts
uint64_t initial_max_billable_cpu = 0;
fc::microseconds delay;
bool is_input = false;
bool apply_context_free = true;
bool enforce_whiteblacklist = true;
fc::time_point deadline = fc::time_point::maximum();
fc::microseconds leeway = fc::microseconds( config::default_subjective_cpu_leeway_us );
int64_t billed_cpu_time_us = 0;
uint32_t subjective_cpu_bill_us = 0;
bool explicit_billed_cpu_time = false;
transaction_checktime_timer transaction_timer;
private:
bool is_initialized = false;
uint64_t net_limit = 0;
bool net_limit_due_to_block = true;
bool net_limit_due_to_greylist = false;
uint64_t eager_net_limit = 0;
uint64_t& net_usage; /// reference to trace->net_usage
bool cpu_limit_due_to_greylist = false;
fc::microseconds initial_objective_duration_limit;
fc::microseconds objective_duration_limit;
fc::time_point _deadline = fc::time_point::maximum();
int64_t deadline_exception_code = block_cpu_usage_exceeded::code_value;
int64_t billing_timer_exception_code = block_cpu_usage_exceeded::code_value;
fc::time_point pseudo_start;
fc::microseconds billed_time;
fc::microseconds billing_timer_duration_limit;
};
} }