Skip to content

Commit

Permalink
BlockTimestamp fix. Optional field impl. Structs like on p2p :)
Browse files Browse the repository at this point in the history
  • Loading branch information
abourget committed Apr 24, 2018
1 parent 05a7e49 commit 5fbf4a7
Show file tree
Hide file tree
Showing 6 changed files with 139 additions and 43 deletions.
28 changes: 28 additions & 0 deletions DIALOG-ANNOTATED.md
Original file line number Diff line number Diff line change
Expand Up @@ -1412,3 +1412,31 @@ d32a


UNAUTHORIZED




0f010000
06
000330907937f721e855bb1ff0b6143af8bd82cba550d1c20438b29dbb30b2a7
4170e244 = 2004 ou 2008, si c'est un nom de secondes depuis l'EPOCH (1970)
d756399dd08666bbbe2e44c0f0967b9dfaa02b33234a2a31e52319961cf2de52
9eb4bc72f5b7b28b86848e837ce30805ae57e81023189eabd77d516a12ac02a7
e9f40f2a2d66d2199a8bc9983e30066f61cbf24230653bb74b9c91e8d7b972ab
0000000000ea3055 eosio
00000000
00 optional not there !!
00205c87c866b524d313866c8c0c036518ee4e898b133d570b41403e31bb072f909d1b8e40775e261e24ae787aeeb127e5f25725ab684f382f7f92a68ee4672e1fac producer_signature 66 bytes
01 []region
0000 region
01 []cycles
01 []shardsummary
00 []readlocks
01 []writelocks
0000000000ea3055 "eosio"
0000000000ea3055 "eosio"
01 []transactions
00 status = executed
13 KCPUUsage = 19
26 NetusageWords = 38
fd25e5ad35924d41b9611304b682dcfca0bf1154008f97268d43bfaba999b104 transaction ID
25 changes: 25 additions & 0 deletions binary.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,15 @@ func (e *Encoder) writeVarint(v int) error {
}

