github.com/SmartMeshFoundation/Spectrum@v0.0.0-20220621030607-452a266fee1e/params/consensus_params.go (about)

     1  package params
     2  
     3  import (
     4  	"bytes"
     5  	"errors"
     6  	"fmt"
     7  	"math/big"
     8  	"os"
     9  	"sort"
    10  	"sync"
    11  
    12  	"github.com/SmartMeshFoundation/Spectrum/common"
    13  )
    14  
    15  const (
    16  	POC_METHOD_DEPOSIT          = "poc_deposit"
    17  	POC_METHOD_START            = "poc_start"
    18  	POC_METHOD_STOP             = "poc_stop"
    19  	POC_METHOD_WITHDRAW         = "poc_withdraw"
    20  	POC_METHOD_WITHDRAW_SURPLUS = "poc_withdrawsurplus"
    21  	POC_METHOD_GET_STATUS       = "poc_getall"
    22  
    23  	Chief100Update = "SIP100Update"
    24  )
    25  
    26  type ChiefInfo struct {
    27  	StartNumber, PocStartNumber *big.Int // 0 is nil
    28  	Version                     string
    29  	Addr, PocAddr, BaseAddr     common.Address
    30  }
    31  type ChiefInfoList []*ChiefInfo
    32  
    33  func (p ChiefInfoList) Len() int { return len(p) }
    34  func (p ChiefInfoList) Less(i, j int) bool {
    35  	if p[i].StartNumber == nil || p[j].StartNumber == nil {
    36  		return true
    37  	}
    38  	return p[i].StartNumber.Int64() > p[j].StartNumber.Int64()
    39  }
    40  func (p ChiefInfoList) Swap(i, j int) {
    41  	p[i], p[j] = p[j], p[i]
    42  }
    43  
    44  func (self *ChiefInfo) String() string {
    45  	return fmt.Sprintf("start: %d , vsn: %s , addr: %s", self.StartNumber.Int64(), self.Version, self.Addr.Hex())
    46  }
    47  
    48  func newChiefInfo(num *big.Int, vsn string, addr common.Address) *ChiefInfo {
    49  	empty := common.HexToAddress("0x")
    50  	return newChiefInfoWithPocBase(num, vsn, addr, empty, empty)
    51  }
    52  
    53  func newChiefInfoWithPocBase(num *big.Int, vsn string, addr, pocAddr, baseAddr common.Address) *ChiefInfo {
    54  	return &ChiefInfo{
    55  		StartNumber: num,
    56  		Version:     vsn,
    57  		Addr:        addr,
    58  		PocAddr:     pocAddr,
    59  		BaseAddr:    baseAddr,
    60  	}
    61  }
    62  
    63  var (
    64  	ChiefBaseBalance = new(big.Int).Mul(big.NewInt(1), big.NewInt(Finney))
    65  	MboxChan         = make(chan Mbox, 32)
    66  	StatuteService   = make(chan Mbox, 384)
    67  	//PocService 用于poc 服务
    68  	PocService = make(chan Mbox, 32)
    69  	//close at tribe.init
    70  	TribeReadyForAcceptTxs = make(chan struct{})
    71  	InitTribe              = make(chan struct{})
    72  	InitMeshbox            = make(chan struct{})
    73  	InitAnmap              = make(chan struct{})
    74  	//close at tribeService
    75  	InitTribeStatus               = make(chan struct{})
    76  	chiefInfoList   ChiefInfoList = nil
    77  	// added by cai.zhihong
    78  	// ChiefTxGas = big.NewInt(400000)
    79  	//abiCache *lru.Cache = nil
    80  	chiefContractCodeCache = new(sync.Map)
    81  )
    82  
    83  func ChainID() (id *big.Int) {
    84  	if IsTestnet() {
    85  		id = TestnetChainConfig.ChainId
    86  	} else if IsDevnet() {
    87  		id = DevnetChainConfig.ChainId
    88  	} else {
    89  		id = MainnetChainConfig.ChainId
    90  	}
    91  	return
    92  }
    93  
    94  func AnmapInfo(num *big.Int, vsn string) (n *big.Int, addr common.Address) {
    95  	if IsTestnet() {
    96  		n = TestnetChainConfig.Anmap001Block
    97  		if n != nil && n.Cmp(big.NewInt(0)) > 0 && n.Cmp(num) <= 0 {
    98  			addr = TestnetChainConfig.Anmap001Address
    99  		}
   100  	} else if IsDevnet() {
   101  		n = DevnetChainConfig.Anmap001Block
   102  		if n != nil && n.Cmp(big.NewInt(0)) > 0 && n.Cmp(num) <= 0 {
   103  			addr = DevnetChainConfig.Anmap001Address
   104  		}
   105  	} else {
   106  		n = MainnetChainConfig.Anmap001Block
   107  		if n != nil && n.Cmp(big.NewInt(0)) > 0 && n.Cmp(num) <= 0 {
   108  			addr = MainnetChainConfig.Anmap001Address
   109  		}
   110  	}
   111  	return
   112  }
   113  
   114  func MeshboxVsn(num *big.Int) (string, error) {
   115  	var n *big.Int
   116  	if IsTestnet() {
   117  		n = TestnetChainConfig.Meshbox002Block
   118  		if n != nil && n.Cmp(big.NewInt(0)) > 0 && n.Cmp(num) <= 0 {
   119  			return "0.0.2", nil
   120  		}
   121  		n = TestnetChainConfig.Meshbox001Block
   122  		if n != nil && n.Cmp(big.NewInt(0)) > 0 && n.Cmp(num) <= 0 {
   123  			return "0.0.1", nil
   124  		}
   125  
   126  	} else if IsDevnet() {
   127  		n = DevnetChainConfig.Meshbox002Block
   128  		if n != nil && n.Cmp(big.NewInt(0)) > 0 && n.Cmp(num) <= 0 {
   129  			return "0.0.2", nil
   130  		}
   131  		n = DevnetChainConfig.Meshbox001Block
   132  		if n != nil && n.Cmp(big.NewInt(0)) > 0 && n.Cmp(num) <= 0 {
   133  			return "0.0.1", nil
   134  		}
   135  	} else {
   136  		n = MainnetChainConfig.Meshbox002Block
   137  		if n != nil && n.Cmp(big.NewInt(0)) > 0 && n.Cmp(num) <= 0 {
   138  			return "0.0.2", nil
   139  		}
   140  		n = MainnetChainConfig.Meshbox001Block
   141  		if n != nil && n.Cmp(big.NewInt(0)) > 0 && n.Cmp(num) <= 0 {
   142  			return "0.0.1", nil
   143  		}
   144  	}
   145  	return "", errors.New("meshbox_service_not_started")
   146  }
   147  
   148  //POCInfo: poc地址
   149  func POCInfo() (addr common.Address) {
   150  	if IsTestnet() {
   151  		addr = TestnetChainConfig.PocAddress
   152  	} else if IsDevnet() {
   153  		addr = DevnetChainConfig.PocAddress
   154  	} else {
   155  		addr = MainnetChainConfig.PocAddress
   156  
   157  	}
   158  	return
   159  }
   160  
   161  func MeshboxInfo(num *big.Int, vsn string) (n *big.Int, addr common.Address) {
   162  	switch vsn {
   163  	case "0.0.1":
   164  		if IsTestnet() {
   165  			n = TestnetChainConfig.Meshbox001Block
   166  			if n != nil && n.Cmp(big.NewInt(0)) > 0 && n.Cmp(num) <= 0 {
   167  				addr = TestnetChainConfig.Meshbox001Address
   168  			}
   169  		} else if IsDevnet() {
   170  			n = DevnetChainConfig.Meshbox001Block
   171  			if n != nil && n.Cmp(big.NewInt(0)) > 0 && n.Cmp(num) <= 0 {
   172  				addr = DevnetChainConfig.Meshbox001Address
   173  			}
   174  		} else {
   175  			n = MainnetChainConfig.Meshbox001Block
   176  			if n != nil && n.Cmp(big.NewInt(0)) > 0 && n.Cmp(num) <= 0 {
   177  				addr = MainnetChainConfig.Meshbox001Address
   178  			}
   179  		}
   180  	case "0.0.2":
   181  		if IsTestnet() {
   182  			n = TestnetChainConfig.Meshbox002Block
   183  			if n != nil && n.Cmp(big.NewInt(0)) > 0 && n.Cmp(num) <= 0 {
   184  				addr = TestnetChainConfig.Meshbox002Address
   185  			}
   186  		} else if IsDevnet() {
   187  			n = DevnetChainConfig.Meshbox002Block
   188  			if n != nil && n.Cmp(big.NewInt(0)) > 0 && n.Cmp(num) <= 0 {
   189  				addr = DevnetChainConfig.Meshbox002Address
   190  			}
   191  		} else {
   192  			n = MainnetChainConfig.Meshbox002Block
   193  			if n != nil && n.Cmp(big.NewInt(0)) > 0 && n.Cmp(num) <= 0 {
   194  				addr = MainnetChainConfig.Meshbox002Address
   195  			}
   196  		}
   197  	}
   198  	return
   199  }
   200  
   201  // if input num less then nr001block ,enable new role for chief.tx's gaspool
   202  func IsSIP001Block(num *big.Int) bool {
   203  	if IsTestnet() {
   204  		if TestnetChainConfig.SIP001Block.Cmp(num) <= 0 {
   205  			return true
   206  		}
   207  	} else if IsDevnet() {
   208  		if DevnetChainConfig.SIP001Block.Cmp(num) <= 0 {
   209  			return true
   210  		}
   211  	} else {
   212  		if MainnetChainConfig.SIP001Block.Cmp(num) <= 0 {
   213  			return true
   214  		}
   215  	}
   216  	return false
   217  }
   218  
   219  // new_rule_002 to change block period
   220  // SIP002Block must big then zero
   221  func IsSIP002Block(num *big.Int) bool {
   222  	if IsTestnet() {
   223  		if TestnetChainConfig.SIP002Block.Cmp(big.NewInt(0)) > 0 && TestnetChainConfig.SIP002Block.Cmp(num) <= 0 {
   224  			return true
   225  		}
   226  	} else if IsDevnet() {
   227  		if DevnetChainConfig.SIP002Block.Cmp(num) <= 0 {
   228  			return true
   229  		}
   230  	} else {
   231  		if MainnetChainConfig.SIP002Block.Cmp(big.NewInt(0)) > 0 && MainnetChainConfig.SIP002Block.Cmp(num) <= 0 {
   232  			return true
   233  		}
   234  	}
   235  	return false
   236  }
   237  
   238  // add by liangc : 18-09-13 : incompatible HomesteadSigner begin at this number
   239  func IsSIP003Block(num *big.Int) bool {
   240  	if IsTestnet() {
   241  		if TestnetChainConfig.SIP003Block.Cmp(big.NewInt(0)) > 0 && TestnetChainConfig.SIP003Block.Cmp(num) <= 0 {
   242  			return true
   243  		}
   244  	} else if IsDevnet() {
   245  		if DevnetChainConfig.SIP003Block.Cmp(num) <= 0 {
   246  			return true
   247  		}
   248  	} else {
   249  		if MainnetChainConfig.SIP003Block.Cmp(big.NewInt(0)) > 0 && MainnetChainConfig.SIP003Block.Cmp(num) <= 0 {
   250  			return true
   251  		}
   252  	}
   253  	return false
   254  }
   255  
   256  // add by liangc : 22-01-29
   257  func IsSIP004Block(num *big.Int) bool {
   258  	if IsTestnet() {
   259  		if TestnetChainConfig.Sip004Block.Cmp(big.NewInt(0)) > 0 && TestnetChainConfig.Sip004Block.Cmp(num) <= 0 {
   260  			return true
   261  		}
   262  	} else if IsDevnet() {
   263  		if DevnetChainConfig.Sip004Block.Cmp(big.NewInt(0)) > 0 && DevnetChainConfig.Sip004Block.Cmp(num) <= 0 {
   264  			return true
   265  		}
   266  	} else {
   267  		if MainnetChainConfig.Sip004Block.Cmp(big.NewInt(0)) > 0 && MainnetChainConfig.Sip004Block.Cmp(num) <= 0 {
   268  			return true
   269  		}
   270  	}
   271  	return false
   272  }
   273  
   274  // add by liangc : 22-01-29
   275  func EqualSIP004Block(num *big.Int) bool {
   276  	if IsTestnet() {
   277  		if TestnetChainConfig.Sip004Block.Cmp(num) == 0 {
   278  			return true
   279  		}
   280  	} else if IsDevnet() {
   281  		if DevnetChainConfig.Sip004Block.Cmp(num) == 0 {
   282  			return true
   283  		}
   284  	} else {
   285  		if MainnetChainConfig.Sip004Block.Cmp(num) == 0 {
   286  			return true
   287  		}
   288  	}
   289  	return false
   290  }
   291  
   292  // add by liangc : 19-05-31 : for smc-1.0.0
   293  // may be discard
   294  func IsSIP100Block(num *big.Int) bool {
   295  	if IsTestnet() {
   296  		if TestnetChainConfig.Chief100Block != nil && TestnetChainConfig.Chief100Block.Cmp(big.NewInt(0)) > 0 && TestnetChainConfig.Chief100Block.Cmp(num) <= 0 {
   297  			return true
   298  		}
   299  	} else if IsDevnet() {
   300  		if DevnetChainConfig.Chief100Block != nil && DevnetChainConfig.Chief100Block.Cmp(big.NewInt(0)) > 0 && DevnetChainConfig.Chief100Block.Cmp(num) <= 0 {
   301  			return true
   302  		}
   303  	} else {
   304  		if MainnetChainConfig.Chief100Block != nil && MainnetChainConfig.Chief100Block.Cmp(big.NewInt(0)) > 0 && MainnetChainConfig.Chief100Block.Cmp(num) <= 0 {
   305  			return true
   306  		}
   307  	}
   308  	return false
   309  }
   310  
   311  func IsReadyMeshbox(num *big.Int) bool {
   312  	n := MainnetChainConfig.Meshbox002Block
   313  	if IsTestnet() {
   314  		n = TestnetChainConfig.Meshbox002Block
   315  	} else if IsDevnet() {
   316  		n = DevnetChainConfig.Meshbox002Block
   317  	}
   318  	if n != nil && n.Cmp(big.NewInt(0)) > 0 && n.Cmp(num) <= 0 {
   319  		return true
   320  	}
   321  
   322  	n = MainnetChainConfig.Meshbox001Block
   323  	if IsTestnet() {
   324  		n = TestnetChainConfig.Meshbox001Block
   325  	} else if IsDevnet() {
   326  		n = DevnetChainConfig.Meshbox001Block
   327  	}
   328  	if n != nil && n.Cmp(big.NewInt(0)) > 0 && n.Cmp(num) <= 0 {
   329  		return true
   330  	}
   331  	return false
   332  }
   333  
   334  func IsReadyAnmap(num *big.Int) bool {
   335  	n := MainnetChainConfig.Anmap001Block
   336  	if IsTestnet() {
   337  		n = TestnetChainConfig.Anmap001Block
   338  	} else if IsDevnet() {
   339  		n = DevnetChainConfig.Anmap001Block
   340  	}
   341  	if n != nil && n.Cmp(big.NewInt(0)) > 0 && n.Cmp(num) <= 0 {
   342  		return true
   343  	}
   344  	return false
   345  }
   346  
   347  // startNumber and address must from chain's config
   348  // 针对老的分叉版本在检测时跳过,从1.0.0版本开始不再跳过,所有以后版本本列表不再增加新的项
   349  func beforechief100AddressList() (list ChiefInfoList) {
   350  	if chiefInfoList != nil {
   351  		return chiefInfoList
   352  	}
   353  	if IsTestnet() {
   354  		list = ChiefInfoList{
   355  			// at same account and block number to deploy this contract can be get the same address
   356  			newChiefInfo(TestnetChainConfig.Chief002Block, "0.0.2", TestnetChainConfig.Chief002Address),
   357  			/*
   358  				newChiefInfo(TestnetChainConfig.Chief003Block, "0.0.3", TestnetChainConfig.Chief003Address),
   359  				newChiefInfo(TestnetChainConfig.Chief004Block, "0.0.4", TestnetChainConfig.Chief004Address),
   360  				newChiefInfo(TestnetChainConfig.Chief005Block, "0.0.5", TestnetChainConfig.Chief005Address),
   361  				newChiefInfo(TestnetChainConfig.Chief006Block, "0.0.6", TestnetChainConfig.Chief006Address),
   362  			*/
   363  		}
   364  	} else if IsDevnet() {
   365  		list = ChiefInfoList{
   366  			newChiefInfo(DevnetChainConfig.Chief007Block, "0.0.7", DevnetChainConfig.Chief007Address),
   367  		}
   368  	} else {
   369  		list = ChiefInfoList{
   370  			// at same account and block number to deploy this contract can be get the same address
   371  			newChiefInfo(MainnetChainConfig.Chief005Block, "0.0.5", MainnetChainConfig.Chief005Address),
   372  			newChiefInfo(MainnetChainConfig.Chief006Block, "0.0.6", MainnetChainConfig.Chief006Address),
   373  		}
   374  	}
   375  	chiefInfoList = list
   376  	return
   377  }
   378  
   379  // startNumber and address must from chain's config
   380  func chiefAddressList() (list ChiefInfoList) {
   381  	if chiefInfoList != nil {
   382  		return chiefInfoList
   383  	}
   384  	if IsTestnet() {
   385  		list = ChiefInfoList{
   386  			// at same account and block number to deploy this contract can be get the same address
   387  			newChiefInfo(TestnetChainConfig.Chief002Block, "0.0.2", TestnetChainConfig.Chief002Address),
   388  			/*
   389  				newChiefInfo(TestnetChainConfig.Chief003Block, "0.0.3", TestnetChainConfig.Chief003Address),
   390  				newChiefInfo(TestnetChainConfig.Chief004Block, "0.0.4", TestnetChainConfig.Chief004Address),
   391  				newChiefInfo(TestnetChainConfig.Chief005Block, "0.0.5", TestnetChainConfig.Chief005Address),
   392  				newChiefInfo(TestnetChainConfig.Chief006Block, "0.0.6", TestnetChainConfig.Chief006Address),
   393  			*/
   394  			newChiefInfoWithPocBase(TestnetChainConfig.Chief100Block, "1.0.0", TestnetChainConfig.Chief100Address, TestnetChainConfig.PocAddress, TestnetChainConfig.ChiefBaseAddress),
   395  		}
   396  	} else if IsDevnet() {
   397  		list = ChiefInfoList{
   398  			newChiefInfo(DevnetChainConfig.Chief007Block, "0.0.7", DevnetChainConfig.Chief007Address),
   399  			newChiefInfoWithPocBase(DevnetChainConfig.Chief100Block, "1.0.0", DevnetChainConfig.Chief100Address, DevnetChainConfig.PocAddress, DevnetChainConfig.ChiefBaseAddress),
   400  		}
   401  	} else {
   402  		list = ChiefInfoList{
   403  			// at same account and block number to deploy this contract can be get the same address
   404  			newChiefInfo(MainnetChainConfig.Chief005Block, "0.0.5", MainnetChainConfig.Chief005Address),
   405  			newChiefInfo(MainnetChainConfig.Chief006Block, "0.0.6", MainnetChainConfig.Chief006Address),
   406  			newChiefInfoWithPocBase(MainnetChainConfig.Chief100Block, "1.0.0", MainnetChainConfig.Chief100Address, MainnetChainConfig.PocAddress, MainnetChainConfig.ChiefBaseAddress),
   407  		}
   408  	}
   409  	chiefInfoList = list
   410  	return
   411  }
   412  
   413  func GetChiefInfoByVsn(vsn string) *ChiefInfo {
   414  	for _, ci := range chiefAddressList() {
   415  		if ci.StartNumber != nil && ci.StartNumber.Int64() > 0 && ci.Version == vsn {
   416  			return ci
   417  		}
   418  	}
   419  	return nil
   420  }
   421  func GetChiefInfo(blockNumber *big.Int) *ChiefInfo {
   422  	if blockNumber != nil && blockNumber.Cmp(big.NewInt(0)) > 0 {
   423  		return getChiefInfo(chiefAddressList(), blockNumber)
   424  	}
   425  	return nil
   426  }
   427  func getChiefInfo(list ChiefInfoList, blockNumber *big.Int) *ChiefInfo {
   428  	// TODO sort once only
   429  	sort.Sort(list)
   430  	for _, c := range list {
   431  		if c.StartNumber != nil && blockNumber.Int64() >= c.StartNumber.Int64() {
   432  			return c
   433  		}
   434  	}
   435  	return nil
   436  }
   437  
   438  // skip verify difficulty on this old hardfork block number
   439  func IsBeforeChief100block(blockNumber *big.Int) bool {
   440  	//return isChiefBlock(oldchiefAddressList(), blockNumber)
   441  	for _, ci := range beforechief100AddressList() {
   442  		//log.Info("isChief", "a", ci.StartNumber, "b", blockNumber)
   443  		if ci.StartNumber != nil && ci.StartNumber.Cmp(blockNumber) == 0 {
   444  			return true
   445  		}
   446  	}
   447  	return false
   448  }
   449  
   450  func IsChiefUpdate(data []byte) bool {
   451  	if len(data) < 4 {
   452  		return false
   453  	} else {
   454  		if bytes.Equal(data[:4], []byte{28, 27, 135, 114}) {
   455  			return true
   456  		}
   457  	}
   458  	return false
   459  }
   460  
   461  func AnmapBindInfo(addr common.Address, blockHash common.Hash) (from common.Address, nodeids []common.Address, err error) {
   462  	select {
   463  	case <-InitAnmap:
   464  		rtn := make(chan MBoxSuccess)
   465  		m := Mbox{
   466  			Method: "bindInfo",
   467  			Rtn:    rtn,
   468  		}
   469  		emptyHash := common.Hash{} == blockHash
   470  		if emptyHash {
   471  			m.Params = map[string]interface{}{"addr": addr}
   472  		} else {
   473  			m.Params = map[string]interface{}{"addr": addr, "hash": blockHash}
   474  		}
   475  		StatuteService <- m
   476  		success := <-rtn
   477  		if success.Success {
   478  			m := success.Entity.(map[string]interface{})
   479  			from = m["from"].(common.Address)
   480  			nodeids = m["nodeids"].([]common.Address)
   481  		} else {
   482  			err = success.Entity.(error)
   483  		}
   484  	default:
   485  		err = errors.New("anmap_not_ready")
   486  	}
   487  	return
   488  }
   489  
   490  func AnmapBind(from, nodeid common.Address, sigHex string) (string, error) {
   491  	select {
   492  	case <-InitAnmap:
   493  		rtn := make(chan MBoxSuccess)
   494  		m := Mbox{
   495  			Method: "bind",
   496  			Rtn:    rtn,
   497  		}
   498  		m.Params = map[string]interface{}{"from": from, "nodeid": nodeid, "sigHex": sigHex}
   499  		StatuteService <- m
   500  		success := <-rtn
   501  		if success.Success {
   502  			return success.Entity.(string), nil
   503  		} else {
   504  			return "", success.Entity.(error)
   505  		}
   506  	default:
   507  		return "", errors.New("anmap_not_ready")
   508  	}
   509  }
   510  
   511  func AnmapUnbind(from, nodeid common.Address, sigHex string) (string, error) {
   512  	select {
   513  	case <-InitAnmap:
   514  		rtn := make(chan MBoxSuccess)
   515  		m := Mbox{
   516  			Method: "unbind",
   517  			Rtn:    rtn,
   518  		}
   519  		m.Params = map[string]interface{}{"from": from, "nodeid": nodeid, "sigHex": sigHex}
   520  		StatuteService <- m
   521  		success := <-rtn
   522  		if success.Success {
   523  			return success.Entity.(string), nil
   524  		} else {
   525  			return "", success.Entity.(error)
   526  		}
   527  	default:
   528  		return "", errors.New("anmap_not_ready")
   529  	}
   530  }
   531  
   532  //PocDeposit poc质押操作
   533  func PocDeposit(from common.Address, sigHex string) (string, error) {
   534  	rtn := make(chan MBoxSuccess)
   535  	m := Mbox{
   536  		Method: "poc_deposit",
   537  		Rtn:    rtn,
   538  	}
   539  	m.Params = map[string]interface{}{"from": from, "sigHex": sigHex}
   540  	StatuteService <- m
   541  	success := <-rtn
   542  	if success.Success {
   543  		return success.Entity.(string), nil
   544  	} else {
   545  		return "", success.Entity.(error)
   546  	}
   547  }
   548  func pocHelper(method string, from, nodeID common.Address) (string, error) {
   549  	rtn := make(chan MBoxSuccess)
   550  	m := Mbox{
   551  		Method: method,
   552  		Rtn:    rtn,
   553  	}
   554  	m.Params = map[string]interface{}{"from": from, "nodeid": nodeID}
   555  	StatuteService <- m
   556  	success := <-rtn
   557  	if success.Success {
   558  		return success.Entity.(string), nil
   559  	} else {
   560  		return "", success.Entity.(error)
   561  	}
   562  }
   563  
   564  //PocStart 因为错过出块被拉黑以后,在一个epoch之后需要手工恢复出块资格
   565  func PocStart(from, nodeID common.Address) (string, error) {
   566  	return pocHelper(POC_METHOD_START, from, nodeID)
   567  }
   568  
   569  //PocStop 因为不想参与挖矿,准备撤回抵押
   570  func PocStop(from, nodeID common.Address) (string, error) {
   571  	return pocHelper(POC_METHOD_STOP, from, nodeID)
   572  }
   573  
   574  //PocWithdraw 在停止PocStop两周后,可以从poc合约中撤回押金到自己账户
   575  func PocWithdraw(from, nodeID common.Address) (string, error) {
   576  	return pocHelper(POC_METHOD_WITHDRAW, from, nodeID)
   577  }
   578  
   579  //PocWithdrawSurplus  因为手工调用Poc Withdraw合约,一次性抵押过多,后续可以选择撤回多余的抵押
   580  func PocWithdrawSurplus(from, nodeID common.Address) (string, error) {
   581  	return pocHelper(POC_METHOD_WITHDRAW_SURPLUS, from, nodeID)
   582  }
   583  
   584  //PocStatus Poc状态
   585  type PocStatus struct {
   586  	MinerList       []common.Address
   587  	AmountList      []*big.Int
   588  	BlockList       []*big.Int
   589  	OwnerList       []common.Address
   590  	BlackStatusList []*big.Int
   591  }
   592  
   593  //PocGetAll 获取poc status
   594  func PocGetAll(hash common.Hash, number *big.Int) (ps *PocStatus, err error) {
   595  	rtn := make(chan MBoxSuccess)
   596  	m := Mbox{
   597  		Method: POC_METHOD_GET_STATUS,
   598  		Rtn:    rtn,
   599  	}
   600  	if number == nil || hash == common.HexToHash("0x") {
   601  		panic(errors.New("hash and number can not nil"))
   602  	}
   603  	m.Params = map[string]interface{}{"hash": hash, "number": number}
   604  	StatuteService <- m
   605  	success := <-rtn
   606  	if success.Success {
   607  		return success.Entity.(*PocStatus), nil
   608  	} else {
   609  		return nil, success.Entity.(error)
   610  	}
   611  }
   612  func MeshboxExistAddress(addr common.Address) bool {
   613  	select {
   614  	case <-InitMeshbox:
   615  		rtn := make(chan MBoxSuccess)
   616  		m := Mbox{
   617  			Method: "existAddress",
   618  			Rtn:    rtn,
   619  		}
   620  		m.Params = map[string]interface{}{"addr": addr}
   621  		StatuteService <- m
   622  		success := <-rtn
   623  		if success.Success && success.Entity.(int64) > 0 {
   624  			return true
   625  		}
   626  	default:
   627  		return false
   628  	}
   629  	return false
   630  }
   631  
   632  /*
   633  func GetVRFByHash(hash common.Hash) ([]byte, error) {
   634  	rtn := make(chan MBoxSuccess)
   635  	m := Mbox{
   636  		Method: "GetVRF",
   637  		Rtn:    rtn,
   638  	}
   639  	if hash == common.HexToHash("0x") {
   640  		panic(errors.New("hash and number can not nil"))
   641  	}
   642  	m.Params = map[string]interface{}{"hash": hash}
   643  	MboxChan <- m
   644  
   645  	success := <-rtn
   646  	if success.Success {
   647  		return success.Entity.([]byte), nil
   648  	}
   649  	return nil, success.Entity.(error)
   650  }*/
   651  
   652  func SetChiefContractCode(addr common.Address, code []byte) {
   653  	chiefContractCodeCache.Store(addr, code)
   654  }
   655  
   656  func GetChiefContractCode(addr common.Address) ([]byte, error) {
   657  	val, ok := chiefContractCodeCache.Load(addr)
   658  	if !ok {
   659  		return nil, errors.New("not_found")
   660  	}
   661  	return val.([]byte), nil
   662  }
   663  
   664  var chiefCalledMap = map[string]string{
   665  	TestnetChainConfig.Chief100Address.Hex():  TestnetChainConfig.ChiefBaseAddress.Hex(),
   666  	TestnetChainConfig.ChiefBaseAddress.Hex(): TestnetChainConfig.PocAddress.Hex(),
   667  
   668  	MainnetChainConfig.Chief100Address.Hex():  MainnetChainConfig.ChiefBaseAddress.Hex(),
   669  	MainnetChainConfig.ChiefBaseAddress.Hex(): MainnetChainConfig.PocAddress.Hex(),
   670  
   671  	DevnetChainConfig.Chief100Address.Hex():  DevnetChainConfig.ChiefBaseAddress.Hex(),
   672  	DevnetChainConfig.ChiefBaseAddress.Hex(): DevnetChainConfig.PocAddress.Hex(),
   673  }
   674  
   675  func IsChiefCalled(from, to common.Address) (yes bool) {
   676  	if t, ok := chiefCalledMap[from.Hex()]; ok && t == to.Hex() {
   677  		yes = true
   678  	}
   679  	//fmt.Println("params.IsChiefCalled", from.Hex(), "->", to.Hex(), yes)
   680  	return
   681  }
   682  
   683  func IsChiefAddress(addr common.Address) (yes bool) {
   684  	yes = isChiefAddress(chiefAddressList(), addr)
   685  	//t := stack.Trace()
   686  	return
   687  }
   688  
   689  func isChiefAddress(list ChiefInfoList, addr common.Address) bool {
   690  	if addr == common.HexToAddress("0x") {
   691  		return false
   692  	}
   693  	for _, ci := range list {
   694  		if ci.Addr == addr {
   695  			return true
   696  		}
   697  	}
   698  	return false
   699  }
   700  
   701  func IsChiefAddressOnBlock(number *big.Int, addr common.Address) (yes bool) {
   702  	yes = isChiefAddressOnBlock(number, chiefAddressList(), addr)
   703  	//t := stack.Trace()
   704  	return
   705  }
   706  func isChiefAddressOnBlock(number *big.Int, list ChiefInfoList, addr common.Address) bool {
   707  	if addr == common.HexToAddress("0x") {
   708  		return false
   709  	}
   710  	if IsSIP100Block(number) { //sip100以后需要验证to地址必须和新的共识合约相同
   711  		for _, ci := range list {
   712  			if ci.Addr == addr && ci.Version == "1.0.0" {
   713  				return true
   714  			}
   715  		}
   716  	} else {
   717  		for _, ci := range list {
   718  			if ci.Addr == addr {
   719  				return true
   720  			}
   721  		}
   722  	}
   723  
   724  	return false
   725  }
   726  
   727  // chief service message box obj
   728  type Mbox struct {
   729  	Method string
   730  	Rtn    chan MBoxSuccess
   731  	Params map[string]interface{}
   732  }
   733  
   734  type MBoxSuccess struct {
   735  	Success bool
   736  	Entity  interface{}
   737  }
   738  
   739  func TribeGetStatus(num *big.Int, hash common.Hash) (ChiefStatus, error) {
   740  	rtn := SendToMsgBoxWithHash("GetStatus", hash, num)
   741  	r := <-rtn
   742  	if !r.Success {
   743  		return ChiefStatus{}, r.Entity.(error)
   744  	}
   745  	cs := r.Entity.(ChiefStatus)
   746  	return cs, nil
   747  }
   748  
   749  // called by chief.GetStatus
   750  func SendToMsgBoxWithHash(method string, hash common.Hash, number *big.Int) chan MBoxSuccess {
   751  	rtn := make(chan MBoxSuccess)
   752  	m := Mbox{
   753  		Method: method,
   754  		Rtn:    rtn,
   755  	}
   756  	if number == nil || hash == common.HexToHash("0x") {
   757  		panic(errors.New("hash and number can not nil"))
   758  	}
   759  	m.Params = map[string]interface{}{"hash": hash, "number": number}
   760  	MboxChan <- m
   761  	return rtn
   762  }
   763  
   764  func SendToMsgBoxForFilterVolunteer(hash common.Hash, number *big.Int, addr common.Address) chan MBoxSuccess {
   765  	rtn := make(chan MBoxSuccess)
   766  	m := Mbox{
   767  		Method: "FilterVolunteer",
   768  		Rtn:    rtn,
   769  	}
   770  	if number == nil || hash == common.HexToHash("0x") {
   771  		panic(errors.New("hash and number can not nil"))
   772  	}
   773  	m.Params = map[string]interface{}{"hash": hash, "number": number, "address": addr}
   774  	MboxChan <- m
   775  	return rtn
   776  }
   777  
   778  /*
   779  依据vrf,依据上一块的状态来选取下一轮的出块地址
   780  */
   781  func Chief100GetNextRoundSigner(hash common.Hash, number *big.Int, vrf *big.Int) common.Address {
   782  	rtn := make(chan MBoxSuccess)
   783  	m := Mbox{
   784  		Method: Chief100Update,
   785  		Rtn:    rtn,
   786  	}
   787  	m.Params = map[string]interface{}{
   788  		"hash":   hash,
   789  		"number": number,
   790  		"vrfn":   vrf,
   791  	}
   792  	MboxChan <- m
   793  	success := <-rtn
   794  	return success.Entity.(common.Address) //必须成功,不成功就返回空地址
   795  
   796  }
   797  func SendToMsgBox(method string) chan MBoxSuccess {
   798  	rtn := make(chan MBoxSuccess)
   799  	m := Mbox{
   800  		Method: method,
   801  		Rtn:    rtn,
   802  	}
   803  	MboxChan <- m
   804  	return rtn
   805  }
   806  
   807  func VerifyMiner(parenthash common.Hash, addr common.Address, vrfn []byte) bool {
   808  	rtn := make(chan MBoxSuccess)
   809  	m := Mbox{
   810  		Method: "VerifyMiner",
   811  		Rtn:    rtn,
   812  	}
   813  	if parenthash == common.HexToHash("0x") {
   814  		panic(errors.New("hash can not nil"))
   815  	}
   816  	if vrfn == nil {
   817  		panic(errors.New("vrfn can not nil"))
   818  	}
   819  	m.Params = map[string]interface{}{"parenthash": parenthash, "addr": addr, "vrfn": vrfn}
   820  	MboxChan <- m
   821  	success := <-rtn
   822  	if success.Success {
   823  		return success.Entity.(bool)
   824  	}
   825  	return false
   826  }
   827  
   828  // clone from chief.getStatus return struct
   829  // for return to tribe by channel
   830  type ChiefStatus struct {
   831  	LeaderList     []common.Address
   832  	VolunteerList  []common.Address
   833  	SignerList     []common.Address
   834  	BlackList      []common.Address // append by vsn 0.0.3
   835  	ScoreList      []*big.Int
   836  	NumberList     []*big.Int
   837  	Number         *big.Int
   838  	Epoch          *big.Int
   839  	LeaderLimit    *big.Int
   840  	SignerLimit    *big.Int
   841  	VolunteerLimit *big.Int
   842  	TotalVolunteer *big.Int
   843  }
   844  
   845  // clone from chief.getVolunteers return struct
   846  // for return to tribe by channel
   847  // append by vsn 0.0.6
   848  type ChiefVolunteers struct {
   849  	VolunteerList []common.Address
   850  	WeightList    []*big.Int
   851  	Length        *big.Int
   852  }
   853  
   854  func GetIPCPath() string {
   855  	return os.Getenv("IPCPATH")
   856  }
   857  
   858  func IsTestnet() bool {
   859  	return os.Getenv("TESTNET") == "1"
   860  }
   861  
   862  func IsDevnet() bool {
   863  	return os.Getenv("DEVNET") == "1"
   864  }
   865  
   866  func TribePeriod() uint64 {
   867  	if IsTestnet() && TestnetChainConfig.Tribe.Period > 0 {
   868  		return TestnetChainConfig.Tribe.Period
   869  	} else if IsDevnet() && DevnetChainConfig.Tribe.Period > 0 {
   870  		return DevnetChainConfig.Tribe.Period
   871  	} else if MainnetChainConfig.Tribe.Period > 0 {
   872  		return MainnetChainConfig.Tribe.Period
   873  	}
   874  	return 14
   875  }