Skip to content

Commit 69599db

Browse files
authored
Merge pull request #388 from heifner/deferred_transaction
Move deferred transaction into deferred_transaction.hpp
2 parents 7a2c492 + d81cb90 commit 69599db

3 files changed

Lines changed: 148 additions & 103 deletions

File tree

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
/**
2+
* @file
3+
* @copyright defined in eos/LICENSE
4+
*/
5+
#pragma once
6+
#include "system.hpp"
7+
#include "transaction.hpp"
8+
#include "../../core/eosio/serialize.hpp"
9+
10+
#include <vector>
11+
12+
namespace eosio {
13+
namespace internal_use_do_not_use {
14+
extern "C" {
15+
__attribute__((eosio_wasm_import))
16+
void send_deferred(const uint128_t&, uint64_t, const char*, size_t, uint32_t);
17+
18+
__attribute__((eosio_wasm_import))
19+
int cancel_deferred(const uint128_t&);
20+
}
21+
}
22+
23+
/**
24+
* @defgroup deferred_transaction Transaction
25+
* @ingroup contracts
26+
* @brief Type-safe C++ wrappers for transaction C API
27+
*
28+
* deferred_transaction is no longer supported on Vaulta. This class is provided to
29+
* support legacy test contracts that use deferred transactions.
30+
*
31+
* @details An inline message allows one contract to send another contract a message
32+
* which is processed immediately after the current message's processing
33+
* ends such that the success or failure of the parent transaction is
34+
* dependent on the success of the message. If an inline message fails in
35+
* processing then the whole tree of transactions and actions rooted in the
36+
* block will me marked as failing and none of effects on the database will
37+
* persist.
38+
*
39+
* Inline actions and Deferred transactions must adhere to the permissions
40+
* available to the parent transaction or, in the future, delegated to the
41+
* contract account for future use.
42+
*
43+
* @note There are some methods from the @ref transactioncapi that can be used directly from C++
44+
*/
45+
46+
/**
47+
* Class transaction contains the actions, context_free_actions and extensions type for a transaction
48+
*
49+
* @ingroup transaction
50+
*/
51+
class deferred_transaction : public transaction {
52+
public:
53+
54+
/**
55+
* Construct a new deferred_transaction with an expiration of now + 60 seconds.
56+
*/
57+
deferred_transaction(time_point_sec exp = time_point_sec(current_time_point()) + 60) : transaction( exp ) {}
58+
59+
/**
60+
* Sends this transaction, packs the transaction then sends it as a deferred transaction
61+
*
62+
* @details Writes the symbol_code as a string to the provided char buffer
63+
* @param sender_id - ID of sender
64+
* @param payer - Account paying for RAM
65+
* @param replace_existing - Defaults to false, if this is `0`/false then if the provided sender_id is already in use by an in-flight transaction from this contract, which will be a failing assert. If `1` then transaction will atomically cancel/replace the inflight transaction
66+
*/
67+
void send(const uint128_t& sender_id, name payer, bool replace_existing = false) const {
68+
auto serialize = pack(*static_cast<const transaction*>(this));
69+
internal_use_do_not_use::send_deferred(sender_id, payer.value, serialize.data(), serialize.size(), replace_existing);
70+
}
71+
72+
};
73+
74+
/**
75+
* Struct onerror contains and sender id and packed transaction
76+
*
77+
* @ingroup transaction
78+
*/
79+
struct onerror {
80+
uint128_t sender_id;
81+
std::vector<char> sent_trx;
82+
83+
/**
84+
* from_current_action unpacks and returns a onerror struct
85+
*
86+
* @ingroup transaction
87+
*/
88+
static onerror from_current_action() {
89+
return unpack_action_data<onerror>();
90+
}
91+
92+
/**
93+
* Unpacks and returns a transaction
94+
*/
95+
transaction unpack_sent_trx() const {
96+
return unpack<transaction>(sent_trx);
97+
}
98+
99+
EOSLIB_SERIALIZE( onerror, (sender_id)(sent_trx) )
100+
};
101+
102+
/**
103+
* Send a deferred transaction
104+
*
105+
* @ingroup transaction
106+
* @param sender_id - Account name of the sender of this deferred transaction
107+
* @param payer - Account name responsible for paying the RAM for this deferred transaction
108+
* @param serialized_transaction - The packed transaction to be deferred
109+
* @param size - The size of the packed transaction, required for persistence.
110+
* @param replace - If true, will replace an existing transaction.
111+
*/
112+
inline void send_deferred(const uint128_t& sender_id, name payer, const char* serialized_transaction, size_t size, bool replace = false) {
113+
internal_use_do_not_use::send_deferred(sender_id, payer.value, serialized_transaction, size, replace);
114+
}
115+
116+
/**
117+
* Cancels a deferred transaction.
118+
*
119+
* @ingroup transaction
120+
* @param sender_id - The id of the sender
121+
*
122+
* @pre The deferred transaction ID exists.
123+
* @pre The deferred transaction ID has not yet been published.
124+
* @post Deferred transaction canceled.
125+
*
126+
* @return 1 if transaction was canceled, 0 if transaction was not found
127+
*
128+
* Example:
129+
*
130+
* @code
131+
* id = 0xffffffffffffffff
132+
* cancel_deferred( id );
133+
* @endcode
134+
*/
135+
inline int cancel_deferred(const uint128_t& sender_id) {
136+
return internal_use_do_not_use::cancel_deferred(sender_id);
137+
}
138+
}

