From 31074e4cd66c87289e33da44a1da2f7cc0720de9 Mon Sep 17 00:00:00 2001 From: Anthony Martin <github@martin-studio.com> Date: Thu, 11 Oct 2018 13:16:18 -0700 Subject: [PATCH] added prefixsub module for dealing with mainnet prefix #143 --- test/prefixsub_test.py | 99 ++++++++++++++++++++++++++++++++++++++++++ tinman/main.py | 2 + tinman/prefixsub.py | 79 +++++++++++++++++++++++++++++++++ 3 files changed, 180 insertions(+) create mode 100644 test/prefixsub_test.py create mode 100644 tinman/prefixsub.py diff --git a/test/prefixsub_test.py b/test/prefixsub_test.py new file mode 100644 index 0000000..85601d1 --- /dev/null +++ b/test/prefixsub_test.py @@ -0,0 +1,99 @@ +import unittest +import json +import shutil + +from tinman import prefixsub + +class PrefixsubTest(unittest.TestCase): + def test_transform_prefix_str(self): + object = "STM6LLegbAgLAy28EHrffBVuANFWcFgmqRMW13wBmTExqFE9SCkg4" + result = prefixsub.transform_prefix(object) + expected_result = "TST6LLegbAgLAy28EHrffBVuANFWcFgmqRMW13wBmTExqFE9SCkg4" + self.assertEqual(result, expected_result) + + def test_transform_prefix_str_wrong_length(self): + object = "STM6LLeg" + result = prefixsub.transform_prefix(object) + expected_result = "STM6LLeg" + self.assertEqual(result, expected_result) + + def test_transform_prefix_list(self): + object = ["STM6LLegbAgLAy28EHrffBVuANFWcFgmqRMW13wBmTExqFE9SCkg4"] + prefixsub.transform_prefix(object) + expected_result = ["TST6LLegbAgLAy28EHrffBVuANFWcFgmqRMW13wBmTExqFE9SCkg4"] + self.assertEqual(object, expected_result) + + def test_transform_prefix_dict(self): + object = {"public_key": "STM6LLegbAgLAy28EHrffBVuANFWcFgmqRMW13wBmTExqFE9SCkg4"} + prefixsub.transform_prefix(object) + expected_result = {"public_key": "TST6LLegbAgLAy28EHrffBVuANFWcFgmqRMW13wBmTExqFE9SCkg4"} + self.assertEqual(object, expected_result) + + def test_transform_prefix_trivial_account_update_operation(self): + object = { + "account":"alice", + "json_metadata":"{\"profile\":{\"about\":\"Curiousness\",\"location\":\"Wonderland\",\"name\":\"Alice\"}}", + "memo_key":"STM6XzTJphLvDCifPvmQ2WtUWxgQk9AZiFEMucPiTKikJCNMZabAq" + } + prefixsub.transform_prefix(object) + expected_result = { + "account":"alice", + "json_metadata":"{\"profile\":{\"about\":\"Curiousness\",\"location\":\"Wonderland\",\"name\":\"Alice\"}}", + "memo_key":"TST6XzTJphLvDCifPvmQ2WtUWxgQk9AZiFEMucPiTKikJCNMZabAq" + } + self.assertEqual(object, expected_result) + + def test_transform_prefix_complex_account_update_operation(self): + """ + Note, this test contains a public key pattern in the json_metadata field + which should be ignored for the test to pass. + """ + + object = { + "account":"bob", + "active":{ + "account_auths":[], + "key_auths":[["STM714aBC2zNkqfrrWSC1dVnZKPeFiXZg4RAHPRNzdr7Asue3mtnF", 1]], + "weight_threshold":1 + }, + "json_metadata":"{\"profile\":{\"cover_image\":\"https://imgur.org/STM714aBC2zNkqfrrWSC1dVnZKPeFiXZg4RAHPRNzdr7Asue3mtnF.jpg\"}}", + "memo_key":"STM5AjkXufK1oDPNqRVyLoj3uYoHTnwyP1pcbKCZGkRLscSToh2xV", + "owner":{ + "account_auths":[], + "key_auths":[["STM8QVEwTJG6NZuhZcR8fT66yKAfYG6ep8hT8eTLgAGMaq2RXPVCW", 1]], + "weight_threshold":1 + }, + "posting":{ + "account_auths":[ + ["alice", 1], + ["charlie", 1] + ], + "key_auths":[["STM7vBuapLzXVi9qo9vu8VUD2YieNTZ6w8iMjGUGf2j3eePYA2Y5k", 1]], + "weight_threshold":1 + } + } + prefixsub.transform_prefix(object) + expected_result = { + "account":"bob", + "active":{ + "account_auths":[], + "key_auths":[["TST714aBC2zNkqfrrWSC1dVnZKPeFiXZg4RAHPRNzdr7Asue3mtnF", 1]], + "weight_threshold":1 + }, + "json_metadata":"{\"profile\":{\"cover_image\":\"https://imgur.org/STM714aBC2zNkqfrrWSC1dVnZKPeFiXZg4RAHPRNzdr7Asue3mtnF.jpg\"}}", + "memo_key":"TST5AjkXufK1oDPNqRVyLoj3uYoHTnwyP1pcbKCZGkRLscSToh2xV", + "owner":{ + "account_auths":[], + "key_auths":[["TST8QVEwTJG6NZuhZcR8fT66yKAfYG6ep8hT8eTLgAGMaq2RXPVCW", 1]], + "weight_threshold":1 + }, + "posting":{ + "account_auths":[ + ["alice", 1], + ["charlie", 1] + ], + "key_auths":[["TST7vBuapLzXVi9qo9vu8VUD2YieNTZ6w8iMjGUGf2j3eePYA2Y5k", 1]], + "weight_threshold":1 + } + } + self.assertEqual(object, expected_result) diff --git a/tinman/main.py b/tinman/main.py index 6e9611c..67ba1da 100755 --- a/tinman/main.py +++ b/tinman/main.py @@ -12,6 +12,7 @@ from . import submit from . import warden from . import amountsub from . import durables +from . import prefixsub class Help(object): @@ -33,6 +34,7 @@ commands = collections.OrderedDict(( ("warden" , warden ), ("amountsub" , amountsub ), ("durables" , durables ), + ("prefixsub", prefixsub), ("help" , Help ), )) diff --git a/tinman/prefixsub.py b/tinman/prefixsub.py new file mode 100644 index 0000000..37e8c29 --- /dev/null +++ b/tinman/prefixsub.py @@ -0,0 +1,79 @@ +#!/usr/bin/env python3 + +from . import util + +import argparse +import json +import sys +import math + +MAINNET_PREFIX = "STM" +TESTNET_PREFIX = "TST" +PUB_KEY_LEN = 53 +MAINNET_DISABLED_WITNESS_KEY = "STM1111111111111111111111111111111114T1Anm" +TESTNET_DISABLED_WITNESS_KEY = "TST1111111111111111111111111111111114T1Anm" + +def transform_prefix(object): + if isinstance(object, list): + for i, e in enumerate(object): + if isinstance(e, str): + object[i] = transform_prefix(e) + else: + transform_prefix(e) + elif isinstance(object, dict): + for key in object.keys(): + field = object[key] + + if isinstance(field, str): + object[key] = transform_prefix(field) + else: + transform_prefix(field) + + elif isinstance(object, str): + if len(object) == PUB_KEY_LEN and object[:3] == MAINNET_PREFIX: + return TESTNET_PREFIX + object[3:] + elif object == MAINNET_DISABLED_WITNESS_KEY: + return TESTNET_DISABLED_WITNESS_KEY + else: + return object + +def main(argv): + parser = argparse.ArgumentParser(prog=argv[0], description="Substitute prefix") + parser.add_argument("-i", "--input-file", default="-", dest="input_file", metavar="FILE", help="File to read actions from") + parser.add_argument("-o", "--output-file", default="-", dest="output_file", metavar="FILE", help="File to write actions to") + args = parser.parse_args(argv[1:]) + + if args.output_file == "-": + output_file = sys.stdout + else: + output_file = open(args.output_file, "w") + + if args.input_file == "-": + input_file = sys.stdin + else: + input_file = open(args.input_file, "r") + + for line in input_file: + line = line.strip() + act, act_args = json.loads(line) + if act != "submit_transaction": + continue + + if not act_args["tx"]: + continue + + for op in act_args["tx"]["operations"]: + transform_prefix(op["value"]) + + transformed_line = json.dumps([act, act_args]) + + output_file.write(transformed_line) + output_file.write("\n") + output_file.flush() + if args.input_file != "-": + input_file.close() + if args.output_file != "-": + output_file.close() + +if __name__ == "__main__": + main(sys.argv) -- GitLab