Skip to content

Commit

Permalink
Fixed ReadSymbol binary decoding and Symbol encoding
Browse files Browse the repository at this point in the history
A Symbol is encoded using a single 64 bits value. However, the decoder
was instead assuming a precision 8 bits followed by a string encoded
binary data.

In fact, a symbol is encoded using a single 64 bits value, the most
significant byte being the precision and the rest is interpreted as a
SymbolCode.
  • Loading branch information
Matthieu Vachon committed Apr 30, 2019
1 parent dc31757 commit bbf1173
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 11 deletions.
10 changes: 10 additions & 0 deletions abidecoder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -629,6 +629,16 @@ func TestABI_Read_TimePointSec(t *testing.T) {
assert.Equal(t, `{"name":"2018-10-30T18:06:09"}`, string(out))
}

func TestABI_Read_Symbol(t *testing.T) {
abi := ABI{}
data, err := hex.DecodeString("04454f5300000000")
require.NoError(t, err)

out, err := abi.decodeField(NewDecoder(data), "name", "symbol", false, false, []byte("{}"))
require.NoError(t, err)
assert.Equal(t, `{"name":"4,EOS"}`, string(out))
}

func TestABIDecoder_analyseFieldType(t *testing.T) {

testCases := []map[string]interface{}{
Expand Down
2 changes: 1 addition & 1 deletion abiencoder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ func TestABI_Write(t *testing.T) {
{"caseName": "public_key err", "typeName": "public_key", "expectedValue": "", "json": "{\"testField\":\"EOS1111111111111111111111114T1Anm\"}", "expectedError": fmt.Errorf("writing field: public_key: checkDecode: invalid checksum")},
{"caseName": "signature", "typeName": "signature", "expectedValue": "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "json": "{\"testField\":\"SIG_K1_111111111111111111111111111111111111111111111111111111111111111116uk5ne\"}", "expectedError": nil},
{"caseName": "signature err", "typeName": "signature", "expectedValue": "", "json": "{\"testField\":\"SIG_K1_BADX11111111111111111111111111111111111111111111111111111111111116uk5ne\"}", "expectedError": fmt.Errorf("writing field: public_key: signature checksum failed, found 3aea1e96 expected e72f76ff")},
{"caseName": "symbol", "typeName": "symbol", "expectedValue": "0403454f53", "json": "{\"testField\":\"4,EOS\"}", "expectedError": nil},
{"caseName": "symbol", "typeName": "symbol", "expectedValue": "04454f5300000000", "json": "{\"testField\":\"4,EOS\"}", "expectedError": nil},
{"caseName": "symbol format error", "typeName": "symbol", "expectedValue": "", "json": "{\"testField\":\"4EOS\"}", "expectedError": fmt.Errorf("writing field: symbol: symbol should be of format '4,EOS'")},
{"caseName": "symbol format error", "typeName": "symbol", "expectedValue": "", "json": "{\"testField\":\"abc,EOS\"}", "expectedError": fmt.Errorf("writing field: symbol: strconv.ParseUint: parsing \"abc\": invalid syntax")},
{"caseName": "symbol_code", "typeName": "symbol_code", "expectedValue": "ffffffffffffffff", "json": "{\"testField\":18446744073709551615}", "expectedError": nil},
Expand Down
18 changes: 8 additions & 10 deletions decoder.go
Original file line number Diff line number Diff line change
Expand Up @@ -793,26 +793,24 @@ func (d *Decoder) ReadExtendedAsset() (out ExtendedAsset, err error) {
}

func (d *Decoder) ReadSymbol() (out *Symbol, err error) {

precision, err := d.ReadUInt8()
if err != nil {
return out, fmt.Errorf("read symbol: read precision: %s", err)
}
symbol, err := d.ReadString()
rawValue, err := d.ReadUint64()
if err != nil {
return out, fmt.Errorf("read symbol: read symbol: %s", err)
return out, fmt.Errorf("read symbol: %s", err)
}

precision := uint8(rawValue & 0xFF)
symbolCode := SymbolCode(rawValue >> 8).String()

out = &Symbol{
Precision: precision,
Symbol: symbol,
Symbol: symbolCode,
}
decoderLog.Debug("read symbol", zap.String("symbol", symbol), zap.Uint8("precision", precision))

decoderLog.Debug("read symbol", zap.String("symbol", symbolCode), zap.Uint8("precision", precision))
return
}

func (d *Decoder) ReadSymbolCode() (out SymbolCode, err error) {

n, err := d.ReadUint64()
out = SymbolCode(n)

Expand Down
7 changes: 7 additions & 0 deletions encoder.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,13 @@ func (e *Encoder) Encode(v interface{}) (err error) {
return e.writeBlockTimestamp(cv)
case CurrencyName:
return e.writeCurrencyName(cv)
case Symbol:
value, err := cv.ToUint64()
if err != nil {
return fmt.Errorf("encoding symbol: %s", err)
}

return e.writeUint64(value)
case SymbolCode:
return e.writeUint64(uint64(cv))
case Asset:
Expand Down

0 comments on commit bbf1173

Please sign in to comment.