Latest Threat Research:SANDWORM_MODE: Shai-Hulud-Style npm Worm Hijacks CI Workflows and Poisons AI Toolchains.Details
Socket
Book a DemoInstallSign in
Socket

canoser

Package Overview
Dependencies
Maintainers
1
Versions
35
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

canoser - npm Package Compare versions

Comparing version
0.8.1
to
0.8.2
+1
-1
canoser.egg-info/PKG-INFO
Metadata-Version: 2.1
Name: canoser
Version: 0.8.1
Version: 0.8.2
Summary: A python implementation of the LCS(Libra Canonical Serialization) for the Libra network.

@@ -5,0 +5,0 @@ Home-page: https://github.com/yuan-xy/canoser-python.git

@@ -34,4 +34,3 @@ README.md

test/test_struct.py
test/test_transaction_print.py
test/test_types.py
test/test_util.py

@@ -22,3 +22,3 @@ from canoser.base import Base

if self.encode_len:
output += Uint32.encode(len(arr))
output += Uint32.serialize_uint32_as_uleb128(len(arr))
for item in arr:

@@ -31,3 +31,3 @@ output += self.atype.encode(item)

if self.encode_len:
size = Uint32.decode(cursor)
size = Uint32.parse_uint32_from_uleb128(cursor)
if self.fixed_len is not None and size != self.fixed_len:

@@ -34,0 +34,0 @@ raise TypeError(f"{size} is not equal to predefined value: {self.fixed_len}")

@@ -19,3 +19,3 @@ import struct

if self.encode_len:
output += Uint32.encode(len(value))
output += Uint32.serialize_uint32_as_uleb128(len(value))
output += value

@@ -27,3 +27,3 @@ return output

if self.encode_len:
size = Uint32.decode(cursor)
size = Uint32.parse_uint32_from_uleb128(cursor)
if self.fixed_len is not None and size != self.fixed_len:

@@ -52,1 +52,27 @@ raise TypeError(f"{size} is not equal to predefined value: {self.fixed_len}")

class ByteArrayT(Base):
def encode(self, value):
output = b""
output += Uint32.serialize_uint32_as_uleb128(len(value))
output += bytes(value)
return output
def decode(self, cursor):
size = Uint32.parse_uint32_from_uleb128(cursor)
return bytearray(cursor.read_bytes(size))
def check_value(self, value):
if not isinstance(value, bytearray):
raise TypeError('value {} is not bytearray'.format(value))
def __eq__(self, other):
if not isinstance(other, ByteArrayT):
return False
return True
def to_json_serializable(cls, obj):
return obj.hex()

@@ -0,1 +1,2 @@

from __future__ import annotations
import struct

@@ -139,2 +140,32 @@ from random import randint

@classmethod
def serialize_uint32_as_uleb128(cls, value: Uint32) -> bytes:
ret = bytearray()
while value >= 0x80:
# Write 7 (lowest) bits of data and set the 8th bit to 1.
byte = (value & 0x7f)
ret.append(byte | 0x80)
value >>= 7
# Write the remaining bits of data and set the highest bit to 0.
ret.append(value)
return bytes(ret)
@classmethod
def parse_uint32_from_uleb128(cls, cursor: Cursor) -> Uint32:
max_shift = 28
value = 0
shift = 0
while not cursor.is_finished():
byte = cursor.read_u8()
val = byte & 0x7f
value |= (val << shift)
if val == byte:
return value
shift += 7
if shift > max_shift:
break
bail(f"invalid ULEB128 representation for Uint32")
class Uint64(IntType):

@@ -141,0 +172,0 @@ pack_str = "<Q"

@@ -12,3 +12,3 @@ from canoser.base import Base

output = b""
output += Uint32.encode(len(kvs))
output += Uint32.serialize_uint32_as_uleb128(len(kvs))
odict = {}

@@ -24,3 +24,3 @@ for k, v in kvs.items():

kvs = {}
size = Uint32.decode(cursor)
size = Uint32.parse_uint32_from_uleb128(cursor)
for _ in range(size):

@@ -27,0 +27,0 @@ k = self.ktype.decode(cursor)

@@ -76,3 +76,3 @@ from canoser.base import Base

