github.com/cheng762/platon-go@v1.8.17-0.20190529111256-7deff2d7be26/core/vm/ppos_precontracts.go (about) 1 package vm 2 3 import ( 4 "bytes" 5 "encoding/hex" 6 "errors" 7 "fmt" 8 "github.com/PlatONnetwork/PlatON-Go/common" 9 "github.com/PlatONnetwork/PlatON-Go/common/byteutil" 10 "github.com/PlatONnetwork/PlatON-Go/log" 11 "github.com/PlatONnetwork/PlatON-Go/rlp" 12 gerr "github.com/go-errors/errors" 13 "reflect" 14 ) 15 16 // Ppos pre-compiled contract address 17 var PrecompiledContractsPpos = map[common.Address]PrecompiledContract{ 18 common.CandidatePoolAddr: &CandidateContract{}, 19 common.TicketPoolAddr: &TicketContract{}, 20 } 21 22 var ( 23 ErrParamsRlpDecode = errors.New("Rlp decode fail") 24 ErrParamsBaselen = errors.New("Params Base length does not match") 25 ErrParamsLen = errors.New("Params length does not match") 26 ErrUndefFunction = errors.New("Undefined function") 27 ErrTxType = errors.New("Transaction type does not match the function") 28 ) 29 30 // execute decode input data and call the function. 31 func execute(input []byte, command map[string]interface{}) ([]byte, error) { 32 log.Info("Input to execute==> ", "input: ", hex.EncodeToString(input)) 33 defer func() { 34 if err := recover(); nil != err { 35 // catch call panic 36 msg := fmt.Sprintf("panic: %v\n", gerr.Wrap(err, 2).ErrorStack()) 37 log.Error("Failed to execute==> ", "err: ", fmt.Sprint(err), "\nstack: ", msg) 38 } 39 }() 40 var source [][]byte 41 if err := rlp.Decode(bytes.NewReader(input), &source); nil != err { 42 log.Error("Failed to execute==> ", err.Error()) 43 return nil, ErrParamsRlpDecode 44 } 45 if len(source) < 2 { 46 log.Error("Failed to execute==> ", "ErrParamsBaselen: ", ErrParamsBaselen.Error()) 47 return nil, ErrParamsBaselen 48 } 49 // get func and param list 50 if _, ok := command[byteutil.BytesToString(source[1])]; !ok { 51 log.Error("Failed to execute==> ", "ErrUndefFunction: ", ErrUndefFunction.Error()) 52 return nil, ErrUndefFunction 53 } 54 funcValue := command[byteutil.BytesToString(source[1])] 55 // validate transaction type 56 var txTypeMap = map[string]uint64{ 57 "VoteTicket": 1000, 58 "CandidateDeposit": 1001, 59 "CandidateApplyWithdraw": 1002, 60 "CandidateWithdraw": 1003, 61 "SetCandidateExtra": 1004, 62 } 63 if txType, ok := txTypeMap[byteutil.BytesToString(source[1])]; ok { 64 if txType != byteutil.BytesTouint64(source[0]) { 65 log.Error("Failed to execute==> ", "ErrTxType: ", ErrTxType.Error()) 66 return nil, ErrTxType 67 } 68 } 69 paramList := reflect.TypeOf(funcValue) 70 paramNum := paramList.NumIn() 71 params := make([]reflect.Value, paramNum) 72 if paramNum != len(source)-2 { 73 log.Error("Failed to execute==> ", "ErrParamsLen: ", ErrParamsLen.Error()) 74 return nil, ErrParamsLen 75 } 76 for i := 0; i < paramNum; i++ { 77 targetType := paramList.In(i).String() 78 originByte := []reflect.Value{reflect.ValueOf(source[i+2])} 79 params[i] = reflect.ValueOf(byteutil.Command[targetType]).Call(originByte)[0] 80 } 81 result := reflect.ValueOf(funcValue).Call(params) 82 log.Info("Result of execute==> ", "result[0]: ", result[0].Bytes()) 83 if _, err := result[1].Interface().(error); !err { 84 return result[0].Bytes(), nil 85 } 86 log.Error("Result of execute==> ", "result[1]: err ", result[1].Interface().(error).Error()) 87 return result[0].Bytes(), result[1].Interface().(error) 88 } 89 90 // ResultCommon is the struct of transaction event. 91 type ResultCommon struct { 92 Ret bool 93 Data string 94 ErrMsg string 95 } 96 97 // DecodeResultStr format the string of value to bytes. 98 func DecodeResultStr(result string) []byte { 99 resultBytes := []byte(result) 100 strHash := common.BytesToHash(common.Int32ToBytes(32)) 101 sizeHash := common.BytesToHash(common.Int64ToBytes(int64((len(resultBytes))))) 102 var dataRealSize = len(resultBytes) 103 if (dataRealSize % 32) != 0 { 104 dataRealSize = dataRealSize + (32 - (dataRealSize % 32)) 105 } 106 dataByt := make([]byte, dataRealSize) 107 copy(dataByt[0:], resultBytes) 108 109 finalData := make([]byte, 0) 110 finalData = append(finalData, strHash.Bytes()...) 111 finalData = append(finalData, sizeHash.Bytes()...) 112 finalData = append(finalData, dataByt...) 113 return finalData 114 }