Skip to content

Commit 65a3bab

Browse files
authored
Merge pull request #25 from brave-intl/fix/address-removal
Fix failure to remove
2 parents 11b432c + 3a41c5c commit 65a3bab

File tree

3 files changed

+378
-66
lines changed

3 files changed

+378
-66
lines changed

generate-address-list.py

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,6 @@
1010
FEATURE_TYPE_TEXT = "Digital Currency Address - "
1111
NAMESPACE = {'sdn': 'https://sanctionslistservice.ofac.treas.gov/api/PublicationPreview/exports/ADVANCED_XML'}
1212

13-
# List of assets that have been sanctioned by the OFAC.
14-
# Possible assets be seen by grepping the sdn_advanced.xml file for "Digital Currency Address".
15-
POSSIBLE_ASSETS = ["XBT", "ETH", "XMR", "LTC", "ZEC", "DASH", "BTG", "ETC",
16-
"BSV", "BCH", "XVG", "USDT", "XRP", "ARB", "BSC", "USDC",
17-
"TRX"]
18-
1913
# List of implemented output formats
2014
OUTPUT_FORMATS = ["TXT", "JSON"]
2115

@@ -130,6 +124,19 @@ def main():
130124
else:
131125
output_formats = args.format
132126

127+
# Delete old output files to ensure removed addresses/assets are cleaned up
128+
# This loop handles the case where an asset is completely removed from OFAC list
129+
for fmt in output_formats:
130+
if fmt == "TXT":
131+
pattern = "sanctioned_addresses_*.txt"
132+
elif fmt == "JSON":
133+
pattern = "sanctioned_addresses_*.json"
134+
else:
135+
continue
136+
137+
for old_file in args.outpath.glob(pattern):
138+
old_file.unlink()
139+
133140
for asset in assets:
134141
address_id = get_address_id(root, asset)
135142
addresses = get_sanctioned_addresses(root, address_id)

update_s3_objects.py

Lines changed: 38 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -196,32 +196,29 @@ def process_action_chunk(action_chunk, bucket, prefix, dry_run, s3_client):
196196
}
197197

198198
for action in action_chunk:
199-
created = False
200-
removed = False
199+
success = False
200+
error = None
201+
201202
match action['action']:
202203
case 'add':
203-
created, error = create_s3_object(
204-
action['address'],
205-
bucket,
206-
prefix,
207-
dry_run,
208-
s3_client
204+
success, error = create_s3_object(
205+
action['address'], bucket, prefix, dry_run, s3_client
209206
)
207+
if success:
208+
results['created'] += 1
209+
else:
210+
results['errors'] += 1
211+
if error: logger.error(error)
210212
case 'remove':
211-
removed, error = delete_s3_object(
212-
action['address'],
213-
bucket,
214-
prefix,
215-
dry_run,
216-
s3_client
213+
success, error = delete_s3_object(
214+
action['address'], bucket, prefix, dry_run, s3_client
217215
)
218-
if created:
219-
results['created'] += 1
220-
if removed:
221-
results['removed'] += 1
222-
else:
223-
results['errors'] += 1
224-
logger.error(error)
216+
if success:
217+
results['removed'] += 1
218+
else:
219+
results['errors'] += 1
220+
if error:
221+
logger.error(error)
225222

226223
return results
227224

@@ -326,28 +323,31 @@ def main():
326323
s3_resource = boto3.resource('s3')
327324
bucket = s3_resource.Bucket(args.bucket)
328325

329-
# Read sanctioned addresses
330326
sdn_addresses = read_sanctioned_addresses(args.directory)
331-
s3_addresses = [decode(obj.key.replace(OBJECT_PREFIX, "")) for obj in bucket.objects.all()]
327+
s3_addresses = [
328+
decode(obj.key.replace(OBJECT_PREFIX, ""))
329+
for obj in bucket.objects.all()
330+
]
332331

333-
if not sdn_addresses:
334-
logger.error("No addresses found in SDN list. Exiting.")
335-
return
332+
# If SDN is empty, this will generate 'remove' actions for all S3 objects
336333
actions = generate_actions(sdn_addresses, s3_addresses)
334+
# Safety check - but allow it to proceed if SDN is legitimately empty
337335
remove_count = sum(1 for a in actions if a['action'] == 'remove')
338336
total_count = len(s3_addresses)
339-
percent_removed = (remove_count / total_count) * 100
340-
if percent_removed > 15:
341-
# Only manual runs by whitelisted actors can bypass the 15% limit
342-
if os.getenv('GITHUB_ACTOR') not in ["mrose17", "Sneagan", "mschfh"]:
343-
logger.error("Too many addresses are set to be removed. Human "
344-
f'review required.\nTotal addresses: {total_count}\n'
345-
f'Addresses to remove: {remove_count}')
346-
raise Exception("Too many addresses are set to be removed. Human "
347-
f'review required.\nTotal addresses: {total_count}'
348-
f'\nAddresses to remove: {remove_count}')
349-
350-
# Create S3 objects
337+
338+
if total_count > 0:
339+
percent_removed = (remove_count / total_count) * 100
340+
if percent_removed > 15:
341+
# Only manual runs by whitelisted actors can bypass the 15% limit
342+
if os.getenv('GITHUB_ACTOR') not in ["mrose17", "Sneagan", "mschfh"]:
343+
logger.error("Too many addresses are set to be removed. Human "
344+
f'review required.\nTotal addresses: {total_count}\n'
345+
f'Addresses to remove: {remove_count}')
346+
raise Exception("Too many addresses are set to be removed. Human "
347+
f'review required.\nTotal addresses: {total_count}'
348+
f'\nAddresses to remove: {remove_count}')
349+
350+
# Create/delete S3 objects
351351
result = reconcile_s3(
352352
actions=actions,
353353
bucket=args.bucket,

0 commit comments

Comments
 (0)