func (b *Encoder) Encode(v interface{}) (err error) {
if i, ok := v.(OptionalBinaryMarshaler); ok {
if i.OptionalBinaryMarshalerPresent() {
b.w.Write([]byte(0x01))
} else {
b.w.Write([]byte(0x00))
return nil
}
}

switch cv := v.(type) {
case encoding.BinaryMarshaler:
buf, err := cv.MarshalBinary()
Expand Down Expand Up @@ -229,6 +238,10 @@ type UnmarshalBinaryWithCurrentAction interface {
UnmarshalBinaryWithCurrentAction(data []byte, act Action) error
}

type OptionalBinaryMarshaler interface {
OptionalBinaryMarshalerPresent()
}

func (d *Decoder) Decode(v interface{}) (err error) {

defer func() {
Expand All @@ -238,6 +251,18 @@ func (d *Decoder) Decode(v interface{}) (err error) {
}
}()

if _, ok := v.(OptionalBinaryMarshaler); ok {
isPresent := make([]byte, 1, 1)
_, err := d.r.Read(isPresent)
if err != nil {
return err
}

if isPresent[0] == 0 {
return nil
}
}

fmt.Printf("MAMA!!!: %#v %T\n", v, v)
if i, ok := v.(UnmarshalBinaryReader); ok {
return i.UnmarshalBinaryRead(d.r)
Expand Down
22 changes: 4 additions & 18 deletions p2p.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,14 +63,11 @@ func NewMessageType(aType byte) (t P2PMessageType, err error) {
}

func (t P2PMessageType) isValid() bool {

index := byte(t)
return int(index) < len(messageAttributes) && index >= 0

}

func (t P2PMessageType) Name() (string, bool) {

index := byte(t)

if !t.isValid() {
Expand All @@ -82,7 +79,6 @@ func (t P2PMessageType) Name() (string, bool) {
}

func (t P2PMessageType) Attributes() (MessageAttributes, bool) {

index := byte(t)

if !t.isValid() {
Expand All @@ -100,20 +96,15 @@ type P2PMessageEnvelope struct {
}

func (p2pMsg P2PMessageEnvelope) AsMessage() (P2PMessage, error) {

attr, ok := p2pMsg.Type.Attributes()

if attr.ReflectType != nil {

fmt.Println("P2P message type:", attr.ReflectType.Name())
}

if !ok {
return nil, UnknownMessageTypeError
}

if attr.ReflectType == nil {
return nil, errors.New("Missing reflect type ")
} else {
fmt.Println("P2P message type:", attr.ReflectType.Name())
}

msg := reflect.New(attr.ReflectType)
Expand All @@ -127,28 +118,25 @@ func (p2pMsg P2PMessageEnvelope) AsMessage() (P2PMessage, error) {
}

func (p2pMsg P2PMessageEnvelope) DecodePayload(message interface{}) error {

attr, ok := p2pMsg.Type.Attributes()

if !ok {
return UnknownMessageTypeError
}

if attr.ReflectType == nil {
return errors.New("Missing reflect type ")
return errors.New("missing reflect type")
}

messageType := reflect.TypeOf(message).Elem()
if messageType != attr.ReflectType {
return errors.New(fmt.Sprintf("Given message type [%s] to not match payload type [%s]", messageType.Name(), attr.ReflectType.Name()))
return fmt.Errorf("given message type [%s] to not match payload type [%s]", messageType.Name(), attr.ReflectType.Name())
}

return UnmarshalBinary(p2pMsg.Payload, message)

}

func (p2pMsg P2PMessageEnvelope) MarshalBinary() ([]byte, error) {

data := make([]byte, p2pMsg.Length+4, p2pMsg.Length+4)
binary.LittleEndian.PutUint32(data[0:4], p2pMsg.Length)
data[4] = byte(p2pMsg.Type)
Expand All @@ -158,11 +146,9 @@ func (p2pMsg P2PMessageEnvelope) MarshalBinary() ([]byte, error) {
}

func (p2pMsg *P2PMessageEnvelope) UnmarshalBinaryRead(r io.Reader) (err error) {

lengthBytes := make([]byte, 4, 4)
_, err = r.Read(lengthBytes)
if err != nil {
fmt.Errorf("error: [%s]\n", err)
return
}

Expand Down
4 changes: 4 additions & 0 deletions p2p_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package eos

import (
"encoding/hex"
"encoding/json"
"testing"

"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -64,6 +65,9 @@ func TestP2PMessage_DecodePayload(t *testing.T) {
assert.NoError(t, UnmarshalBinary(decoded, &p2pMessage), c.Name)

assert.NoError(t, p2pMessage.DecodePayload(c.ExpectedStruct), c.Name)
jsonCnt, err := json.MarshalIndent(c.ExpectedStruct, "", " ")
assert.NoError(t, err)
assert.Equal(t, `superob`, string(jsonCnt))
//fmt.Println(c.ExpectedStruct)
}

Expand Down
49 changes: 27 additions & 22 deletions p2ptypes.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package eos

import "github.com/eoscanada/eos-go/ecc"
import (
"github.com/eoscanada/eos-go/ecc"
)

type P2PMessage interface {
}
Expand Down Expand Up @@ -59,16 +61,16 @@ const (
TransactionStatusExecuted TransactionStatus = iota ///< succeed, no error handler executed
TransactionStatusSoftFail ///< objectively failed (not executed), error handler executed
TransactionStatusHardFail ///< objectively failed and error handler objectively failed thus no state change
TransactionStatusSelayed ///< transaction delayed
TransactionStatusDelayed ///< transaction delayed
)

type TransactionId SHA256Bytes
type TransactionID SHA256Bytes

type TransactionReceipt struct {
Status TransactionStatus `json:"status"`
KCPUUsage uint32 `json:"kcpu_usage"`
NeUsageWords uint32 `json:"net_usage_words"`
Id TransactionId `json:"id"`
Status TransactionStatus `json:"status"`
KCPUUsage Varuint32 `json:"kcpu_usage"`
NetUsageWords Varuint32 `json:"net_usage_words"`
ID TransactionID `json:"id"`
}

type ShardLock struct {
Expand All @@ -89,32 +91,35 @@ type RegionSummary struct {
}

type ProducerKey struct {
AccountName AccountName `json:"account_name"`
BlockSigningKey SHA256Bytes `json:"block_signing_key"` //todo: Surely not good
AccountName AccountName `json:"account_name"`
BlockSigningKey ecc.PublicKey `json:"block_signing_key"`
}

type ProducerScheduleType struct {
type ProducerSchedule struct {
Version uint32 `json:"version"`
Producers []ProducerKey `json:"producers"`
}

type BlockHeader struct {
Digest SHA256Bytes `json:"digest"`
BlockNumber uint32 `json:"block_number"`
NumFromId uint32 `json:"num_from_id"`
Previous SHA256Bytes `json:"previous"`
Timestamp Tstamp `json:"timestamp"`
TransactionMRoot SHA256Bytes `json:"transaction_mroot"`
ActionMRoot SHA256Bytes `json:"action_mroot"`
BlockMRoot SHA256Bytes `json:"block_mroot"`
Producer AccountName `json:"producer"`
ScheduleVersion uint32 `json:"schedule_version"`
NewProducers []ProducerKey `json:"new_producers"`
Previous SHA256Bytes `json:"previous"`
Timestamp BlockTimestamp `json:"timestamp"`
TransactionMRoot SHA256Bytes `json:"transaction_mroot"`
ActionMRoot SHA256Bytes `json:"action_mroot"`
BlockMRoot SHA256Bytes `json:"block_mroot"`
Producer AccountName `json:"producer"`
ScheduleVersion uint32 `json:"schedule_version"`
NewProducers *OptionalProducerSchedule `json:"new_producers"`
}

type OptionalProducerSchedule struct {
ProducerSchedule
}

func (a *OptionalProducerSchedule) OptionalBinaryMarshalerPresent() bool { return a == nil }

type SignedBlockHeader struct {
BlockHeader
ProducerSignature SHA256Bytes `json:"producer_signature"` //todo: Surely not good
ProducerSignature ecc.Signature `json:"producer_signature"`
}

type SignedBlockSummaryMessage struct {
Expand Down
54 changes: 51 additions & 3 deletions types.go
Original file line number Diff line number Diff line change
Expand Up @@ -400,9 +400,8 @@ func (t *Tstamp) UnmarshalJSON(data []byte) (err error) {
return err
}
}
seconds := unixNano / 1e9
nanoSecs := unixNano*1e9 - seconds
*t = Tstamp{time.Unix(seconds, nanoSecs)}

*t = Tstamp{time.Unix(0, unixNano)}

return nil
}
Expand All @@ -422,3 +421,52 @@ func (t Tstamp) MarshalBinary() ([]byte, error) {
binary.LittleEndian.PutUint64(out, uint64(t.UnixNano()))
return out, nil
}

// Block timestamp, has EPOCH Y2K. Adds 946684800000ms to the incoming value.

type BlockTimestamp struct {
time.Time
}

// func (t BlockTimestamp) MarshalJSON() ([]byte, error) {
// return json.Marshal(fmt.Sprintf("%d", t.UnixNano()))
// }

// func (t *BlockTimestamp) UnmarshalJSON(data []byte) (err error) {
// var unixNano int64
// if data[0] == '"' {
// var s string
// if err = json.Unmarshal(data, &s); err != nil {
// return
// }

// unixNano, err = strconv.ParseInt(s, 10, 64)
// if err != nil {
// return err
// }

// } else {
// unixNano, err = strconv.ParseInt(string(data), 10, 64)
// if err != nil {
// return err
// }
// }

// *t = BlockTimestamp{time.Unix(0, unixNano)}

// return nil
// }

func (t *BlockTimestamp) UnmarshalBinary(data []byte) error {
unixSec := int64(binary.LittleEndian.Uint32(data))
t.Time = time.Unix(unixSec+946684800, 0).UTC()
return nil
}

func (t BlockTimestamp) UnmarshalBinarySize() int { return 4 }

func (t BlockTimestamp) MarshalBinary() ([]byte, error) {
out := []byte{0, 0, 0, 0}
binary.LittleEndian.PutUint32(out, uint32(t.Unix()-946684800))
return out, nil
}

0 comments on commit 5fbf4a7

Please sign in to comment.