github.com/amazechain/amc@v0.1.3/internal/avm/rlp/raw.go (about) 1 // Copyright 2023 The AmazeChain Authors 2 // This file is part of the AmazeChain library. 3 // 4 // The AmazeChain library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The AmazeChain library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the AmazeChain library. If not, see <http://www.gnu.org/licenses/>. 16 17 package rlp 18 19 import ( 20 "io" 21 "reflect" 22 ) 23 24 // RawValue represents an encoded RLP value and can be used to delay 25 // RLP decoding or to precompute an encoding. Note that the decoder does 26 // not verify whether the content of RawValues is valid RLP. 27 type RawValue []byte 28 29 var rawValueType = reflect.TypeOf(RawValue{}) 30 31 // StringSize returns the encoded size of a string. 32 func StringSize(s string) uint64 { 33 switch { 34 case len(s) == 0: 35 return 1 36 case len(s) == 1: 37 if s[0] <= 0x7f { 38 return 1 39 } else { 40 return 2 41 } 42 default: 43 return uint64(headsize(uint64(len(s))) + len(s)) 44 } 45 } 46 47 // BytesSize returns the encoded size of a byte slice. 48 func BytesSize(b []byte) uint64 { 49 switch { 50 case len(b) == 0: 51 return 1 52 case len(b) == 1: 53 if b[0] <= 0x7f { 54 return 1 55 } else { 56 return 2 57 } 58 default: 59 return uint64(headsize(uint64(len(b))) + len(b)) 60 } 61 } 62 63 // ListSize returns the encoded size of an RLP list with the given 64 // content size. 65 func ListSize(contentSize uint64) uint64 { 66 return uint64(headsize(contentSize)) + contentSize 67 } 68 69 // IntSize returns the encoded size of the integer x. 70 func IntSize(x uint64) int { 71 if x < 0x80 { 72 return 1 73 } 74 return 1 + intsize(x) 75 } 76 77 // Split returns the content of first RLP value and any 78 // bytes after the value as subslices of b. 79 func Split(b []byte) (k Kind, content, rest []byte, err error) { 80 k, ts, cs, err := readKind(b) 81 if err != nil { 82 return 0, nil, b, err 83 } 84 return k, b[ts : ts+cs], b[ts+cs:], nil 85 } 86 87 // SplitString splits b into the content of an RLP string 88 // and any remaining bytes after the string. 89 func SplitString(b []byte) (content, rest []byte, err error) { 90 k, content, rest, err := Split(b) 91 if err != nil { 92 return nil, b, err 93 } 94 if k == List { 95 return nil, b, ErrExpectedString 96 } 97 return content, rest, nil 98 } 99 100 // SplitUint64 decodes an integer at the beginning of b. 101 // It also returns the remaining data after the integer in 'rest'. 102 func SplitUint64(b []byte) (x uint64, rest []byte, err error) { 103 content, rest, err := SplitString(b) 104 if err != nil { 105 return 0, b, err 106 } 107 switch { 108 case len(content) == 0: 109 return 0, rest, nil 110 case len(content) == 1: 111 if content[0] == 0 { 112 return 0, b, ErrCanonInt 113 } 114 return uint64(content[0]), rest, nil 115 case len(content) > 8: 116 return 0, b, errUintOverflow 117 default: 118 x, err = readSize(content, byte(len(content))) 119 if err != nil { 120 return 0, b, ErrCanonInt 121 } 122 return x, rest, nil 123 } 124 } 125 126 // SplitList splits b into the content of a list and any remaining 127 // bytes after the list. 128 func SplitList(b []byte) (content, rest []byte, err error) { 129 k, content, rest, err := Split(b) 130 if err != nil { 131 return nil, b, err 132 } 133 if k != List { 134 return nil, b, ErrExpectedList 135 } 136 return content, rest, nil 137 } 138 139 // CountValues counts the number of encoded values in b. 140 func CountValues(b []byte) (int, error) { 141 i := 0 142 for ; len(b) > 0; i++ { 143 _, tagsize, size, err := readKind(b) 144 if err != nil { 145 return 0, err 146 } 147 b = b[tagsize+size:] 148 } 149 return i, nil 150 } 151 152 func readKind(buf []byte) (k Kind, tagsize, contentsize uint64, err error) { 153 if len(buf) == 0 { 154 return 0, 0, 0, io.ErrUnexpectedEOF 155 } 156 b := buf[0] 157 switch { 158 case b < 0x80: 159 k = Byte 160 tagsize = 0 161 contentsize = 1 162 case b < 0xB8: 163 k = String 164 tagsize = 1 165 contentsize = uint64(b - 0x80) 166 // Reject strings that should've been single bytes. 167 if contentsize == 1 && len(buf) > 1 && buf[1] < 128 { 168 return 0, 0, 0, ErrCanonSize 169 } 170 case b < 0xC0: 171 k = String 172 tagsize = uint64(b-0xB7) + 1 173 contentsize, err = readSize(buf[1:], b-0xB7) 174 case b < 0xF8: 175 k = List 176 tagsize = 1 177 contentsize = uint64(b - 0xC0) 178 default: 179 k = List 180 tagsize = uint64(b-0xF7) + 1 181 contentsize, err = readSize(buf[1:], b-0xF7) 182 } 183 if err != nil { 184 return 0, 0, 0, err 185 } 186 // Reject values larger than the input slice. 187 if contentsize > uint64(len(buf))-tagsize { 188 return 0, 0, 0, ErrValueTooLarge 189 } 190 return k, tagsize, contentsize, err 191 } 192 193 func readSize(b []byte, slen byte) (uint64, error) { 194 if int(slen) > len(b) { 195 return 0, io.ErrUnexpectedEOF 196 } 197 var s uint64 198 switch slen { 199 case 1: 200 s = uint64(b[0]) 201 case 2: 202 s = uint64(b[0])<<8 | uint64(b[1]) 203 case 3: 204 s = uint64(b[0])<<16 | uint64(b[1])<<8 | uint64(b[2]) 205 case 4: 206 s = uint64(b[0])<<24 | uint64(b[1])<<16 | uint64(b[2])<<8 | uint64(b[3]) 207 case 5: 208 s = uint64(b[0])<<32 | uint64(b[1])<<24 | uint64(b[2])<<16 | uint64(b[3])<<8 | uint64(b[4]) 209 case 6: 210 s = uint64(b[0])<<40 | uint64(b[1])<<32 | uint64(b[2])<<24 | uint64(b[3])<<16 | uint64(b[4])<<8 | uint64(b[5]) 211 case 7: 212 s = uint64(b[0])<<48 | uint64(b[1])<<40 | uint64(b[2])<<32 | uint64(b[3])<<24 | uint64(b[4])<<16 | uint64(b[5])<<8 | uint64(b[6]) 213 case 8: 214 s = uint64(b[0])<<56 | uint64(b[1])<<48 | uint64(b[2])<<40 | uint64(b[3])<<32 | uint64(b[4])<<24 | uint64(b[5])<<16 | uint64(b[6])<<8 | uint64(b[7]) 215 } 216 // Reject sizes < 56 (shouldn't have separate size) and sizes with 217 // leading zero bytes. 218 if s < 56 || b[0] == 0 { 219 return 0, ErrCanonSize 220 } 221 return s, nil 222 } 223 224 // AppendUint64 appends the RLP encoding of i to b, and returns the resulting slice. 225 func AppendUint64(b []byte, i uint64) []byte { 226 if i == 0 { 227 return append(b, 0x80) 228 } else if i < 128 { 229 return append(b, byte(i)) 230 } 231 switch { 232 case i < (1 << 8): 233 return append(b, 0x81, byte(i)) 234 case i < (1 << 16): 235 return append(b, 0x82, 236 byte(i>>8), 237 byte(i), 238 ) 239 case i < (1 << 24): 240 return append(b, 0x83, 241 byte(i>>16), 242 byte(i>>8), 243 byte(i), 244 ) 245 case i < (1 << 32): 246 return append(b, 0x84, 247 byte(i>>24), 248 byte(i>>16), 249 byte(i>>8), 250 byte(i), 251 ) 252 case i < (1 << 40): 253 return append(b, 0x85, 254 byte(i>>32), 255 byte(i>>24), 256 byte(i>>16), 257 byte(i>>8), 258 byte(i), 259 ) 260 261 case i < (1 << 48): 262 return append(b, 0x86, 263 byte(i>>40), 264 byte(i>>32), 265 byte(i>>24), 266 byte(i>>16), 267 byte(i>>8), 268 byte(i), 269 ) 270 case i < (1 << 56): 271 return append(b, 0x87, 272 byte(i>>48), 273 byte(i>>40), 274 byte(i>>32), 275 byte(i>>24), 276 byte(i>>16), 277 byte(i>>8), 278 byte(i), 279 ) 280 281 default: 282 return append(b, 0x88, 283 byte(i>>56), 284 byte(i>>48), 285 byte(i>>40), 286 byte(i>>32), 287 byte(i>>24), 288 byte(i>>16), 289 byte(i>>8), 290 byte(i), 291 ) 292 } 293 }