github.com/palisadeinc/bor@v0.0.0-20230615125219-ab7196213d15/consensus/bor/contract/client.go (about)

     1  package contract
     2  
     3  import (
     4  	"context"
     5  	"math"
     6  	"math/big"
     7  	"strings"
     8  
     9  	"github.com/ethereum/go-ethereum/accounts/abi"
    10  	"github.com/ethereum/go-ethereum/common"
    11  	"github.com/ethereum/go-ethereum/common/hexutil"
    12  	"github.com/ethereum/go-ethereum/consensus/bor/api"
    13  	"github.com/ethereum/go-ethereum/consensus/bor/clerk"
    14  	"github.com/ethereum/go-ethereum/consensus/bor/statefull"
    15  	"github.com/ethereum/go-ethereum/core/state"
    16  	"github.com/ethereum/go-ethereum/core/types"
    17  	"github.com/ethereum/go-ethereum/internal/ethapi"
    18  	"github.com/ethereum/go-ethereum/log"
    19  	"github.com/ethereum/go-ethereum/params"
    20  	"github.com/ethereum/go-ethereum/rlp"
    21  	"github.com/ethereum/go-ethereum/rpc"
    22  )
    23  
    24  var (
    25  	vABI, _ = abi.JSON(strings.NewReader(validatorsetABI))
    26  	sABI, _ = abi.JSON(strings.NewReader(stateReceiverABI))
    27  )
    28  
    29  func ValidatorSet() abi.ABI {
    30  	return vABI
    31  }
    32  
    33  func StateReceiver() abi.ABI {
    34  	return sABI
    35  }
    36  
    37  type GenesisContractsClient struct {
    38  	validatorSetABI       abi.ABI
    39  	stateReceiverABI      abi.ABI
    40  	ValidatorContract     string
    41  	StateReceiverContract string
    42  	chainConfig           *params.ChainConfig
    43  	ethAPI                api.Caller
    44  }
    45  
    46  const (
    47  	validatorsetABI  = `[{"constant":true,"inputs":[],"name":"SPRINT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"SYSTEM_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"CHAIN","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"FIRST_END_BLOCK","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"producers","outputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"power","type":"uint256"},{"internalType":"address","name":"signer","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"ROUND_TYPE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"BOR_ID","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"spanNumbers","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"VOTE_TYPE","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"validators","outputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"power","type":"uint256"},{"internalType":"address","name":"signer","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"spans","outputs":[{"internalType":"uint256","name":"number","type":"uint256"},{"internalType":"uint256","name":"startBlock","type":"uint256"},{"internalType":"uint256","name":"endBlock","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"startBlock","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"endBlock","type":"uint256"}],"name":"NewSpan","type":"event"},{"constant":true,"inputs":[],"name":"currentSprint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"span","type":"uint256"}],"name":"getSpan","outputs":[{"internalType":"uint256","name":"number","type":"uint256"},{"internalType":"uint256","name":"startBlock","type":"uint256"},{"internalType":"uint256","name":"endBlock","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getCurrentSpan","outputs":[{"internalType":"uint256","name":"number","type":"uint256"},{"internalType":"uint256","name":"startBlock","type":"uint256"},{"internalType":"uint256","name":"endBlock","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getNextSpan","outputs":[{"internalType":"uint256","name":"number","type":"uint256"},{"internalType":"uint256","name":"startBlock","type":"uint256"},{"internalType":"uint256","name":"endBlock","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"number","type":"uint256"}],"name":"getSpanByBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"currentSpanNumber","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"span","type":"uint256"}],"name":"getValidatorsTotalStakeBySpan","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"span","type":"uint256"}],"name":"getProducersTotalStakeBySpan","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"span","type":"uint256"},{"internalType":"address","name":"signer","type":"address"}],"name":"getValidatorBySigner","outputs":[{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"power","type":"uint256"},{"internalType":"address","name":"signer","type":"address"}],"internalType":"struct BorValidatorSet.Validator","name":"result","type":"tuple"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"span","type":"uint256"},{"internalType":"address","name":"signer","type":"address"}],"name":"isValidator","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"span","type":"uint256"},{"internalType":"address","name":"signer","type":"address"}],"name":"isProducer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"signer","type":"address"}],"name":"isCurrentValidator","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"signer","type":"address"}],"name":"isCurrentProducer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"number","type":"uint256"}],"name":"getBorValidators","outputs":[{"internalType":"address[]","name":"","type":"address[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getInitialValidators","outputs":[{"internalType":"address[]","name":"","type":"address[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getValidators","outputs":[{"internalType":"address[]","name":"","type":"address[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"newSpan","type":"uint256"},{"internalType":"uint256","name":"startBlock","type":"uint256"},{"internalType":"uint256","name":"endBlock","type":"uint256"},{"internalType":"bytes","name":"validatorBytes","type":"bytes"},{"internalType":"bytes","name":"producerBytes","type":"bytes"}],"name":"commitSpan","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"span","type":"uint256"},{"internalType":"bytes32","name":"dataHash","type":"bytes32"},{"internalType":"bytes","name":"sigs","type":"bytes"}],"name":"getStakePowerBySigs","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"rootHash","type":"bytes32"},{"internalType":"bytes32","name":"leaf","type":"bytes32"},{"internalType":"bytes","name":"proof","type":"bytes"}],"name":"checkMembership","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"d","type":"bytes32"}],"name":"leafNode","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"left","type":"bytes32"},{"internalType":"bytes32","name":"right","type":"bytes32"}],"name":"innerNode","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"pure","type":"function"}]`
    48  	stateReceiverABI = `[{"constant":true,"inputs":[],"name":"SYSTEM_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"lastStateId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"syncTime","type":"uint256"},{"internalType":"bytes","name":"recordBytes","type":"bytes"}],"name":"commitState","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"}]`
    49  )
    50  
    51  func NewGenesisContractsClient(
    52  	chainConfig *params.ChainConfig,
    53  	validatorContract,
    54  	stateReceiverContract string,
    55  	ethAPI api.Caller,
    56  ) *GenesisContractsClient {
    57  	return &GenesisContractsClient{
    58  		validatorSetABI:       ValidatorSet(),
    59  		stateReceiverABI:      StateReceiver(),
    60  		ValidatorContract:     validatorContract,
    61  		StateReceiverContract: stateReceiverContract,
    62  		chainConfig:           chainConfig,
    63  		ethAPI:                ethAPI,
    64  	}
    65  }
    66  
    67  func (gc *GenesisContractsClient) CommitState(
    68  	event *clerk.EventRecordWithTime,
    69  	state *state.StateDB,
    70  	header *types.Header,
    71  	chCtx statefull.ChainContext,
    72  ) (uint64, error) {
    73  	eventRecord := event.BuildEventRecord()
    74  
    75  	recordBytes, err := rlp.EncodeToBytes(eventRecord)
    76  	if err != nil {
    77  		return 0, err
    78  	}
    79  
    80  	const method = "commitState"
    81  
    82  	t := event.Time.Unix()
    83  
    84  	data, err := gc.stateReceiverABI.Pack(method, big.NewInt(0).SetInt64(t), recordBytes)
    85  	if err != nil {
    86  		log.Error("Unable to pack tx for commitState", "error", err)
    87  		return 0, err
    88  	}
    89  
    90  	msg := statefull.GetSystemMessage(common.HexToAddress(gc.StateReceiverContract), data)
    91  	gasUsed, err := statefull.ApplyMessage(context.Background(), msg, state, header, gc.chainConfig, chCtx)
    92  
    93  	// Logging event log with time and individual gasUsed
    94  	log.Info("→ committing new state", "eventRecord", event.String(gasUsed))
    95  
    96  	if err != nil {
    97  		return 0, err
    98  	}
    99  
   100  	return gasUsed, nil
   101  }
   102  
   103  func (gc *GenesisContractsClient) LastStateId(state *state.StateDB, number uint64, hash common.Hash) (*big.Int, error) {
   104  	blockNr := rpc.BlockNumber(number)
   105  
   106  	const method = "lastStateId"
   107  
   108  	data, err := gc.stateReceiverABI.Pack(method)
   109  	if err != nil {
   110  		log.Error("Unable to pack tx for LastStateId", "error", err)
   111  
   112  		return nil, err
   113  	}
   114  
   115  	msgData := (hexutil.Bytes)(data)
   116  	toAddress := common.HexToAddress(gc.StateReceiverContract)
   117  	gas := (hexutil.Uint64)(uint64(math.MaxUint64 / 2))
   118  
   119  	// Do a call with state so that we can fetch the last state ID from a given (incoming)
   120  	// state instead of local(canonical) chain.
   121  	result, err := gc.ethAPI.CallWithState(context.Background(), ethapi.TransactionArgs{
   122  		Gas:  &gas,
   123  		To:   &toAddress,
   124  		Data: &msgData,
   125  	}, rpc.BlockNumberOrHash{BlockNumber: &blockNr, BlockHash: &hash}, state, nil)
   126  	if err != nil {
   127  		return nil, err
   128  	}
   129  
   130  	ret := new(*big.Int)
   131  	if err := gc.stateReceiverABI.UnpackIntoInterface(ret, method, result); err != nil {
   132  		return nil, err
   133  	}
   134  
   135  	return *ret, nil
   136  }