github.com/mavryk-network/mvgo@v1.19.9/codec/utils.go (about) 1 // Copyright (c) 2020-2022 Blockwatch Data Inc. 2 // Author: alex@blockwatch.cc 3 4 package codec 5 6 import ( 7 "bytes" 8 "encoding/binary" 9 "fmt" 10 "io" 11 "math" 12 13 "github.com/mavryk-network/mvgo/mavryk" 14 "github.com/mavryk-network/mvgo/micheline" 15 ) 16 17 // TODO: fetch dynamic from /chains/main/mempool/filter 18 const ( 19 minFeeFixedNanoMav int64 = 100_000 20 minFeeByteNanoMav int64 = 1_000 21 minFeeGasNanoMav int64 = 100 22 ) 23 24 // CalculateMinFee returns the minimum fee at/above which bakers will accept 25 // this operation under default config settings. Lower fee operations may not 26 // pass the fee filter and may time out in the mempool. 27 func CalculateMinFee(o Operation, gas int64, withHeader bool, p *mavryk.Params) int64 { 28 buf := bytes.NewBuffer(nil) 29 _ = o.EncodeBuffer(buf, p) 30 sz := int64(buf.Len()) 31 if withHeader { 32 sz += 32 + 64 // branch + signature 33 } 34 fee := minFeeFixedNanoMav + sz*minFeeByteNanoMav + gas*minFeeGasNanoMav 35 return int64(math.Ceil(float64(fee) / 1000)) // nano -> micro, round up 36 } 37 38 // ensureTagAndSize reads the binary operation's tag and matches it against the expected 39 // type tag and minimum size for the operation under the current protocol. It returns 40 // an error when tag does not match or when the buffer is too short for reading the 41 // mandatory operation contents. 42 func ensureTagAndSize(buf *bytes.Buffer, typ mavryk.OpType, ver int) error { 43 if buf == nil { 44 return io.ErrShortBuffer 45 } 46 47 tag, err := buf.ReadByte() 48 if err != nil { 49 // unread so the caller is able to repair 50 buf.UnreadByte() 51 return err 52 } 53 54 if tag != typ.TagVersion(ver) { 55 // unread so the caller is able to repair 56 buf.UnreadByte() 57 return fmt.Errorf("invalid tag %d for op type %s", tag, typ) 58 } 59 60 // don't fail size checks for undefined ops 61 sz := typ.MinSizeVersion(ver) 62 if buf.Len() < sz-1 { 63 fmt.Printf("short buffer for tag %d for op type %s: exp=%d got=%d\n", tag, typ, 64 sz-1, buf.Len()) 65 buf.UnreadByte() 66 return io.ErrShortBuffer 67 } 68 69 return nil 70 } 71 72 func readInt64(buf []byte) (int64, error) { 73 if len(buf) != 8 { 74 return 0, io.ErrShortBuffer 75 } 76 return int64(enc.Uint64(buf)), nil 77 } 78 79 func readInt32(buf []byte) (int32, error) { 80 if len(buf) != 4 { 81 return 0, io.ErrShortBuffer 82 } 83 return int32(enc.Uint32(buf)), nil 84 } 85 86 func readInt16(buf []byte) (int16, error) { 87 if len(buf) != 2 { 88 return 0, io.ErrShortBuffer 89 } 90 return int16(enc.Uint16(buf)), nil 91 } 92 93 func readUint32(buf []byte) (uint32, error) { 94 if len(buf) != 4 { 95 return 0, io.ErrShortBuffer 96 } 97 return enc.Uint32(buf), nil 98 } 99 100 func readBool(buf []byte) (bool, error) { 101 if len(buf) != 1 { 102 return false, io.ErrShortBuffer 103 } 104 return buf[0] == 255, nil 105 } 106 107 func readByte(buf []byte) (byte, error) { 108 if len(buf) != 1 { 109 return 0, io.ErrShortBuffer 110 } 111 return buf[0], nil 112 } 113 114 func max64(x, y int64) int64 { 115 if x > y { 116 return x 117 } 118 return y 119 } 120 121 func writeBytesWithLen(buf *bytes.Buffer, b mavryk.HexBytes) (err error) { 122 err = binary.Write(buf, enc, uint32(len(b))) 123 if err != nil { 124 return 125 } 126 _, err = buf.Write(b) 127 return err 128 } 129 130 func readBytesWithLen(buf *bytes.Buffer) (b mavryk.HexBytes, err error) { 131 var l uint32 132 l, err = readUint32(buf.Next(4)) 133 if err != nil { 134 return 135 } 136 err = b.ReadBytes(buf, int(l)) 137 return 138 } 139 140 func readPrimWithLen(buf *bytes.Buffer) (p micheline.Prim, err error) { 141 var l uint32 142 l, err = readUint32(buf.Next(4)) 143 if err != nil { 144 return 145 } 146 err = p.UnmarshalBinary(buf.Next(int(l))) 147 return 148 } 149 150 func writePrimWithLen(buf *bytes.Buffer, p micheline.Prim) error { 151 v, err := p.MarshalBinary() 152 if err != nil { 153 return err 154 } 155 if err := binary.Write(buf, enc, uint32(len(v))); err != nil { 156 return err 157 } 158 _, err = buf.Write(v) 159 return err 160 } 161 162 func readStringWithLen(buf *bytes.Buffer) (s string, err error) { 163 var l uint32 164 l, err = readUint32(buf.Next(4)) 165 if err != nil { 166 return 167 } 168 if b := buf.Next(int(l)); len(b) != int(l) { 169 err = io.ErrShortBuffer 170 return 171 } else { 172 s = string(b) 173 } 174 return 175 } 176 177 func writeStringWithLen(buf *bytes.Buffer, s string) error { 178 if err := binary.Write(buf, enc, uint32(len(s))); err != nil { 179 return err 180 } 181 _, err := buf.WriteString(s) 182 return err 183 }