def encode(cls, enum):
ret = Uint32.encode(enum.index)
ret = Uint32.serialize_uint32_as_uleb128(enum.index)
if enum.value_type is not None:

@@ -84,3 +84,3 @@ ret += enum.value_type.encode(enum.value)

def decode(cls, cursor):
index = Uint32.decode(cursor)
index = Uint32.parse_uint32_from_uleb128(cursor)
_name, datatype = cls._enums[index]

@@ -87,0 +87,0 @@ if datatype is not None:

@@ -9,3 +9,3 @@ from canoser.int_type import Uint32

utf8 = value.encode('utf-8')
output += Uint32.encode(len(utf8))
output += Uint32.serialize_uint32_as_uleb128(len(utf8))
output += utf8

@@ -16,3 +16,3 @@ return output

def decode(self, cursor):
strlen = Uint32.decode(cursor)
strlen = Uint32.parse_uint32_from_uleb128(cursor)
return str(cursor.read_bytes(strlen), encoding='utf-8')

@@ -19,0 +19,0 @@

@@ -5,3 +5,3 @@ from canoser.int_type import Uint8

from canoser.str_t import StrT
from canoser.bytes_t import BytesT
from canoser.bytes_t import BytesT, ByteArrayT
from canoser.bool_t import BoolT

@@ -26,2 +26,4 @@ from canoser.array_t import ArrayT

return BytesT()
elif field_type == bytearray:
return ByteArrayT()
elif field_type == bool:

@@ -28,0 +30,0 @@ return BoolT

@@ -1,1 +0,1 @@

version = "0.8.1"
version = "0.8.2"
Metadata-Version: 2.1
Name: canoser
Version: 0.8.1
Version: 0.8.2
Summary: A python implementation of the LCS(Libra Canonical Serialization) for the Libra network.

@@ -5,0 +5,0 @@ Home-page: https://github.com/yuan-xy/canoser-python.git

import setuptools
from canoser.version import version
import re
with open("canoser/version.py", "r") as fp:
try:
version = re.findall(
r"^version = \"([0-9\.]+)\"", fp.read(), re.M
)[0]
except IndexError:
raise RuntimeError("Unable to determine version.")
with open("README.md", "r") as fh:

@@ -9,2 +19,13 @@ content = fh.read()

