Task: Implement Compact<u32> for Marshaling assetID in assets.Transfer method of polkadot in ChainSafe Gossamer (Golang)
Bug Summary
- The current Gossamer implementation does not correctly marshal substrate
Compact types required for assetID, which causes interoperability while decoding when dealing with Polkadot/Substrate protocol messages.
When scale marshaling assetId -> 31337 uint32 result is [105,122,0,0] 0x697a0000 this results in 7,834 when decoded using polkadot js library
However the polkadot protocol expects assetId as Compact which is currently not implemented in Gossammer
assetId -> 31337 CompactU32 result should be [166 233 1 0] -> 0xa6e90100
Expected Behavior
- Support for
Compact encoding should follow the [[SCALE codec specification]
https://docs.rs/parity-scale-codec/latest/src/parity_scale_codec/compact.rs.html#331
Current Behavior
- the implementation is missing, resulting in wrong payloads.
- Decoded assetID values does not match what is expected by Rust-based nodes.
Possible Solution
type CompactU32 uint32
func encodeCompactU32(val CompactU32) []byte {
switch {
case val <= 0b0011_1111: // 6 bits
// 1 byte: [value (6 bits) << 2] + mode 00 (last 2 bits)
// So just shift val by 2 to left, mode bits are 00 so no OR needed.
return []byte{byte(val << 2)}
case val <= 0b0011_1111_1111_1111: // 14 bits
// 2 bytes: [value (14 bits) << 2] + mode 01
// Pack into uint16 and encode little endian
v := uint16(val)<<2 | 0b01
buf := make([]byte, 2)
binary.LittleEndian.PutUint16(buf, v)
return buf
case val <= 0b0011_1111_1111_1111_1111_1111_1111_1111: // 30 bits
// 4 bytes: [value (30 bits) << 2] + mode 10
v := val<<2 | 0b10
buf := make([]byte, 4)
binary.LittleEndian.PutUint32(buf, uint32(v))
return buf
default:
// 5 bytes: 1 byte mode 11 + 4 bytes original value
buf := make([]byte, 5)
buf[0] = 0b11
binary.LittleEndian.PutUint32(buf[1:], uint32(val))
return buf
}
}
in marshal function
add a case
case CompactU32:
err = es.encodeCompactU32(in)
To Reproduce
- Attempt to marsha assetID using uint32 implementation in Gossamer for asset.Transfer method.
Log Output
Log Output
Specification
Acceptance Criteria
Implementation Task
Thank you 🙏
Task: Implement
Compact<u32>for Marshaling assetID in assets.Transfer method of polkadot in ChainSafe Gossamer (Golang)Bug Summary
Compacttypes required for assetID, which causes interoperability while decoding when dealing with Polkadot/Substrate protocol messages.When scale marshaling assetId -> 31337 uint32 result is [105,122,0,0]
0x697a0000this results in 7,834 when decoded using polkadot js libraryHowever the polkadot protocol expects assetId as Compact which is currently not implemented in Gossammer
assetId -> 31337 CompactU32 result should be [166 233 1 0] ->
0xa6e90100Expected Behavior
Compactencoding should follow the [[SCALE codec specification]https://docs.rs/parity-scale-codec/latest/src/parity_scale_codec/compact.rs.html#331
Current Behavior
Possible Solution
To Reproduce
Log Output
Log Output
Specification
Acceptance Criteria
Implementation Task
Thank you 🙏