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  }