tree checksum vpatch file split hunks

all signers:

antecedents: 9982-getdata 9981-replay-notice 9980-preserve-bounces

press order:

genesis
9992-handle-edge-cases-add-feedback
9991-improved-logging
9990-keep-ephemeral-ports-open
9989-show-wot-nicks
9988-hash-dedup
9987-embargoing
9986-rebroadcast-simple-hearsay-and-more
9985-single-thread
9984-unbork-at-command
9983-knobs
9982-getdata
9981-replay-notice
9980-preserve-bounces
9979-presence

patch:

- 58ABF7C81C8F6A960D5A083EE890B0B7C4D3F8834ECEF3D4523522E50AF04FD4893EED6AA16AFDCFC491FEA6D583543914EFE8C24F60A143A2CB028360187492
+ 431C84D2FA991B4C43090296E80765E1460288DE0FDB2D81ACF73A18977ACC16164111F210AF83488A80B92FA35D307ECAC26E59C860BBC12CD59A5C2A3E4C00
blatta/Makefile
(1 . 4)(1 . 4)
5 VERSION := 9980
6 VERSION := 9979
7
8 DISTFILES = Makefile blatta README.txt lib migrations tests test_net_configs start_test_net.sh
9
- AE28C098E89D25444FBD5FD93B6031D40CE4CEF4ACE438A887A6837FAFDE32137C304766A672B58898E36B75F5E8E0B784F58A0803994539D2B8C41CEFE187D1
+ 4446F38DF71CAB018B132851C12E5DF188949618983D81EAA098C41276CF5B8A96D9FEDF55EE3D5EF73412B3D5F3690CA0EA890ADCFD61867171A569D7C6E605
blatta/lib/client.py
(178 . 11)(178 . 6)
14 channel.add_member(self)
15 self.channels[irc_lower(channelname)] = channel
16 self.message_channel(channel, "JOIN", channelname, True)
17 self.reply("353 %s = %s :%s"
18 % (self.nickname,
19 channelname,
20 " ".join(sorted(x
21 for x in self.state.get_peer_handles()))))
22 self.reply("366 %s %s :End of NAMES list" % (self.nickname, channelname))
23
24 def list_handler():
(538 . 7)(533 . 19)
26 def pest_reply(self, msg):
27 self.message(":Pest NOTICE %s :%s" % (self.server.channel_name, msg))
28
29 def reply_403(self, channel):
30 def send_join(self, handle):
31 self.message(":%s JOIN %s" % (handle, self.server.channel_name))
32
33 def send_part(self, handle):
34 self.message(":%s PART %s" % (handle, self.server.channel_name))
35
36 def send_away(self, handle):
37 self.message(":%s AWAY :No recent messages" % (handle))
38
39 def send_back(self, handle):
40 self.message(":%s AWAY" % (handle))
41
42 def reply_403(self, channeyl):
43 self.reply("403 %s %s :No such channel" % (self.nickname, channel))
44
45 def reply_461(self, command):
- 225CCF41F5E87FFF8D9837F1EAF03D4806FA62F9A2A1608F4642660DFA9BC863F10860FD02879A42283CE862C9C0C0B034FD2B0158A4506FB15FA4FFD33FFFC9
+ 4AEC359E99DB8141CFDE356AF8447E0CFDA4572052407791FA5EAEB913B371254D9E9E77CC59628D4B732A61EF653B198DEB2B056444D74045A0FE4015A26D77
blatta/lib/server.py
(104 . 6)(104 . 7)
50 last_short_buffer_check = time.time()
51 last_rubbish_dispatch = time.time()
52 last_order_buffer_check = time.time()
53 last_presence_check = time.time()
54
55 while True:
56 # we don't want to be listening for client connections if there's already a client connected
(163 . 6)(164 . 11)
58 self.station.check_order_buffer()
59 last_order_buffer_check = now
60
61 # check presence
62 if last_presence_check + int(self.station.state.get_knob('presence_check_seconds')) < now:
63 self.station.report_presence()
64 last_presence_check = now
65
66 def create_directory(path):
67 if not os.path.isdir(path):
68 os.makedirs(path)
- 770B11A71459E33F5F4D2C72CF55DCB79B18C711F3041D8D23375A1419224D309A50C4F10C466527DC7EE910DBDA120ABE877D68E8981C7F51CA4A401BF54775
+ CA409E06CB9491B00378C24BB0A189ED752C01A46B3D8406F403F7E7D378D4A62F91A1ADA8EAB3FFDF374E4A62EA3A5EDF3EDB48CD5500BBDE30F3E8153C209F
blatta/lib/state.py
(1 . 22)(1 . 33)
73 import calendar
74
75 from peer import Peer
76 from message import EMPTY_CHAIN
77 from message import Message
78 import sqlite3
79 import imp
80 import binascii
81 import logging
82 import datetime
83 import time
84 import caribou
85
86 from itertools import chain
87
88 KNOBS=({'max_bounces': 3,
89 KNOBS=(
90 {
91 'max_bounces': 3,
92 'embargo_interval_seconds': 1,
93 'rubbish_interval_seconds': 10,
94 'nick': '',
95 'order_buffer_check_seconds': 5 * 60,
96 'order_buffer_expiration_seconds': 5 * 60,
97 'short_buffer_expiration_seconds': 1,
98 'short_buffer_check_interval_seconds': 1})
99 'short_buffer_check_interval_seconds': 1,
100 'peer_offline_interval_seconds': 60,
101 'peer_away_interval_seconds': 10 * 60,
102 'presence_check_seconds': 5,
103 }
104 )
105
106 class State(object):
107 def __init__(self, station, db_path=None):
(155 . 7)(166 . 7)
109 cursor = self.cursor()
110 at = []
111 if handle == None:
112 results = cursor.execute("select handle_id, address, port, updated_at from at\
113 results = cursor.execute("select handle_id, address, port, updated_at, strftime('%s', updated_at) from at\
114 order by updated_at desc").fetchall()
115 else:
116 result = cursor.execute("select handle_id from handles where handle=?",
(164 . 16)(175 . 27)
118 handle_id = result[0]
119 else:
120 return []
121 results = cursor.execute("select handle_id, address, port, updated_at from at \
122 results = cursor.execute("select handle_id, address, port, updated_at, strftime('%s', updated_at) from at \
123 where handle_id=? order by updated_at desc",
124 (handle_id,)).fetchall()
125 for result in results:
126 handle_id, address, port, updated_at = result
127 handle_id, address, port, updated_at_utc, updated_at_unixtime = result
128 h = cursor.execute("select handle from handles where handle_id=?",
129 (handle_id,)).fetchone()[0]
130 at.append({"handle": h,
131 "address": "%s:%s" % (address, port),
132 "active_at": updated_at if updated_at else "no packets received from this address"})
133 if updated_at_utc:
134 dt_format = '%Y-%m-%d %H:%M:%S.%f'
135 dt_utc = datetime.datetime.strptime(updated_at_utc, dt_format)
136 dt_local = self.utc_to_local(dt_utc)
137 updated_at = datetime.datetime.strftime(dt_local, dt_format)
138 else:
139 updated_at = "no packets received from this address"
140
141 at.append({
142 "handle": h,
143 "address": "%s:%s" % (address, port),
144 "active_at": updated_at,
145 "active_at_unixtime": int(updated_at_unixtime) if updated_at_unixtime else 0
146 })
147 return at
148
149 def import_at_and_wot(self, at_path):
(210 . 7)(232 . 7)
151 (handle_id,)).fetchone()
152
153 # if there are no AT entries for this handle, insert one
154 timestamp = datetime.datetime.now() if set_active_at else None
155 timestamp = datetime.datetime.utcnow() if set_active_at else None
156 if at_entry == None:
157 cursor.execute("insert into at(handle_id, address, port, updated_at) values(?, ?, ?, ?)",
158 (handle_id,
(357 . 7)(379 . 37)
160 peers.append(peer)
161 return peers
162
163
164
165 def handle_is_online(self, handle):
166 # last rubbish message from peer associated with handle is
167 # sufficiently recent
168 at = self.get_at(handle)[0]
169 if at["active_at_unixtime"] > time.time() - int(self.get_knob("peer_offline_interval_seconds")):
170 return True
171 else:
172 return False
173
174 def utc_to_local(self, utc_dt):
175 # get integer timestamp to avoid precision lost
176 timestamp = calendar.timegm(utc_dt.timetuple())
177 local_dt = datetime.datetime.fromtimestamp(timestamp)
178 assert utc_dt.resolution >= datetime.timedelta(microseconds=1)
179 return local_dt.replace(microsecond=utc_dt.microsecond)
180
181 def handle_is_away(self, handle):
182 # last broadcast or dm is sufficiently old
183 cursor = self.cursor()
184 away_interval_seconds = int(self.get_knob("peer_away_interval_seconds"))
185 dt = datetime.datetime.utcfromtimestamp(
186 time.time() - away_interval_seconds
187 )
188 raw_messages = cursor.execute("select message_bytes from log where created_at > ?", (dt,)).fetchall()
189 for message_bytes in raw_messages:
190 int_ts, self_chain, net_chain, speaker, body = Message._unpack_message(message_bytes[0][:])
191 if speaker == handle:
192 return False
193 return True
194
195 def get_peer_by_handle(self, handle):
196 cursor = self.cursor()
197 handle_info = cursor.execute("select handle_id, peer_id from handles where handle=?",
- B715A5E7A750D2BB552B5792E87AA5741F36B521F3C68D17B312D49D9872C842B1F1E4C87DB6E733EF3836B59D91CDC66B9217C908FB3A74DD5DEDD485EDA4A1
+ A82E5B4C782B1484C844FD7843441BF0220BD18A796963B836C23DBC00A0F4031677D7699EC86A6A4B892B194871869E3CF55F481A5D978559E235869A7C3417
blatta/lib/station.py
(1 . 6)(1 . 8)
202 import time
203
204 VERSION = 9980
205 VERSION = 9979
206 STATUS_ONLINE = 0
207 STATUS_AWAY = 1
208
209 import binascii
210 import logging
(41 . 6)(43 . 7)
212 GETDATA: self.handle_getdata,
213 IGNORE: self.handle_ignore
214 }
215 self.presence = {}
216
217 def start(self):
218 self.server.start()
(168 . 6)(171 . 33)
220 message.reporting_peers = message_with_stats['reporting_peers']
221 self.rebroadcast(message)
222
223 def report_presence(self):
224 # if handle isn't in the presence dict, check if rubbish received and send /join if so
225 for handle in self.state.get_peer_handles():
226 if self.state.handle_is_online(handle):
227 if self.presence.get(handle) is None:
228 if self.client:
229 self.presence[handle] = STATUS_ONLINE
230 self.client.send_join(handle)
231 else:
232 if self.presence.get(handle):
233 if self.client:
234 del self.presence[handle]
235 self.client.send_part(handle)
236
237 # if handle IS in the presence dict, check last message received from handle and send /away
238 for handle in self.presence.keys():
239 if self.presence[handle] is not STATUS_AWAY:
240 if self.state.handle_is_away(handle):
241 if self.client:
242 self.presence[handle] = STATUS_AWAY
243 self.client.send_away(handle)
244 # need to check if the handle is back
245 else:
246 if not self.state.handle_is_away(handle):
247 self.presence[handle] = STATUS_ONLINE
248 self.client.send_back(handle)
249
250 def report_error(self, error_code, message):
251 packet_info = message['metadata']["packet_info"]
252 address = packet_info[0]