github.com/amazechain/amc@v0.1.3/utils/util.go (about) 1 // Copyright 2022 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 utils 18 19 import ( 20 "context" 21 "encoding/binary" 22 "encoding/hex" 23 "fmt" 24 "github.com/amazechain/amc/api/protocol/types_pb" 25 "github.com/amazechain/amc/common/types" 26 "github.com/holiman/uint256" 27 "github.com/libp2p/go-libp2p/core/crypto" 28 "golang.org/x/crypto/sha3" 29 "os" 30 "strings" 31 ) 32 33 func Hash256toS(data []byte) string { 34 h := sha3.NewLegacyKeccak256() 35 h.Write(data) 36 hash := h.Sum(nil) 37 return hex.EncodeToString(hash) 38 } 39 40 func Keccak256(data ...[]byte) []byte { 41 d := sha3.NewLegacyKeccak256() 42 43 for _, b := range data { 44 d.Write(b) 45 } 46 47 return d.Sum(nil) 48 } 49 50 // Keccak256Hash calculates and returns the Keccak256 hash of the input data, 51 // converting it to an internal Hash data structure. 52 func Keccak256Hash(data ...[]byte) (h types.Hash) { 53 d := sha3.NewLegacyKeccak256() 54 55 for _, b := range data { 56 d.Write(b) 57 } 58 d.Sum(h[:]) 59 return h 60 } 61 62 func StringToPrivate(s string) (crypto.PrivKey, error) { 63 bKey, err := crypto.ConfigDecodeKey(s) 64 if err != nil { 65 return nil, err 66 } 67 68 return crypto.UnmarshalPrivateKey(bKey) 69 } 70 71 func PrivateToString(key crypto.PrivKey) (string, error) { 72 priv, err := crypto.MarshalPrivateKey(key) 73 if err != nil { 74 return "", err 75 } 76 77 return crypto.ConfigEncodeKey(priv), nil 78 } 79 80 func PublicToString(key crypto.PubKey) (string, error) { 81 pub, err := crypto.MarshalPublicKey(key) 82 if err != nil { 83 return "", err 84 } 85 return crypto.ConfigEncodeKey(pub), nil 86 } 87 88 func StringToPublic(s string) (crypto.PubKey, error) { 89 b, err := crypto.ConfigDecodeKey(s) 90 if err != nil { 91 return nil, err 92 } 93 94 return crypto.UnmarshalPublicKey(b) 95 } 96 97 func Exists(path string) bool { 98 _, err := os.Stat(path) 99 if err != nil { 100 if os.IsExist(err) { 101 return true 102 } 103 return false 104 } 105 106 return true 107 } 108 func MkdirAll(path string, perm os.FileMode) error { 109 if err := os.MkdirAll(path, perm); err != nil { 110 return err 111 } 112 113 return nil 114 } 115 116 func HexPrefix(a, b []byte) ([]byte, int) { 117 var i, length = 0, len(a) 118 if len(b) < length { 119 length = len(b) 120 } 121 122 for ; i < length; i++ { 123 if a[i] != b[i] { 124 break 125 } 126 } 127 128 return a[:i], i 129 } 130 131 type appKey struct{} 132 133 type AppInfo interface { 134 ID() string 135 Name() string 136 Version() string 137 Amcdata() map[string]string 138 Endpoint() []string 139 } 140 141 // NewContext returns a new Context that carries value. 142 func NewContext(ctx context.Context, s AppInfo) context.Context { 143 return context.WithValue(ctx, appKey{}, s) 144 } 145 146 // FromContext returns the Transport value stored in ctx, if any. 147 func FromContext(ctx context.Context) (s AppInfo, ok bool) { 148 s, ok = ctx.Value(appKey{}).(AppInfo) 149 return 150 } 151 152 func ByteCount(b uint64) string { 153 const unit = 1024 154 if b < unit { 155 return fmt.Sprintf("%dB", b) 156 } 157 bGb, exp := MBToGB(b) 158 return fmt.Sprintf("%.1f%cB", bGb, "KMGTPE"[exp]) 159 } 160 161 func MBToGB(b uint64) (float64, int) { 162 const unit = 1024 163 if b < unit { 164 return float64(b), 0 165 } 166 167 div, exp := uint64(unit), 0 168 for n := b / unit; n >= unit; n /= unit { 169 div *= unit 170 exp++ 171 } 172 173 return float64(b) / float64(div), exp 174 } 175 176 func EnsureEnoughSize(in []byte, size int) []byte { 177 if cap(in) < size { 178 newBuf := make([]byte, size) 179 copy(newBuf, in) 180 return newBuf 181 } 182 return in[:size] // Reuse the space if it has enough capacity 183 } 184 185 func Copy(b []byte) []byte { 186 if b == nil { 187 return nil 188 } 189 c := make([]byte, len(b)) 190 copy(c, b) 191 return c 192 } 193 194 // SplitAndTrim splits input separated by a comma 195 // and trims excessive white space from the substrings. 196 func SplitAndTrim(input string) (ret []string) { 197 l := strings.Split(input, ",") 198 for _, r := range l { 199 if r = strings.TrimSpace(r); r != "" { 200 ret = append(ret, r) 201 } 202 } 203 return ret 204 } 205 206 func ConvertH256ToUint256Int(h256 *types_pb.H256) *uint256.Int { 207 // Note: uint256.Int is an array of 4 uint64 in little-endian order, i.e. most significant word is [3] 208 var i uint256.Int 209 i[3] = h256.Hi.Hi 210 i[2] = h256.Hi.Lo 211 i[1] = h256.Lo.Hi 212 i[0] = h256.Lo.Lo 213 return &i 214 } 215 216 func ConvertUint256IntToH256(i *uint256.Int) *types_pb.H256 { 217 // Note: uint256.Int is an array of 4 uint64 in little-endian order, i.e. most significant word is [3] 218 return &types_pb.H256{ 219 Lo: &types_pb.H128{Lo: i[0], Hi: i[1]}, 220 Hi: &types_pb.H128{Lo: i[2], Hi: i[3]}, 221 } 222 } 223 224 func ConvertH256ToHash(h256 *types_pb.H256) [32]byte { 225 var hash [32]byte 226 if nil == h256 { 227 return hash 228 } 229 binary.BigEndian.PutUint64(hash[0:], h256.Hi.Hi) 230 binary.BigEndian.PutUint64(hash[8:], h256.Hi.Lo) 231 binary.BigEndian.PutUint64(hash[16:], h256.Lo.Hi) 232 binary.BigEndian.PutUint64(hash[24:], h256.Lo.Lo) 233 return hash 234 } 235 236 func ConvertH512ToHash(h512 *types_pb.H512) [64]byte { 237 var b [64]byte 238 binary.BigEndian.PutUint64(b[0:], h512.Hi.Hi.Hi) 239 binary.BigEndian.PutUint64(b[8:], h512.Hi.Hi.Lo) 240 binary.BigEndian.PutUint64(b[16:], h512.Hi.Lo.Hi) 241 binary.BigEndian.PutUint64(b[24:], h512.Hi.Lo.Lo) 242 binary.BigEndian.PutUint64(b[32:], h512.Lo.Hi.Hi) 243 binary.BigEndian.PutUint64(b[40:], h512.Lo.Hi.Lo) 244 binary.BigEndian.PutUint64(b[48:], h512.Lo.Lo.Hi) 245 binary.BigEndian.PutUint64(b[56:], h512.Lo.Lo.Lo) 246 return b 247 } 248 249 func ConvertHashesToH256(hashes []types.Hash) []*types_pb.H256 { 250 res := make([]*types_pb.H256, len(hashes)) 251 for i := range hashes { 252 res[i] = ConvertHashToH256(hashes[i]) 253 } 254 return res 255 } 256 257 func Uint256sToH256(u256s []uint256.Int) []*types_pb.H256 { 258 p := make([]*types_pb.H256, len(u256s)) 259 for i, u := range u256s { 260 p[i] = ConvertUint256IntToH256(&u) 261 } 262 return p 263 } 264 265 func H256sToHashes(h256s []*types_pb.H256) []types.Hash { 266 p := make([]types.Hash, len(h256s)) 267 for i, h := range h256s { 268 p[i] = ConvertH256ToHash(h) 269 } 270 return p 271 } 272 273 func ConvertHashToH256(hash [32]byte) *types_pb.H256 { 274 return &types_pb.H256{ 275 Lo: &types_pb.H128{Lo: binary.BigEndian.Uint64(hash[24:]), Hi: binary.BigEndian.Uint64(hash[16:])}, 276 Hi: &types_pb.H128{Lo: binary.BigEndian.Uint64(hash[8:]), Hi: binary.BigEndian.Uint64(hash[0:])}, 277 } 278 } 279 280 func ConvertHashToH512(hash [64]byte) *types_pb.H512 { 281 return ConvertBytesToH512(hash[:]) 282 } 283 284 func ConvertH160toAddress(h160 *types_pb.H160) [20]byte { 285 var addr [20]byte 286 binary.BigEndian.PutUint64(addr[0:], h160.Hi.Hi) 287 binary.BigEndian.PutUint64(addr[8:], h160.Hi.Lo) 288 binary.BigEndian.PutUint32(addr[16:], h160.Lo) 289 return addr 290 } 291 292 func ConvertH160ToPAddress(h160 *types_pb.H160) *types.Address { 293 p := new(types.Address) 294 addr := ConvertH160toAddress(h160) 295 p.SetBytes(addr[:]) 296 return p 297 } 298 299 func ConvertAddressToH160(addr [20]byte) *types_pb.H160 { 300 return &types_pb.H160{ 301 Lo: binary.BigEndian.Uint32(addr[16:]), 302 Hi: &types_pb.H128{Lo: binary.BigEndian.Uint64(addr[8:]), Hi: binary.BigEndian.Uint64(addr[0:])}, 303 } 304 } 305 306 func ConvertAddrsToH160(ps []types.Address) []*types_pb.H160 { 307 b := make([]*types_pb.H160, len(ps)) 308 for i, p := range ps { 309 b[i] = ConvertAddressToH160(p) 310 } 311 return b 312 } 313 314 func H160sToAddress(ps []*types_pb.H160) []types.Address { 315 b := make([]types.Address, len(ps)) 316 for i, p := range ps { 317 b[i] = ConvertH160toAddress(p) 318 } 319 return b 320 } 321 322 func ConvertH512ToBytes(h512 *types_pb.H512) []byte { 323 b := ConvertH512ToHash(h512) 324 return b[:] 325 } 326 327 func ConvertBytesToH512(b []byte) *types_pb.H512 { 328 if len(b) < 64 { 329 var b1 [64]byte 330 copy(b1[:], b) 331 b = b1[:] 332 } 333 return &types_pb.H512{ 334 Lo: &types_pb.H256{ 335 Lo: &types_pb.H128{Lo: binary.BigEndian.Uint64(b[56:]), Hi: binary.BigEndian.Uint64(b[48:])}, 336 Hi: &types_pb.H128{Lo: binary.BigEndian.Uint64(b[40:]), Hi: binary.BigEndian.Uint64(b[32:])}, 337 }, 338 Hi: &types_pb.H256{ 339 Lo: &types_pb.H128{Lo: binary.BigEndian.Uint64(b[24:]), Hi: binary.BigEndian.Uint64(b[16:])}, 340 Hi: &types_pb.H128{Lo: binary.BigEndian.Uint64(b[8:]), Hi: binary.BigEndian.Uint64(b[0:])}, 341 }, 342 } 343 } 344 345 func ConvertH384ToPublicKey(h384 *types_pb.H384) [48]byte { 346 var pub [48]byte 347 binary.BigEndian.PutUint64(pub[0:], h384.Hi.Hi.Hi) 348 binary.BigEndian.PutUint64(pub[8:], h384.Hi.Hi.Lo) 349 binary.BigEndian.PutUint64(pub[16:], h384.Hi.Lo.Hi) 350 binary.BigEndian.PutUint64(pub[24:], h384.Hi.Lo.Lo) 351 binary.BigEndian.PutUint64(pub[32:], h384.Lo.Hi) 352 binary.BigEndian.PutUint64(pub[40:], h384.Lo.Lo) 353 return pub 354 } 355 356 func ConvertPublicKeyToH384(p [48]byte) *types_pb.H384 { 357 return &types_pb.H384{ 358 Lo: &types_pb.H128{ 359 Lo: binary.BigEndian.Uint64(p[40:]), 360 Hi: binary.BigEndian.Uint64(p[32:]), 361 }, 362 Hi: &types_pb.H256{ 363 Lo: &types_pb.H128{Lo: binary.BigEndian.Uint64(p[24:]), Hi: binary.BigEndian.Uint64(p[16:])}, 364 Hi: &types_pb.H128{Lo: binary.BigEndian.Uint64(p[8:]), Hi: binary.BigEndian.Uint64(p[0:])}, 365 }, 366 } 367 } 368 369 func ConvertPubsToH384(ps []types.PublicKey) []*types_pb.H384 { 370 b := make([]*types_pb.H384, len(ps)) 371 for i, p := range ps { 372 b[i] = ConvertPublicKeyToH384(p) 373 } 374 return b 375 } 376 377 func H384sToPubs(ps []*types_pb.H384) []types.PublicKey { 378 b := make([]types.PublicKey, len(ps)) 379 for i, p := range ps { 380 b[i] = ConvertH384ToPublicKey(p) 381 } 382 return b 383 } 384 func ConvertH768ToSignature(h768 *types_pb.H768) [96]byte { 385 var b [96]byte 386 binary.BigEndian.PutUint64(b[0:], h768.Hi.Hi.Hi.Hi) 387 binary.BigEndian.PutUint64(b[8:], h768.Hi.Hi.Hi.Lo) 388 binary.BigEndian.PutUint64(b[16:], h768.Hi.Hi.Lo.Hi) 389 binary.BigEndian.PutUint64(b[24:], h768.Hi.Hi.Lo.Lo) 390 binary.BigEndian.PutUint64(b[32:], h768.Hi.Lo.Hi) 391 binary.BigEndian.PutUint64(b[40:], h768.Hi.Lo.Lo) 392 393 binary.BigEndian.PutUint64(b[48:], h768.Lo.Hi.Hi.Hi) 394 binary.BigEndian.PutUint64(b[56:], h768.Lo.Hi.Hi.Lo) 395 binary.BigEndian.PutUint64(b[64:], h768.Lo.Hi.Lo.Hi) 396 binary.BigEndian.PutUint64(b[72:], h768.Lo.Hi.Lo.Lo) 397 binary.BigEndian.PutUint64(b[80:], h768.Lo.Lo.Hi) 398 binary.BigEndian.PutUint64(b[88:], h768.Lo.Lo.Lo) 399 return b 400 } 401 402 func ConvertSignatureToH768(p [96]byte) *types_pb.H768 { 403 return &types_pb.H768{ 404 Lo: &types_pb.H384{ 405 Lo: &types_pb.H128{ 406 Lo: binary.BigEndian.Uint64(p[88:]), 407 Hi: binary.BigEndian.Uint64(p[80:]), 408 }, 409 Hi: &types_pb.H256{ 410 Lo: &types_pb.H128{Lo: binary.BigEndian.Uint64(p[72:]), Hi: binary.BigEndian.Uint64(p[64:])}, 411 Hi: &types_pb.H128{Lo: binary.BigEndian.Uint64(p[56:]), Hi: binary.BigEndian.Uint64(p[48:])}, 412 }, 413 }, 414 Hi: &types_pb.H384{ 415 Lo: &types_pb.H128{Lo: binary.BigEndian.Uint64(p[40:]), Hi: binary.BigEndian.Uint64(p[32:])}, 416 Hi: &types_pb.H256{ 417 Lo: &types_pb.H128{Lo: binary.BigEndian.Uint64(p[24:]), Hi: binary.BigEndian.Uint64(p[16:])}, 418 Hi: &types_pb.H128{Lo: binary.BigEndian.Uint64(p[8:]), Hi: binary.BigEndian.Uint64(p[0:])}, 419 }, 420 }, 421 } 422 } 423 424 func ConvertH2048ToBloom(h2048 *types_pb.H2048) [256]byte { 425 var bloom [256]byte 426 copy(bloom[:], ConvertH512ToBytes(h2048.Hi.Hi)) 427 copy(bloom[64:], ConvertH512ToBytes(h2048.Hi.Lo)) 428 copy(bloom[128:], ConvertH512ToBytes(h2048.Lo.Hi)) 429 copy(bloom[192:], ConvertH512ToBytes(h2048.Lo.Lo)) 430 return bloom 431 } 432 433 func ConvertBytesToH2048(data []byte) *types_pb.H2048 { 434 return &types_pb.H2048{ 435 Hi: &types_pb.H1024{ 436 Hi: ConvertBytesToH512(data), 437 Lo: ConvertBytesToH512(data[64:]), 438 }, 439 Lo: &types_pb.H1024{ 440 Hi: ConvertBytesToH512(data[128:]), 441 Lo: ConvertBytesToH512(data[192:]), 442 }, 443 } 444 }