tests_require = [
'pytest',
'hypothesis',
]
install_requires = [
]
setuptools.setup(

@@ -20,2 +41,4 @@ name="canoser",

packages=setuptools.find_packages(),
install_requires=install_requires,
tests_require=tests_require,
classifiers=[

@@ -22,0 +45,0 @@ "Programming Language :: Python :: 3",

@@ -18,3 +18,3 @@ from canoser import *

def test_enocde_len():
expected_output = bytes([32, 0, 0, 0]) + input
expected_output = bytes([32]) + input
actual_output = Address1.encode(input)

@@ -35,2 +35,12 @@ assert expected_output == actual_output

addr2 = AddrStruct.deserialize(ser)
assert addrs.map == addr2.map
assert addrs.map == addr2.map
class BArrayStruct(Struct):
_fields = [('map', {Address2: bytearray})]
def test_bytearray():
amap = {input: bytearray(b'ba')}
addrs = BArrayStruct(amap)
ser = addrs.serialize()
addr2 = BArrayStruct.deserialize(ser)
assert addrs.map == addr2.map

@@ -16,5 +16,5 @@ from canoser import *

bstr = t12.serialize()
assert bstr == bytes([12]) + Uint32.encode(2) + t1.serialize() + t2.serialize()
assert bstr == bytes([12]) + Uint32.serialize_uint32_as_uleb128(2) + t1.serialize() + t2.serialize()
tt = Circular.deserialize(bstr)
assert tt == t12
assert Circular.deserialize(t1.serialize()) == t1

@@ -39,4 +39,4 @@ from canoser import *

bs = Bools.encode(x)
assert bs == b'\x03\x00\x00\x00\x01\x00\x01'
assert bs == b'\x03\x01\x00\x01'
x2 = Bools.deserialize(bs)
assert x == x2

@@ -42,3 +42,3 @@ import pytest

assert t_arg.value_type == Uint64
assert t_arg.serialize() == b"\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00"
assert t_arg.serialize() == b"\x00\x02\x00\x00\x00\x00\x00\x00\x00"
assert t_arg == TransactionArgument.deserialize(t_arg.serialize())

@@ -77,8 +77,8 @@ t_arg.value = 3

assert Enum1.new_with_index_value(1, None) == Enum1('opt2')
assert Enum1.encode(e1) == b'\x00\x00\x00\x00\x01\x00\x00\x00\x05'
assert Enum1.encode(e2) == b'\x01\x00\x00\x00'
obj = Enum1.decode(Cursor(b'\x00\x00\x00\x00\x01\x00\x00\x00\x05'))
assert Enum1.encode(e1) == b'\x00\x01\x05'
assert Enum1.encode(e2) == b'\x01'
obj = Enum1.decode(Cursor(b'\x00\x01\x05'))
assert obj.index == 0
assert obj.value == [5]
obj = Enum1.decode(Cursor(b'\x01\x00\x00\x00'))
obj = Enum1.decode(Cursor(b'\x01'))
assert obj.index == 1

@@ -99,3 +99,3 @@ assert obj.value == None

sx = x.serialize()
assert sx == b'\x00\x00\x00\x00'
assert sx == b'\x00'
x2 = EStruct.deserialize(sx)

@@ -118,5 +118,5 @@ assert x.enum.index == x2.enum.index

sx = x.serialize()
assert sx == b'\x01\x00\x00\x00\x03\x00\x00\x00' +\
b'\x02\x00\x00\x00' + b'\x02\x00\x00\x00ab' + b'\x01\x00\x00\x00c' +\
b'\x01\x00\x00\x00' + b'\x01\x00\x00\x00d' + b'\x00\x00\x00\x00'
assert sx == b'\x01\x03' +\
b'\x02' + b'\x02ab' + b'\x01c' +\
b'\x01' + b'\x01d' + b'\x00'
x2 = EStruct2.deserialize(sx)

@@ -123,0 +123,0 @@ assert x.enum.index == x2.enum.index

@@ -7,9 +7,14 @@ import pytest

#copy form libra source code
TEST_VECTOR_1 = "ffffffffffffffff060000006463584d4237640000000000000009000000000102\
03040506070820000000050505050505050505050505050505050505050505050505\
05050505050505056300000001030000000100000001030000001615430300000000\
381503000000160a05040000001415596903000000c9175a"
TEST_VECTOR_1 = [
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x06, 0x64, 0x63, 0x58, 0x4d, 0x42, 0x37,
0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
0x06, 0x07, 0x08, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
0x05, 0x05, 0x05, 0x05, 0x05, 0x63, 0x00, 0x00, 0x00, 0x01, 0x03, 0x01, 0x01, 0x03, 0x16,
0x15, 0x43, 0x03, 0x00, 0x38, 0x15, 0x03, 0x16, 0x0a, 0x05, 0x04, 0x14, 0x15, 0x59, 0x69,
0x03, 0xc9, 0x17, 0x5a,
]
class Addr(Struct):
_fields = [('addr', [Uint8, 32])]
_fields = [('addr', [Uint8, 32, False])]

@@ -62,5 +67,5 @@

str1 = foo.serialize()
str2 = bytes.fromhex(TEST_VECTOR_1)
str2 = bytes(TEST_VECTOR_1)
assert str1 == str2
foo2 = Foo.deserialize(str1)
assert foo == foo2

@@ -29,3 +29,3 @@ from canoser import *

def test_enocde_len():
expected_output0 = [32, 0, 0, 0] + expected_output
expected_output0 = [32] + expected_output
actual_output = Address1.encode(input)

@@ -32,0 +32,0 @@ assert bytes(expected_output0) == actual_output

@@ -52,3 +52,3 @@ import pytest

sx = x.serialize()
assert b"\3\0\0\0\1\0\1" == sx
assert b"\3\1\0\1" == sx
x2 = ArrayS.deserialize(sx)

@@ -59,3 +59,3 @@ assert x.array == x2.array

with pytest.raises(TypeError):
ArrayS.deserialize(b"\3\0\0\0\1\0\2")
ArrayS.deserialize(b"\3\1\0\2")
x = ArrayS([])

@@ -145,3 +145,3 @@ with pytest.raises(TypeError):

sx = x.serialize()
assert sx == b'\x03\x00\x00\x00\x61\x62\x63\x01\x00\x02\x00'
assert sx == b'\x03\x61\x62\x63\x01\x00\x02\x00'
x2 = TupleS.deserialize(sx)

@@ -148,0 +148,0 @@ assert x.tp == x2.tp

@@ -174,13 +174,13 @@ from canoser import *

arrt = ArrayT(Uint8, 2)
assert arrt.encode([1, 2]) == b'\x02\x00\x00\x00\x01\x02'
arr = arrt.decode(Cursor(b'\x02\x00\x00\x00\x01\x02'))
assert arrt.encode([1, 2]) == b'\x02\x01\x02'
arr = arrt.decode(Cursor(b'\x02\x01\x02'))
assert arr == [1, 2]
with pytest.raises(TypeError):
arrt.decode(Cursor(b'\x01\x00\x00\x00\x01\x02'))
arrt.decode(Cursor(b'\x01\x01\x02'))
with pytest.raises(TypeError):
arrt.decode(Cursor(b'\x03\x00\x00\x00\x01\x02'))
arrt.decode(Cursor(b'\x03\x01\x02'))
def test_deserialize_int_array():
arrt = ArrayT(BoolT, 2)
bools = arrt.decode(Cursor([2,0,0,0,1,0]))
bools = arrt.decode(Cursor([2,1,0]))
assert bools == [True, False]

@@ -190,4 +190,4 @@

tuplet = TupleT(StrT, Uint8, BoolT)
assert tuplet.encode(("abc", 1, False)) == b'\x03\x00\x00\x00\x61\x62\x63\x01\x00'
ret = tuplet.decode(Cursor(b'\x03\x00\x00\x00\x61\x62\x63\x01\x00'))
assert tuplet.encode(("abc", 1, False)) == b'\x03\x61\x62\x63\x01\x00'
ret = tuplet.decode(Cursor(b'\x03\x61\x62\x63\x01\x00'))
assert ret == ("abc", 1, False)

@@ -194,0 +194,0 @@

import pytest
import pdb
from canoser import *
from datetime import datetime
import struct
import json
# Test Example in https://github.com/libra/libra/tree/master/common/canonical_serialization/README.md
ADDRESS_LENGTH = 32
ED25519_PUBLIC_KEY_LENGTH = 32
ED25519_SIGNATURE_LENGTH = 64
class Address(DelegateT):
delegate_type = [Uint8, ADDRESS_LENGTH]
class ByteArray(DelegateT):
delegate_type = [Uint8]
class TransactionArgument(RustEnum):
_enums = [
('U64', Uint64),
('Address', Address),
('String', str),
('ByteArray', ByteArray)
]
class WriteOp(RustEnum):
_enums = [
('Deletion', None),
('Value', ByteArray)
]
class AccessPath(Struct):
_fields = [
('address', Address),
('path', ByteArray)
]
class Program(Struct):
_fields = [
('code', [Uint8]),
('args', [TransactionArgument]),
('modules', [[Uint8]])
]
# `WriteSet` contains all access paths that one transaction modifies. Each of them is a `WriteOp`
# where `Value(val)` means that serialized representation should be updated to `val`, and
# `Deletion` means that we are going to delete this access path.
class WriteSet(Struct):
_fields = [
('write_set', [(AccessPath, WriteOp)])
]
class Module(Struct):
_fields = [
('code', [Uint8])
]
class Script(Struct):
_fields = [
('code', [Uint8]),
('args', [TransactionArgument])
]
class TransactionPayload(RustEnum):
_enums = [
('Program', Program),
('WriteSet', WriteSet),
('Script', Script),
('Module', Module)
]
class RawTransaction(Struct):
_fields = [
('sender', Address),
('sequence_number', Uint64),
('payload', TransactionPayload),
('max_gas_amount', Uint64),
('gas_unit_price', Uint64),
('expiration_time', Uint64)
]
def test_readme_example1():
lcs = '0200000020000000A71D76FAA2D2D5C3224EC3D41DEB293973564A791E55C6782BA76C2BF0495F9A2100000001217DA6C6B3E19F1825CFB2676DAECCE3BF3DE03CF26647C78DF00B371B25CC970000000020000000C4C63F80C74B11263E421EBF8486A4E398D0DBC09FA7D4F62CCDB309F3AEA81F0900000001217DA6C6B3E19F180100000004000000CAFED00D'
tx = WriteSet.deserialize(bytes.fromhex(lcs))
print(tx)
def test_readme_example2():
lcs = '00000000040000006D6F766502000000020000000900000043414645204430304402000000090000006361666520643030640300000001000000CA02000000FED0010000000D'
tx = TransactionPayload.deserialize(bytes.fromhex(lcs))
print(tx)
def test_readme_example3():
lcs = '010000000200000020000000A71D76FAA2D2D5C3224EC3D41DEB293973564A791E55C6782BA76C2BF0495F9A2100000001217DA6C6B3E19F1825CFB2676DAECCE3BF3DE03CF26647C78DF00B371B25CC970000000020000000C4C63F80C74B11263E421EBF8486A4E398D0DBC09FA7D4F62CCDB309F3AEA81F0900000001217DA6C6B3E19F180100000004000000CAFED00D'
tx = TransactionPayload.deserialize(bytes.fromhex(lcs))
print(tx)
def test_readme_example4():
lcs = '200000003A24A61E05D129CACE9E0EFC8BC9E33831FEC9A9BE66F50FD352A2638A49B9EE200000000000000000000000040000006D6F766502000000020000000900000043414645204430304402000000090000006361666520643030640300000001000000CA02000000FED0010000000D1027000000000000204E0000000000008051010000000000'
tx = RawTransaction.deserialize(bytes.fromhex(lcs))
assert tx.__str__() == """{
"sender": "3a24a61e05d129cace9e0efc8bc9e33831fec9a9be66f50fd352a2638a49b9ee",
"sequence_number": 32,
"payload": {
"Program": {
"code": "6d6f7665",
"args": [
{
"String": "CAFE D00D"
},
{
"String": "cafe d00d"
}
],
"modules": [
"ca",
"fed0",
"0d"
]
}
},
"max_gas_amount": 10000,
"gas_unit_price": 20000,
"expiration_time": 86400
}"""
def test_readme_example5():
lcs = '20000000C3398A599A6F3B9F30B635AF29F2BA046D3A752C26E9D0647B9647D1F4C04AD42000000000000000010000000200000020000000A71D76FAA2D2D5C3224EC3D41DEB293973564A791E55C6782BA76C2BF0495F9A2100000001217DA6C6B3E19F1825CFB2676DAECCE3BF3DE03CF26647C78DF00B371B25CC970000000020000000C4C63F80C74B11263E421EBF8486A4E398D0DBC09FA7D4F62CCDB309F3AEA81F0900000001217DA6C6B3E19F180100000004000000CAFED00D00000000000000000000000000000000FFFFFFFFFFFFFFFF'
tx = RawTransaction.deserialize(bytes.fromhex(lcs))
assert tx.__str__() == """{
"sender": "c3398a599a6f3b9f30b635af29f2ba046d3a752c26e9d0647b9647d1f4c04ad4",
"sequence_number": 32,
"payload": {
"WriteSet": {
"write_set": [
[
{
"address": "a71d76faa2d2d5c3224ec3d41deb293973564a791e55c6782ba76c2bf0495f9a",
"path": "01217da6c6b3e19f1825cfb2676daecce3bf3de03cf26647c78df00b371b25cc97"
},
"Deletion"
],
[
{
"address": "c4c63f80c74b11263e421ebf8486a4e398d0dbc09fa7d4f62ccdb309f3aea81f",
"path": "01217da6c6b3e19f18"
},
{
"Value": "cafed00d"
}
]
]
}
},
"max_gas_amount": 0,
"gas_unit_price": 0,
"expiration_time": 18446744073709551615
}"""
amap = tx.to_json_serializable()
assert tx.to_json(indent=2) == json.dumps(amap, sort_keys=False, indent=2)
assert tx.to_json(indent=2) == tx.__str__()