From 2e8c228076ed38b2f59d2cefa0dbfc38a9d40355 Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Tue, 25 Apr 2023 16:54:25 +0200 Subject: [PATCH] Adding api/message/msgpack --- api/go.mod | 2 + api/go.sum | 5 + api/message/msgpack/codec.go | 18 ++ api/message/msgpack/codec_test.go | 106 +++++++++++ api/message/msgpack/msgpack.go | 301 ++++++++++++++++++++++++++++++ 5 files changed, 432 insertions(+) create mode 100644 api/message/msgpack/codec.go create mode 100644 api/message/msgpack/codec_test.go create mode 100644 api/message/msgpack/msgpack.go diff --git a/api/go.mod b/api/go.mod index 5b118a1..9637124 100644 --- a/api/go.mod +++ b/api/go.mod @@ -6,6 +6,8 @@ require ( github.com/alicebob/miniredis/v2 v2.30.2 github.com/go-redis/redis/v8 v8.11.5 github.com/go-redis/redismock/v8 v8.11.5 + github.com/shamaton/msgpack/v2 v2.1.0 + github.com/shamaton/msgpackgen v0.3.0 github.com/stretchr/testify v1.8.2 ) diff --git a/api/go.sum b/api/go.sum index ef22168..bac83be 100644 --- a/api/go.sum +++ b/api/go.sum @@ -7,6 +7,7 @@ github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/dave/jennifer v1.4.1/go.mod h1:7jEdnm+qBcxl8PC0zyp7vxcpSRnzXSt9r39tpTVGlwA= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -52,6 +53,10 @@ github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE= github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/shamaton/msgpack/v2 v2.1.0 h1:9jJ2eGZw2Wa9KExPX3KaDDckVjgr4zhXGFCfWagUWqg= +github.com/shamaton/msgpack/v2 v2.1.0/go.mod h1:aTUEmh31ziGX1Ml7wMPLVY0f4vT3CRsCvZRoSCs+VGg= +github.com/shamaton/msgpackgen v0.3.0 h1:q6o7prOEJFdF9BAPgkOtfzJbs55pQi7g44RUnEVUxtM= +github.com/shamaton/msgpackgen v0.3.0/go.mod h1:fd99fDDuxuTiWzkHC59uEGzrt/WDu+ltGZTbEWwVXIc= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= diff --git a/api/message/msgpack/codec.go b/api/message/msgpack/codec.go new file mode 100644 index 0000000..c61e16c --- /dev/null +++ b/api/message/msgpack/codec.go @@ -0,0 +1,18 @@ +package msgpack + +import ( + "github.com/shamaton/msgpack/v2" + + "github.com/eosswedenorg/thalos/api/message" +) + +//go:generate go run github.com/shamaton/msgpackgen -v -input-file ../types.go -output-file msgpack.go + +func init() { + RegisterGeneratedResolver() + + message.RegisterCodec("msgpack", message.Codec{ + Encoder: msgpack.Marshal, + Decoder: msgpack.Unmarshal, + }) +} diff --git a/api/message/msgpack/codec_test.go b/api/message/msgpack/codec_test.go new file mode 100644 index 0000000..b336308 --- /dev/null +++ b/api/message/msgpack/codec_test.go @@ -0,0 +1,106 @@ +package msgpack + +import ( + "testing" + + "github.com/eosswedenorg/thalos/api/message" + "github.com/shamaton/msgpack/v2" + "github.com/stretchr/testify/assert" +) + +func TestMsgpack_EncodeActionTrace(t *testing.T) { + RegisterGeneratedResolver() + + msg := message.ActionTrace{ + TxID: "edc06dce6320459fd644756972048da453b2816b0a434c37ddffde36778dcab3", + Name: "sellitem", + Contract: "mygame", + Receiver: "eosio", + Data: map[interface{}]interface{}{ + "item": map[interface{}]interface{}{ + "id": "2131242", + "name": "Great Sword", + "str": "100", + "agi": "20", + "dur": "100", + "qual": "epic", + }, + "from": "account1", + "to": "account2", + "amount": "1000.0000 SCAM", + }, + HexData: "d0fa1b2ab8a6fd0d1b0173df91aa9ffd277642d05780cf750", + } + + data, err := msgpack.Marshal(msg) + assert.NoError(t, err) + + res := message.ActionTrace{} + err = msgpack.Unmarshal(data, &res) + assert.NoError(t, err) + + assert.Equal(t, msg, res) +} + +func TestMsgpack_Decode(t *testing.T) { + RegisterGeneratedResolver() + + data := []byte("\x86\xa5tx_id\xd9@edc06dce6320459fd644756972048da453b2816b0a434c37ddffde36778dcab3\xa4name\xa8sellitem\xa8contract\xa6mygame\xa8receiver\xa5eosio\xa4data\x84\xa4item\x86\xa4name\xabGreat Sword\xa3str\xa3100\xa3agi\xa220\xa3dur\xa3100\xa4qual\xa4epic\xa2id\xa72131242\xa4from\xa8account1\xa2to\xa8account2\xa6amount\xae1000.0000 SCAM\xa8hex_data\xd91d0fa1b2ab8a6fd0d1b0173df91aa9ffd277642d05780cf750") + + expected := message.ActionTrace{ + TxID: "edc06dce6320459fd644756972048da453b2816b0a434c37ddffde36778dcab3", + Name: "sellitem", + Contract: "mygame", + Receiver: "eosio", + Data: map[interface{}]interface{}{ + "item": map[interface{}]interface{}{ + "id": "2131242", + "name": "Great Sword", + "str": "100", + "agi": "20", + "dur": "100", + "qual": "epic", + }, + "from": "account1", + "to": "account2", + "amount": "1000.0000 SCAM", + }, + HexData: "d0fa1b2ab8a6fd0d1b0173df91aa9ffd277642d05780cf750", + } + + res := message.ActionTrace{} + err := msgpack.Unmarshal(data, &res) + assert.NoError(t, err) + + assert.Equal(t, res, expected) +} + +func TestMsgpack_EncodeHeartbeat(t *testing.T) { + RegisterGeneratedResolver() + + msg := message.HeartBeat{ + BlockNum: 1234, + HeadBlockNum: 1235, + LastIrreversibleBlockNum: 1236, + } + + data, err := msgpack.Marshal(msg) + assert.NoError(t, err) + + assert.Equal(t, data, []byte{0x83, 0xa8, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x6e, 0x75, 0x6d, 0xcd, 0x4, 0xd2, 0xad, 0x68, 0x65, 0x61, 0x64, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x6e, 0x75, 0x6d, 0xcd, 0x4, 0xd3, 0xba, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x69, 0x72, 0x72, 0x65, 0x76, 0x65, 0x72, 0x73, 0x69, 0x62, 0x6c, 0x65, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x6e, 0x75, 0x6d, 0xcd, 0x4, 0xd4}) +} + +func TestMsgpack_DecodeHeartbeat(t *testing.T) { + data := []byte{0x83, 0xa8, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x6e, 0x75, 0x6d, 0xcd, 0x03, 0xe8, 0xad, 0x68, 0x65, 0x61, 0x64, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x6e, 0x75, 0x6d, 0xcd, 0x0b, 0xb8, 0xba, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x69, 0x72, 0x72, 0x65, 0x76, 0x65, 0x72, 0x73, 0x69, 0x62, 0x6c, 0x65, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x6e, 0x75, 0x6d, 0xcd, 0x04, 0x06} + + expected := message.HeartBeat{ + BlockNum: 1000, + HeadBlockNum: 3000, + LastIrreversibleBlockNum: 1030, + } + + msg := message.HeartBeat{} + err := msgpack.Unmarshal(data, &msg) + assert.NoError(t, err) + assert.Equal(t, expected, msg) +} diff --git a/api/message/msgpack/msgpack.go b/api/message/msgpack/msgpack.go new file mode 100644 index 0000000..29afd13 --- /dev/null +++ b/api/message/msgpack/msgpack.go @@ -0,0 +1,301 @@ +// Code generated by msgpackgen. DO NOT EDIT. + +package msgpack + +import ( + "fmt" + message "github.com/eosswedenorg/thalos/api/message" + msgpack "github.com/shamaton/msgpackgen/msgpack" + dec "github.com/shamaton/msgpackgen/msgpack/dec" + enc "github.com/shamaton/msgpackgen/msgpack/enc" +) + +// RegisterGeneratedResolver registers generated resolver. +func RegisterGeneratedResolver() { + msgpack.SetResolver(___encodeAsMap, ___encodeAsArray, ___decodeAsMap, ___decodeAsArray) +} + +// encode +func ___encode(i interface{}) ([]byte, error) { + if msgpack.StructAsArray() { + return ___encodeAsArray(i) + } else { + return ___encodeAsMap(i) + } +} + +// encodeAsArray +func ___encodeAsArray(i interface{}) ([]byte, error) { + switch v := i.(type) { + case message.HeartBeat: + encoder := enc.NewEncoder() + size, err := ___calcArraySizeHeartBeat_27424f445a2085e7723342fb0df638c626b43c59240988bc64f2d60167ee4080(v, encoder) + if err != nil { + return nil, err + } + encoder.MakeBytes(size) + b, offset, err := ___encodeArrayHeartBeat_27424f445a2085e7723342fb0df638c626b43c59240988bc64f2d60167ee4080(v, encoder, 0) + if err != nil { + return nil, err + } + if size != offset { + return nil, fmt.Errorf("%s size / offset different %d : %d", "github.com/eosswedenorg/thalos/api/message.HeartBeat", size, offset) + } + return b, err + case *message.HeartBeat: + encoder := enc.NewEncoder() + size, err := ___calcArraySizeHeartBeat_27424f445a2085e7723342fb0df638c626b43c59240988bc64f2d60167ee4080(*v, encoder) + if err != nil { + return nil, err + } + encoder.MakeBytes(size) + b, offset, err := ___encodeArrayHeartBeat_27424f445a2085e7723342fb0df638c626b43c59240988bc64f2d60167ee4080(*v, encoder, 0) + if err != nil { + return nil, err + } + if size != offset { + return nil, fmt.Errorf("%s size / offset different %d : %d", "github.com/eosswedenorg/thalos/api/message.HeartBeat", size, offset) + } + return b, err + } + return nil, nil +} + +// encodeAsMap +func ___encodeAsMap(i interface{}) ([]byte, error) { + switch v := i.(type) { + case message.HeartBeat: + encoder := enc.NewEncoder() + size, err := ___calcMapSizeHeartBeat_27424f445a2085e7723342fb0df638c626b43c59240988bc64f2d60167ee4080(v, encoder) + if err != nil { + return nil, err + } + encoder.MakeBytes(size) + b, offset, err := ___encodeMapHeartBeat_27424f445a2085e7723342fb0df638c626b43c59240988bc64f2d60167ee4080(v, encoder, 0) + if err != nil { + return nil, err + } + if size != offset { + return nil, fmt.Errorf("%s size / offset different %d : %d", "github.com/eosswedenorg/thalos/api/message.HeartBeat", size, offset) + } + return b, err + case *message.HeartBeat: + encoder := enc.NewEncoder() + size, err := ___calcMapSizeHeartBeat_27424f445a2085e7723342fb0df638c626b43c59240988bc64f2d60167ee4080(*v, encoder) + if err != nil { + return nil, err + } + encoder.MakeBytes(size) + b, offset, err := ___encodeMapHeartBeat_27424f445a2085e7723342fb0df638c626b43c59240988bc64f2d60167ee4080(*v, encoder, 0) + if err != nil { + return nil, err + } + if size != offset { + return nil, fmt.Errorf("%s size / offset different %d : %d", "github.com/eosswedenorg/thalos/api/message.HeartBeat", size, offset) + } + return b, err + } + return nil, nil +} + +// decode +func ___decode(data []byte, i interface{}) (bool, error) { + if msgpack.StructAsArray() { + return ___decodeAsArray(data, i) + } else { + return ___decodeAsMap(data, i) + } +} + +// decodeAsArray +func ___decodeAsArray(data []byte, i interface{}) (bool, error) { + switch v := i.(type) { + case *message.HeartBeat: + decoder := dec.NewDecoder(data) + offset, err := ___decodeArrayHeartBeat_27424f445a2085e7723342fb0df638c626b43c59240988bc64f2d60167ee4080(v, decoder, 0) + if err == nil && offset != decoder.Len() { + return true, fmt.Errorf("read length is different [%d] [%d] ", offset, decoder.Len()) + } + return true, err + case **message.HeartBeat: + decoder := dec.NewDecoder(data) + offset, err := ___decodeArrayHeartBeat_27424f445a2085e7723342fb0df638c626b43c59240988bc64f2d60167ee4080(*v, decoder, 0) + if err == nil && offset != decoder.Len() { + return true, fmt.Errorf("read length is different [%d] [%d] ", offset, decoder.Len()) + } + return true, err + } + return false, nil +} + +// decodeAsMap +func ___decodeAsMap(data []byte, i interface{}) (bool, error) { + switch v := i.(type) { + case *message.HeartBeat: + decoder := dec.NewDecoder(data) + offset, err := ___decodeMapHeartBeat_27424f445a2085e7723342fb0df638c626b43c59240988bc64f2d60167ee4080(v, decoder, 0) + if err == nil && offset != decoder.Len() { + return true, fmt.Errorf("read length is different [%d] [%d] ", offset, decoder.Len()) + } + return true, err + case **message.HeartBeat: + decoder := dec.NewDecoder(data) + offset, err := ___decodeMapHeartBeat_27424f445a2085e7723342fb0df638c626b43c59240988bc64f2d60167ee4080(*v, decoder, 0) + if err == nil && offset != decoder.Len() { + return true, fmt.Errorf("read length is different [%d] [%d] ", offset, decoder.Len()) + } + return true, err + } + return false, nil +} + +// calculate size from github.com/eosswedenorg/thalos/api/message.HeartBeat +func ___calcArraySizeHeartBeat_27424f445a2085e7723342fb0df638c626b43c59240988bc64f2d60167ee4080(v message.HeartBeat, encoder *enc.Encoder) (int, error) { + size := 0 + size += encoder.CalcStructHeaderFix(3) + size += encoder.CalcUint32(v.BlockNum) + size += encoder.CalcUint32(v.HeadBlockNum) + size += encoder.CalcUint32(v.LastIrreversibleBlockNum) + return size, nil +} + +// calculate size from github.com/eosswedenorg/thalos/api/message.HeartBeat +func ___calcMapSizeHeartBeat_27424f445a2085e7723342fb0df638c626b43c59240988bc64f2d60167ee4080(v message.HeartBeat, encoder *enc.Encoder) (int, error) { + size := 0 + size += encoder.CalcStructHeaderFix(3) + size += encoder.CalcStringFix(8) + size += encoder.CalcUint32(v.BlockNum) + size += encoder.CalcStringFix(12) + size += encoder.CalcUint32(v.HeadBlockNum) + size += encoder.CalcStringFix(24) + size += encoder.CalcUint32(v.LastIrreversibleBlockNum) + return size, nil +} + +// encode from github.com/eosswedenorg/thalos/api/message.HeartBeat +func ___encodeArrayHeartBeat_27424f445a2085e7723342fb0df638c626b43c59240988bc64f2d60167ee4080(v message.HeartBeat, encoder *enc.Encoder, offset int) ([]byte, int, error) { + var err error + offset = encoder.WriteStructHeaderFixAsArray(3, offset) + offset = encoder.WriteUint32(v.BlockNum, offset) + offset = encoder.WriteUint32(v.HeadBlockNum, offset) + offset = encoder.WriteUint32(v.LastIrreversibleBlockNum, offset) + return encoder.EncodedBytes(), offset, err +} + +// encode from github.com/eosswedenorg/thalos/api/message.HeartBeat +func ___encodeMapHeartBeat_27424f445a2085e7723342fb0df638c626b43c59240988bc64f2d60167ee4080(v message.HeartBeat, encoder *enc.Encoder, offset int) ([]byte, int, error) { + var err error + offset = encoder.WriteStructHeaderFixAsMap(3, offset) + offset = encoder.WriteStringFix("BlockNum", 8, offset) + offset = encoder.WriteUint32(v.BlockNum, offset) + offset = encoder.WriteStringFix("HeadBlockNum", 12, offset) + offset = encoder.WriteUint32(v.HeadBlockNum, offset) + offset = encoder.WriteStringFix("LastIrreversibleBlockNum", 24, offset) + offset = encoder.WriteUint32(v.LastIrreversibleBlockNum, offset) + return encoder.EncodedBytes(), offset, err +} + +// decode to github.com/eosswedenorg/thalos/api/message.HeartBeat +func ___decodeArrayHeartBeat_27424f445a2085e7723342fb0df638c626b43c59240988bc64f2d60167ee4080(v *message.HeartBeat, decoder *dec.Decoder, offset int) (int, error) { + offset, err := decoder.CheckStructHeader(3, offset) + if err != nil { + return 0, err + } + { + var vv uint32 + vv, offset, err = decoder.AsUint32(offset) + if err != nil { + return 0, err + } + v.BlockNum = vv + } + { + var vv uint32 + vv, offset, err = decoder.AsUint32(offset) + if err != nil { + return 0, err + } + v.HeadBlockNum = vv + } + { + var vv uint32 + vv, offset, err = decoder.AsUint32(offset) + if err != nil { + return 0, err + } + v.LastIrreversibleBlockNum = vv + } + return offset, err +} + +// decode to github.com/eosswedenorg/thalos/api/message.HeartBeat +func ___decodeMapHeartBeat_27424f445a2085e7723342fb0df638c626b43c59240988bc64f2d60167ee4080(v *message.HeartBeat, decoder *dec.Decoder, offset int) (int, error) { + keys := [][]byte{ + {uint8(0x42), uint8(0x6c), uint8(0x6f), uint8(0x63), uint8(0x6b), uint8(0x4e), uint8(0x75), uint8(0x6d)}, // BlockNum + {uint8(0x48), uint8(0x65), uint8(0x61), uint8(0x64), uint8(0x42), uint8(0x6c), uint8(0x6f), uint8(0x63), uint8(0x6b), uint8(0x4e), uint8(0x75), uint8(0x6d)}, // HeadBlockNum + {uint8(0x4c), uint8(0x61), uint8(0x73), uint8(0x74), uint8(0x49), uint8(0x72), uint8(0x72), uint8(0x65), uint8(0x76), uint8(0x65), uint8(0x72), uint8(0x73), uint8(0x69), uint8(0x62), uint8(0x6c), uint8(0x65), uint8(0x42), uint8(0x6c), uint8(0x6f), uint8(0x63), uint8(0x6b), uint8(0x4e), uint8(0x75), uint8(0x6d)}, // LastIrreversibleBlockNum + } + offset, err := decoder.CheckStructHeader(3, offset) + if err != nil { + return 0, err + } + count := 0 + for count < 3 { + var dataKey []byte + dataKey, offset, err = decoder.AsStringBytes(offset) + if err != nil { + return 0, err + } + fieldIndex := -1 + for i, key := range keys { + if len(dataKey) != len(key) { + continue + } + fieldIndex = i + for dataKeyIndex := range dataKey { + if dataKey[dataKeyIndex] != key[dataKeyIndex] { + fieldIndex = -1 + break + } + } + if fieldIndex >= 0 { + break + } + } + switch fieldIndex { + case 0: + { + var vv uint32 + vv, offset, err = decoder.AsUint32(offset) + if err != nil { + return 0, err + } + v.BlockNum = vv + } + count++ + case 1: + { + var vv uint32 + vv, offset, err = decoder.AsUint32(offset) + if err != nil { + return 0, err + } + v.HeadBlockNum = vv + } + count++ + case 2: + { + var vv uint32 + vv, offset, err = decoder.AsUint32(offset) + if err != nil { + return 0, err + } + v.LastIrreversibleBlockNum = vv + } + count++ + default: + return 0, fmt.Errorf("unknown key[%s] found", string(dataKey)) + } + } + return offset, err +}