libraries/eosiolib/contracts/eosio/transaction.hpp

Lines changed: 8 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,6 @@
1313
namespace eosio {
1414
namespace internal_use_do_not_use {
1515
extern "C" {
16-
__attribute__((eosio_wasm_import))
17-
void send_deferred(const uint128_t&, uint64_t, const char*, size_t, uint32_t);
18-
19-
__attribute__((eosio_wasm_import))
20-
int cancel_deferred(const uint128_t&);
21-
2216
__attribute__((eosio_wasm_import))
2317
size_t read_transaction(char*, size_t);
2418

@@ -47,17 +41,7 @@ namespace eosio {
4741
* @ingroup contracts
4842
* @brief Type-safe C++ wrappers for transaction C API
4943
*
50-
* @details An inline message allows one contract to send another contract a message
51-
* which is processed immediately after the current message's processing
52-
* ends such that the success or failure of the parent transaction is
53-
* dependent on the success of the message. If an inline message fails in
54-
* processing then the whole tree of transactions and actions rooted in the
55-
* block will me marked as failing and none of effects on the database will
56-
* persist.
57-
*
58-
* Inline actions and Deferred transactions must adhere to the permissions
59-
* available to the parent transaction or, in the future, delegated to the
60-
* contract account for future use.
44+
* @details See action for the ability to send an inline action.
6145
*
6246
* @note There are some methods from the @ref transactioncapi that can be used directly from C++
6347
*/
@@ -83,17 +67,17 @@ namespace eosio {
8367
public:
8468

8569
/**
86-
* Construct a new transaction_header with an expiration of now + 60 seconds.
70+
* Construct a new transaction_header
8771
*
88-
* @brief Construct a new transaction_header object initialising the transaction header expiration to now + 60 seconds
72+
* @brief Construct a new transaction_header object
8973
*/
90-
transaction_header( time_point_sec exp = time_point_sec(current_time_point()) + 60)
74+
transaction_header( time_point_sec exp = time_point_sec{} )
9175
:expiration(exp)
9276
{}
9377

9478
time_point_sec expiration;
95-
uint16_t ref_block_num;
96-
uint32_t ref_block_prefix;
79+
uint16_t ref_block_num = 0UL;
80+
uint32_t ref_block_prefix = 0UL;
9781
unsigned_int max_net_usage_words = 0UL; /// number of 8 byte words this transaction can serialize into after compressions
9882
uint8_t max_cpu_usage_ms = 0UL; /// number of CPU usage units to bill transaction for
9983
unsigned_int delay_sec = 0UL; /// number of seconds to delay transaction, default: 0
@@ -110,22 +94,9 @@ namespace eosio {
11094
public:
11195

11296
/**
113-
* Construct a new transaction with an expiration of now + 60 seconds.
114-
*/
115-
transaction(time_point_sec exp = time_point_sec(current_time_point()) + 60) : transaction_header( exp ) {}
116-
117-
/**
118-
* Sends this transaction, packs the transaction then sends it as a deferred transaction
119-
*
120-
* @details Writes the symbol_code as a string to the provided char buffer
121-
* @param sender_id - ID of sender
122-
* @param payer - Account paying for RAM
123-
* @param replace_existing - Defaults to false, if this is `0`/false then if the provided sender_id is already in use by an in-flight transaction from this contract, which will be a failing assert. If `1` then transaction will atomically cancel/replace the inflight transaction
97+
* Construct a new transaction
12498
*/
125-
void send(const uint128_t& sender_id, name payer, bool replace_existing = false) const {
126-
auto serialize = pack(*this);
127-
internal_use_do_not_use::send_deferred(sender_id, payer.value, serialize.data(), serialize.size(), replace_existing);
128-
}
99+
transaction(time_point_sec exp = time_point_sec{}) : transaction_header( exp ) {}
129100

130101
std::vector<action> context_free_actions;
131102
std::vector<action> actions;
@@ -134,47 +105,6 @@ namespace eosio {
134105
EOSLIB_SERIALIZE_DERIVED( transaction, transaction_header, (context_free_actions)(actions)(transaction_extensions) )
135106
};
136107

137-
/**
138-
* Struct onerror contains and sender id and packed transaction
139-
*
140-
* @ingroup transaction
141-
*/
142-
struct onerror {
143-
uint128_t sender_id;
144-
std::vector<char> sent_trx;
145-
146-
/**
147-
* from_current_action unpacks and returns a onerror struct
148-
*
149-
* @ingroup transaction
150-
*/
151-
static onerror from_current_action() {
152-
return unpack_action_data<onerror>();
153-
}
154-
155-
/**
156-
* Unpacks and returns a transaction
157-
*/
158-
transaction unpack_sent_trx() const {
159-
return unpack<transaction>(sent_trx);
160-
}
161-
162-
EOSLIB_SERIALIZE( onerror, (sender_id)(sent_trx) )
163-
};
164-
165-
/**
166-
* Send a deferred transaction
167-
*
168-
* @ingroup transaction
169-
* @param sender_id - Account name of the sender of this deferred transaction
170-
* @param payer - Account name responsible for paying the RAM for this deferred transaction
171-
* @param serialized_transaction - The packed transaction to be deferred
172-
* @param size - The size of the packed transaction, required for persistence.
173-
* @param replace - If true, will replace an existing transaction.
174-
*/
175-
inline void send_deferred(const uint128_t& sender_id, name payer, const char* serialized_transaction, size_t size, bool replace = false) {
176-
internal_use_do_not_use::send_deferred(sender_id, payer.value, serialized_transaction, size, replace);
177-
}
178108
/**
179109
* Retrieve the indicated action from the active transaction.
180110
*
@@ -204,29 +134,6 @@ namespace eosio {
204134
return internal_use_do_not_use::read_transaction( ptr, sz );
205135
}
206136

207-
/**
208-
* Cancels a deferred transaction.
209-
*
210-
* @ingroup transaction
211-
* @param sender_id - The id of the sender
212-
*
213-
* @pre The deferred transaction ID exists.
214-
* @pre The deferred transaction ID has not yet been published.
215-
* @post Deferred transaction canceled.
216-
*
217-
* @return 1 if transaction was canceled, 0 if transaction was not found
218-
*
219-
* Example:
220-
*
221-
* @code
222-
* id = 0xffffffffffffffff
223-
* cancel_deferred( id );
224-
* @endcode
225-
*/
226-
inline int cancel_deferred(const uint128_t& sender_id) {
227-
return internal_use_do_not_use::cancel_deferred(sender_id);
228-
}
229-
230137
/**
231138
* Gets the size of the currently executing transaction.
232139
*

tests/unit/test_contracts/simple_tests.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#include <eosio/eosio.hpp>
2-
#include <eosio/transaction.hpp>
2+
#include <eosio/deferred_transaction.hpp>
33
#include <eosio/bitset.hpp>
44

55
#include "transfer.hpp"
@@ -52,7 +52,7 @@ class [[eosio::contract]] simple_tests : public contract {
5252

5353
[[eosio::action]]
5454
void testd(name nm) {
55-
transaction t;
55+
deferred_transaction t;
5656
action act;
5757
act.account = "other"_n;
5858
act.name = "testc"_n;

0 commit comments

Comments
 (0)