1
1
import asyncio
2
2
import json
3
3
import logging
4
- from dataclasses import asdict
5
4
from enum import IntEnum
6
5
from typing import Dict , Optional , Tuple , List
7
6
8
- from aleph_message .models import MessageConfirmation
9
7
from bson import ObjectId
10
8
from pydantic import ValidationError
11
9
from pymongo import UpdateOne
26
24
from aleph .model .pending import PendingMessage , PendingTX
27
25
from aleph .network import verify_signature
28
26
from aleph .permissions import check_sender_authorization
29
- from aleph .storage import get_json , pin_hash , add_json , get_message_content
30
- from .tx_context import TxContext
31
- from aleph .schemas .pending_messages import (
32
- BasePendingMessage ,
33
- )
27
+ from aleph .schemas .pending_messages import BasePendingMessage
34
28
from aleph .schemas .validated_message import (
35
29
validate_pending_message ,
36
30
ValidatedStoreMessage ,
37
31
ValidatedForgetMessage ,
38
32
make_confirmation_update_query ,
39
- make_message_upsert_query ,
33
+ make_message_upsert_query ,
40
34
)
35
+ from ..schemas .message_confirmation import MessageConfirmation
36
+ from aleph .storage import get_json , pin_hash , add_json , get_message_content
37
+ from .tx_context import TxContext
41
38
42
39
LOGGER = logging .getLogger ("chains.common" )
43
40
@@ -65,21 +62,17 @@ async def mark_confirmed_data(chain_name, tx_hash, height):
65
62
66
63
async def delayed_incoming (
67
64
message : BasePendingMessage ,
68
- chain_name : Optional [str ] = None ,
69
- tx_hash : Optional [str ] = None ,
70
- height : Optional [int ] = None ,
65
+ tx_context : Optional [TxContext ] = None ,
66
+ check_message : bool = True ,
71
67
):
72
68
if message is None :
73
69
return
70
+
74
71
await PendingMessage .collection .insert_one (
75
72
{
76
73
"message" : message .dict (exclude = {"content" }),
77
- "source" : dict (
78
- chain_name = chain_name ,
79
- tx_hash = tx_hash ,
80
- height = height ,
81
- check_message = True , # should we store this?
82
- ),
74
+ "tx_context" : tx_context .dict () if tx_context else None ,
75
+ "check_message" : check_message ,
83
76
}
84
77
)
85
78
@@ -92,27 +85,15 @@ class IncomingStatus(IntEnum):
92
85
93
86
async def mark_message_for_retry (
94
87
message : BasePendingMessage ,
95
- chain_name : Optional [str ],
96
- tx_hash : Optional [str ],
97
- height : Optional [int ],
88
+ tx_context : Optional [TxContext ],
98
89
check_message : bool ,
99
90
retrying : bool ,
100
91
existing_id ,
101
92
):
102
93
message_dict = message .dict (exclude = {"content" })
103
94
104
95
if not retrying :
105
- await PendingMessage .collection .insert_one (
106
- {
107
- "message" : message_dict ,
108
- "source" : dict (
109
- chain_name = chain_name ,
110
- tx_hash = tx_hash ,
111
- height = height ,
112
- check_message = check_message , # should we store this?
113
- ),
114
- }
115
- )
96
+ await delayed_incoming (message , tx_context , check_message )
116
97
else :
117
98
LOGGER .debug (f"Incrementing for { existing_id } " )
118
99
result = await PendingMessage .collection .update_one (
@@ -123,9 +104,7 @@ async def mark_message_for_retry(
123
104
124
105
async def incoming (
125
106
pending_message : BasePendingMessage ,
126
- chain_name : Optional [str ] = None ,
127
- tx_hash : Optional [str ] = None ,
128
- height : Optional [int ] = None ,
107
+ tx_context : Optional [TxContext ] = None ,
129
108
seen_ids : Optional [Dict [Tuple , int ]] = None ,
130
109
check_message : bool = True ,
131
110
retrying : bool = False ,
@@ -140,16 +119,23 @@ async def incoming(
140
119
item_hash = pending_message .item_hash
141
120
sender = pending_message .sender
142
121
confirmations = []
122
+ chain_name = tx_context .chain if tx_context is not None else None
143
123
ids_key = (item_hash , sender , chain_name )
144
124
145
- if chain_name and tx_hash and height :
125
+ if tx_context :
146
126
if seen_ids is not None :
147
127
if ids_key in seen_ids .keys ():
148
- if height > seen_ids [ids_key ]:
128
+ if tx_context . height > seen_ids [ids_key ]:
149
129
return IncomingStatus .MESSAGE_HANDLED , []
150
130
151
131
confirmations .append (
152
- MessageConfirmation (chain = chain_name , hash = tx_hash , height = height )
132
+ MessageConfirmation (
133
+ chain = tx_context .chain ,
134
+ hash = tx_context .hash ,
135
+ height = tx_context .height ,
136
+ time = tx_context .time ,
137
+ publisher = tx_context .publisher ,
138
+ )
153
139
)
154
140
155
141
filters = {
@@ -179,14 +165,14 @@ async def incoming(
179
165
updates : Dict [str , Dict ] = {}
180
166
181
167
if existing :
182
- if seen_ids is not None and height is not None :
168
+ if seen_ids is not None and tx_context is not None :
183
169
if ids_key in seen_ids .keys ():
184
- if height > seen_ids [ids_key ]:
170
+ if tx_context . height > seen_ids [ids_key ]:
185
171
return IncomingStatus .MESSAGE_HANDLED , []
186
172
else :
187
- seen_ids [ids_key ] = height
173
+ seen_ids [ids_key ] = tx_context . height
188
174
else :
189
- seen_ids [ids_key ] = height
175
+ seen_ids [ids_key ] = tx_context . height
190
176
191
177
LOGGER .debug ("Updating %s." % item_hash )
192
178
@@ -206,9 +192,7 @@ async def incoming(
206
192
LOGGER .exception ("Can't get content of object %r" % item_hash )
207
193
await mark_message_for_retry (
208
194
message = pending_message ,
209
- chain_name = chain_name ,
210
- tx_hash = tx_hash ,
211
- height = height ,
195
+ tx_context = tx_context ,
212
196
check_message = check_message ,
213
197
retrying = retrying ,
214
198
existing_id = existing_id ,
@@ -217,13 +201,14 @@ async def incoming(
217
201
218
202
try :
219
203
validated_message = validate_pending_message (
220
- pending_message = pending_message , content = content , confirmations = confirmations
204
+ pending_message = pending_message ,
205
+ content = content ,
206
+ confirmations = confirmations ,
221
207
)
222
208
except ValidationError as e :
223
209
LOGGER .warning ("Invalid pending message: %s - %s" , item_hash , str (e ))
224
210
return IncomingStatus .FAILED_PERMANENTLY , []
225
211
226
-
227
212
# warning: those handlers can modify message and content in place
228
213
# and return a status. None has to be retried, -1 is discarded, True is
229
214
# handled and kept.
@@ -250,9 +235,7 @@ async def incoming(
250
235
LOGGER .debug ("Message type handler has failed, retrying later." )
251
236
await mark_message_for_retry (
252
237
message = pending_message ,
253
- chain_name = chain_name ,
254
- tx_hash = tx_hash ,
255
- height = height ,
238
+ tx_context = tx_context ,
256
239
check_message = check_message ,
257
240
retrying = retrying ,
258
241
existing_id = existing_id ,
@@ -270,14 +253,14 @@ async def incoming(
270
253
LOGGER .warning ("Invalid sender for %s" % item_hash )
271
254
return IncomingStatus .MESSAGE_HANDLED , []
272
255
273
- if seen_ids is not None and height is not None :
256
+ if seen_ids is not None and tx_context is not None :
274
257
if ids_key in seen_ids .keys ():
275
- if height > seen_ids [ids_key ]:
258
+ if tx_context . height > seen_ids [ids_key ]:
276
259
return IncomingStatus .MESSAGE_HANDLED , []
277
260
else :
278
- seen_ids [ids_key ] = height
261
+ seen_ids [ids_key ] = tx_context . height
279
262
else :
280
- seen_ids [ids_key ] = height
263
+ seen_ids [ids_key ] = tx_context . height
281
264
282
265
LOGGER .debug ("New message to store for %s." % item_hash )
283
266
@@ -392,5 +375,5 @@ async def incoming_chaindata(content: Dict, context: TxContext):
392
375
For now we only add it to the database, it will be processed later.
393
376
"""
394
377
await PendingTX .collection .insert_one (
395
- {"content" : content , "context" : asdict ( context )}
378
+ {"content" : content , "context" : context . dict ( )}
396
379
)
0 commit comments