/* * Stress test the curve. If the '-num' argument is given, runs the loop * |num| times and prints the resulting X-coordinate. Otherwise runs the test * the default number of times and compares against the expected result. */ int setup_tests(void) { const char *p; if (!atoi64(NUM_REPEATS, &num_repeats)) { TEST_error("Cannot parse " NUM_REPEATS); return 0; } /* * TODO(openssl-team): code under test/ should be able to reuse the option * parsing framework currently in apps/. */ p = test_get_option_argument("-num"); if (p != NULL) { if (!atoi64(p, &num_repeats) || num_repeats < 0) return 0; print_mode = 1; } #ifndef OPENSSL_NO_EC ADD_TEST(test_curve); #endif return 1; }
// Convert a cobol argument to a C integer. Make allowances for different // data types, since constants get passed as DISPLAY (NSU or NTS) and fields // should be BINARY (NBS or NBU) static ISC_UINT64 CvtArgToInt(const argument_entry *arg) { ISC_UINT64 temp; char *stemp; char sign; switch (arg->a_type) { case 1: // NSU temp = (ISC_UINT64)atoi64((char *)CobolToString(arg)); break; case 2: // NTS stemp = (char *)CobolToString(arg); sign = *(stemp + strlen(stemp) - 1); *(stemp + strlen(stemp) - 1) = '\0'; if (sign == '-') temp = (ISC_UINT64)((ISC_INT64)atoi64(stemp) * -1); else temp = atoi64(stemp); break; case 11: // NBS case 12: // NBU temp = CvtCobolToInt(arg->a_address, (ISC_USHORT)arg->a_length, arg->a_type); break; default: temp = 0; break; } return (temp); }
/* ** Return a prepared statement which, when stepped, will return in its ** first column the blob associated with segment zId. If zId begins with ** 'r' then it is a rowid of a %_segdir entry. Otherwise it is a ** %_segment entry. */ static sqlite3_stmt *prepareToGetSegment( sqlite3 *db, /* The database */ const char *zTab, /* The FTS3/4 table name */ const char *zId /* ID of the segment to open */ ) { sqlite3_stmt *pStmt; if( zId[0]=='r' ) { pStmt = prepare(db, "SELECT root FROM '%q_segdir' WHERE rowid=%lld", zTab, atoi64(zId+1)); } else { pStmt = prepare(db, "SELECT block FROM '%q_segments' WHERE blockid=%lld", zTab, atoi64(zId)); } return pStmt; }
///値の加算 ///@note Available since 2.0.0. bool server_type::api_hincrby(client_type * client) { auto current = client->get_time(); auto & key = *client->get_keys()[0]; auto & field = *client->get_fields()[0]; auto & increment = client->get_argument(3); bool is_valid = true; int64_t intval = atoi64(increment, is_valid); if (!is_valid) { throw std::runtime_error("ERR increment is not valid integer"); } auto db = writable_db(client); std::shared_ptr<type_hash> hash = db->get_hash(key, current); std::string oldval = "0"; if (hash) { auto r = hash->hget(field); if (r.second) { oldval = r.first; } } int64_t newval = incrby(oldval, intval); std::string newstr = format("%"PRId64, newval); if (!hash) { hash.reset(new type_hash(current)); hash->hset(field, newstr); db->replace(key, hash); } else { hash->hset(field, newstr); hash->update(current); } client->response_integer(newval); return true; }
int64_t ArgsManager::GetArg(const std::string& strArg, int64_t nDefault) { LOCK(cs_args); if (mapArgs.count(strArg)) return atoi64(mapArgs[strArg]); return nDefault; }
int64_t ArgsManager::GetArg(const std::string& strArg, int64_t nDefault) const { LOCK(cs_args); auto it = mapArgs.find(strArg); if (it != mapArgs.end()) return atoi64(it->second); return nDefault; }
int64_t ArgsManager::GetArg(const std::string& strArg, int64_t nDefault) const { if (IsArgNegated(strArg)) return 0; std::pair<bool,std::string> found_res = ArgsManagerHelper::GetArg(*this, strArg); if (found_res.first) return atoi64(found_res.second); return nDefault; }
static void MutateTxVersion(CMutableTransaction& tx, const std::string& cmdVal) { int64_t newVersion = atoi64(cmdVal); if (newVersion < 1 || newVersion > CTransaction::MAX_STANDARD_VERSION) throw std::runtime_error("Invalid TX version requested"); tx.nVersion = (int) newVersion; }
static void MutateTxLocktime(CMutableTransaction& tx, const std::string& cmdVal) { int64_t newLocktime = atoi64(cmdVal); if (newLocktime < 0LL || newLocktime > 0xffffffffLL) throw std::runtime_error("Invalid TX locktime requested"); tx.nLockTime = (unsigned int) newLocktime; }
inline void check_header(const std::string &name, const std::string &value, std::string &content_type, boost::int64_t &content_length, std::string &location) { if (headers_equal(name, "Content-Type")) content_type = value; else if (headers_equal(name, "Content-Length")) content_length = atoi64(value.c_str()); else if (headers_equal(name, "Location")) location = value; }
/* ** Print the content of a doclist. The segment or segdir-root is ** identified by azExtra[0]. If the first character of azExtra[0] ** is 'r' then the remainder is the integer rowid of the %_segdir entry. ** If the first character of azExtra[0] is not 'r' then, then all of ** azExtra[0] is an integer which is the block number. The offset ** into the segment is identified by azExtra[1]. The size of the doclist ** is azExtra[2]. ** ** If the --raw option is present in azExtra, then a hex dump is provided. ** Otherwise a decoding is shown. */ static void showDoclist(sqlite3 *db, const char *zTab){ const unsigned char *aData; sqlite3_int64 offset, nData; sqlite3_stmt *pStmt; offset = atoi64(azExtra[1]); nData = atoi64(azExtra[2]); pStmt = prepareToGetSegment(db, zTab, azExtra[0]); if( sqlite3_step(pStmt)!=SQLITE_ROW ){ sqlite3_finalize(pStmt); return; } aData = sqlite3_column_blob(pStmt, 0); printf("Doclist at %s offset %lld of size %lld bytes:\n", azExtra[0], offset, nData); if( findOption("raw", 0, 0)!=0 ){ printBlob(aData+offset, nData); }else{ decodeDoclist(aData+offset, nData); } sqlite3_finalize(pStmt); }
/* * Allocate target specific config data, and link them to table. * This function is called only when, flags is not READONLY and * therefore we can add things to pdev list. This should not a * problem because this routine is called only from dm_table_load_ioctl. * @argv[0] is name, * @argv[1] is physical data offset. */ static int dm_target_linear_init(dm_dev_t * dmv, void **target_config, char *params) { dm_target_linear_config_t *tlc; dm_pdev_t *dmp; char **ap, *argv[3]; if (params == NULL) return EINVAL; /* * Parse a string, containing tokens delimited by white space, * into an argument vector */ for (ap = argv; ap < &argv[2] && (*ap = strsep(¶ms, " \t")) != NULL;) { if (**ap != '\0') ap++; } aprint_debug("Linear target init function called %s--%s!!\n", argv[0], argv[1]); /* XXX: temp hack */ if (argv[0] == NULL) return EINVAL; /* Insert dmp to global pdev list */ if ((dmp = dm_pdev_insert(argv[0])) == NULL) return ENOENT; if ((tlc = kmalloc(sizeof(dm_target_linear_config_t), M_DMLINEAR, M_WAITOK)) == NULL) return ENOMEM; tlc->pdev = dmp; tlc->offset = 0; /* default settings */ /* Check user input if it is not leave offset as 0. */ tlc->offset = atoi64(argv[1]); *target_config = tlc; dmv->dev_type = DM_LINEAR_DEV; return 0; }
bool ParseMoney(const char* pszIn, int64& nRet) { string strWhole; int64 nCents = 0; const char* p = pszIn; while (isspace(*p)) p++; for (; *p; p++) { if (*p == ',' && p > pszIn && isdigit(p[-1]) && isdigit(p[1]) && isdigit(p[2]) && isdigit(p[3]) && !isdigit(p[4])) continue; if (*p == '.') { p++; if (isdigit(*p)) { nCents = 10 * (*p++ - '0'); if (isdigit(*p)) nCents += (*p++ - '0'); } break; } if (isspace(*p)) break; if (!isdigit(*p)) return false; strWhole.insert(strWhole.end(), *p); } for (; *p; p++) if (!isspace(*p)) return false; if (strWhole.size() > 14) return false; if (nCents < 0 || nCents > 99) return false; int64 nWhole = atoi64(strWhole); int64 nPreValue = nWhole * 100 + nCents; int64 nValue = nPreValue * CENT; if (nValue / CENT != nPreValue) return false; if (nValue / COIN != nWhole) return false; nRet = nValue; return true; }
bool ParseMoney(const char* pszIn, int64& nRet) { string strWhole; int64 nUnits = 0; const char* p = pszIn; while (isspace(*p)) p++; for (; *p; p++) { if (*p == ',' && p > pszIn && isdigit(p[-1]) && isdigit(p[1]) && isdigit(p[2]) && isdigit(p[3]) && !isdigit(p[4])) continue; if (*p == '.') { p++; int64 nMult = CENT*10; while (isdigit(*p) && (nMult > 0)) { nUnits += nMult * (*p++ - '0'); nMult /= 10; } break; } if (isspace(*p)) break; if (!isdigit(*p)) return false; strWhole.insert(strWhole.end(), *p); } for (; *p; p++) if (!isspace(*p)) return false; if (strWhole.size() > 14) return false; if (nUnits < 0 || nUnits > COIN) return false; int64 nWhole = atoi64(strWhole); int64 nValue = nWhole*COIN + nUnits; nRet = nValue; return true; }
bool ParseMoney(const char* pszIn, CAmount& nRet) { std::string strWhole; int64_t nUnits = 0; const char* p = pszIn; while (isspace(*p)) p++; for (; *p; p++) { if (*p == '.') { p++; int64_t nMult = CENT*10; while (isdigit(*p) && (nMult > 0)) { nUnits += nMult * (*p++ - '0'); nMult /= 10; } break; } if (isspace(*p)) break; if (!isdigit(*p)) return false; strWhole.insert(strWhole.end(), *p); } for (; *p; p++) if (!isspace(*p)) return false; if (strWhole.size() > 10) // guard against 63 bit overflow return false; if (nUnits < 0 || nUnits > COIN) return false; int64_t nWhole = atoi64(strWhole); CAmount nValue = nWhole*COIN + nUnits; nRet = nValue; return true; }
CDECL EXPORT int setvar(char *varname, char *value) { VARMAP *p; for (p=varmap; p->name!=NULL; p++) { if (strcmp(p->name,varname)==0) { if (p->type==VT_INTEGER) { int64 v = atoi64(value); if (v>=(int64)p->min && v<=(int64)p->max) { *(int64*)(p->addr) = v; return 1; } else return 0; } else if (p->type==VT_DOUBLE) { double v = atof(value); if (v>=p->min && v<=p->max) { *(double*)(p->addr) = v; return 1; } else return 0; } else if (p->type==VT_STRING) { strncpy((char*)(p->addr),value,(unsigned)p->min-1); return 1; } } } return 0; }
char *gld_loadHndl::read_object_prop(char *buffer, size_t len){ //wchar_t wbuff[1024]; //char tbuff[1024]; char *rand_ptr = NULL; char *rand_mode_ptr = NULL; char *unit_ptr = NULL; double realval = 0.0; UNIT *unit=NULL; SAXParseException *e = NULL; void *addr = object_get_addr(obj, propname); /* get the & to set later */ if(this->obj == NULL){ sprintf(errmsg, "Null object pointer in read_object_prop(%s)", buffer); return errmsg; // no object } if(this->prop == NULL){ if (strcmp(propname, "parent")==0){ if (strcmp(propname, "root")==0){ obj->parent = NULL; } else { add_unresolved(obj,PT_object,(void*)&obj->parent,oclass,buffer,"XML",42,UR_RANKS); } } else if (strcmp(propname, "rank")==0){ obj->rank = atoi(buffer); } else if (strcmp(propname, "clock")==0){ obj->clock = atoi64(buffer); } else if (strcmp(propname, "latitude")==0){ obj->latitude = load_latitude(buffer); } else if (strcmp(propname, "longitude")==0){ obj->longitude = load_longitude(buffer); } else if (strcmp(propname, "in")==0){ obj->in_svc = convert_to_timestamp(buffer); } else if (strcmp(propname, "out")==0){ obj->out_svc = convert_to_timestamp(buffer); } else { sprintf(errmsg, "Null property pointer in read_object_prop(%s)", buffer); return errmsg; } return NULL; } // determine property type switch(prop->ptype){ case PT_double: // scan for "random" if(strncmp("random.", buffer, 7) == 0){ char temp[256]; char *modep = NULL; double first = 0.0, second = 0.0; RANDOMTYPE rt; strncpy(temp, buffer, 256); modep = strtok(temp+7, "("); if(modep == NULL){ //output_error("XML_Load: misformed random() value"); load_state = false; sprintf(errmsg, "Misformed random() value in read_object_prop(%s)", buffer); return errmsg; } rt = random_type(modep); if(rt == 0){ //output_message("XML_Load: '%s' ~ %s is not a valid random distribution", buffer, modep); load_state = false; sprintf(errmsg, "Invalid random distribution in read_object_prop(%s)", buffer); return errmsg; } else { first = atof(strtok(NULL, ",")); second = atof(strtok(NULL, ")")); realval = random_value(rt, first, second); } if(strlen(strchr(buffer, ')')+1) > 0){ /* look for units */ unit = unit_find(strchr(buffer, ')') + 2); if (unit!=NULL && prop->unit!=NULL && unit_convert_ex(unit,prop->unit,&realval)==0){ sprintf(errmsg, "Cannot convert units from %s to %s in read_object_prop(%s)", unit->name,prop->unit->name, buffer); load_state = false; return errmsg; } } } else { unit_ptr = NULL; realval = strtod(buffer, &unit_ptr); if(unit_ptr != NULL){ while(*unit_ptr == ' ') ++unit_ptr; unit = unit_find(unit_ptr); if(strlen(unit_ptr) > 0){ if (unit!=NULL && prop->unit!=NULL && unit_convert_ex(unit,prop->unit,&realval)==0){ sprintf(errmsg, "Cannot convert units from %s to %s in read_object_prop(%s)", unit->name,prop->unit->name, buffer); load_state = false; return errmsg; } } } } /* if((unit_ptr != NULL) && (*unit_ptr != '\0')){;} */ if(object_set_double_by_name(obj, propname, realval) == 0){ sprintf(errmsg, "Could not set \"%s\" to %f in read_object_prop(%s)", propname, realval, buffer); load_state = false; return errmsg; } else { return NULL; /* success */ } break; case PT_object: if(add_unresolved(obj,PT_object,(void*)addr,oclass,buffer,"XML",42,UR_NONE) == NULL){ sprintf(errmsg, "Failure with add_unresolved() in read_object_prop(%s)", buffer); return errmsg; } break; default: if(prop->ptype < _PT_LAST){ // set value by name if (object_set_value_by_name(obj, propname, buffer)==0) { //output_error("XML_Load: property %s of %s:%s could not be set to '%s'", propname, obj->oclass->name, obj->id, buffer); sprintf(errmsg, "Property %s of %s:%i could not be set to \"%s\" in read_object_prop()", propname, obj->oclass->name, obj->id, buffer); load_state = false; return errmsg; } else { ; } } else { sprintf(errmsg, "Invalid property id = %i in read_object_prop(%s)", prop->ptype, buffer); return errmsg; } } return 0; }
void type_string::to_int() { if (!int_type) { int_value = atoi64(string_value, int_type); } }
// 转换监管协议 char * PConvert::convert_lprov( const string &key, const string &seqid, const string &val , int &len, string &areacode ) { MapString map ; if ( ! parse_jkpt_value( val, map ) ) { OUT_ERROR( NULL, 0, NULL, "parse data %s failed", val.c_str() ) ; return NULL ; } string stype ; if ( ! get_map_string( map , "TYPE", stype ) ) { OUT_ERROR( NULL, 0, NULL, "get data %s type failed", val.c_str() ) ; return NULL ; } // 取得省域ID if ( ! get_map_string( map, "AREA_CODE", areacode ) ) { OUT_ERROR( NULL, 0, NULL, "get area code failed, %s", val.c_str() ) ; return NULL ; } char *buf = NULL ; // AREA_CODE:省代码,CARNO:车牌颜色_车牌号,ACCESS_CODE:运营商接入码,TYPE:XXX,k1:v1... if ( stype == "D_PLAT" ) { string sval ; // 如果为平台查岗消息处理 if ( get_map_string( map, "PLATQUERY" , sval ) ) { // 查岗对象的类型(1:当前连接的下级平台,2:下级平台所属单一业户,3:下级平台所属所有业户)|查岗对象的ID|信息ID|应答内容" vector<string> vec ; if ( ! splitvector( sval, vec, "|" , 0 ) ) { OUT_ERROR( NULL, 0, areacode.c_str(), "split vector failed, sval %s" , sval.c_str() ) ; return NULL ; } // 如果拆分个数小于四个则直接返回 if ( vec.size() < 4 ) { OUT_ERROR( NULL, 0, areacode.c_str(), "split vector param too less, value %s" , sval.c_str() ) ; return NULL ; } int dlen = 0 ; char *ptr = _pEnv->GetMsgCache()->GetData( key.c_str(), dlen , false ) ; if ( ptr == NULL ) { OUT_ERROR( NULL, 0, areacode.c_str(), "get plat msg failed , key %s" , key.c_str() ) ; return NULL ; } string content = vec[3] ; CBase64 base; if ( base.Decode( content.c_str(), content.length() ) ) { content = base.GetBuffer() ; } len = sizeof(UpPlatformMsgPostQueryAck) + content.length() + sizeof(Footer) ; buf = new char[len+1] ; // 处理平台查岗的消息 UpPlatformMsgPostQueryAck *rsp = (UpPlatformMsgPostQueryAck *) ptr ; rsp->header.msg_len = ntouv32( len ) ; rsp->up_platform_msg.data_length = ntouv32( sizeof(UpPlatformMsgpostqueryData) + content.length() ) ; rsp->up_platform_post.msg_len = ntouv32( content.length() ) ; rsp->up_platform_post.object_type = atoi( vec[0].c_str() ) ; safe_memncpy( rsp->up_platform_post.object_id, vec[1].c_str(), sizeof(rsp->up_platform_post.object_id) ) ; rsp->up_platform_post.info_id = ntouv32( atoi(vec[2].c_str()) ) ; memcpy( buf, rsp, sizeof(UpPlatformMsgPostQueryAck) ) ; memcpy( buf+sizeof(UpPlatformMsgPostQueryAck) , content.c_str(), content.length() ) ; Footer footer ; memcpy( buf+sizeof(UpPlatformMsgPostQueryAck) + content.length(), &footer, sizeof(footer) ) ; OUT_PRINT( NULL, 0, areacode.c_str(), "platquery message %s", content.c_str() ) ; return buf ; } // 平台间消息 if ( get_map_string( map, "PLATMSG", sval ) ) { // 从缓存中取数据, 针对平台间消息和平台查岗暂时不回收资源 char *ptr = _pEnv->GetMsgCache()->GetData( key.c_str(), len , false ) ; if ( buf == NULL ) { OUT_ERROR( NULL, 0, areacode.c_str(), "get msg from cache failed, key %s", key.c_str() ) ; return NULL ; } // 重新拷贝处理 buf = new char[len+1] ; memset( buf, 0, len + 1 ) ; memcpy( buf, ptr, len ) ; // 处理平台消息的ID UpPlatFormMsgInfoAck *ack = (UpPlatFormMsgInfoAck *) buf ; ack->info_id = ntouv32( atoi(sval.c_str()) ) ; return buf ; } } else { // 除平台查岗处理 string macid ; // 取得车牌颜色和车牌号 if ( ! get_map_string( map, "CARNO" , macid ) ) { OUT_ERROR( NULL, 0, areacode.c_str(), "get carno failed, %s", val.c_str() ) ; return NULL ; } unsigned char carcolor = 0 ; string carnum ; // 通过MACID取得车颜色和车牌号 if ( ! get_carinfobymacid( macid, carcolor, carnum ) ) { OUT_ERROR( NULL, 0, areacode.c_str(), "get car color and car num by macid failed, %d" , macid.c_str() ) ; return NULL ; } string sval ; // 如果为报警业务 if ( stype == "D_WARN" ) { // 报警督办 if ( get_map_string( map, "WARNTODO", sval ) ) { buf = _pEnv->GetMsgCache()->GetData( key.c_str(), len ) ; if ( buf == NULL ) { OUT_ERROR( NULL, 0, areacode.c_str(), "get msg data failed, key %s, macid %s" , key.c_str(), macid.c_str() ) ; return NULL ; } UpWarnMsgUrgeTodoAck *rsp = ( UpWarnMsgUrgeTodoAck *) buf ; rsp->result = atoi(sval.c_str()) ; return buf ; } // 处理上报报警 if ( get_map_string( map, "WARNINFO" , sval ) ) { // 报警信息来源(1:车载终端,2:企业监控平台,3:政府监管平台,9:其它)|报警类型(详见5.3“报警类型编码表”)|报警时间(UTC时间格式)|信息ID|报警信息内容 vector<string> vec ; // 处理所有逗号分割处理 if ( ! splitvector( sval , vec, "|" , 0 ) ) { OUT_ERROR( NULL, 0, areacode.c_str(), "WARNINFO split vector error, key %s, macid %s, value: %s" , key.c_str(), macid.c_str() , sval.c_str() ) ; return false ; } if ( vec.size() < 5 ) { OUT_ERROR( NULL, 0, areacode.c_str(), "WARNINFO arg too less error, key %s, macid %s, value: %s" , key.c_str(), macid.c_str() , sval.c_str() ) ; return false ; } int nlen = vec[4].length() ; len = sizeof(UpWarnMsgAdptInfoHeader) + sizeof(UpWarnMsgAdptInfoBody) + nlen + sizeof(Footer) ; UpWarnMsgAdptInfoHeader req ; req.header.msg_len = ntouv32( len ) ; // 修正长度不正 req.header.msg_type = ntouv16( UP_WARN_MSG ) ; req.header.msg_seq = ntouv32( _seq_gen.get_next_seq() ) ; req.warn_msg_header.vehicle_color = carcolor ; safe_memncpy( req.warn_msg_header.vehicle_no, carnum.c_str(), sizeof(req.warn_msg_header.vehicle_no) ) ; req.warn_msg_header.data_type = ntouv16( UP_WARN_MSG_ADPT_INFO ) ; req.warn_msg_header.data_length = ntouv32( sizeof(UpWarnMsgAdptInfoBody) + nlen ) ; UpWarnMsgAdptInfoBody body ; body.warn_src = atoi( vec[0].c_str() ) ; body.warn_type = ntouv16( atoi(vec[1].c_str()) ) ; body.warn_time = ntouv64( atoi64(vec[2].c_str()) ) ; body.info_id = ntouv32( atoi(vec[3].c_str()) ) ; body.info_length = ntouv32( nlen ) ; int offset = 0 ; buf = new char[len+1] ; memcpy( buf+offset, &req, sizeof(req) ) ; offset += sizeof(req) ; memcpy( buf+offset, &body, sizeof(body) ) ; offset += sizeof(body) ; memcpy( buf+offset, vec[4].c_str(), nlen ) ; offset += nlen ; Footer footer ; memcpy( buf+offset, &footer, sizeof(footer) ) ; return buf ; } // 处理主动上报报警结果 if ( get_map_string( map, "UPWARN", sval ) ) { // 报警信息ID|报警处理结果(0:处理中,1:已处理完毕,2:不作处理,3:将来处理) size_t pos = sval.find( "|" ) ; if ( pos == string::npos ) { OUT_ERROR( NULL, 0, areacode.c_str(), "upwarn result command error, value: %s" , val.c_str() ) ; return NULL ; } // 组装主动上报处理理结果的数据包 UpWarnMsgAdptTodoInfo req ; req.header.msg_len = ntouv32( sizeof(UpWarnMsgAdptTodoInfo) ) ; req.header.msg_type = ntouv16( UP_WARN_MSG ) ; req.header.msg_seq = ntouv32( _seq_gen.get_next_seq() ) ; req.warn_msg_header.vehicle_color = carcolor ; safe_memncpy( req.warn_msg_header.vehicle_no, carnum.c_str(), sizeof(req.warn_msg_header.vehicle_no) ) ; req.warn_msg_header.data_type = ntouv16( UP_WARN_MSG_ADPT_TODO_INFO ) ; req.warn_msg_header.data_length = ntouv32( sizeof(WarnMsgAdptTodoInfoBody) ) ; req.warn_msg_body.info_id = ntouv32( atoi( sval.c_str() ) ) ; req.warn_msg_body.result = atoi( sval.substr(pos+1).c_str() ) ; len = sizeof(req) ; buf = new char[len+1] ; memcpy( buf, &req, sizeof(req) ) ; return buf ; } } else if ( stype == "D_MESG" ) { // 如果下发申请交换车辆信息 if ( get_map_string( map, "MONITORSTARTUP" , sval ) ) { // 开始时间(UTC时间格式)|结束时间(UTC时间格式) size_t pos = sval.find( "|" ) ; if ( pos == string::npos ) { OUT_ERROR( NULL, 0, areacode.c_str(), "down command error , value : %s" , val.c_str() ) ; return NULL ; } uint64 start = atoi64( sval.substr(0, pos).c_str() ) ; uint64 end = atoi64( sval.substr( pos+1).c_str() ) ; UpExgMsgApplyForMonitorStartup req ; req.header.msg_len = ntouv32( sizeof(req) ) ; req.header.msg_seq = ntouv32( _seq_gen.get_next_seq() ) ; req.exg_msg_header.vehicle_color = carcolor ; safe_memncpy( req.exg_msg_header.vehicle_no, carnum.c_str(), sizeof(req.exg_msg_header.vehicle_no) ) ; req.exg_msg_header.data_length = ntouv32( sizeof(uint64) * 2 ) ; req.start_time = ntouv64( start ) ; req.end_time = ntouv64( end ) ; len = sizeof(req) ; buf = new char[len+1] ; memcpy( buf, &req, sizeof(req) ) ; _pEnv->GetPasClient()->AddMacId2SeqId( UP_EXG_MSG_APPLY_FOR_MONITOR_STARTUP , macid.c_str(), seqid.c_str() ) ; return buf ; } // 结束车辆交换信息 if ( get_map_string( map , "MONITOREND" , sval ) ) { UpExgMsgApplyForMonitorEnd req ; req.header.msg_len = ntouv32( sizeof(req) ) ; req.header.msg_seq = ntouv32( _seq_gen.get_next_seq() ) ; req.exg_msg_header.vehicle_color = carcolor ; safe_memncpy( req.exg_msg_header.vehicle_no, carnum.c_str(), sizeof(req.exg_msg_header.vehicle_no) ) ; req.exg_msg_header.data_length = ntouv32( 0 ) ; len = sizeof(req) ; buf = new char[len+1] ; memcpy( buf, &req, sizeof(req) ) ; _pEnv->GetPasClient()->AddMacId2SeqId( UP_EXG_MSG_APPLY_FOR_MONITOR_END , macid.c_str(), seqid.c_str() ) ; return buf ; } // 这是平台主动下发,还有一种平台自动下发情况,补发指定时间车辆信息 if ( get_map_string( map, "HISGNSSDATA" , sval ) ) { // 开始时间(UTC时间格式)|结束时间(UTC时间格式) size_t pos = sval.find( "|" ) ; if ( pos == string::npos ) { OUT_ERROR( NULL, 0, areacode.c_str(), "down command error , value : %s" , val.c_str() ) ; return NULL ; } uint64 start = atoi64( sval.substr(0, pos).c_str() ) ; uint64 end = atoi64( sval.substr( pos+1).c_str() ) ; UpExgApplyHisGnssDataReq req ; req.header.msg_len = ntouv32( sizeof(req) ) ; req.header.msg_type = ntouv16( UP_EXG_MSG ) ; req.header.msg_seq = ntouv32( _seq_gen.get_next_seq() ) ; req.exg_msg_header.vehicle_color = carcolor ; safe_memncpy( req.exg_msg_header.vehicle_no, carnum.c_str(), sizeof(req.exg_msg_header.vehicle_no) ) ; req.exg_msg_header.data_length = ntouv32( sizeof(uint64) * 2 ) ; req.exg_msg_header.data_type = ntouv16( UP_EXG_MSG_APPLY_HISGNSSDATA_REQ ) ; req.start_time = ntouv64( start ) ; req.end_time = ntouv64( end ) ; len = sizeof(req) ; buf = new char[len+1] ; memcpy( buf, &req, sizeof(req) ) ; _pEnv->GetPasClient()->AddMacId2SeqId( UP_EXG_MSG_APPLY_HISGNSSDATA_REQ , macid.c_str(), seqid.c_str() ) ; return buf ; } // 处理历史数据上报 size_t pos = val.find( "HISTORY" ) ; // 取得车辆的历史位数据情况 if ( pos != string::npos ) { size_t end = val.find( "}" , pos+8 ) ; if ( end == string::npos || end < pos ){ OUT_ERROR( NULL, 0, areacode.c_str(), "HISTORY split vector error, key %s, macid %s, value: %s" , key.c_str(), macid.c_str() , val.c_str() ) ; return false; } sval = val.substr( pos+8, end - pos - 8 ) ; vector<string> vec ; // 处理所有逗号分割处理 if ( ! splitvector( sval , vec, "|" , 0 ) ) { OUT_ERROR( NULL, 0, areacode.c_str(), "HISTORY split vector error, key %s, macid %s, value: %s" , key.c_str(), macid.c_str() , sval.c_str() ) ; return false ; } int nsize = vec.size() ; UpExgMsgHistoryHeader msg ; msg.header.msg_type = ntouv16( UP_EXG_MSG ) ; msg.header.msg_seq = ntouv32( _seq_gen.get_next_seq() ) ; msg.exg_msg_header.vehicle_color = carcolor ; safe_memncpy( msg.exg_msg_header.vehicle_no, carnum.c_str(), sizeof(msg.exg_msg_header.vehicle_no) ) ; msg.exg_msg_header.data_type = ntouv16(UP_EXG_MSG_HISTORY_LOCATION) ; DataBuffer dbuf ; unsigned char ncount = 0 ; for ( int i = 0; i < nsize; ++ i ) { MapString gpsmap ; if ( ! split2map( vec[i] , gpsmap ) ) { continue ; } GnssData gnssdata; if ( ! convert_gps_info( gpsmap, gnssdata ) ){ continue ; } dbuf.writeBlock( &gnssdata, sizeof(GnssData) ) ; ++ ncount ; } len = sizeof(msg) + sizeof(char) + ncount*sizeof(GnssData) + sizeof(Footer) ; msg.exg_msg_header.data_length = ntouv32( sizeof(char) + ncount*sizeof(GnssData) ) ; msg.header.msg_len = ntouv32( len ) ; buf = new char[len+1] ; int offset = 0 ; memcpy( buf, &msg, sizeof(msg) ) ; offset += sizeof(msg) ; memcpy( buf+offset , &ncount, sizeof(char) ) ; offset += sizeof(char) ; memcpy( buf+offset, dbuf.getBuffer(), dbuf.getLength() ) ; offset += dbuf.getLength() ; Footer footer ; memcpy( buf+offset, &footer, sizeof(footer) ) ; return buf ; } // 接入广州809精简版监管,提交车辆静态数据,子业务类型为DOWN_EXG_MSG_CAR_INFO if (get_map_string(map, "U_BASE", sval)) { CBase64 base64; if( ! base64.Decode(sval.c_str(), sval.length())) { OUT_ERROR( NULL, 0, areacode.c_str(), "base64 decode error, value : %s" , val.c_str() ) ; return NULL; } len = sizeof(DownExgMsgCarInfoHeader) + base64.GetLength() + sizeof(Footer); buf = new char[len + 1]; DownExgMsgCarInfoHeader msg; msg.header.msg_len = ntouv32( len ) ; msg.header.msg_seq = ntouv32( _seq_gen.get_next_seq() ) ; msg.header.msg_type = ntouv16( UP_EXG_MSG ); msg.exg_msg_header.vehicle_color = carcolor ; strncpy(msg.exg_msg_header.vehicle_no, carnum.c_str(), sizeof(msg.exg_msg_header.vehicle_no)); msg.exg_msg_header.data_type = ntouv16(DOWN_EXG_MSG_CAR_INFO); msg.exg_msg_header.data_length = ntouv32(base64.GetLength()); int msgpos = 0; memcpy(buf + msgpos, &msg, sizeof(DownExgMsgCarInfoHeader)); msgpos += sizeof(DownExgMsgCarInfoHeader); memcpy(buf + msgpos, base64.GetBuffer(), base64.GetLength()); msgpos += base64.GetLength(); Footer footer ; memcpy( buf + msgpos, &footer, sizeof(footer) ) ; return buf ; } } } return NULL ; }
static UniValue getblocktemplate(const JSONRPCRequest& request) { if (request.fHelp || request.params.size() > 1) throw std::runtime_error( "getblocktemplate ( TemplateRequest )\n" "\nIf the request parameters include a 'mode' key, that is used to explicitly select between the default 'template' request or a 'proposal'.\n" "It returns data needed to construct a block to work on.\n" "For full specification, see BIPs 22, 23, 9, and 145:\n" " https://github.com/bitcoin/bips/blob/master/bip-0022.mediawiki\n" " https://github.com/bitcoin/bips/blob/master/bip-0023.mediawiki\n" " https://github.com/bitcoin/bips/blob/master/bip-0009.mediawiki#getblocktemplate_changes\n" " https://github.com/bitcoin/bips/blob/master/bip-0145.mediawiki\n" "\nArguments:\n" "1. template_request (json object, optional) A json object in the following spec\n" " {\n" " \"mode\":\"template\" (string, optional) This must be set to \"template\", \"proposal\" (see BIP 23), or omitted\n" " \"capabilities\":[ (array, optional) A list of strings\n" " \"support\" (string) client side supported feature, 'longpoll', 'coinbasetxn', 'coinbasevalue', 'proposal', 'serverlist', 'workid'\n" " ,...\n" " ],\n" " \"rules\":[ (array, optional) A list of strings\n" " \"support\" (string) client side supported softfork deployment\n" " ,...\n" " ]\n" " }\n" "\n" "\nResult:\n" "{\n" " \"version\" : n, (numeric) The preferred block version\n" " \"rules\" : [ \"rulename\", ... ], (array of strings) specific block rules that are to be enforced\n" " \"vbavailable\" : { (json object) set of pending, supported versionbit (BIP 9) softfork deployments\n" " \"rulename\" : bitnumber (numeric) identifies the bit number as indicating acceptance and readiness for the named softfork rule\n" " ,...\n" " },\n" " \"vbrequired\" : n, (numeric) bit mask of versionbits the server requires set in submissions\n" " \"previousblockhash\" : \"xxxx\", (string) The hash of current highest block\n" " \"transactions\" : [ (array) contents of non-coinbase transactions that should be included in the next block\n" " {\n" " \"data\" : \"xxxx\", (string) transaction data encoded in hexadecimal (byte-for-byte)\n" " \"txid\" : \"xxxx\", (string) transaction id encoded in little-endian hexadecimal\n" " \"hash\" : \"xxxx\", (string) hash encoded in little-endian hexadecimal (including witness data)\n" " \"depends\" : [ (array) array of numbers \n" " n (numeric) transactions before this one (by 1-based index in 'transactions' list) that must be present in the final block if this one is\n" " ,...\n" " ],\n" " \"fee\": n, (numeric) difference in value between transaction inputs and outputs (in satoshis); for coinbase transactions, this is a negative Number of the total collected block fees (ie, not including the block subsidy); if key is not present, fee is unknown and clients MUST NOT assume there isn't one\n" " \"sigops\" : n, (numeric) total SigOps cost, as counted for purposes of block limits; if key is not present, sigop cost is unknown and clients MUST NOT assume it is zero\n" " \"weight\" : n, (numeric) total transaction weight, as counted for purposes of block limits\n" " }\n" " ,...\n" " ],\n" " \"coinbaseaux\" : { (json object) data that should be included in the coinbase's scriptSig content\n" " \"flags\" : \"xx\" (string) key name is to be ignored, and value included in scriptSig\n" " },\n" " \"coinbasevalue\" : n, (numeric) maximum allowable input to coinbase transaction, including the generation award and transaction fees (in satoshis)\n" " \"coinbasetxn\" : { ... }, (json object) information for coinbase transaction\n" " \"target\" : \"xxxx\", (string) The hash target\n" " \"mintime\" : xxx, (numeric) The minimum timestamp appropriate for next block time in seconds since epoch (Jan 1 1970 GMT)\n" " \"mutable\" : [ (array of string) list of ways the block template may be changed \n" " \"value\" (string) A way the block template may be changed, e.g. 'time', 'transactions', 'prevblock'\n" " ,...\n" " ],\n" " \"noncerange\" : \"00000000ffffffff\",(string) A range of valid nonces\n" " \"sigoplimit\" : n, (numeric) limit of sigops in blocks\n" " \"sizelimit\" : n, (numeric) limit of block size\n" " \"weightlimit\" : n, (numeric) limit of block weight\n" " \"curtime\" : ttt, (numeric) current timestamp in seconds since epoch (Jan 1 1970 GMT)\n" " \"bits\" : \"xxxxxxxx\", (string) compressed target of next block\n" " \"height\" : n (numeric) The height of the next block\n" "}\n" "\nExamples:\n" + HelpExampleCli("getblocktemplate", "{\"rules\": [\"segwit\"]}") + HelpExampleRpc("getblocktemplate", "{\"rules\": [\"segwit\"]}") ); LOCK(cs_main); std::string strMode = "template"; UniValue lpval = NullUniValue; std::set<std::string> setClientRules; int64_t nMaxVersionPreVB = -1; if (!request.params[0].isNull()) { const UniValue& oparam = request.params[0].get_obj(); const UniValue& modeval = find_value(oparam, "mode"); if (modeval.isStr()) strMode = modeval.get_str(); else if (modeval.isNull()) { /* Do nothing */ } else throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid mode"); lpval = find_value(oparam, "longpollid"); if (strMode == "proposal") { const UniValue& dataval = find_value(oparam, "data"); if (!dataval.isStr()) throw JSONRPCError(RPC_TYPE_ERROR, "Missing data String key for proposal"); CBlock block; if (!DecodeHexBlk(block, dataval.get_str())) throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Block decode failed"); uint256 hash = block.GetHash(); const CBlockIndex* pindex = LookupBlockIndex(hash); if (pindex) { if (pindex->IsValid(BLOCK_VALID_SCRIPTS)) return "duplicate"; if (pindex->nStatus & BLOCK_FAILED_MASK) return "duplicate-invalid"; return "duplicate-inconclusive"; } CBlockIndex* const pindexPrev = chainActive.Tip(); // TestBlockValidity only supports blocks built on the current Tip if (block.hashPrevBlock != pindexPrev->GetBlockHash()) return "inconclusive-not-best-prevblk"; CValidationState state; TestBlockValidity(state, Params(), block, pindexPrev, false, true); return BIP22ValidationResult(state); } const UniValue& aClientRules = find_value(oparam, "rules"); if (aClientRules.isArray()) { for (unsigned int i = 0; i < aClientRules.size(); ++i) { const UniValue& v = aClientRules[i]; setClientRules.insert(v.get_str()); } } else { // NOTE: It is important that this NOT be read if versionbits is supported const UniValue& uvMaxVersion = find_value(oparam, "maxversion"); if (uvMaxVersion.isNum()) { nMaxVersionPreVB = uvMaxVersion.get_int64(); } } } if (strMode != "template") throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid mode"); if(!g_connman) throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled"); if (g_connman->GetNodeCount(CConnman::CONNECTIONS_ALL) == 0) throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, "Bitcoin is not connected!"); if (IsInitialBlockDownload()) throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, "Bitcoin is downloading blocks..."); static unsigned int nTransactionsUpdatedLast; if (!lpval.isNull()) { // Wait to respond until either the best block changes, OR a minute has passed and there are more transactions uint256 hashWatchedChain; std::chrono::steady_clock::time_point checktxtime; unsigned int nTransactionsUpdatedLastLP; if (lpval.isStr()) { // Format: <hashBestChain><nTransactionsUpdatedLast> std::string lpstr = lpval.get_str(); hashWatchedChain = ParseHashV(lpstr.substr(0, 64), "longpollid"); nTransactionsUpdatedLastLP = atoi64(lpstr.substr(64)); } else { // NOTE: Spec does not specify behaviour for non-string longpollid, but this makes testing easier hashWatchedChain = chainActive.Tip()->GetBlockHash(); nTransactionsUpdatedLastLP = nTransactionsUpdatedLast; } // Release the wallet and main lock while waiting LEAVE_CRITICAL_SECTION(cs_main); { checktxtime = std::chrono::steady_clock::now() + std::chrono::minutes(1); WAIT_LOCK(g_best_block_mutex, lock); while (g_best_block == hashWatchedChain && IsRPCRunning()) { if (g_best_block_cv.wait_until(lock, checktxtime) == std::cv_status::timeout) { // Timeout: Check transactions for update if (mempool.GetTransactionsUpdated() != nTransactionsUpdatedLastLP) break; checktxtime += std::chrono::seconds(10); } } } ENTER_CRITICAL_SECTION(cs_main); if (!IsRPCRunning()) throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, "Shutting down"); // TODO: Maybe recheck connections/IBD and (if something wrong) send an expires-immediately template to stop miners? } const struct VBDeploymentInfo& segwit_info = VersionBitsDeploymentInfo[Consensus::DEPLOYMENT_SEGWIT]; // If the caller is indicating segwit support, then allow CreateNewBlock() // to select witness transactions, after segwit activates (otherwise // don't). bool fSupportsSegwit = setClientRules.find(segwit_info.name) != setClientRules.end(); // Update block static CBlockIndex* pindexPrev; static int64_t nStart; static std::unique_ptr<CBlockTemplate> pblocktemplate; // Cache whether the last invocation was with segwit support, to avoid returning // a segwit-block to a non-segwit caller. static bool fLastTemplateSupportsSegwit = true; if (pindexPrev != chainActive.Tip() || (mempool.GetTransactionsUpdated() != nTransactionsUpdatedLast && GetTime() - nStart > 5) || fLastTemplateSupportsSegwit != fSupportsSegwit) { // Clear pindexPrev so future calls make a new block, despite any failures from here on pindexPrev = nullptr; // Store the pindexBest used before CreateNewBlock, to avoid races nTransactionsUpdatedLast = mempool.GetTransactionsUpdated(); CBlockIndex* pindexPrevNew = chainActive.Tip(); nStart = GetTime(); fLastTemplateSupportsSegwit = fSupportsSegwit; // Create new block CScript scriptDummy = CScript() << OP_TRUE; pblocktemplate = BlockAssembler(Params()).CreateNewBlock(scriptDummy, fSupportsSegwit); if (!pblocktemplate) throw JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory"); // Need to update only after we know CreateNewBlock succeeded pindexPrev = pindexPrevNew; } assert(pindexPrev); CBlock* pblock = &pblocktemplate->block; // pointer for convenience const Consensus::Params& consensusParams = Params().GetConsensus(); // Update nTime UpdateTime(pblock, consensusParams, pindexPrev); pblock->nNonce = 0; // NOTE: If at some point we support pre-segwit miners post-segwit-activation, this needs to take segwit support into consideration const bool fPreSegWit = (ThresholdState::ACTIVE != VersionBitsState(pindexPrev, consensusParams, Consensus::DEPLOYMENT_SEGWIT, versionbitscache)); UniValue aCaps(UniValue::VARR); aCaps.push_back("proposal"); UniValue transactions(UniValue::VARR); std::map<uint256, int64_t> setTxIndex; int i = 0; for (const auto& it : pblock->vtx) { const CTransaction& tx = *it; uint256 txHash = tx.GetHash(); setTxIndex[txHash] = i++; if (tx.IsCoinBase()) continue; UniValue entry(UniValue::VOBJ); entry.pushKV("data", EncodeHexTx(tx)); entry.pushKV("txid", txHash.GetHex()); entry.pushKV("hash", tx.GetWitnessHash().GetHex()); UniValue deps(UniValue::VARR); for (const CTxIn &in : tx.vin) { if (setTxIndex.count(in.prevout.hash)) deps.push_back(setTxIndex[in.prevout.hash]); } entry.pushKV("depends", deps); int index_in_template = i - 1; entry.pushKV("fee", pblocktemplate->vTxFees[index_in_template]); int64_t nTxSigOps = pblocktemplate->vTxSigOpsCost[index_in_template]; if (fPreSegWit) { assert(nTxSigOps % WITNESS_SCALE_FACTOR == 0); nTxSigOps /= WITNESS_SCALE_FACTOR; } entry.pushKV("sigops", nTxSigOps); entry.pushKV("weight", GetTransactionWeight(tx)); transactions.push_back(entry); } UniValue aux(UniValue::VOBJ); aux.pushKV("flags", HexStr(COINBASE_FLAGS.begin(), COINBASE_FLAGS.end())); arith_uint256 hashTarget = arith_uint256().SetCompact(pblock->nBits); UniValue aMutable(UniValue::VARR); aMutable.push_back("time"); aMutable.push_back("transactions"); aMutable.push_back("prevblock"); UniValue result(UniValue::VOBJ); result.pushKV("capabilities", aCaps); UniValue aRules(UniValue::VARR); UniValue vbavailable(UniValue::VOBJ); for (int j = 0; j < (int)Consensus::MAX_VERSION_BITS_DEPLOYMENTS; ++j) { Consensus::DeploymentPos pos = Consensus::DeploymentPos(j); ThresholdState state = VersionBitsState(pindexPrev, consensusParams, pos, versionbitscache); switch (state) { case ThresholdState::DEFINED: case ThresholdState::FAILED: // Not exposed to GBT at all break; case ThresholdState::LOCKED_IN: // Ensure bit is set in block version pblock->nVersion |= VersionBitsMask(consensusParams, pos); // FALL THROUGH to get vbavailable set... case ThresholdState::STARTED: { const struct VBDeploymentInfo& vbinfo = VersionBitsDeploymentInfo[pos]; vbavailable.pushKV(gbt_vb_name(pos), consensusParams.vDeployments[pos].bit); if (setClientRules.find(vbinfo.name) == setClientRules.end()) { if (!vbinfo.gbt_force) { // If the client doesn't support this, don't indicate it in the [default] version pblock->nVersion &= ~VersionBitsMask(consensusParams, pos); } } break; } case ThresholdState::ACTIVE: { // Add to rules only const struct VBDeploymentInfo& vbinfo = VersionBitsDeploymentInfo[pos]; aRules.push_back(gbt_vb_name(pos)); if (setClientRules.find(vbinfo.name) == setClientRules.end()) { // Not supported by the client; make sure it's safe to proceed if (!vbinfo.gbt_force) { // If we do anything other than throw an exception here, be sure version/force isn't sent to old clients throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Support for '%s' rule requires explicit client support", vbinfo.name)); } } break; } } } result.pushKV("version", pblock->nVersion); result.pushKV("rules", aRules); result.pushKV("vbavailable", vbavailable); result.pushKV("vbrequired", int(0)); if (nMaxVersionPreVB >= 2) { // If VB is supported by the client, nMaxVersionPreVB is -1, so we won't get here // Because BIP 34 changed how the generation transaction is serialized, we can only use version/force back to v2 blocks // This is safe to do [otherwise-]unconditionally only because we are throwing an exception above if a non-force deployment gets activated // Note that this can probably also be removed entirely after the first BIP9 non-force deployment (ie, probably segwit) gets activated aMutable.push_back("version/force"); } result.pushKV("previousblockhash", pblock->hashPrevBlock.GetHex()); result.pushKV("transactions", transactions); result.pushKV("coinbaseaux", aux); result.pushKV("coinbasevalue", (int64_t)pblock->vtx[0]->vout[0].nValue); result.pushKV("longpollid", chainActive.Tip()->GetBlockHash().GetHex() + i64tostr(nTransactionsUpdatedLast)); result.pushKV("target", hashTarget.GetHex()); result.pushKV("mintime", (int64_t)pindexPrev->GetMedianTimePast()+1); result.pushKV("mutable", aMutable); result.pushKV("noncerange", "00000000ffffffff"); int64_t nSigOpLimit = MAX_BLOCK_SIGOPS_COST; int64_t nSizeLimit = MAX_BLOCK_SERIALIZED_SIZE; if (fPreSegWit) { assert(nSigOpLimit % WITNESS_SCALE_FACTOR == 0); nSigOpLimit /= WITNESS_SCALE_FACTOR; assert(nSizeLimit % WITNESS_SCALE_FACTOR == 0); nSizeLimit /= WITNESS_SCALE_FACTOR; } result.pushKV("sigoplimit", nSigOpLimit); result.pushKV("sizelimit", nSizeLimit); if (!fPreSegWit) { result.pushKV("weightlimit", (int64_t)MAX_BLOCK_WEIGHT); } result.pushKV("curtime", pblock->GetBlockTime()); result.pushKV("bits", strprintf("%08x", pblock->nBits)); result.pushKV("height", (int64_t)(pindexPrev->nHeight+1)); if (!pblocktemplate->vchCoinbaseCommitment.empty() && fSupportsSegwit) { result.pushKV("default_witness_commitment", HexStr(pblocktemplate->vchCoinbaseCommitment.begin(), pblocktemplate->vchCoinbaseCommitment.end())); } return result; }
int64 GetArg(const std::string& strArg, int64 nDefault) { if (mapArgs.count(strArg)) return atoi64(mapArgs[strArg]); return nDefault; }
UniValue gobject(const JSONRPCRequest& request) { std::string strCommand; if (request.params.size() >= 1) strCommand = request.params[0].get_str(); if (request.fHelp || ( #ifdef ENABLE_WALLET strCommand != "prepare" && #endif // ENABLE_WALLET strCommand != "vote-many" && strCommand != "vote-conf" && strCommand != "vote-name" && strCommand != "submit" && strCommand != "count" && strCommand != "deserialize" && strCommand != "get" && strCommand != "getvotes" && strCommand != "getcurrentvotes" && strCommand != "list" && strCommand != "diff" && strCommand != "check" )) throw std::runtime_error( "gobject \"command\"...\n" "Manage governance objects\n" "\nAvailable commands:\n" " check - Validate governance object data (proposal only)\n" #ifdef ENABLE_WALLET " prepare - Prepare governance object by signing and creating tx\n" #endif // ENABLE_WALLET " submit - Submit governance object to network\n" " deserialize - Deserialize governance object from hex string to JSON\n" " count - Count governance objects and votes (additional param: 'json' or 'all', default: 'json')\n" " get - Get governance object by hash\n" " getvotes - Get all votes for a governance object hash (including old votes)\n" " getcurrentvotes - Get only current (tallying) votes for a governance object hash (does not include old votes)\n" " list - List governance objects (can be filtered by signal and/or object type)\n" " diff - List differences since last diff\n" " vote-name - Vote on a governance object by masternode name (using masternode.conf setup)\n" " vote-conf - Vote on a governance object by masternode configured in syscoin.conf\n" " vote-many - Vote on a governance object by all masternodes (using masternode.conf setup)\n" ); if(strCommand == "count") { std::string strMode{"json"}; if (request.params.size() == 2) { strMode = request.params[1].get_str(); } if (request.params.size() > 2 || (strMode != "json" && strMode != "all")) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Correct usage is 'gobject count ( \"json\"|\"all\" )'"); } return strMode == "json" ? governance.ToJson() : governance.ToString(); } /* ------ Example Governance Item ------ gobject submit 6e622bb41bad1fb18e7f23ae96770aeb33129e18bd9efe790522488e580a0a03 0 1 1464292854 "beer-reimbursement" 5b5b22636f6e7472616374222c207b2270726f6a6563745f6e616d65223a20225c22626565722d7265696d62757273656d656e745c22222c20227061796d656e745f61646472657373223a20225c225879324c4b4a4a64655178657948726e34744744514238626a6876464564615576375c22222c2022656e645f64617465223a202231343936333030343030222c20226465736372697074696f6e5f75726c223a20225c227777772e646173687768616c652e6f72672f702f626565722d7265696d62757273656d656e745c22222c2022636f6e74726163745f75726c223a20225c22626565722d7265696d62757273656d656e742e636f6d2f3030312e7064665c22222c20227061796d656e745f616d6f756e74223a20223233342e323334323232222c2022676f7665726e616e63655f6f626a6563745f6964223a2037342c202273746172745f64617465223a202231343833323534303030227d5d5d1 */ // DEBUG : TEST DESERIALIZATION OF GOVERNANCE META DATA if(strCommand == "deserialize") { if (request.params.size() != 2) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Correct usage is 'gobject deserialize <data-hex>'"); } std::string strHex = request.params[1].get_str(); std::vector<unsigned char> v = ParseHex(strHex); std::string s(v.begin(), v.end()); UniValue u(UniValue::VOBJ); u.read(s); return u.write().c_str(); } // VALIDATE A GOVERNANCE OBJECT PRIOR TO SUBMISSION if(strCommand == "check") { if (request.params.size() != 2) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Correct usage is 'gobject check <data-hex>'"); } // ASSEMBLE NEW GOVERNANCE OBJECT FROM USER PARAMETERS uint256 hashParent; int nRevision = 1; int64_t nTime = GetAdjustedTime(); std::string strDataHex = request.params[1].get_str(); CGovernanceObject govobj(hashParent, nRevision, nTime, uint256(), strDataHex); if(govobj.GetObjectType() == GOVERNANCE_OBJECT_PROPOSAL) { CProposalValidator validator(strDataHex); if(!validator.Validate()) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid proposal data, error messages:" + validator.GetErrorMessages()); } } else { throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid object type, only proposals can be validated"); } UniValue objResult(UniValue::VOBJ); objResult.push_back(Pair("Object status", "OK")); return objResult; } #ifdef ENABLE_WALLET // PREPARE THE GOVERNANCE OBJECT BY CREATING A COLLATERAL TRANSACTION if(strCommand == "prepare") { if (!EnsureWalletIsAvailable(request.fHelp)) return NullUniValue; if (request.params.size() != 5) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Correct usage is 'gobject prepare <parent-hash> <revision> <time> <data-hex>'"); } // ASSEMBLE NEW GOVERNANCE OBJECT FROM USER PARAMETERS uint256 hashParent; // -- attach to root node (root node doesn't really exist, but has a hash of zero) if(request.params[1].get_str() == "0") { hashParent = uint256(); } else { hashParent = ParseHashV(request.params[1], "fee-txid, parameter 1"); } std::string strRevision = request.params[2].get_str(); std::string strTime = request.params[3].get_str(); int nRevision = atoi(strRevision); int64_t nTime = atoi64(strTime); std::string strDataHex = request.params[4].get_str(); // CREATE A NEW COLLATERAL TRANSACTION FOR THIS SPECIFIC OBJECT CGovernanceObject govobj(hashParent, nRevision, nTime, uint256(), strDataHex); if(govobj.GetObjectType() == GOVERNANCE_OBJECT_PROPOSAL) { CProposalValidator validator(strDataHex); if(!validator.Validate()) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid proposal data, error messages:" + validator.GetErrorMessages()); } } if(govobj.GetObjectType() == GOVERNANCE_OBJECT_TRIGGER) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Trigger objects need not be prepared (however only masternodes can create them)"); } if(govobj.GetObjectType() == GOVERNANCE_OBJECT_WATCHDOG) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Watchdogs are deprecated"); } { LOCK(cs_main); std::string strError = ""; if (!govobj.IsValidLocally(strError, false)) throw JSONRPCError(RPC_INTERNAL_ERROR, "Governance object is not valid - " + govobj.GetHash().ToString() + " - " + strError); } EnsureWalletIsUnlocked(); CWalletTx wtx; if(!pwalletMain->GetBudgetSystemCollateralTX(wtx, govobj.GetHash(), govobj.GetMinCollateralFee(), false)) { throw JSONRPCError(RPC_INTERNAL_ERROR, "Error making collateral transaction for governance object. Please check your wallet balance and make sure your wallet is unlocked."); } // -- make our change address CReserveKey reservekey(pwalletMain); // -- send the tx to the network CValidationState state; if (!pwalletMain->CommitTransaction(wtx, reservekey, g_connman.get(), state, NetMsgType::TX)) { throw JSONRPCError(RPC_INTERNAL_ERROR, "CommitTransaction failed! Reason given: " + state.GetRejectReason()); } DBG( std::cout << "gobject: prepare " << " GetDataAsPlainString = " << govobj.GetDataAsPlainString() << ", hash = " << govobj.GetHash().GetHex() << ", txidFee = " << wtx.GetHash().GetHex() << std::endl; ); return wtx.GetHash().ToString(); }
UniValue getblocktemplate(const JSONRPCRequest& request) { if (request.fHelp || request.params.size() > 1) throw std::runtime_error( "getblocktemplate ( TemplateRequest )\n" "\nIf the request parameters include a 'mode' key, that is used to explicitly select between the default 'template' request or a 'proposal'.\n" "It returns data needed to construct a block to work on.\n" "For full specification, see BIPs 22, 23, and 9:\n" " https://github.com/bitcoin/bips/blob/master/bip-0022.mediawiki\n" " https://github.com/bitcoin/bips/blob/master/bip-0023.mediawiki\n" " https://github.com/bitcoin/bips/blob/master/bip-0009.mediawiki#getblocktemplate_changes\n" "\nArguments:\n" "1. template_request (json object, optional) A json object in the following spec\n" " {\n" " \"mode\":\"template\" (string, optional) This must be set to \"template\", \"proposal\" (see BIP 23), or omitted\n" " \"capabilities\":[ (array, optional) A list of strings\n" " \"support\" (string) client side supported feature, 'longpoll', 'coinbasetxn', 'coinbasevalue', 'proposal', 'serverlist', 'workid'\n" " ,...\n" " ],\n" " \"rules\":[ (array, optional) A list of strings\n" " \"support\" (string) client side supported softfork deployment\n" " ,...\n" " ]\n" " }\n" "\n" "\nResult:\n" "{\n" " \"capabilities\" : [ \"capability\", ... ], (array of strings) specific client side supported features\n" " \"version\" : n, (numeric) The preferred block version\n" " \"rules\" : [ \"rulename\", ... ], (array of strings) specific block rules that are to be enforced\n" " \"vbavailable\" : { (json object) set of pending, supported versionbit (BIP 9) softfork deployments\n" " \"rulename\" : bitnumber (numeric) identifies the bit number as indicating acceptance and readiness for the named softfork rule\n" " ,...\n" " },\n" " \"vbrequired\" : n, (numeric) bit mask of versionbits the server requires set in submissions\n" " \"previousblockhash\" : \"xxxx\", (string) The hash of current highest block\n" " \"transactions\" : [ (array) contents of non-coinbase transactions that should be included in the next block\n" " {\n" " \"data\" : \"xxxx\", (string) transaction data encoded in hexadecimal (byte-for-byte)\n" " \"hash\" : \"xxxx\", (string) hash/id encoded in little-endian hexadecimal\n" " \"depends\" : [ (array) array of numbers \n" " n (numeric) transactions before this one (by 1-based index in 'transactions' list) that must be present in the final block if this one is\n" " ,...\n" " ],\n" " \"fee\": n, (numeric) difference in value between transaction inputs and outputs (in duffs); for coinbase transactions, this is a negative Number of the total collected block fees (ie, not including the block subsidy); if key is not present, fee is unknown and clients MUST NOT assume there isn't one\n" " \"sigops\" : n, (numeric) total number of SigOps, as counted for purposes of block limits; if key is not present, sigop count is unknown and clients MUST NOT assume there aren't any\n" " \"required\" : true|false (boolean) if provided and true, this transaction must be in the final block\n" " }\n" " ,...\n" " ],\n" " \"coinbaseaux\" : { (json object) data that should be included in the coinbase's scriptSig content\n" " \"flags\" : \"xx\" (string) key name is to be ignored, and value included in scriptSig\n" " },\n" " \"coinbasevalue\" : n, (numeric) maximum allowable input to coinbase transaction, including the generation award and transaction fees (in duffs)\n" " \"coinbasetxn\" : { ... }, (json object) information for coinbase transaction\n" " \"target\" : \"xxxx\", (string) The hash target\n" " \"mintime\" : xxx, (numeric) The minimum timestamp appropriate for next block time in seconds since epoch (Jan 1 1970 GMT)\n" " \"mutable\" : [ (array of string) list of ways the block template may be changed \n" " \"value\" (string) A way the block template may be changed, e.g. 'time', 'transactions', 'prevblock'\n" " ,...\n" " ],\n" " \"noncerange\" : \"00000000ffffffff\",(string) A range of valid nonces\n" " \"sigoplimit\" : n, (numeric) limit of sigops in blocks\n" " \"sizelimit\" : n, (numeric) limit of block size\n" " \"curtime\" : ttt, (numeric) current timestamp in seconds since epoch (Jan 1 1970 GMT)\n" " \"bits\" : \"xxxxxxxx\", (string) compressed target of next block\n" " \"previousbits\" : \"xxxxxxxx\", (string) compressed target of current highest block\n" " \"height\" : n (numeric) The height of the next block\n" " \"masternode\" : [ (array) required masternode payments that must be included in the next block\n" " {\n" " \"payee\" : \"xxxx\", (string) payee address\n" " \"script\" : \"xxxx\", (string) payee scriptPubKey\n" " \"amount\": n (numeric) required amount to pay\n" " }\n" " },\n" " \"masternode_payments_started\" : true|false, (boolean) true, if masternode payments started\n" " \"masternode_payments_enforced\" : true|false, (boolean) true, if masternode payments are enforced\n" " \"superblock\" : [ (array) required superblock payees that must be included in the next block\n" " {\n" " \"payee\" : \"xxxx\", (string) payee address\n" " \"script\" : \"xxxx\", (string) payee scriptPubKey\n" " \"amount\": n (numeric) required amount to pay\n" " }\n" " ,...\n" " ],\n" " \"superblocks_started\" : true|false, (boolean) true, if superblock payments started\n" " \"superblocks_enabled\" : true|false, (boolean) true, if superblock payments are enabled\n" " \"coinbase_payload\" : \"xxxxxxxx\" (string) coinbase transaction payload data encoded in hexadecimal\n" "}\n" "\nExamples:\n" + HelpExampleCli("getblocktemplate", "") + HelpExampleRpc("getblocktemplate", "") ); LOCK(cs_main); std::string strMode = "template"; UniValue lpval = NullUniValue; std::set<std::string> setClientRules; int64_t nMaxVersionPreVB = -1; if (request.params.size() > 0) { const UniValue& oparam = request.params[0].get_obj(); const UniValue& modeval = find_value(oparam, "mode"); if (modeval.isStr()) strMode = modeval.get_str(); else if (modeval.isNull()) { /* Do nothing */ } else throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid mode"); lpval = find_value(oparam, "longpollid"); if (strMode == "proposal") { const UniValue& dataval = find_value(oparam, "data"); if (!dataval.isStr()) throw JSONRPCError(RPC_TYPE_ERROR, "Missing data String key for proposal"); CBlock block; if (!DecodeHexBlk(block, dataval.get_str())) throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Block decode failed"); uint256 hash = block.GetHash(); BlockMap::iterator mi = mapBlockIndex.find(hash); if (mi != mapBlockIndex.end()) { CBlockIndex *pindex = mi->second; if (pindex->IsValid(BLOCK_VALID_SCRIPTS)) return "duplicate"; if (pindex->nStatus & BLOCK_FAILED_MASK) return "duplicate-invalid"; return "duplicate-inconclusive"; } CBlockIndex* const pindexPrev = chainActive.Tip(); // TestBlockValidity only supports blocks built on the current Tip if (block.hashPrevBlock != pindexPrev->GetBlockHash()) return "inconclusive-not-best-prevblk"; CValidationState state; TestBlockValidity(state, Params(), block, pindexPrev, false, true); return BIP22ValidationResult(state); } const UniValue& aClientRules = find_value(oparam, "rules"); if (aClientRules.isArray()) { for (unsigned int i = 0; i < aClientRules.size(); ++i) { const UniValue& v = aClientRules[i]; setClientRules.insert(v.get_str()); } } else { // NOTE: It is important that this NOT be read if versionbits is supported const UniValue& uvMaxVersion = find_value(oparam, "maxversion"); if (uvMaxVersion.isNum()) { nMaxVersionPreVB = uvMaxVersion.get_int64(); } } } if (strMode != "template") throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid mode"); if(!g_connman) throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled"); if (Params().MiningRequiresPeers()) { if (g_connman->GetNodeCount(CConnman::CONNECTIONS_ALL) == 0) throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, "Dash Core is not connected!"); if (IsInitialBlockDownload()) throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, "Dash Core is downloading blocks..."); } // when enforcement is on we need information about a masternode payee or otherwise our block is going to be orphaned by the network std::vector<CTxOut> voutMasternodePayments; if (sporkManager.IsSporkActive(SPORK_8_MASTERNODE_PAYMENT_ENFORCEMENT) && !masternodeSync.IsWinnersListSynced() && !mnpayments.GetBlockTxOuts(chainActive.Height() + 1, 0, voutMasternodePayments)) throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, "Dash Core is downloading masternode winners..."); // next bock is a superblock and we need governance info to correctly construct it if (sporkManager.IsSporkActive(SPORK_9_SUPERBLOCKS_ENABLED) && !masternodeSync.IsSynced() && CSuperblock::IsValidBlockHeight(chainActive.Height() + 1)) throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, "Dash Core is syncing with network..."); static unsigned int nTransactionsUpdatedLast; if (!lpval.isNull()) { // Wait to respond until either the best block changes, OR a minute has passed and there are more transactions uint256 hashWatchedChain; boost::system_time checktxtime; unsigned int nTransactionsUpdatedLastLP; if (lpval.isStr()) { // Format: <hashBestChain><nTransactionsUpdatedLast> std::string lpstr = lpval.get_str(); hashWatchedChain.SetHex(lpstr.substr(0, 64)); nTransactionsUpdatedLastLP = atoi64(lpstr.substr(64)); } else { // NOTE: Spec does not specify behaviour for non-string longpollid, but this makes testing easier hashWatchedChain = chainActive.Tip()->GetBlockHash(); nTransactionsUpdatedLastLP = nTransactionsUpdatedLast; } // Release the wallet and main lock while waiting LEAVE_CRITICAL_SECTION(cs_main); { checktxtime = boost::get_system_time() + boost::posix_time::minutes(1); boost::unique_lock<boost::mutex> lock(csBestBlock); while (chainActive.Tip()->GetBlockHash() == hashWatchedChain && IsRPCRunning()) { if (!cvBlockChange.timed_wait(lock, checktxtime)) { // Timeout: Check transactions for update if (mempool.GetTransactionsUpdated() != nTransactionsUpdatedLastLP) break; checktxtime += boost::posix_time::seconds(10); } } } ENTER_CRITICAL_SECTION(cs_main); if (!IsRPCRunning()) throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, "Shutting down"); // TODO: Maybe recheck connections/IBD and (if something wrong) send an expires-immediately template to stop miners? } // Update block static CBlockIndex* pindexPrev; static int64_t nStart; static std::unique_ptr<CBlockTemplate> pblocktemplate; if (pindexPrev != chainActive.Tip() || (mempool.GetTransactionsUpdated() != nTransactionsUpdatedLast && GetTime() - nStart > 5)) { // Clear pindexPrev so future calls make a new block, despite any failures from here on pindexPrev = nullptr; // Store the chainActive.Tip() used before CreateNewBlock, to avoid races nTransactionsUpdatedLast = mempool.GetTransactionsUpdated(); CBlockIndex* pindexPrevNew = chainActive.Tip(); nStart = GetTime(); // Create new block CScript scriptDummy = CScript() << OP_TRUE; pblocktemplate = BlockAssembler(Params()).CreateNewBlock(scriptDummy); if (!pblocktemplate) throw JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory"); // Need to update only after we know CreateNewBlock succeeded pindexPrev = pindexPrevNew; } CBlock* pblock = &pblocktemplate->block; // pointer for convenience const Consensus::Params& consensusParams = Params().GetConsensus(); // Update nTime UpdateTime(pblock, consensusParams, pindexPrev); pblock->nNonce = 0; UniValue aCaps(UniValue::VARR); aCaps.push_back("proposal"); UniValue transactions(UniValue::VARR); std::map<uint256, int64_t> setTxIndex; int i = 0; for (const auto& it : pblock->vtx) { const CTransaction& tx = *it; uint256 txHash = tx.GetHash(); setTxIndex[txHash] = i++; if (tx.IsCoinBase()) continue; UniValue entry(UniValue::VOBJ); entry.push_back(Pair("data", EncodeHexTx(tx))); entry.push_back(Pair("hash", txHash.GetHex())); UniValue deps(UniValue::VARR); BOOST_FOREACH (const CTxIn &in, tx.vin) { if (setTxIndex.count(in.prevout.hash)) deps.push_back(setTxIndex[in.prevout.hash]); } entry.push_back(Pair("depends", deps)); int index_in_template = i - 1; entry.push_back(Pair("fee", pblocktemplate->vTxFees[index_in_template])); entry.push_back(Pair("sigops", pblocktemplate->vTxSigOps[index_in_template])); transactions.push_back(entry); } UniValue aux(UniValue::VOBJ); aux.push_back(Pair("flags", HexStr(COINBASE_FLAGS.begin(), COINBASE_FLAGS.end()))); arith_uint256 hashTarget = arith_uint256().SetCompact(pblock->nBits); UniValue aMutable(UniValue::VARR); aMutable.push_back("time"); aMutable.push_back("transactions"); aMutable.push_back("prevblock"); UniValue result(UniValue::VOBJ); result.push_back(Pair("capabilities", aCaps)); UniValue aRules(UniValue::VARR); UniValue vbavailable(UniValue::VOBJ); for (int j = 0; j < (int)Consensus::MAX_VERSION_BITS_DEPLOYMENTS; ++j) { Consensus::DeploymentPos pos = Consensus::DeploymentPos(j); ThresholdState state = VersionBitsState(pindexPrev, consensusParams, pos, versionbitscache); switch (state) { case THRESHOLD_DEFINED: case THRESHOLD_FAILED: // Not exposed to GBT at all break; case THRESHOLD_LOCKED_IN: // Ensure bit is set in block version pblock->nVersion |= VersionBitsMask(consensusParams, pos); // FALL THROUGH to get vbavailable set... case THRESHOLD_STARTED: { const struct BIP9DeploymentInfo& vbinfo = VersionBitsDeploymentInfo[pos]; vbavailable.push_back(Pair(gbt_vb_name(pos), consensusParams.vDeployments[pos].bit)); if (setClientRules.find(vbinfo.name) == setClientRules.end()) { if (!vbinfo.gbt_force) { // If the client doesn't support this, don't indicate it in the [default] version pblock->nVersion &= ~VersionBitsMask(consensusParams, pos); } } break; } case THRESHOLD_ACTIVE: { // Add to rules only const struct BIP9DeploymentInfo& vbinfo = VersionBitsDeploymentInfo[pos]; aRules.push_back(gbt_vb_name(pos)); if (setClientRules.find(vbinfo.name) == setClientRules.end()) { // Not supported by the client; make sure it's safe to proceed if (!vbinfo.gbt_force) { // If we do anything other than throw an exception here, be sure version/force isn't sent to old clients throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Support for '%s' rule requires explicit client support", vbinfo.name)); } } break; } } } result.push_back(Pair("version", pblock->nVersion)); result.push_back(Pair("rules", aRules)); result.push_back(Pair("vbavailable", vbavailable)); result.push_back(Pair("vbrequired", int(0))); if (nMaxVersionPreVB >= 2) { // If VB is supported by the client, nMaxVersionPreVB is -1, so we won't get here // Because BIP 34 changed how the generation transaction is serialized, we can only use version/force back to v2 blocks // This is safe to do [otherwise-]unconditionally only because we are throwing an exception above if a non-force deployment gets activated // Note that this can probably also be removed entirely after the first BIP9 non-force deployment (ie, probably segwit) gets activated aMutable.push_back("version/force"); } result.push_back(Pair("previousblockhash", pblock->hashPrevBlock.GetHex())); result.push_back(Pair("transactions", transactions)); result.push_back(Pair("coinbaseaux", aux)); result.push_back(Pair("coinbasevalue", (int64_t)pblock->vtx[0]->GetValueOut())); result.push_back(Pair("longpollid", chainActive.Tip()->GetBlockHash().GetHex() + i64tostr(nTransactionsUpdatedLast))); result.push_back(Pair("target", hashTarget.GetHex())); result.push_back(Pair("mintime", (int64_t)pindexPrev->GetMedianTimePast()+1)); result.push_back(Pair("mutable", aMutable)); result.push_back(Pair("noncerange", "00000000ffffffff")); result.push_back(Pair("sigoplimit", (int64_t)MaxBlockSigOps(fDIP0001ActiveAtTip))); result.push_back(Pair("sizelimit", (int64_t)MaxBlockSize(fDIP0001ActiveAtTip))); result.push_back(Pair("curtime", pblock->GetBlockTime())); result.push_back(Pair("bits", strprintf("%08x", pblock->nBits))); result.push_back(Pair("previousbits", strprintf("%08x", pblocktemplate->nPrevBits))); result.push_back(Pair("height", (int64_t)(pindexPrev->nHeight+1))); UniValue masternodeObj(UniValue::VARR); for (const auto& txout : pblocktemplate->voutMasternodePayments) { CTxDestination address1; ExtractDestination(txout.scriptPubKey, address1); CBitcoinAddress address2(address1); UniValue obj(UniValue::VOBJ); obj.push_back(Pair("payee", address2.ToString().c_str())); obj.push_back(Pair("script", HexStr(txout.scriptPubKey))); obj.push_back(Pair("amount", txout.nValue)); masternodeObj.push_back(obj); } result.push_back(Pair("masternode", masternodeObj)); result.push_back(Pair("masternode_payments_started", pindexPrev->nHeight + 1 > consensusParams.nMasternodePaymentsStartBlock)); result.push_back(Pair("masternode_payments_enforced", deterministicMNManager->IsDeterministicMNsSporkActive() || sporkManager.IsSporkActive(SPORK_8_MASTERNODE_PAYMENT_ENFORCEMENT))); UniValue superblockObjArray(UniValue::VARR); if(pblocktemplate->voutSuperblockPayments.size()) { for (const auto& txout : pblocktemplate->voutSuperblockPayments) { UniValue entry(UniValue::VOBJ); CTxDestination address1; ExtractDestination(txout.scriptPubKey, address1); CBitcoinAddress address2(address1); entry.push_back(Pair("payee", address2.ToString().c_str())); entry.push_back(Pair("script", HexStr(txout.scriptPubKey))); entry.push_back(Pair("amount", txout.nValue)); superblockObjArray.push_back(entry); } } result.push_back(Pair("superblock", superblockObjArray)); result.push_back(Pair("superblocks_started", pindexPrev->nHeight + 1 > consensusParams.nSuperblockStartBlock)); result.push_back(Pair("superblocks_enabled", sporkManager.IsSporkActive(SPORK_9_SUPERBLOCKS_ENABLED))); result.push_back(Pair("coinbase_payload", HexStr(pblock->vtx[0]->vExtraPayload))); return result; }
CScript ParseScript(const std::string& s) { CScript result; static std::map<std::string, opcodetype> mapOpNames; if (mapOpNames.empty()) { for (unsigned int op = 0; op <= MAX_OPCODE; op++) { // Allow OP_RESERVED to get into mapOpNames if (op < OP_NOP && op != OP_RESERVED) continue; const char* name = GetOpName((opcodetype)op); if (strcmp(name, "OP_UNKNOWN") == 0) continue; std::string strName(name); mapOpNames[strName] = (opcodetype)op; // Convenience: OP_ADD and just ADD are both recognized: boost::algorithm::replace_first(strName, "OP_", ""); mapOpNames[strName] = (opcodetype)op; } } std::vector<std::string> words; boost::algorithm::split(words, s, boost::algorithm::is_any_of(" \t\n"), boost::algorithm::token_compress_on); for (std::vector<std::string>::const_iterator w = words.begin(); w != words.end(); ++w) { if (w->empty()) { // Empty string, ignore. (boost::split given '' will return one word) } else if (all(*w, boost::algorithm::is_digit()) || (boost::algorithm::starts_with(*w, "-") && all(std::string(w->begin()+1, w->end()), boost::algorithm::is_digit()))) { // Number int64_t n = atoi64(*w); result << n; } else if (boost::algorithm::starts_with(*w, "0x") && (w->begin()+2 != w->end()) && IsHex(std::string(w->begin()+2, w->end()))) { // Raw hex data, inserted NOT pushed onto stack: std::vector<unsigned char> raw = ParseHex(std::string(w->begin()+2, w->end())); result.insert(result.end(), raw.begin(), raw.end()); } else if (w->size() >= 2 && boost::algorithm::starts_with(*w, "'") && boost::algorithm::ends_with(*w, "'")) { // Single-quoted string, pushed as data. NOTE: this is poor-man's // parsing, spaces/tabs/newlines in single-quoted strings won't work. std::vector<unsigned char> value(w->begin()+1, w->end()-1); result << value; } else if (mapOpNames.count(*w)) { // opcode, e.g. OP_ADD or ADD: result << mapOpNames[*w]; } else { throw std::runtime_error("script parse error"); } } return result; }
int mp4_split_options_set(struct mp4_split_options_t* options, const char* args_data, unsigned int args_size) { int result = 1; { const char* first = args_data; const char* last = first + args_size + 1; if(*first == '?') { ++first; } { char const* key = first; char const* val = NULL; int is_key = 1; size_t key_len = 0; float vbegin = 0.0f; float vend = 0.0f; while(first != last) { // the args_data is not necessarily 0 terminated, so fake it int ch = (first == last - 1) ? '\0' : *first; switch(ch) { case '=': val = first + 1; key_len = first - key; is_key = 0; break; case '&': case '\0': if(!is_key) { // make sure the value is zero-terminated (for strtod,atoi64) int val_len = first - val; char* valz = (char*)malloc(val_len + 1); memcpy(valz, val, val_len); valz[val_len] = '\0'; if(!strncmp("client", key, key_len)) { options->client_is_flash = starts_with(valz, "FLASH"); } else if(!strncmp("start", key, key_len)) { options->start = (float)(strtod(valz, NULL)); options->start_integer = atoi64(valz); } else if(!strncmp("end", key, key_len)) { options->end = (float)(strtod(valz, NULL)); } else if(!strncmp("exact", key, key_len)) { options->exact = 1; } else if(!strncmp("vbegin", key, key_len)) { vbegin = (float)(strtod(valz, NULL)); } else if(!strncmp("vend", key, key_len)) { vend = (float)(strtod(valz, NULL)); } else if(!strncmp("adaptive", key, key_len)) { options->adaptive = 1; } else if(!strncmp("bitrate", key, key_len)) { options->fragment_bitrate = (unsigned int)(atoi64(valz)); } else if(!strncmp("video", key, key_len)) { options->fragments = 1; options->fragment_type = fragment_type_video; options->fragment_start = atoi64(valz); } else if(!strncmp("audio", key, key_len)) { options->fragments = 1; options->fragment_type = fragment_type_audio; options->fragment_start = atoi64(valz); } else if(!strncmp("format", key, key_len)) { if(!strncmp("flv", val, val_len)) { options->output_format = OUTPUT_FORMAT_FLV; } else if(!strncmp("ts", val, val_len)) { options->output_format = OUTPUT_FORMAT_TS; } } else if(!strncmp("input", key, key_len)) { if(!strncmp("flv", val, val_len)) { options->input_format = INPUT_FORMAT_FLV; } } free(valz); } key = first + 1; val = NULL; is_key = 1; break; } ++first; } // If we have specified a begin point of the virtual video clip, // then adjust the start offset options->start += vbegin; // If we have specified an end, adjust it in case of a virtual video clip. if(options->end) { options->end += vbegin; } else { options->end = vend; } // Validate the start/end for the virtual video clip (begin). if(vbegin) { if(options->start < vbegin) result = 0; if(options->end && options->end < vbegin) result = 0; } // Validate the start/end for the virtual video clip (end). if(vend) { if(options->start > vend) result = 0; if(options->end && options->end > vend) result = 0; } } } return result; }
/* * Init function called from dm_table_load_ioctl. * * Example line sent to dm from lvm tools when using striped target. * start length striped #stripes chunk_size device1 offset1 ... deviceN offsetN * 0 65536 striped 2 512 /dev/hda 0 /dev/hdb 0 */ static int dm_target_stripe_init(dm_dev_t *dmv, void **target_config, char *params) { dm_target_stripe_config_t *tsc; int n; char *ap; if (params == NULL) return EINVAL; /* * nstripes */ ap = strsep(¶ms, " \t"); if (ap == NULL) return EINVAL; n = (int)atoi64(ap); if (n < 0 || n > MAX_STRIPES) { kprintf("dm: Error %d stripes not supported (%d max)\n", n, MAX_STRIPES); return ENOTSUP; } tsc = kmalloc(sizeof(dm_target_stripe_config_t), M_DMSTRIPE, M_WAITOK | M_ZERO); tsc->stripe_num = n; ap = strsep(¶ms, " \t"); if (ap == NULL) return EINVAL; tsc->stripe_chunksize = atoi64(ap); if (tsc->stripe_chunksize < 1 || tsc->stripe_chunksize * DEV_BSIZE > MAXPHYS) { kprintf("dm: Error unsupported chunk size %jdKB\n", (intmax_t)tsc->stripe_chunksize * DEV_BSIZE / 1024); dm_target_stripe_destroy_config(tsc); return EINVAL; } /* * Parse the devices */ kprintf("dm: Stripe %d devices chunk size %dKB\n", (int)tsc->stripe_num, (int)tsc->stripe_chunksize ); for (n = 0; n < tsc->stripe_num; ++n) { ap = strsep(¶ms, " \t"); if (ap == NULL) break; tsc->stripe_devs[n].pdev = dm_pdev_insert(ap); if (tsc->stripe_devs[n].pdev == NULL) break; ap = strsep(¶ms, " \t"); if (ap == NULL) break; tsc->stripe_devs[n].offset = atoi64(ap); } if (n != tsc->stripe_num) { dm_target_stripe_destroy_config(tsc); return (ENOENT); } *target_config = tsc; dmv->dev_type = DM_STRIPE_DEV; return 0; }