github.com/igggame/nebulas-go@v2.1.0+incompatible/nf/nvm/random.go (about)

     1  package nvm
     2  
     3  /*
     4  #include "v8/lib/nvm_error.h"
     5  */
     6  import "C"
     7  
     8  import (
     9  	"crypto/md5"
    10  	"encoding/binary"
    11  	"io"
    12  	"strconv"
    13  	"unsafe"
    14  
    15  	"math/rand"
    16  
    17  	"github.com/nebulasio/go-nebulas/util/logging"
    18  	"github.com/sirupsen/logrus"
    19  )
    20  
    21  //GetTxRandomFunc return random
    22  //export GetTxRandomFunc
    23  func GetTxRandomFunc(handler unsafe.Pointer, gasCnt *C.size_t, result **C.char, exceptionInfo **C.char) int {
    24  	engine, _ := getEngineByStorageHandler(uint64(uintptr(handler)))
    25  	if engine == nil || engine.ctx.block == nil {
    26  		logging.VLog().Error("random.GetTxRandomFunc Unexpected error: failed to get engine")
    27  		return C.NVM_UNEXPECTED_ERR
    28  	}
    29  	// calculate Gas.
    30  	*gasCnt = C.size_t(GetTxRandomGasBase)
    31  
    32  	if engine.ctx.contextRand == nil {
    33  		logging.VLog().WithFields(logrus.Fields{
    34  			"height": engine.ctx.block.Height(),
    35  		}).Error("ContextRand is nil")
    36  		*exceptionInfo = C.CString("random.GetTxRandomFunc(), contextRand is nil")
    37  		return C.NVM_EXCEPTION_ERR
    38  	}
    39  
    40  	if engine.ctx.contextRand.rand == nil {
    41  		bs := engine.ctx.block.RandomSeed()
    42  		if len(bs) == 0 {
    43  			logging.VLog().WithFields(logrus.Fields{
    44  				"height": engine.ctx.block.Height(),
    45  			}).Error("block seed is nil")
    46  			*exceptionInfo = C.CString("random.GetTxRandomFunc(), randomSeed len is zero")
    47  			return C.NVM_EXCEPTION_ERR
    48  		}
    49  
    50  		txhash := engine.ctx.tx.Hash().String()
    51  		if len(txhash) == 0 {
    52  			logging.VLog().WithFields(logrus.Fields{
    53  				"height": engine.ctx.block.Height(),
    54  			}).Error("transaction hash is nil")
    55  			*exceptionInfo = C.CString("random.GetTxRandomFunc(), randomSeed len is zero")
    56  			return C.NVM_EXCEPTION_ERR
    57  		}
    58  
    59  		m := md5.New()
    60  		io.WriteString(m, bs)
    61  		io.WriteString(m, txhash)
    62  		seed := int64(binary.BigEndian.Uint64(m.Sum(nil)))
    63  		engine.ctx.contextRand.rand = rand.New(rand.NewSource(seed))
    64  	}
    65  	*result = C.CString(strconv.FormatFloat(engine.ctx.contextRand.rand.Float64(), 'f', -1, 64))
    66  	return C.NVM_SUCCESS
    67  }