From ab198b404966640a2c78a155d66cda816f639fe8 Mon Sep 17 00:00:00 2001 From: Leonard Lyubich Date: Mon, 11 May 2020 16:31:39 +0300 Subject: [PATCH] state: implement SignedDataSource on ChangeStateRequest message --- state/sign.go | 35 +++++++++++++++++++++++++++++++++++ state/sign_test.go | 12 ++++++++++++ state/types.go | 24 ++++++++++++++++++++++++ state/types_test.go | 18 ++++++++++++++++++ 4 files changed, 89 insertions(+) create mode 100644 state/types.go create mode 100644 state/types_test.go diff --git a/state/sign.go b/state/sign.go index 8316b52..9193ebc 100644 --- a/state/sign.go +++ b/state/sign.go @@ -1,5 +1,9 @@ package state +import ( + "io" +) + // SignedData returns payload bytes of the request. // // Always returns an empty slice. @@ -34,3 +38,34 @@ func (m DumpRequest) SignedData() ([]byte, error) { func (m DumpVarsRequest) SignedData() ([]byte, error) { return make([]byte, 0), nil } + +// SignedData returns payload bytes of the request. +func (m ChangeStateRequest) SignedData() ([]byte, error) { + data := make([]byte, m.SignedDataSize()) + + if _, err := m.ReadSignedData(data); err != nil { + return nil, err + } + + return data, nil +} + +// SignedDataSize returns payload size of the request. +func (m ChangeStateRequest) SignedDataSize() int { + return m.GetState().Size() +} + +// ReadSignedData copies payload bytes to passed buffer. +// +// If the Request size is insufficient, io.ErrUnexpectedEOF returns. +func (m ChangeStateRequest) ReadSignedData(p []byte) (int, error) { + if len(p) < m.SignedDataSize() { + return 0, io.ErrUnexpectedEOF + } + + var off int + + off += copy(p[off:], m.GetState().Bytes()) + + return off, nil +} diff --git a/state/sign_test.go b/state/sign_test.go index dd55d21..9b2bca9 100644 --- a/state/sign_test.go +++ b/state/sign_test.go @@ -47,6 +47,18 @@ func TestRequestSign(t *testing.T) { return new(DumpVarsRequest) }, }, + { + constructor: func() sigType { + return new(ChangeStateRequest) + }, + payloadCorrupt: []func(sigType){ + func(s sigType) { + req := s.(*ChangeStateRequest) + + req.SetState(req.GetState() + 1) + }, + }, + }, } for _, item := range items { diff --git a/state/types.go b/state/types.go new file mode 100644 index 0000000..6b572db --- /dev/null +++ b/state/types.go @@ -0,0 +1,24 @@ +package state + +import ( + "encoding/binary" +) + +// SetState is a State field setter. +func (m *ChangeStateRequest) SetState(st ChangeStateRequest_State) { + m.State = st +} + +// Size returns the size of the state binary representation. +func (ChangeStateRequest_State) Size() int { + return 4 +} + +// Bytes returns the state binary representation. +func (x ChangeStateRequest_State) Bytes() []byte { + data := make([]byte, x.Size()) + + binary.BigEndian.PutUint32(data, uint32(x)) + + return data +} diff --git a/state/types_test.go b/state/types_test.go new file mode 100644 index 0000000..5d5f5de --- /dev/null +++ b/state/types_test.go @@ -0,0 +1,18 @@ +package state + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestChangeStateRequestGettersSetters(t *testing.T) { + t.Run("state", func(t *testing.T) { + st := ChangeStateRequest_State(1) + m := new(ChangeStateRequest) + + m.SetState(st) + + require.Equal(t, st, m.GetState()) + }) +}