From 9885633cf68a5c75c658448de452074e7e290910 Mon Sep 17 00:00:00 2001 From: mike31 Date: Thu, 9 Nov 2017 14:45:39 +0200 Subject: [PATCH 01/71] Per-asset permissions, no coin selection --- src/chainparams/params.cpp | 20 ++++++ src/chainparams/state.h | 8 +++ src/entities/asset.cpp | 42 ++++++++++++- src/entities/asset.h | 3 + src/permissions/permission.cpp | 34 +++++++++- src/permissions/permission.h | 5 +- src/protocol/multichaintx.cpp | 112 +++++++++++++++++++++++++++++---- src/rpc/rpcassets.cpp | 30 ++++++++- src/rpc/rpcpermissions.cpp | 9 ++- src/rpc/rpcrawdata.cpp | 33 ++++++++++ src/rpc/rpcutils.cpp | 17 ++++- src/version/version.cpp | 6 +- 12 files changed, 290 insertions(+), 29 deletions(-) diff --git a/src/chainparams/params.cpp b/src/chainparams/params.cpp index a87d7017..ed80a5af 100644 --- a/src/chainparams/params.cpp +++ b/src/chainparams/params.cpp @@ -1960,3 +1960,23 @@ int mc_Features::FixedIsUnspendable() return ret; } +int mc_Features::PerAssetPermissions() +{ + int ret=0; + if(mc_gState->m_NetworkParams->IsProtocolMultichain() == 0) + { + return 0; + } + int protocol=mc_gState->m_NetworkParams->ProtocolVersion(); + + if(protocol) + { + if(protocol >= 20002) + { + ret=1; + } + } + + return ret; +} + diff --git a/src/chainparams/state.h b/src/chainparams/state.h index e18d4ef4..a321da11 100644 --- a/src/chainparams/state.h +++ b/src/chainparams/state.h @@ -130,6 +130,7 @@ typedef struct mc_Features int FixedIn1000920001(); int MultipleStreamKeys(); int FixedIsUnspendable(); + int PerAssetPermissions(); } mc_Features; typedef struct mc_BlockHeaderInfo @@ -170,6 +171,7 @@ typedef struct mc_State mc_Script *m_TmpScript1; mc_Buffer *m_TmpAssetsOut; mc_Buffer *m_TmpAssetsIn; + mc_Buffer *m_TmpAssetsTmp; mc_Buffer *m_BlockHeaderSuccessors; @@ -193,6 +195,8 @@ typedef struct mc_State mc_InitABufferMap(m_TmpAssetsOut); m_TmpAssetsIn=new mc_Buffer; mc_InitABufferMap(m_TmpAssetsIn); + m_TmpAssetsTmp=new mc_Buffer; + mc_InitABufferMap(m_TmpAssetsTmp); m_Compatibility=MC_VCM_NONE; m_BlockHeaderSuccessors=new mc_Buffer; @@ -242,6 +246,10 @@ typedef struct mc_State { delete m_TmpAssetsIn; } + if(m_TmpAssetsTmp) + { + delete m_TmpAssetsTmp; + } if(m_BlockHeaderSuccessors) { delete m_BlockHeaderSuccessors; diff --git a/src/entities/asset.cpp b/src/entities/asset.cpp index e1150cfb..bef46f15 100644 --- a/src/entities/asset.cpp +++ b/src/entities/asset.cpp @@ -536,7 +536,31 @@ void mc_EntityDetails::Set(mc_EntityLedgerRow* row) } m_Flags |= MC_ENT_FLAG_OFFSET_IS_SET; } - + + m_Permissions=0; + switch(m_LedgerRow.m_EntityType) + { + case MC_ENT_TYPE_ASSET: + m_Permissions |= MC_PTP_ADMIN | MC_PTP_ISSUE; + if(mc_gState->m_Features->PerAssetPermissions()) + { + m_Permissions |= MC_PTP_ACTIVATE; + } + break; + case MC_ENT_TYPE_STREAM: + m_Permissions |= MC_PTP_ADMIN | MC_PTP_ACTIVATE | MC_PTP_WRITE; + break; + default: + if(mc_gState->m_Features->FixedIn10007()) + { + if(m_LedgerRow.m_EntityType <= MC_ENT_TYPE_STREAM_MAX) + { + m_Permissions = MC_PTP_WRITE | MC_PTP_ACTIVATE; + } + } + break; + } + if(script_size) { value_offset=mc_FindSpecialParamInDetailsScript(m_LedgerRow.m_Script,m_LedgerRow.m_ScriptSize,MC_ENT_SPRM_NAME,&value_size); @@ -566,6 +590,16 @@ void mc_EntityDetails::Set(mc_EntityLedgerRow* row) mc_StringLowerCase(m_Name,value_size); m_Flags |= MC_ENT_FLAG_NAME_IS_SET; } + + value_offset=mc_FindSpecialParamInDetailsScript(m_LedgerRow.m_Script,m_LedgerRow.m_ScriptSize,MC_ENT_SPRM_PERMISSIONS,&value_size); + if(value_offset <= m_LedgerRow.m_ScriptSize) + { + if((value_size>0) && (value_size<=4)) + { + m_Permissions |= (uint32_t)mc_GetLE(m_LedgerRow.m_Script+value_offset,value_size); + } + } + } mc_ZeroABRaw(m_FullRef); @@ -1710,6 +1744,12 @@ int mc_EntityDetails::AllowedFollowOns() return 0; } +uint32_t mc_EntityDetails::Permissions() +{ + return m_Permissions; +} + + int mc_EntityDetails::AnyoneCanWrite() { unsigned char *ptr; diff --git a/src/entities/asset.h b/src/entities/asset.h index f92d52ee..2a36fac2 100644 --- a/src/entities/asset.h +++ b/src/entities/asset.h @@ -56,6 +56,7 @@ #define MC_ENT_SPRM_ISSUER 0x03 #define MC_ENT_SPRM_ANYONE_CAN_WRITE 0x04 #define MC_ENT_SPRM_JSON_DETAILS 0x05 +#define MC_ENT_SPRM_PERMISSIONS 0x06 #define MC_ENT_SPRM_ASSET_MULTIPLE 0x41 #define MC_ENT_SPRM_UPGRADE_PROTOCOL_VERSION 0x42 #define MC_ENT_SPRM_UPGRADE_START_BLOCK 0x43 @@ -135,6 +136,7 @@ typedef struct mc_EntityDetails unsigned char m_FullRef[MC_AST_ASSET_QUANTITY_OFFSET]; // Full Entity reference, derived from short txid from v 10007 char m_Name[MC_ENT_MAX_NAME_SIZE+6]; // Entity name uint32_t m_Flags; + uint32_t m_Permissions; unsigned char m_Reserved[36]; mc_EntityLedgerRow m_LedgerRow; void Zero(); @@ -150,6 +152,7 @@ typedef struct mc_EntityDetails int IsFollowOn(); // int HasFollowOns(); int AllowedFollowOns(); + uint32_t Permissions(); int AnyoneCanWrite(); int UpgradeProtocolVersion(); uint32_t UpgradeStartBlock(); diff --git a/src/permissions/permission.cpp b/src/permissions/permission.cpp index ac7435d0..3903bd58 100644 --- a/src/permissions/permission.cpp +++ b/src/permissions/permission.cpp @@ -710,6 +710,29 @@ int mc_MemcmpCheckSize(const void *s1,const char *s2,size_t s1_size) return memcmp(s1,s2,s1_size); } +uint32_t mc_Permissions::GetPossiblePermissionTypes(const void* entity_details) +{ + uint32_t full_type; + mc_EntityDetails *entity; + entity=(mc_EntityDetails *)entity_details; + + if(entity) + { + if(entity->GetEntityType()) + { + return entity->Permissions(); + } + } + + full_type = MC_PTP_GLOBAL_ALL; + if(mc_gState->m_Features->Streams() == 0) + { + full_type-=MC_PTP_CREATE; + } + + return full_type; +} + uint32_t mc_Permissions::GetPossiblePermissionTypes(uint32_t entity_type) { uint32_t full_type; @@ -746,15 +769,20 @@ uint32_t mc_Permissions::GetPossiblePermissionTypes(uint32_t entity_type) /** Return ORed MC_PTP_ constants by textual value */ -uint32_t mc_Permissions::GetPermissionType(const char *str,int entity_type) +uint32_t mc_Permissions::GetPermissionType(const char *str,const void* entity_details) +{ + return GetPermissionType(str,GetPossiblePermissionTypes(entity_details)); +} + +uint32_t mc_Permissions::GetPermissionType(const char *str,uint32_t full_type) { - uint32_t result,perm_type,full_type; + uint32_t result,perm_type; char* ptr; char* start; char* ptrEnd; char c; - full_type=GetPossiblePermissionTypes(entity_type); +// full_type=GetPossiblePermissionTypes(entity_details); ptr=(char*)str; ptrEnd=ptr+strlen(ptr); diff --git a/src/permissions/permission.h b/src/permissions/permission.h index e8a09a45..61d39fb8 100644 --- a/src/permissions/permission.h +++ b/src/permissions/permission.h @@ -290,8 +290,11 @@ typedef struct mc_Permissions int RollBackToCheckPoint(); uint32_t GetAllPermissions(const void* lpEntity,const void* lpAddress,uint32_t type); - uint32_t GetPermissionType(const char *str,int entity_type); + uint32_t GetPermissionType(const char *str,uint32_t full_type); +// uint32_t GetPermissionType(const char *str,int entity_type); + uint32_t GetPermissionType(const char *str,const void *entity_details); uint32_t GetPossiblePermissionTypes(uint32_t entity_type); + uint32_t GetPossiblePermissionTypes(const void *entity_details); int GetAdminCount(); int GetMinerCount(); diff --git a/src/protocol/multichaintx.cpp b/src/protocol/multichaintx.cpp index 94157bf9..03bc66ef 100644 --- a/src/protocol/multichaintx.cpp +++ b/src/protocol/multichaintx.cpp @@ -6,6 +6,7 @@ #include "core/main.h" #include "utils/util.h" +#include "utils/utilparse.h" #include "multichain/multichain.h" #include "structs/base58.h" @@ -47,7 +48,60 @@ uint160 mc_GenesisAdmin(const CTransaction& tx) return 0; } -bool mc_ExtractInputAssetQuantities(const CScript& script1, uint256 hash, string& reason) +bool mc_VerifyAssetPermissions(mc_Buffer *assets, vector addressRets, int required_permissions, uint32_t permission, string& reason) +{ + mc_EntityDetails entity; + + for(int i=0;iGetCount();i++) + { + if(mc_gState->m_Assets->FindEntityByFullRef(&entity,assets->GetRow(i))) + { + if( entity.Permissions() & (MC_PTP_SEND | MC_PTP_RECEIVE) ) + { + if(assets->GetCount() > 1) + { + if(permission == MC_PTP_SEND) + { + reason="One of multiple assets in input has per-asset permissions"; + } + if(permission == MC_PTP_RECEIVE) + { + reason="One of multiple assets in output has per-asset permissions"; + } + return false; + } + if(entity.Permissions() & permission) + { + int found=required_permissions; + for(int j=0;j<(int)addressRets.size();j++) + { + if(mc_gState->m_Permissions->GetPermission(entity.GetTxID(),GetAddressIDPtr(addressRets[i]),permission)) + { + found--; + } + } + if(found > 0) + { + if(permission == MC_PTP_SEND) + { + reason="One of the inputs doesn't have per-asset send permission"; + } + if(permission == MC_PTP_RECEIVE) + { + reason="One of the outputs doesn't have per-asset receive permission"; + } + return false; + } + } + } + } + } + + return true; +} + + +bool mc_ExtractInputAssetQuantities(mc_Buffer *assets, const CScript& script1, uint256 hash, string& reason) { int err; int64_t quantity; @@ -59,7 +113,7 @@ bool mc_ExtractInputAssetQuantities(const CScript& script1, uint256 hash, string for (int e = 0; e < mc_gState->m_TmpScript->GetNumElements(); e++) { mc_gState->m_TmpScript->SetElement(e); - err=mc_gState->m_TmpScript->GetAssetQuantities(mc_gState->m_TmpAssetsIn,MC_SCR_ASSET_SCRIPT_TYPE_TRANSFER | MC_SCR_ASSET_SCRIPT_TYPE_FOLLOWON); + err=mc_gState->m_TmpScript->GetAssetQuantities(assets,MC_SCR_ASSET_SCRIPT_TYPE_TRANSFER | MC_SCR_ASSET_SCRIPT_TYPE_FOLLOWON); if((err != MC_ERR_NOERROR) && (err != MC_ERR_WRONG_SCRIPT)) { reason="Asset transfer script rejected - error in script"; @@ -82,17 +136,17 @@ bool mc_ExtractInputAssetQuantities(const CScript& script1, uint256 hash, string } } memcpy(buf_amounts,entity.GetFullRef(),MC_AST_ASSET_FULLREF_SIZE); - int row=mc_gState->m_TmpAssetsIn->Seek(buf_amounts); + int row=assets->Seek(buf_amounts); if(row>=0) { - int64_t last=mc_GetABQuantity(mc_gState->m_TmpAssetsIn->GetRow(row)); + int64_t last=mc_GetABQuantity(assets->GetRow(row)); quantity+=last; - mc_SetABQuantity(mc_gState->m_TmpAssetsIn->GetRow(row),quantity); + mc_SetABQuantity(assets->GetRow(row),quantity); } else { mc_SetABQuantity(buf_amounts,quantity); - mc_gState->m_TmpAssetsIn->Add(buf_amounts); + assets->Add(buf_amounts); } } else @@ -114,13 +168,13 @@ bool mc_ExtractInputAssetQuantities(const CScript& script1, uint256 hash, string return true; } -bool mc_ExtractOutputAssetQuantities(string& reason) +bool mc_ExtractOutputAssetQuantities(mc_Buffer *assets,string& reason) { int err; for (int e = 0; e < mc_gState->m_TmpScript->GetNumElements(); e++) { mc_gState->m_TmpScript->SetElement(e); - err=mc_gState->m_TmpScript->GetAssetQuantities(mc_gState->m_TmpAssetsOut,MC_SCR_ASSET_SCRIPT_TYPE_TRANSFER); + err=mc_gState->m_TmpScript->GetAssetQuantities(assets,MC_SCR_ASSET_SCRIPT_TYPE_TRANSFER); if((err != MC_ERR_NOERROR) && (err != MC_ERR_WRONG_SCRIPT)) { reason="Asset transfer script rejected - error in output transfer script"; @@ -651,6 +705,12 @@ bool AcceptAssetGenesisFromPredefinedIssuers(const CTransaction &tx, (unsigned char*)issuers[0].begin(),0,(uint32_t)(-1),timestamp,flags | MC_PFL_ENTITY_GENESIS ,update_mempool,offset); } + uint32_t all_permissions=MC_PTP_ADMIN | MC_PTP_ISSUE; + if(mc_gState->m_Features->PerAssetPermissions()) + { + all_permissions |= MC_PTP_ACTIVATE | MC_PTP_SEND | MC_PTP_RECEIVE; + } + for (unsigned int i = 0; i < issuers.size(); i++) { if(err == MC_ERR_NOERROR) @@ -664,8 +724,8 @@ bool AcceptAssetGenesisFromPredefinedIssuers(const CTransaction &tx, mc_gState->m_TmpScript->SetSpecialParamValue(MC_ENT_SPRM_ISSUER,issuer_buf,sizeof(issuer_buf)); } if(new_issue) - { - err=mc_gState->m_Permissions->SetPermission(&txid,issuer_buf,MC_PTP_ADMIN | MC_PTP_ISSUE, + { + err=mc_gState->m_Permissions->SetPermission(&txid,issuer_buf,all_permissions, (unsigned char*)issuers[0].begin(),0,(uint32_t)(-1),timestamp,flags | MC_PFL_ENTITY_GENESIS ,update_mempool,offset); } stored_issuers.insert(issuers[i]); @@ -938,10 +998,23 @@ bool AcceptMultiChainTransaction(const CTransaction& tx, vInputHashTypes.push_back(sighash_type); - if(!mc_ExtractInputAssetQuantities(script1,prevout.hash,reason)) // Filling input asset quantity list + if(mc_gState->m_Features->PerAssetPermissions()) { - return false; + mc_gState->m_TmpAssetsTmp->Clear(); + if(!mc_ExtractInputAssetQuantities(mc_gState->m_TmpAssetsTmp,script1,prevout.hash,reason)) // Filling input asset quantity list + { + return false; + } + if(!mc_VerifyAssetPermissions(mc_gState->m_TmpAssetsTmp,addressRets,1,MC_PTP_SEND,reason)) + { + return false; + } } + + if(!mc_ExtractInputAssetQuantities(mc_gState->m_TmpAssetsIn,script1,prevout.hash,reason)) + { + return false; + } } vInputCanGrantAdminMine.push_back(!fCheckCachedScript); @@ -1668,7 +1741,20 @@ bool AcceptMultiChainTransaction(const CTransaction& tx, if(pass == 3) { - if(!mc_ExtractOutputAssetQuantities(reason)) // Filling output asset quantity list + if(mc_gState->m_Features->PerAssetPermissions()) + { + mc_gState->m_TmpAssetsTmp->Clear(); + if(!mc_ExtractOutputAssetQuantities(mc_gState->m_TmpAssetsTmp,reason)) // Filling output asset quantity list + { + fReject=true; + goto exitlbl; + } + if(!mc_VerifyAssetPermissions(mc_gState->m_TmpAssetsTmp,addressRets,receive_required,MC_PTP_RECEIVE,reason)) + { + return false; + } + } + if(!mc_ExtractOutputAssetQuantities(mc_gState->m_TmpAssetsOut,reason)) // Filling output asset quantity list { fReject=true; goto exitlbl; diff --git a/src/rpc/rpcassets.cpp b/src/rpc/rpcassets.cpp index 1d928f9b..273c46a8 100644 --- a/src/rpc/rpcassets.cpp +++ b/src/rpc/rpcassets.cpp @@ -127,13 +127,13 @@ Value issuefromcmd(const Array& params, bool fHelp) lpDetailsScript=NULL; mc_Script *lpDetails; - lpDetails=new mc_Script; - lpDetails->AddElement(); + lpDetails=NULL; int ret,type; string asset_name=""; bool is_open=false; bool name_is_found=false; + uint32_t permissions=0; if (params.size() > 2 && params[2].type() != null_type)// && !params[2].get_str().empty()) { @@ -161,6 +161,24 @@ Value issuefromcmd(const Array& params, bool fHelp) throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid value for 'open' field, should be boolean"); } } + if(s.name_ == "permissions") + { + if(mc_gState->m_Features->PerAssetPermissions() == 0) + { + throw JSONRPCError(RPC_NOT_SUPPORTED, "Per-asset permissions not supported for this protocol version"); + } + if(permissions == 0) + { + if(s.value_.type() == str_type) + { + permissions=mc_gState->m_Permissions->GetPermissionType(s.value_.get_str().c_str(),MC_PTP_SEND | MC_PTP_RECEIVE); + if(permissions == 0) + { + throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid value for 'permissions' field"); + } + } + } + } } } else @@ -202,6 +220,9 @@ Value issuefromcmd(const Array& params, bool fHelp) } } + lpDetails=new mc_Script; + lpDetails->AddElement(); + if(mc_gState->m_Features->OpDropDetailsScripts()) { if(asset_name.size()) @@ -217,6 +238,11 @@ Value issuefromcmd(const Array& params, bool fHelp) lpDetails->SetSpecialParamValue(MC_ENT_SPRM_FOLLOW_ONS,&b,1); } + if(permissions) + { + lpDetails->SetSpecialParamValue(MC_ENT_SPRM_PERMISSIONS,(unsigned char*)&permissions,sizeof(uint32_t)); + } + /* if (params.size() > 6) { diff --git a/src/rpc/rpcpermissions.cpp b/src/rpc/rpcpermissions.cpp index c6507cd9..31552c68 100644 --- a/src/rpc/rpcpermissions.cpp +++ b/src/rpc/rpcpermissions.cpp @@ -117,7 +117,8 @@ Value grantoperation(const Array& params) LogPrintf("mchn: Granting %s permission(s) to address %s (%ld-%ld), Entity TxID: %s, Name: %s\n",permission_type,params[1].get_str(),from,to, ((uint256*)entity.GetTxID())->ToString().c_str(),entity.GetName()); - type=mc_gState->m_Permissions->GetPermissionType(permission_type.c_str(),entity.GetEntityType()); +// type=mc_gState->m_Permissions->GetPermissionType(permission_type.c_str(),entity.GetEntityType()); + type=mc_gState->m_Permissions->GetPermissionType(permission_type.c_str(),&entity); if(type == 0) throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid permission"); @@ -126,7 +127,8 @@ Value grantoperation(const Array& params) } else { - type=mc_gState->m_Permissions->GetPermissionType(permission_type.c_str(),MC_ENT_TYPE_NONE); + type=mc_gState->m_Permissions->GetPermissionType(permission_type.c_str(),&entity); +// type=mc_gState->m_Permissions->GetPermissionType(permission_type.c_str(),MC_ENT_TYPE_NONE); if(type == 0) throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid permission"); @@ -472,7 +474,8 @@ Value listpermissions(const Array& params, bool fHelp) lpEntity=entity.GetTxID(); } - type=mc_gState->m_Permissions->GetPermissionType(permission_type.c_str(),entity.GetEntityType()); +// type=mc_gState->m_Permissions->GetPermissionType(permission_type.c_str(),entity.GetEntityType()); + type=mc_gState->m_Permissions->GetPermissionType(permission_type.c_str(),&entity); if(type == 0) throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid permission"); diff --git a/src/rpc/rpcrawdata.cpp b/src/rpc/rpcrawdata.cpp index 2c5ffa36..f22c50b7 100644 --- a/src/rpc/rpcrawdata.cpp +++ b/src/rpc/rpcrawdata.cpp @@ -525,6 +525,7 @@ CScript RawDataScriptIssue(Value *param,mc_Script *lpDetails,mc_Script *lpDetail string entity_name; int multiple=1; int is_open=0; + uint32_t permissions=0; bool missing_name=true; bool missing_multiple=true; bool missing_open=true; @@ -606,6 +607,38 @@ CScript RawDataScriptIssue(Value *param,mc_Script *lpDetails,mc_Script *lpDetail missing_open=false; field_parsed=true; } + if(d.name_ == "permissions") + { + if(mc_gState->m_Features->PerAssetPermissions() == 0) + { + throw JSONRPCError(RPC_NOT_SUPPORTED, "Per-asset permissions not supported for this protocol version"); + } + if(permissions == 0) + { + if(d.value_.type() == str_type) + { + permissions=mc_gState->m_Permissions->GetPermissionType(d.value_.get_str().c_str(),MC_PTP_SEND | MC_PTP_RECEIVE); + if(permissions == 0) + { + *strError=string("Invalid permission"); + } + } + else + { + *strError=string("Invalid permission"); + } + } + else + { + *strError=string("permissions field can appear only once in the object"); + } + if(permissions) + { + lpDetails->SetSpecialParamValue(MC_ENT_SPRM_PERMISSIONS,(unsigned char*)&permissions,sizeof(uint32_t)); + } + field_parsed=true; + } + if(d.name_ == "details") { if(!missing_details) diff --git a/src/rpc/rpcutils.cpp b/src/rpc/rpcutils.cpp index b2aef927..b26118e8 100644 --- a/src/rpc/rpcutils.cpp +++ b/src/rpc/rpcutils.cpp @@ -486,7 +486,8 @@ Array PermissionEntries(const CTxOut& txout,mc_Script *lpScript,bool fLong) { Object entry; entry.push_back(Pair("for", PermissionForFieldEntry(&entity))); - full_type=mc_gState->m_Permissions->GetPossiblePermissionTypes(entity.GetEntityType()); +// full_type=mc_gState->m_Permissions->GetPossiblePermissionTypes(entity.GetEntityType()); + full_type=mc_gState->m_Permissions->GetPossiblePermissionTypes(&entity); if(full_type & MC_PTP_CONNECT)entry.push_back(Pair("connect", (type & MC_PTP_CONNECT) ? true : false)); if(full_type & MC_PTP_SEND)entry.push_back(Pair("send", (type & MC_PTP_SEND) ? true : false)); if(full_type & MC_PTP_RECEIVE)entry.push_back(Pair("receive", (type & MC_PTP_RECEIVE) ? true : false)); @@ -1005,7 +1006,7 @@ Object AssetEntry(const unsigned char *txid,int64_t quantity,uint32_t output_lev // output_level constants // 0x0000 minimal: name, assetref, non-negative qty, negative actual issueqty // 0x0001 raw -// 0x0002 multiple, units, open, details +// 0x0002 multiple, units, open, details, permissions // 0x0004 issuetxid, // 0x0008 subscribed/synchronized // 0x0020 issuers @@ -1071,9 +1072,11 @@ Object AssetEntry(const unsigned char *txid,int64_t quantity,uint32_t output_lev uint64_t multiple=1; const unsigned char *ptr; double units=1.; + uint32_t permissions; ptr=entity.GetScript(); multiple=genesis_entity.GetAssetMultiple(); + permissions=genesis_entity.Permissions(); units= 1./(double)multiple; if(output_level & 0x0002) { @@ -1089,6 +1092,13 @@ Object AssetEntry(const unsigned char *txid,int64_t quantity,uint32_t output_lev { entry.push_back(Pair("open",false)); } + if(mc_gState->m_Features->PerAssetPermissions()) + { + Object pObject; + pObject.push_back(Pair("send",(permissions & MC_PTP_SEND) ? true : false)); + pObject.push_back(Pair("receive",(permissions & MC_PTP_RECEIVE) ? true : false)); + entry.push_back(Pair("permissions",pObject)); + } } } @@ -1570,7 +1580,8 @@ string ParseRawOutputObject(Value param,CAmount& nAmount,mc_Script *lpScript, in if(type_string.size()) { - type=mc_gState->m_Permissions->GetPermissionType(type_string.c_str(),entity.GetEntityType()); + type=mc_gState->m_Permissions->GetPermissionType(type_string.c_str(),&entity); +// type=mc_gState->m_Permissions->GetPermissionType(type_string.c_str(),entity.GetEntityType()); if(entity.GetEntityType() == MC_ENT_TYPE_NONE) { if(required) diff --git a/src/version/version.cpp b/src/version/version.cpp index df793c07..7f89846f 100644 --- a/src/version/version.cpp +++ b/src/version/version.cpp @@ -7,8 +7,8 @@ int mc_State::VersionInfo(int version) { - int this_build=20000101; - int this_protocol=20001; + int this_build=20000102; + int this_protocol=20002; if(version < 0) { return 0; @@ -32,7 +32,7 @@ int mc_State::VersionInfo(int version) if(version < 10004)return -10000201; // last build supporting this version (negative) if(version < 10010)return -this_build; // supported by this version if(version < 20001)return 20001; // next version - if(version < 20002)return -this_build; // supported by this version + if(version < this_protocol+1)return -this_build; // supported by this version return VersionInfo(MULTICHAIN_VERSION_CODE_BUILD)-1; // Created by the following builds } From 11335e5d3f533520900464b5cc868489271fd5a3 Mon Sep 17 00:00:00 2001 From: mike31 Date: Thu, 9 Nov 2017 17:05:21 +0200 Subject: [PATCH 02/71] Coin selection for per-asset permissions --- src/protocol/multichaintx.cpp | 51 ---------------------------------- src/utils/utilparse.cpp | 52 +++++++++++++++++++++++++++++++++++ src/utils/utilparse.h | 1 + src/wallet/walletcoins.cpp | 24 +++++++++++++++- 4 files changed, 76 insertions(+), 52 deletions(-) diff --git a/src/protocol/multichaintx.cpp b/src/protocol/multichaintx.cpp index 03bc66ef..cc01b815 100644 --- a/src/protocol/multichaintx.cpp +++ b/src/protocol/multichaintx.cpp @@ -48,57 +48,6 @@ uint160 mc_GenesisAdmin(const CTransaction& tx) return 0; } -bool mc_VerifyAssetPermissions(mc_Buffer *assets, vector addressRets, int required_permissions, uint32_t permission, string& reason) -{ - mc_EntityDetails entity; - - for(int i=0;iGetCount();i++) - { - if(mc_gState->m_Assets->FindEntityByFullRef(&entity,assets->GetRow(i))) - { - if( entity.Permissions() & (MC_PTP_SEND | MC_PTP_RECEIVE) ) - { - if(assets->GetCount() > 1) - { - if(permission == MC_PTP_SEND) - { - reason="One of multiple assets in input has per-asset permissions"; - } - if(permission == MC_PTP_RECEIVE) - { - reason="One of multiple assets in output has per-asset permissions"; - } - return false; - } - if(entity.Permissions() & permission) - { - int found=required_permissions; - for(int j=0;j<(int)addressRets.size();j++) - { - if(mc_gState->m_Permissions->GetPermission(entity.GetTxID(),GetAddressIDPtr(addressRets[i]),permission)) - { - found--; - } - } - if(found > 0) - { - if(permission == MC_PTP_SEND) - { - reason="One of the inputs doesn't have per-asset send permission"; - } - if(permission == MC_PTP_RECEIVE) - { - reason="One of the outputs doesn't have per-asset receive permission"; - } - return false; - } - } - } - } - } - - return true; -} bool mc_ExtractInputAssetQuantities(mc_Buffer *assets, const CScript& script1, uint256 hash, string& reason) diff --git a/src/utils/utilparse.cpp b/src/utils/utilparse.cpp index bbe01711..2307ae67 100644 --- a/src/utils/utilparse.cpp +++ b/src/utils/utilparse.cpp @@ -27,6 +27,58 @@ const unsigned char* GetAddressIDPtr(const CTxDestination& address) return aptr; } +bool mc_VerifyAssetPermissions(mc_Buffer *assets, vector addressRets, int required_permissions, uint32_t permission, string& reason) +{ + mc_EntityDetails entity; + + for(int i=0;iGetCount();i++) + { + if(mc_gState->m_Assets->FindEntityByFullRef(&entity,assets->GetRow(i))) + { + if( entity.Permissions() & (MC_PTP_SEND | MC_PTP_RECEIVE) ) + { + if(assets->GetCount() > 1) + { + if(permission == MC_PTP_SEND) + { + reason="One of multiple assets in input has per-asset permissions"; + } + if(permission == MC_PTP_RECEIVE) + { + reason="One of multiple assets in output has per-asset permissions"; + } + return false; + } + if(entity.Permissions() & permission) + { + int found=required_permissions; + for(int j=0;j<(int)addressRets.size();j++) + { + if(mc_gState->m_Permissions->GetPermission(entity.GetTxID(),GetAddressIDPtr(addressRets[i]),permission)) + { + found--; + } + } + if(found > 0) + { + if(permission == MC_PTP_SEND) + { + reason="One of the inputs doesn't have per-asset send permission"; + } + if(permission == MC_PTP_RECEIVE) + { + reason="One of the outputs doesn't have per-asset receive permission"; + } + return false; + } + } + } + } + } + + return true; +} + /* * Parses txout script into asset-quantity buffer diff --git a/src/utils/utilparse.h b/src/utils/utilparse.h index ba7dbd72..00cd3c68 100644 --- a/src/utils/utilparse.h +++ b/src/utils/utilparse.h @@ -20,6 +20,7 @@ void LogAssetTxOut(std::string message,uint256 hash,int index,unsigned char* ass bool AddressCanReceive(CTxDestination address); bool FindFollowOnsInScript(const CScript& script1,mc_Buffer *amounts,mc_Script *lpScript); int CheckRequiredPermissions(const CTxDestination& addressRet,int expected_allowed,std::map* mapSpecialEntity,std::string* strFailReason); +bool mc_VerifyAssetPermissions(mc_Buffer *assets, std::vector addressRets, int required_permissions, uint32_t permission, std::string& reason); diff --git a/src/wallet/walletcoins.cpp b/src/wallet/walletcoins.cpp index cbfd9ba8..305c5cc0 100644 --- a/src/wallet/walletcoins.cpp +++ b/src/wallet/walletcoins.cpp @@ -795,8 +795,30 @@ bool FindRelevantCoins(CWallet *lpWallet, } if(is_relevant) { - if(allowed & MC_PTP_SEND) + if(mc_gState->m_Features->PerAssetPermissions()) { + CTxDestination addressRet; + + if(allowed & MC_PTP_SEND) + { + if(ExtractDestinationScriptValid(txout.scriptPubKey, addressRet)) + { + string strPerAssetFailReason; + + vector addressRets; + addressRets.push_back(addressRet); + + if(!mc_VerifyAssetPermissions(tmp_amounts,addressRets,1,MC_PTP_SEND,strPerAssetFailReason) || + !mc_VerifyAssetPermissions(tmp_amounts,addressRets,1,MC_PTP_RECEIVE,strPerAssetFailReason)) + { + allowed -= MC_PTP_SEND; + } + } + } + } + + if(allowed & MC_PTP_SEND) + { if(!InsertCoinIntoMatrix(coin_id,hash,out_i,tmp_amounts,out_amounts,in_amounts,in_map,in_row,in_size,in_special_row,pure_native)) { strFailReason=_("Internal error: Cannot update input amount matrix"); From cdf178d8be954e3a0eaf6dac73528ff1e2b28aca Mon Sep 17 00:00:00 2001 From: mike31 Date: Sun, 12 Nov 2017 15:08:34 +0200 Subject: [PATCH 03/71] Renaming permissions to restrict --- src/rpc/rpcassets.cpp | 6 +++--- src/rpc/rpcrawdata.cpp | 10 +++++----- src/rpc/rpcutils.cpp | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/rpc/rpcassets.cpp b/src/rpc/rpcassets.cpp index 273c46a8..57972963 100644 --- a/src/rpc/rpcassets.cpp +++ b/src/rpc/rpcassets.cpp @@ -161,7 +161,7 @@ Value issuefromcmd(const Array& params, bool fHelp) throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid value for 'open' field, should be boolean"); } } - if(s.name_ == "permissions") + if(s.name_ == "restrict") { if(mc_gState->m_Features->PerAssetPermissions() == 0) { @@ -174,7 +174,7 @@ Value issuefromcmd(const Array& params, bool fHelp) permissions=mc_gState->m_Permissions->GetPermissionType(s.value_.get_str().c_str(),MC_PTP_SEND | MC_PTP_RECEIVE); if(permissions == 0) { - throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid value for 'permissions' field"); + throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid value for restrict field"); } } } @@ -240,7 +240,7 @@ Value issuefromcmd(const Array& params, bool fHelp) if(permissions) { - lpDetails->SetSpecialParamValue(MC_ENT_SPRM_PERMISSIONS,(unsigned char*)&permissions,sizeof(uint32_t)); + lpDetails->SetSpecialParamValue(MC_ENT_SPRM_PERMISSIONS,(unsigned char*)&permissions,1); } /* diff --git a/src/rpc/rpcrawdata.cpp b/src/rpc/rpcrawdata.cpp index f22c50b7..cfbbef2f 100644 --- a/src/rpc/rpcrawdata.cpp +++ b/src/rpc/rpcrawdata.cpp @@ -607,7 +607,7 @@ CScript RawDataScriptIssue(Value *param,mc_Script *lpDetails,mc_Script *lpDetail missing_open=false; field_parsed=true; } - if(d.name_ == "permissions") + if(d.name_ == "restrict") { if(mc_gState->m_Features->PerAssetPermissions() == 0) { @@ -620,21 +620,21 @@ CScript RawDataScriptIssue(Value *param,mc_Script *lpDetails,mc_Script *lpDetail permissions=mc_gState->m_Permissions->GetPermissionType(d.value_.get_str().c_str(),MC_PTP_SEND | MC_PTP_RECEIVE); if(permissions == 0) { - *strError=string("Invalid permission"); + *strError=string("Invalid restrict"); } } else { - *strError=string("Invalid permission"); + *strError=string("Invalid restrict"); } } else { - *strError=string("permissions field can appear only once in the object"); + *strError=string("restrict field can appear only once in the object"); } if(permissions) { - lpDetails->SetSpecialParamValue(MC_ENT_SPRM_PERMISSIONS,(unsigned char*)&permissions,sizeof(uint32_t)); + lpDetails->SetSpecialParamValue(MC_ENT_SPRM_PERMISSIONS,(unsigned char*)&permissions,1); } field_parsed=true; } diff --git a/src/rpc/rpcutils.cpp b/src/rpc/rpcutils.cpp index b26118e8..459acf87 100644 --- a/src/rpc/rpcutils.cpp +++ b/src/rpc/rpcutils.cpp @@ -1097,7 +1097,7 @@ Object AssetEntry(const unsigned char *txid,int64_t quantity,uint32_t output_lev Object pObject; pObject.push_back(Pair("send",(permissions & MC_PTP_SEND) ? true : false)); pObject.push_back(Pair("receive",(permissions & MC_PTP_RECEIVE) ? true : false)); - entry.push_back(Pair("permissions",pObject)); + entry.push_back(Pair("restrict",pObject)); } } } From 54bb71f3bbfcf916f5f9ba8e8fc6c27b945b3d97 Mon Sep 17 00:00:00 2001 From: mike31 Date: Tue, 14 Nov 2017 11:59:37 +0200 Subject: [PATCH 04/71] Fixed asset permission verification in coin selection --- src/utils/utilparse.cpp | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/src/utils/utilparse.cpp b/src/utils/utilparse.cpp index 2307ae67..b095c1ba 100644 --- a/src/utils/utilparse.cpp +++ b/src/utils/utilparse.cpp @@ -30,6 +30,7 @@ const unsigned char* GetAddressIDPtr(const CTxDestination& address) bool mc_VerifyAssetPermissions(mc_Buffer *assets, vector addressRets, int required_permissions, uint32_t permission, string& reason) { mc_EntityDetails entity; + int asset_count=-1; for(int i=0;iGetCount();i++) { @@ -39,15 +40,29 @@ bool mc_VerifyAssetPermissions(mc_Buffer *assets, vector address { if(assets->GetCount() > 1) { - if(permission == MC_PTP_SEND) + if(asset_count < 0) { - reason="One of multiple assets in input has per-asset permissions"; + asset_count=0; + for(int j=0;jGetCount();j++) + { + if(mc_GetABRefType(assets->GetRow(j)) != MC_AST_ASSET_REF_TYPE_SPECIAL) + { + asset_count++; + } + } } - if(permission == MC_PTP_RECEIVE) + if(asset_count > 1) { - reason="One of multiple assets in output has per-asset permissions"; + if(permission == MC_PTP_SEND) + { + reason="One of multiple assets in input has per-asset permissions"; + } + if(permission == MC_PTP_RECEIVE) + { + reason="One of multiple assets in output has per-asset permissions"; + } + return false; } - return false; } if(entity.Permissions() & permission) { From b0ea35f1cefb497fb07b5cea409cdefda9b24e9c Mon Sep 17 00:00:00 2001 From: mike31 Date: Tue, 14 Nov 2017 15:16:49 +0200 Subject: [PATCH 05/71] Per-output data --- src/protocol/multichainscript.cpp | 80 +++++++++++++++++++++++++++++++ src/protocol/multichainscript.h | 3 ++ src/rpc/rpcblockchain.cpp | 4 +- src/rpc/rpcrawtransaction.cpp | 12 +++++ src/rpc/rpcutils.cpp | 80 ++++++++++++++++++++++++++++++- src/rpc/rpcutils.h | 1 + src/rpc/rpcwalletutils.cpp | 7 +++ 7 files changed, 185 insertions(+), 2 deletions(-) diff --git a/src/protocol/multichainscript.cpp b/src/protocol/multichainscript.cpp index 74429a1b..e77a0431 100644 --- a/src/protocol/multichainscript.cpp +++ b/src/protocol/multichainscript.cpp @@ -2214,6 +2214,86 @@ int mc_Script::SetCachedScript(int offset, int *next_offset, int vin, unsigned c return MC_ERR_NOERROR; } +int mc_Script::GetRawData(unsigned char **data,int *size) +{ + unsigned char *ptr; + unsigned char *ptrEnd; + unsigned char f; + + if(data) + { + *data=NULL; + } + + if(m_CurrentElement<0) + { + return MC_ERR_INVALID_PARAMETER_VALUE; + } + + if(m_lpCoord[m_CurrentElement*2+1] < MC_DCT_SCRIPT_IDENTIFIER_LEN+1+1) + { + return MC_ERR_WRONG_SCRIPT; + } + + ptr=m_lpData+m_lpCoord[m_CurrentElement*2+0]; + ptrEnd=ptr+m_lpCoord[m_CurrentElement*2+1]; + + if(memcmp(ptr,MC_DCT_SCRIPT_MULTICHAIN_IDENTIFIER,MC_DCT_SCRIPT_IDENTIFIER_LEN) != 0) + { + return MC_ERR_WRONG_SCRIPT; + } + + + if(ptr[MC_DCT_SCRIPT_IDENTIFIER_LEN] != MC_DCT_SCRIPT_MULTICHAIN_RAW_DATA_PREFIX) + { + return MC_ERR_WRONG_SCRIPT; + } + + ptr+=MC_DCT_SCRIPT_IDENTIFIER_LEN+1; + + if(data) + { + *data=ptr; + *size=ptrEnd-ptr; + } + + return MC_ERR_NOERROR; +} + +int mc_Script::SetRawData(const unsigned char *data,const int size) +{ + int err; + unsigned char buf[MC_DCT_SCRIPT_IDENTIFIER_LEN+1]; + unsigned char f; + + err=AddElement(); + if(err) + { + return err; + } + + memcpy(buf,MC_DCT_SCRIPT_MULTICHAIN_IDENTIFIER,MC_DCT_SCRIPT_IDENTIFIER_LEN); + buf[MC_DCT_SCRIPT_IDENTIFIER_LEN]=MC_DCT_SCRIPT_MULTICHAIN_RAW_DATA_PREFIX; + buf[MC_DCT_SCRIPT_IDENTIFIER_LEN+1]=f; + + err=SetData(buf,MC_DCT_SCRIPT_IDENTIFIER_LEN+1); + if(err) + { + return err; + } + + if(size) + { + err=SetData(data,size); + if(err) + { + return err; + } + } + + return MC_ERR_NOERROR; +} + int mc_Script::GetDataFormat(uint32_t *format) { unsigned char *ptr; diff --git a/src/protocol/multichainscript.h b/src/protocol/multichainscript.h index b9d09d07..1d651e0b 100644 --- a/src/protocol/multichainscript.h +++ b/src/protocol/multichainscript.h @@ -99,6 +99,9 @@ typedef struct mc_Script int GetCachedScript(int offset, int *next_offset, int* vin, unsigned char** script, int *script_size); int SetCachedScript(int offset, int *next_offset, int vin, unsigned char* script, int script_size); + int GetRawData(unsigned char **data,int *size); + int SetRawData(const unsigned char *data,const int size); + int GetDataFormat(uint32_t *format); int SetDataFormat(const uint32_t format); diff --git a/src/rpc/rpcblockchain.cpp b/src/rpc/rpcblockchain.cpp index 31a605f4..53817a26 100644 --- a/src/rpc/rpcblockchain.cpp +++ b/src/rpc/rpcblockchain.cpp @@ -30,6 +30,7 @@ vector ParseBlockSetIdentifier(Value blockset_identifier); bool CreateAssetBalanceList(const CTxOut& out,mc_Buffer *amounts,mc_Script *lpScript); Object AssetEntry(const unsigned char *txid,int64_t quantity,uint32_t output_level); Array PermissionEntries(const CTxOut& txout,mc_Script *lpScript,bool fLong); +Array PerOutputDataEntries(const CTxOut& txout,mc_Script *lpScript,uint256 txid,int vout); string EncodeHexTx(const CTransaction& tx); int OrphanPoolSize(); bool paramtobool(Value param); @@ -560,7 +561,8 @@ Value gettxout(const Array& params, bool fHelp) } Array permissions=PermissionEntries(txout,lpScript,false); ret.push_back(Pair("permissions", permissions)); - + Array data=PerOutputDataEntries(txout,lpScript,hash,n); + ret.push_back(Pair("data", data)); /* MCHN END */ return ret; diff --git a/src/rpc/rpcrawtransaction.cpp b/src/rpc/rpcrawtransaction.cpp index a376a7ec..508613fc 100644 --- a/src/rpc/rpcrawtransaction.cpp +++ b/src/rpc/rpcrawtransaction.cpp @@ -355,6 +355,11 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, Object& entry) { out.push_back(Pair("permissions", permissions)); } + Array peroutputdata=PerOutputDataEntries(txout,lpScript,tx.GetHash(),i); + if(peroutputdata.size()) + { + out.push_back(Pair("data", peroutputdata)); + } Array items; Value data_item_entry=DataItemEntry(tx,i,streams_already_seen, 0x03); @@ -689,6 +694,13 @@ Value listunspent(const Array& params, bool fHelp) } Array permissions=PermissionEntries(txout,lpScript,false); entry.push_back(Pair("permissions", permissions)); + + Array peroutputdata=PerOutputDataEntries(txout,lpScript,hash,out.i); + if(peroutputdata.size()) + { + entry.push_back(Pair("data", peroutputdata)); + } + // entry.push_back(Pair("spendable", out.fSpendable)); /* MCHN END */ results.push_back(entry); diff --git a/src/rpc/rpcutils.cpp b/src/rpc/rpcutils.cpp index 459acf87..c8551ee2 100644 --- a/src/rpc/rpcutils.cpp +++ b/src/rpc/rpcutils.cpp @@ -446,6 +446,42 @@ Value PermissionForFieldEntry(mc_EntityDetails *lpEntity) return Value::null; } +Array PerOutputDataEntries(const CTxOut& txout,mc_Script *lpScript,uint256 txid,int vout) +{ + Array results; + unsigned char *ptr; + int size; + + if(mc_gState->m_NetworkParams->IsProtocolMultichain() == 0) + { + return results; + } + + const CScript& script1 = txout.scriptPubKey; + CScript::const_iterator pc1 = script1.begin(); + + lpScript->Clear(); + lpScript->SetScript((unsigned char*)(&pc1[0]),(size_t)(script1.end()-pc1),MC_SCR_TYPE_SCRIPTPUBKEY); + + for (int e = 0; e < lpScript->GetNumElements(); e++) + { + lpScript->SetElement(e); + if(lpScript->GetRawData(&ptr,&size) == 0) + { + uint32_t format=MC_SCR_DATA_FORMAT_UNKNOWN; + if(e > 0) + { + lpScript->SetElement(e-1); + lpScript->GetDataFormat(&format); + } + results.push_back(OpReturnFormatEntry(ptr,size,txid,vout,format,NULL)); + } + } + + return results; +} + + Array PermissionEntries(const CTxOut& txout,mc_Script *lpScript,bool fLong) { Array results; @@ -1327,7 +1363,8 @@ string ParseRawOutputObject(Value param,CAmount& nAmount,mc_Script *lpScript, in BOOST_FOREACH(const Pair& a, param.get_obj()) { - if(a.value_.type() == obj_type) + if( (a.value_.type() == obj_type) || + (( (a.value_.type() == str_type) || (a.value_.type() == array_type) ) && (a.name_== "data")) ) { bool parsed=false; @@ -1465,6 +1502,47 @@ string ParseRawOutputObject(Value param,CAmount& nAmount,mc_Script *lpScript, in lpScript->SetAssetQuantities(lpFollowonBuffer,MC_SCR_ASSET_SCRIPT_TYPE_FOLLOWON); parsed=true; } + + if(!parsed && (a.name_ == "data")) + { + Array arr; + if( (a.value_.type() == str_type) || (a.value_.type() == obj_type) ) + { + arr.push_back(a.value_); + } + else + { + if(a.value_.type() == array_type) + { + arr=a.value_.get_array(); + } + } + + for(int i=0;i<(int)arr.size();i++) + { + uint32_t data_format=MC_SCR_DATA_FORMAT_UNKNOWN; + int errorCode=RPC_INVALID_PARAMETER; + + mc_gState->m_TmpScript->Clear(); + + vector vData=ParseRawFormattedData(&(arr[i]),&data_format,mc_gState->m_TmpScript,&errorCode,&strError); + if(strError.size()) + { + if(eErrorCode) + { + *eErrorCode=errorCode; + } + goto exitlbl; + } + + if(data_format != MC_SCR_DATA_FORMAT_UNKNOWN) + { + lpScript->SetDataFormat(data_format); + } + lpScript->SetRawData(&(vData[0]),(int)vData.size()); + } + parsed=true; + } if(!parsed && (a.name_ == "permissions")) { diff --git a/src/rpc/rpcutils.h b/src/rpc/rpcutils.h index a4e3f788..55827c6d 100644 --- a/src/rpc/rpcutils.h +++ b/src/rpc/rpcutils.h @@ -85,6 +85,7 @@ int ParseAssetKeyToFullAssetRef(const char* asset_key,unsigned char *full_asset_ Array AddressEntries(const CTxIn& txin,txnouttype& typeRet,mc_Script *lpScript); Array AddressEntries(const CTxOut& txout,txnouttype& typeRet); Value PermissionForFieldEntry(mc_EntityDetails *lpEntity); +Array PerOutputDataEntries(const CTxOut& txout,mc_Script *lpScript,uint256 txid,int vout); Array PermissionEntries(const CTxOut& txout,mc_Script *lpScript,bool fLong); Object StreamEntry(const unsigned char *txid,uint32_t output_level); Object UpgradeEntry(const unsigned char *txid); diff --git a/src/rpc/rpcwalletutils.cpp b/src/rpc/rpcwalletutils.cpp index 3f93f3b0..bbef8f11 100644 --- a/src/rpc/rpcwalletutils.cpp +++ b/src/rpc/rpcwalletutils.cpp @@ -621,6 +621,7 @@ Object TxOutEntry(const CTxOut& TxOutIn,int vout,const CTxIn& TxIn,uint256 hash, Object txout_entry; Array permissions; + Array peroutputdata; isminetype fIsMine=ISMINE_NO; amounts->Clear(); // int iad=-1; @@ -719,6 +720,12 @@ Object TxOutEntry(const CTxOut& TxOutIn,int vout,const CTxIn& TxIn,uint256 hash, { txout_entry.push_back(Pair("permissions", permissions)); } + + peroutputdata=PerOutputDataEntries(txout,lpScript,hash,vout); + if(peroutputdata.size()) + { + txout_entry.push_back(Pair("data", peroutputdata)); + } } } From ad42aff84a0ded543a9acfaf28d5788775ae9f32 Mon Sep 17 00:00:00 2001 From: mike31 Date: Wed, 15 Nov 2017 14:37:54 +0200 Subject: [PATCH 06/71] Fixed compilation errors in per-output data --- src/protocol/multichainscript.cpp | 3 --- src/rpc/rpcstreams.cpp | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/src/protocol/multichainscript.cpp b/src/protocol/multichainscript.cpp index e77a0431..c0f5b87f 100644 --- a/src/protocol/multichainscript.cpp +++ b/src/protocol/multichainscript.cpp @@ -2218,7 +2218,6 @@ int mc_Script::GetRawData(unsigned char **data,int *size) { unsigned char *ptr; unsigned char *ptrEnd; - unsigned char f; if(data) { @@ -2264,7 +2263,6 @@ int mc_Script::SetRawData(const unsigned char *data,const int size) { int err; unsigned char buf[MC_DCT_SCRIPT_IDENTIFIER_LEN+1]; - unsigned char f; err=AddElement(); if(err) @@ -2274,7 +2272,6 @@ int mc_Script::SetRawData(const unsigned char *data,const int size) memcpy(buf,MC_DCT_SCRIPT_MULTICHAIN_IDENTIFIER,MC_DCT_SCRIPT_IDENTIFIER_LEN); buf[MC_DCT_SCRIPT_IDENTIFIER_LEN]=MC_DCT_SCRIPT_MULTICHAIN_RAW_DATA_PREFIX; - buf[MC_DCT_SCRIPT_IDENTIFIER_LEN+1]=f; err=SetData(buf,MC_DCT_SCRIPT_IDENTIFIER_LEN+1); if(err) diff --git a/src/rpc/rpcstreams.cpp b/src/rpc/rpcstreams.cpp index 47ec0153..13a3d5be 100644 --- a/src/rpc/rpcstreams.cpp +++ b/src/rpc/rpcstreams.cpp @@ -988,7 +988,7 @@ int mc_GetHashAndFirstOutput(mc_TxEntityRow *lpEntTx,uint256 *hash) erow.m_Pos=lpEntTx->m_Pos; first_output=(int)mc_GetLE(lpEntTx->m_TxId+MC_TEE_OFFSET_IN_TXID,sizeof(uint32_t)); count=(int)mc_GetLE(lpEntTx->m_TxId+MC_TEE_OFFSET_IN_TXID+sizeof(uint32_t),sizeof(uint32_t)); - if(erow.m_Pos > count) + if((int)erow.m_Pos > count) { erow.m_Pos-=count; if(pwalletTxsMain->GetRow(&erow) == 0) From 042171d09b92a037614c9118cdd1aeb26b1a6ebb Mon Sep 17 00:00:00 2001 From: mike31 Date: Thu, 16 Nov 2017 12:53:40 +0200 Subject: [PATCH 07/71] Allowed per-output formatted data for old protocols --- src/rpc/rpcrawdata.cpp | 8 ++++---- src/rpc/rpcstreams.cpp | 2 +- src/rpc/rpcutils.cpp | 2 +- src/rpc/rpcutils.h | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/rpc/rpcrawdata.cpp b/src/rpc/rpcrawdata.cpp index cfbbef2f..8ff9a43d 100644 --- a/src/rpc/rpcrawdata.cpp +++ b/src/rpc/rpcrawdata.cpp @@ -283,7 +283,7 @@ CScript RawDataScriptRawHex(Value *param,int *errorCode,string *strError) return scriptOpReturn; } -vector ParseRawFormattedData(const Value *value,uint32_t *data_format,mc_Script *lpDetailsScript,int *errorCode,string *strError) +vector ParseRawFormattedData(const Value *value,uint32_t *data_format,mc_Script *lpDetailsScript,bool allow_formatted,int *errorCode,string *strError) { vector vValue; if(value->type() == str_type) @@ -302,7 +302,7 @@ vector ParseRawFormattedData(const Value *value,uint32_t *data_fo } else { - if(mc_gState->m_Features->FormattedData()) + if(allow_formatted || (mc_gState->m_Features->FormattedData() != 0) ) { if(value->type() == obj_type) { @@ -486,7 +486,7 @@ CScript RawDataScriptFormatted(Value *param,uint32_t *data_format,mc_Script *lpD { *strError=string("data object should have single key - json or text"); } - vValue=ParseRawFormattedData(param,data_format,lpDetailsScript,errorCode,strError); + vValue=ParseRawFormattedData(param,data_format,lpDetailsScript,false,errorCode,strError); field_parsed=true; missing_data=false; } @@ -1100,7 +1100,7 @@ CScript RawDataScriptPublish(Value *param,mc_EntityDetails *entity,uint32_t *dat { *strError=string("data field can appear only once in the object"); } - vValue=ParseRawFormattedData(&(d.value_),data_format,lpDetailsScript,errorCode,strError); + vValue=ParseRawFormattedData(&(d.value_),data_format,lpDetailsScript,false,errorCode,strError); field_parsed=true; missing_data=false; } diff --git a/src/rpc/rpcstreams.cpp b/src/rpc/rpcstreams.cpp index 13a3d5be..af25338c 100644 --- a/src/rpc/rpcstreams.cpp +++ b/src/rpc/rpcstreams.cpp @@ -652,7 +652,7 @@ Value publishfrom(const Array& params, bool fHelp) string strError; int errorCode=RPC_INVALID_PARAMETER; - dataData=ParseRawFormattedData(&(params[3]),&data_format,lpDetailsScript,&errorCode,&strError); + dataData=ParseRawFormattedData(&(params[3]),&data_format,lpDetailsScript,false,&errorCode,&strError); if(strError.size()) { diff --git a/src/rpc/rpcutils.cpp b/src/rpc/rpcutils.cpp index c8551ee2..7907c874 100644 --- a/src/rpc/rpcutils.cpp +++ b/src/rpc/rpcutils.cpp @@ -1525,7 +1525,7 @@ string ParseRawOutputObject(Value param,CAmount& nAmount,mc_Script *lpScript, in mc_gState->m_TmpScript->Clear(); - vector vData=ParseRawFormattedData(&(arr[i]),&data_format,mc_gState->m_TmpScript,&errorCode,&strError); + vector vData=ParseRawFormattedData(&(arr[i]),&data_format,mc_gState->m_TmpScript,true,&errorCode,&strError); if(strError.size()) { if(eErrorCode) diff --git a/src/rpc/rpcutils.h b/src/rpc/rpcutils.h index 55827c6d..50d72971 100644 --- a/src/rpc/rpcutils.h +++ b/src/rpc/rpcutils.h @@ -108,7 +108,7 @@ void ParseRawAction(string action,bool& lock_it, bool& sign_it,bool& send_it); bool paramtobool(Value param); int paramtoint(Value param,bool check_for_min,int min_value,string error_message); vector ParseBlockSetIdentifier(Value blockset_identifier); -vector ParseRawFormattedData(const Value *value,uint32_t *data_format,mc_Script *lpDetailsScript,int *errorCode,string *strError); +vector ParseRawFormattedData(const Value *value,uint32_t *data_format,mc_Script *lpDetailsScript,bool allow_formatted,int *errorCode,string *strError); void ParseRawDetails(const Value *value,mc_Script *lpDetails,mc_Script *lpDetailsScript,int *errorCode,string *strError); bool mc_IsJsonObjectForMerge(const Value *value,int level); Value mc_MergeValues(const Value *value1,const Value *value2,uint32_t mode,int level,int *error); From e26fdf6f59db9562c23c3fc9252a68ee98f71c5d Mon Sep 17 00:00:00 2001 From: mike31 Date: Thu, 16 Nov 2017 14:51:37 +0200 Subject: [PATCH 08/71] Hiding empty arrays in gettxout --- src/rpc/rpcblockchain.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/rpc/rpcblockchain.cpp b/src/rpc/rpcblockchain.cpp index 53817a26..92650790 100644 --- a/src/rpc/rpcblockchain.cpp +++ b/src/rpc/rpcblockchain.cpp @@ -557,12 +557,21 @@ Value gettxout(const Array& params, bool fHelp) assets.push_back(asset_entry); } - ret.push_back(Pair("assets", assets)); + if( (assets.size() > 0) || (mc_gState->m_Compatibility & MC_VCM_1_0) ) + { + ret.push_back(Pair("assets", assets)); + } } Array permissions=PermissionEntries(txout,lpScript,false); - ret.push_back(Pair("permissions", permissions)); + if( (permissions.size() > 0) || (mc_gState->m_Compatibility & MC_VCM_1_0) ) + { + ret.push_back(Pair("permissions", permissions)); + } Array data=PerOutputDataEntries(txout,lpScript,hash,n); - ret.push_back(Pair("data", data)); + if(data.size()) + { + ret.push_back(Pair("data", data)); + } /* MCHN END */ return ret; From af4d6eb7d11c9d28293acebc42de24c4ee1fb5be Mon Sep 17 00:00:00 2001 From: mike31 Date: Sun, 19 Nov 2017 13:42:02 +0200 Subject: [PATCH 09/71] Fixed undefined behavior bug --- src/permissions/permission.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/permissions/permission.cpp b/src/permissions/permission.cpp index 3903bd58..3c36752a 100644 --- a/src/permissions/permission.cpp +++ b/src/permissions/permission.cpp @@ -3047,7 +3047,7 @@ int mc_Permissions::SetPermissionInternal(const void* lpEntity,const void* lpAdd mc_PermissionLedgerRow pldLast; int err,i,num_types,thisBlock,lastAllowed,thisAllowed; char msg[256]; - uint32_t types[9]; + uint32_t types[32]; uint32_t pr_entity,pr_address,pr_admin; num_types=0; types[num_types]=MC_PTP_CONNECT;num_types++; From e43c3437ccbe94975af8c31a82a6185da9abefff Mon Sep 17 00:00:00 2001 From: mike31 Date: Sun, 19 Nov 2017 13:47:39 +0200 Subject: [PATCH 10/71] Fixed lost asset subscription on rescan --- src/core/init.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/init.cpp b/src/core/init.cpp index 1ef1c53c..2f1d16b1 100644 --- a/src/core/init.cpp +++ b/src/core/init.cpp @@ -1385,6 +1385,7 @@ bool AppInit2(boost::thread_group& threadGroup,int OutputPipe) case MC_TET_STREAM: case MC_TET_STREAM_KEY: case MC_TET_STREAM_PUBLISHER: + case MC_TET_ASSET: vSubscribedEntities.push_back(stat->m_Entity); break; } From c23d287642d4dbd957f55e9b57bdacddab16fba4 Mon Sep 17 00:00:00 2001 From: mike31 Date: Mon, 20 Nov 2017 18:12:13 +0200 Subject: [PATCH 11/71] Asset grouping with per-asset permissions --- src/rpc/rpchelp.cpp | 2 +- src/wallet/wallet.h | 2 + src/wallet/walletcoins.cpp | 106 ++++++++++++++++++++++++++++++++----- 3 files changed, 96 insertions(+), 14 deletions(-) diff --git a/src/rpc/rpchelp.cpp b/src/rpc/rpchelp.cpp index 8bfe2813..8504b30f 100644 --- a/src/rpc/rpchelp.cpp +++ b/src/rpc/rpchelp.cpp @@ -2895,7 +2895,7 @@ void mc_InitRPCHelpMap13() " \"asset-identifier\" : asset-quantity\n" " ,...\n" " }\n" - "2. lock (boolean, optiona, default=true) Lock prepared unspent output\n" + "2. lock (boolean, optional, default=true) Lock prepared unspent output\n" "\nResult:\n" "{\n" " \"txid\": \"transactionid\", (string) Transaction ID of the output which can be spent in createrawexchange or createrawexchange\n" diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 1e420fca..811fe57b 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -179,6 +179,7 @@ class CAssetGroupTree int nMaxAssetsPerGroup; int nOptimalGroupCount; int nMode; + int nSingleAssetGroupCount; void Clear(); void Destroy(); @@ -187,6 +188,7 @@ class CAssetGroupTree int *lpTmpGroupBuffer; CAssetGroup *FindAndShiftBestGroup(int assets); + CAssetGroup *AddSingleAssetGroup(unsigned char *assetRef); public: diff --git a/src/wallet/walletcoins.cpp b/src/wallet/walletcoins.cpp index 305c5cc0..7ff3953b 100644 --- a/src/wallet/walletcoins.cpp +++ b/src/wallet/walletcoins.cpp @@ -16,7 +16,7 @@ extern mc_WalletTxs* pwalletTxsMain; using namespace std; -bool debug_print=false; +bool debug_print=true; bool csperf_debug_print=false; void CAssetGroupTree::Clear() @@ -25,6 +25,7 @@ void CAssetGroupTree::Clear() nMaxAssetsPerGroup=0; nOptimalGroupCount=0; nMode=0; + nSingleAssetGroupCount=0; lpAssets=NULL; lpAssetGroups=NULL; lpTmpGroupBuffer=NULL; @@ -52,10 +53,12 @@ void CAssetGroupTree::Dump() CAssetGroup *thisGroup; int *aptr; unsigned char *assetrefbin; - int i,j; + int i,j,s; - if(debug_print)printf("Asset Grouping. Group Size: %d. Group Count: %d\n",nAssetsPerGroup,lpAssetGroups->GetCount()-1); - if(fDebug)LogPrint("mchn","mchn: Asset Grouping. Group Size: %d. Group Count: %d\n",nAssetsPerGroup,lpAssetGroups->GetCount()-1); + if(debug_print)printf("Asset Grouping. Assets: %d. Group Size: %d. Group Count: %d. Single-Asset Groups: %d.\n", + lpAssets->GetCount(),nAssetsPerGroup,lpAssetGroups->GetCount()-1,nSingleAssetGroupCount); + if(fDebug)LogPrint("mchn","mchn: Asset Grouping. Assets: %d. Group Size: %d. Group Count: %d. Single-Asset Groups: %d.\n", + lpAssets->GetCount(),nAssetsPerGroup,lpAssetGroups->GetCount()-1,nSingleAssetGroupCount); for(i=1;iGetCount();i++) { thisGroup=(CAssetGroup*)lpAssetGroups->GetRow(i); @@ -63,7 +66,12 @@ void CAssetGroupTree::Dump() { printf("Group: %4d. Asset Count: %d\n",i,thisGroup->nSize); aptr=(int*)(lpAssetGroups->GetRow(i)+sizeof(CAssetGroup)); - for(j=0;jnSize;j++) + s=thisGroup->nSize; + if(s<0) + { + s=1; + } + for(j=0;jGetRow(aptr[j]); @@ -102,8 +110,7 @@ int CAssetGroupTree::Resize(int newAssets) CAssetGroup *thisGroup; n=nAssetsPerGroup; - - while(nOptimalGroupCount*n < lpAssets->GetCount()+newAssets) + while(nOptimalGroupCount*n < lpAssets->GetCount()+newAssets-nSingleAssetGroupCount) { n*=2; } @@ -276,7 +283,6 @@ CAssetGroup *CAssetGroupTree::FindAndShiftBestGroup(int assets) thisGroup->nNextGroup=0; // The group is full } - return thisGroup; } @@ -297,13 +303,14 @@ int CAssetGroupTree::GetGroup(mc_Buffer* assets, int addIfNeeded) return -1; } - int group_id,last_asset_count,new_asset_count; + int group_id,last_asset_count,new_asset_count,only_asset; int i,g; int *iptr; int *aptr; unsigned char *assetRef; CAssetGroup *thisGroup; + only_asset=-1; group_id=-2; // No assets in this buffer last_asset_count=lpAssets->GetCount(); for(i=0;iGetCount();i++) @@ -314,6 +321,14 @@ int CAssetGroupTree::GetGroup(mc_Buffer* assets, int addIfNeeded) (mc_GetABRefType(assetRef) != MC_AST_ASSET_REF_TYPE_GENESIS) ) // if(mc_GetLE(assetRef,4) > 0) { + if(only_asset == -1) + { + only_asset=i; + } + else + { + only_asset=-2; // More than one asset + } g=GetGroup(assetRef,0); if(g>0) { @@ -361,7 +376,17 @@ int CAssetGroupTree::GetGroup(mc_Buffer* assets, int addIfNeeded) thisGroup=NULL; - Resize(new_asset_count - last_asset_count); + if(only_asset >= 0) // Assets which cannot be combined with other + { + thisGroup=AddSingleAssetGroup(assets->GetRow(only_asset)); + if(thisGroup) + { + return thisGroup->nThisGroup; + } + } + +// Resize(new_asset_count - last_asset_count); + Resize(0); // Assets already added if(group_id > 0) // There are old assets, so we know what should be group id { @@ -426,6 +451,47 @@ int CAssetGroupTree::GetGroup(mc_Buffer* assets, int addIfNeeded) return 0; } + +/* + * Returns group id of the asset + * Adds single assets + */ + +CAssetGroup *CAssetGroupTree::AddSingleAssetGroup(unsigned char *assetRef) +{ + mc_EntityDetails entity; + int group_id,asset_id; + int *aptr; + if(mc_gState->m_Features->PerAssetPermissions()) + { + if(mc_gState->m_Assets->FindEntityByFullRef(&entity,assetRef)) + { + if( entity.Permissions() & (MC_PTP_SEND | MC_PTP_RECEIVE) ) + { + asset_id=lpAssets->GetCount()-1; + group_id=lpAssetGroups->GetCount(); + CAssetGroup assetGroup; + assetGroup.nThisGroup=group_id; + assetGroup.nNextGroup=0; + assetGroup.nSize=-1; + memset(lpTmpGroupBuffer,0,nAssetsPerGroup*sizeof(int)); + if(lpAssetGroups->Add(&assetGroup,lpTmpGroupBuffer)) + { + return NULL; + } + *(int*)(lpAssets->GetRow(asset_id)+MC_AST_ASSET_QUANTITY_OFFSET)=group_id; + aptr=(int*)(lpAssetGroups->GetRow(group_id)+sizeof(CAssetGroup)); + aptr[0]=asset_id; + nSingleAssetGroupCount++; + return (CAssetGroup *)(lpAssetGroups->GetRow(group_id)); + } + } + } + + return NULL; +} + + /* * Returns group id of the asset * Adds to the groups if addIfNeeded==1 @@ -2508,7 +2574,7 @@ bool CWallet::InitializeUnspentList() int max_assets_per_group=assets_per_opdrop*MCP_STD_OP_DROP_COUNT; lpAssetGroups->Initialize(1,max_assets_per_group,32,1); - + vector vCoins; mc_Buffer *tmp_amounts; @@ -2532,8 +2598,22 @@ bool CWallet::InitializeUnspentList() ParseMultichainTxOutToBuffer(hash,txout,tmp_amounts,lpScript,NULL,NULL,strError); } asset_count=tmp_amounts->GetCount(); - if(asset_count) // Resize asset grouping to prevent crazy autocombine on - // already autocombined with higher assets-per-group setting + if(mc_gState->m_Features->PerAssetPermissions()) + { + mc_EntityDetails entity; + for(int i=0;iGetCount();i++) + { + if(mc_gState->m_Assets->FindEntityByFullRef(&entity,tmp_amounts->GetRow(i))) + { + if( entity.Permissions() & (MC_PTP_SEND | MC_PTP_RECEIVE) ) + { + asset_count--; + } + } + } + } + if(asset_count > 0) // Resize asset grouping to prevent crazy autocombine on + // already autocombined with higher assets-per-group setting { lpAssetGroups->Resize(asset_count); } From 42e91f4f536dafb56e25b3305cc7018dd2aec923 Mon Sep 17 00:00:00 2001 From: mike31 Date: Tue, 21 Nov 2017 10:25:02 +0200 Subject: [PATCH 12/71] Protocol: no issue/transfer mixture, per-asset permissions for followons --- src/protocol/multichaintx.cpp | 40 ++++++++++++++++++++++++++++++----- src/wallet/walletcoins.cpp | 2 +- 2 files changed, 36 insertions(+), 6 deletions(-) diff --git a/src/protocol/multichaintx.cpp b/src/protocol/multichaintx.cpp index cc01b815..e8fddc2a 100644 --- a/src/protocol/multichaintx.cpp +++ b/src/protocol/multichaintx.cpp @@ -117,13 +117,18 @@ bool mc_ExtractInputAssetQuantities(mc_Buffer *assets, const CScript& script1, u return true; } -bool mc_ExtractOutputAssetQuantities(mc_Buffer *assets,string& reason) +bool mc_ExtractOutputAssetQuantities(mc_Buffer *assets,string& reason,bool with_followons) { int err; + uint32_t script_type=MC_SCR_ASSET_SCRIPT_TYPE_TRANSFER; + if(with_followons) + { + script_type |= MC_SCR_ASSET_SCRIPT_TYPE_FOLLOWON; + } for (int e = 0; e < mc_gState->m_TmpScript->GetNumElements(); e++) { mc_gState->m_TmpScript->SetElement(e); - err=mc_gState->m_TmpScript->GetAssetQuantities(assets,MC_SCR_ASSET_SCRIPT_TYPE_TRANSFER); + err=mc_gState->m_TmpScript->GetAssetQuantities(assets,script_type); if((err != MC_ERR_NOERROR) && (err != MC_ERR_WRONG_SCRIPT)) { reason="Asset transfer script rejected - error in output transfer script"; @@ -221,7 +226,7 @@ bool AcceptAssetGenesisFromPredefinedIssuers(const CTransaction &tx, int err; int64_t quantity,total; uint256 txid; - bool new_issue,follow_on; + bool new_issue,follow_on,issue_in_output; int details_script_type; unsigned char *ptrOut; vector issuers; @@ -379,12 +384,16 @@ bool AcceptAssetGenesisFromPredefinedIssuers(const CTransaction &tx, } else { + mc_gState->m_TmpAssetsTmp->Clear(); + issue_in_output=false; + for (int e = 0; e < mc_gState->m_TmpScript->GetNumElements(); e++) { mc_gState->m_TmpScript->SetElement(e); err=mc_gState->m_TmpScript->GetAssetGenesis(&quantity); if(err == 0) { + issue_in_output=true; new_issue=true; if(quantity+total<0) { @@ -430,6 +439,16 @@ bool AcceptAssetGenesisFromPredefinedIssuers(const CTransaction &tx, reason="Asset issue script rejected - error in script"; return false; } + if(mc_gState->m_Features->PerAssetPermissions()) + { + err=mc_gState->m_TmpScript->GetAssetQuantities(mc_gState->m_TmpAssetsTmp,MC_SCR_ASSET_SCRIPT_TYPE_TRANSFER); + if((err != MC_ERR_NOERROR) && (err != MC_ERR_WRONG_SCRIPT)) + { + reason="Script rejected - error in asset transfer script"; + return false; + } + } + err=mc_gState->m_TmpScript->GetAssetQuantities(mc_gState->m_TmpAssetsOut,MC_SCR_ASSET_SCRIPT_TYPE_FOLLOWON); if((err != MC_ERR_NOERROR) && (err != MC_ERR_WRONG_SCRIPT)) { @@ -446,6 +465,17 @@ bool AcceptAssetGenesisFromPredefinedIssuers(const CTransaction &tx, } } } + if(issue_in_output) + { + if(mc_gState->m_Features->PerAssetPermissions()) + { + if(mc_gState->m_TmpAssetsTmp->GetCount()) + { + reason="Asset issue script rejected - asset transfer in script"; + return false; + } + } + } } } @@ -1693,7 +1723,7 @@ bool AcceptMultiChainTransaction(const CTransaction& tx, if(mc_gState->m_Features->PerAssetPermissions()) { mc_gState->m_TmpAssetsTmp->Clear(); - if(!mc_ExtractOutputAssetQuantities(mc_gState->m_TmpAssetsTmp,reason)) // Filling output asset quantity list + if(!mc_ExtractOutputAssetQuantities(mc_gState->m_TmpAssetsTmp,reason,true)) { fReject=true; goto exitlbl; @@ -1703,7 +1733,7 @@ bool AcceptMultiChainTransaction(const CTransaction& tx, return false; } } - if(!mc_ExtractOutputAssetQuantities(mc_gState->m_TmpAssetsOut,reason)) // Filling output asset quantity list + if(!mc_ExtractOutputAssetQuantities(mc_gState->m_TmpAssetsOut,reason,false)) // Filling output asset quantity list { fReject=true; goto exitlbl; diff --git a/src/wallet/walletcoins.cpp b/src/wallet/walletcoins.cpp index 7ff3953b..22d1eb3c 100644 --- a/src/wallet/walletcoins.cpp +++ b/src/wallet/walletcoins.cpp @@ -16,7 +16,7 @@ extern mc_WalletTxs* pwalletTxsMain; using namespace std; -bool debug_print=true; +bool debug_print=false; bool csperf_debug_print=false; void CAssetGroupTree::Clear() From ffcfd299ee0ae51ff6ddc36d10ec34ba3f39cf6e Mon Sep 17 00:00:00 2001 From: mike31 Date: Tue, 21 Nov 2017 11:08:35 +0200 Subject: [PATCH 13/71] Checking asset restrictions in asset groupin regardless of protocol --- src/wallet/walletcoins.cpp | 36 +++++++++++++++++------------------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/src/wallet/walletcoins.cpp b/src/wallet/walletcoins.cpp index 22d1eb3c..28759f8d 100644 --- a/src/wallet/walletcoins.cpp +++ b/src/wallet/walletcoins.cpp @@ -462,29 +462,27 @@ CAssetGroup *CAssetGroupTree::AddSingleAssetGroup(unsigned char *assetRef) mc_EntityDetails entity; int group_id,asset_id; int *aptr; - if(mc_gState->m_Features->PerAssetPermissions()) + + if(mc_gState->m_Assets->FindEntityByFullRef(&entity,assetRef)) { - if(mc_gState->m_Assets->FindEntityByFullRef(&entity,assetRef)) + if( entity.Permissions() & (MC_PTP_SEND | MC_PTP_RECEIVE) ) { - if( entity.Permissions() & (MC_PTP_SEND | MC_PTP_RECEIVE) ) + asset_id=lpAssets->GetCount()-1; + group_id=lpAssetGroups->GetCount(); + CAssetGroup assetGroup; + assetGroup.nThisGroup=group_id; + assetGroup.nNextGroup=0; + assetGroup.nSize=-1; + memset(lpTmpGroupBuffer,0,nAssetsPerGroup*sizeof(int)); + if(lpAssetGroups->Add(&assetGroup,lpTmpGroupBuffer)) { - asset_id=lpAssets->GetCount()-1; - group_id=lpAssetGroups->GetCount(); - CAssetGroup assetGroup; - assetGroup.nThisGroup=group_id; - assetGroup.nNextGroup=0; - assetGroup.nSize=-1; - memset(lpTmpGroupBuffer,0,nAssetsPerGroup*sizeof(int)); - if(lpAssetGroups->Add(&assetGroup,lpTmpGroupBuffer)) - { - return NULL; - } - *(int*)(lpAssets->GetRow(asset_id)+MC_AST_ASSET_QUANTITY_OFFSET)=group_id; - aptr=(int*)(lpAssetGroups->GetRow(group_id)+sizeof(CAssetGroup)); - aptr[0]=asset_id; - nSingleAssetGroupCount++; - return (CAssetGroup *)(lpAssetGroups->GetRow(group_id)); + return NULL; } + *(int*)(lpAssets->GetRow(asset_id)+MC_AST_ASSET_QUANTITY_OFFSET)=group_id; + aptr=(int*)(lpAssetGroups->GetRow(group_id)+sizeof(CAssetGroup)); + aptr[0]=asset_id; + nSingleAssetGroupCount++; + return (CAssetGroup *)(lpAssetGroups->GetRow(group_id)); } } From 2949ae1d082b7c84808cece25adddfcd5a5c36a3 Mon Sep 17 00:00:00 2001 From: mike31 Date: Tue, 21 Nov 2017 15:39:48 +0200 Subject: [PATCH 14/71] Checking output permissions in coin selection --- src/protocol/multichaintx.cpp | 21 ------ src/utils/utilparse.cpp | 22 ++++++ src/utils/utilparse.h | 1 + src/wallet/walletcoins.cpp | 129 ++++++++++++++++++++++++++++++++++ 4 files changed, 152 insertions(+), 21 deletions(-) diff --git a/src/protocol/multichaintx.cpp b/src/protocol/multichaintx.cpp index e8fddc2a..9479b62c 100644 --- a/src/protocol/multichaintx.cpp +++ b/src/protocol/multichaintx.cpp @@ -117,27 +117,6 @@ bool mc_ExtractInputAssetQuantities(mc_Buffer *assets, const CScript& script1, u return true; } -bool mc_ExtractOutputAssetQuantities(mc_Buffer *assets,string& reason,bool with_followons) -{ - int err; - uint32_t script_type=MC_SCR_ASSET_SCRIPT_TYPE_TRANSFER; - if(with_followons) - { - script_type |= MC_SCR_ASSET_SCRIPT_TYPE_FOLLOWON; - } - for (int e = 0; e < mc_gState->m_TmpScript->GetNumElements(); e++) - { - mc_gState->m_TmpScript->SetElement(e); - err=mc_gState->m_TmpScript->GetAssetQuantities(assets,script_type); - if((err != MC_ERR_NOERROR) && (err != MC_ERR_WRONG_SCRIPT)) - { - reason="Asset transfer script rejected - error in output transfer script"; - return false; - } - } - - return true; -} bool mc_CompareAssetQuantities(string& reason) { diff --git a/src/utils/utilparse.cpp b/src/utils/utilparse.cpp index b095c1ba..10dc9469 100644 --- a/src/utils/utilparse.cpp +++ b/src/utils/utilparse.cpp @@ -27,6 +27,28 @@ const unsigned char* GetAddressIDPtr(const CTxDestination& address) return aptr; } +bool mc_ExtractOutputAssetQuantities(mc_Buffer *assets,string& reason,bool with_followons) +{ + int err; + uint32_t script_type=MC_SCR_ASSET_SCRIPT_TYPE_TRANSFER; + if(with_followons) + { + script_type |= MC_SCR_ASSET_SCRIPT_TYPE_FOLLOWON; + } + for (int e = 0; e < mc_gState->m_TmpScript->GetNumElements(); e++) + { + mc_gState->m_TmpScript->SetElement(e); + err=mc_gState->m_TmpScript->GetAssetQuantities(assets,script_type); + if((err != MC_ERR_NOERROR) && (err != MC_ERR_WRONG_SCRIPT)) + { + reason="Asset transfer script rejected - error in output transfer script"; + return false; + } + } + + return true; +} + bool mc_VerifyAssetPermissions(mc_Buffer *assets, vector addressRets, int required_permissions, uint32_t permission, string& reason) { mc_EntityDetails entity; diff --git a/src/utils/utilparse.h b/src/utils/utilparse.h index 00cd3c68..41c76e8e 100644 --- a/src/utils/utilparse.h +++ b/src/utils/utilparse.h @@ -21,6 +21,7 @@ bool AddressCanReceive(CTxDestination address); bool FindFollowOnsInScript(const CScript& script1,mc_Buffer *amounts,mc_Script *lpScript); int CheckRequiredPermissions(const CTxDestination& addressRet,int expected_allowed,std::map* mapSpecialEntity,std::string* strFailReason); bool mc_VerifyAssetPermissions(mc_Buffer *assets, std::vector addressRets, int required_permissions, uint32_t permission, std::string& reason); +bool mc_ExtractOutputAssetQuantities(mc_Buffer *assets,std::string& reason,bool with_followons); diff --git a/src/wallet/walletcoins.cpp b/src/wallet/walletcoins.cpp index 28759f8d..69dc8017 100644 --- a/src/wallet/walletcoins.cpp +++ b/src/wallet/walletcoins.cpp @@ -1921,6 +1921,130 @@ CAmount BuildAssetTransaction(CWallet *lpWallet, return 0; } +bool CheckOutputPermissions(const vector >& vecSend,mc_Buffer *tmp_amounts,std::string& strFailReason,int *eErrorCode) +{ + int receive_required; + int64_t quantity; + int err; + bool fIsMaybePurePermission,fIsGenesis; + + BOOST_FOREACH (const PAIRTYPE(CScript, CAmount)& s, vecSend) + { + txnouttype typeRet; + int nRequiredRet; + vector addressRets; + if(!ExtractDestinations(s.first,typeRet,addressRets,nRequiredRet)) + { + if(typeRet != TX_NULL_DATA) + { + strFailReason="Non-standard outputs are not supported in coin selection"; + *eErrorCode=RPC_INTERNAL_ERROR; + return false; + } + } + if(addressRets.size()>0) + { + receive_required=addressRets.size(); + if(typeRet == TX_MULTISIG) + { + receive_required-=nRequiredRet; + receive_required+=1; + if(receive_required>(int)addressRets.size()) + { + receive_required=addressRets.size(); + } + } + + CScript::const_iterator pc1 = s.first.begin(); + + mc_gState->m_TmpScript->Clear(); + mc_gState->m_TmpScript->SetScript((unsigned char*)(&pc1[0]),(size_t)(s.first.end()-pc1),MC_SCR_TYPE_SCRIPTPUBKEY); + + tmp_amounts->Clear(); + if(!mc_ExtractOutputAssetQuantities(tmp_amounts,strFailReason,true)) + { + *eErrorCode=RPC_INTERNAL_ERROR; + return false; + } + if(!mc_VerifyAssetPermissions(tmp_amounts,addressRets,receive_required,MC_PTP_RECEIVE,strFailReason)) + { + *eErrorCode=RPC_NOT_ALLOWED; + return false; + } + + fIsMaybePurePermission=true; + fIsGenesis=false; + for (int e = 0; e < mc_gState->m_TmpScript->GetNumElements(); e++) + { + mc_gState->m_TmpScript->SetElement(e); + err=mc_gState->m_TmpScript->GetAssetGenesis(&quantity); + if(err == 0) + { + fIsGenesis=true; + fIsMaybePurePermission=false; + } + err=mc_gState->m_TmpScript->GetRawData(NULL,NULL); + if(err == 0) + { + fIsMaybePurePermission=false; + } + } + + if(tmp_amounts->GetCount()) + { + if(fIsGenesis) + { + strFailReason="Asset issuance and asset transfer are not allowed in one output"; + *eErrorCode=RPC_NOT_ALLOWED; + return false; + } + fIsMaybePurePermission=false; + } + + if( (s.second > 0) || + !fIsMaybePurePermission || + (mc_gState->m_Features->AnyoneCanReceiveEmpty() == 0) ) + { + for(int a=0;a<(int)addressRets.size();a++) + { + CKeyID *lpKeyID=boost::get (&addressRets[a]); + CScriptID *lpScriptID=boost::get (&addressRets[a]); + if((lpKeyID == NULL) && (lpScriptID == NULL)) + { + strFailReason="Wrong destination type"; + *eErrorCode=RPC_INTERNAL_ERROR; + return false; + } + unsigned char* ptr=NULL; + if(lpKeyID != NULL) + { + ptr=(unsigned char*)(lpKeyID); + } + else + { + ptr=(unsigned char*)(lpScriptID); + } + + bool fCanReceive=mc_gState->m_Permissions->CanReceive(NULL,ptr); + + if(fCanReceive) + { + receive_required--; + } + } + if(receive_required>0) + { + strFailReason="One of the outputs doesn't have receive permission"; + *eErrorCode=RPC_INSUFFICIENT_PERMISSIONS; + return false; + } + } + } + } + + return true; +} + bool CreateAssetGroupingTransaction(CWallet *lpWallet, const vector >& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet, std::string& strFailReason, const CCoinControl* coinControl, const set* addresses,int min_conf,int min_inputs,int max_inputs,const vector* lpCoinsToUse,uint32_t flags,int *eErrorCode) @@ -2004,6 +2128,11 @@ bool CreateAssetGroupingTransaction(CWallet *lpWallet, const vectorsize() != 1) ) { From e7bc4e4958253046897ba8d4333f7ad4a85b8e67 Mon Sep 17 00:00:00 2001 From: mike31 Date: Tue, 21 Nov 2017 17:53:51 +0200 Subject: [PATCH 15/71] gettxoutdata for inline metadata --- src/rpc/rpcwallet.cpp | 44 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 35 insertions(+), 9 deletions(-) diff --git a/src/rpc/rpcwallet.cpp b/src/rpc/rpcwallet.cpp index d1c087be..c7dffac2 100644 --- a/src/rpc/rpcwallet.cpp +++ b/src/rpc/rpcwallet.cpp @@ -570,20 +570,46 @@ Value gettxoutdata(const Array& params, bool fHelp) mc_gState->m_TmpScript->Clear(); mc_gState->m_TmpScript->SetScript((unsigned char*)(&pc1[0]),(size_t)(script1.end()-pc1),MC_SCR_TYPE_SCRIPTPUBKEY); + uint32_t format; string metadata=""; + size_t elem_size; + const unsigned char *elem; if(mc_gState->m_TmpScript->IsOpReturnScript() == 0) { - throw JSONRPCError(RPC_OUTPUT_NOT_DATA, "Output without metadata"); + unsigned char *ptr; + int size; + elem=NULL; + + for (int e = 0; e < mc_gState->m_TmpScript->GetNumElements(); e++) + { + mc_gState->m_TmpScript->SetElement(e); + if(mc_gState->m_TmpScript->GetRawData(&ptr,&size) == 0) + { + if(elem) + { + throw JSONRPCError(RPC_NOT_ALLOWED, "This output has more than one data item"); + } + format=MC_SCR_DATA_FORMAT_UNKNOWN; + if(e > 0) + { + mc_gState->m_TmpScript->SetElement(e-1); + mc_gState->m_TmpScript->GetDataFormat(&format); + } + elem=ptr; + elem_size=size; + } + } + if(elem == NULL) + { + throw JSONRPCError(RPC_OUTPUT_NOT_DATA, "Output without metadata"); + } + } + else + { + mc_gState->m_TmpScript->ExtractAndDeleteDataFormat(&format); + elem = mc_gState->m_TmpScript->GetData(mc_gState->m_TmpScript->GetNumElements()-1,&elem_size); } - size_t elem_size; - const unsigned char *elem; - - uint32_t format; - - mc_gState->m_TmpScript->ExtractAndDeleteDataFormat(&format); - - elem = mc_gState->m_TmpScript->GetData(mc_gState->m_TmpScript->GetNumElements()-1,&elem_size); int count,start; count=elem_size; From 5db763b30cfa6f10d7522e666a4ce33043c0e352 Mon Sep 17 00:00:00 2001 From: mike31 Date: Wed, 22 Nov 2017 15:26:13 +0200 Subject: [PATCH 16/71] Forbidden downgrades --- src/chainparams/state.h | 1 + src/core/main.cpp | 5 ++++- src/rpc/rpcupgrades.cpp | 28 +++++++++++++++++++++++++++- src/version/version.cpp | 6 ++++++ src/version/version.h | 1 + 5 files changed, 39 insertions(+), 2 deletions(-) diff --git a/src/chainparams/state.h b/src/chainparams/state.h index a321da11..02a6197f 100644 --- a/src/chainparams/state.h +++ b/src/chainparams/state.h @@ -262,6 +262,7 @@ typedef struct mc_State int GetProtocolVersion(); int MinProtocolVersion(); int MinProtocolDowngradeVersion(); + int MinProtocolForbiddenDowngradeVersion(); int IsSupported(int version); int IsDeprecated(int version); const char* GetSeedNode(); diff --git a/src/core/main.cpp b/src/core/main.cpp index 168b1d64..a9863d63 100644 --- a/src/core/main.cpp +++ b/src/core/main.cpp @@ -393,7 +393,10 @@ int MultichainNode_ApplyUpgrades(int current_height) version=entity.UpgradeProtocolVersion(); if(version >= mc_gState->MinProtocolDowngradeVersion()) { - NewProtocolVersion=version; + if((NewProtocolVersion < mc_gState->MinProtocolForbiddenDowngradeVersion()) || (version >= NewProtocolVersion)) + { + NewProtocolVersion=version; + } } } } diff --git a/src/rpc/rpcupgrades.cpp b/src/rpc/rpcupgrades.cpp index 84abb5cd..3c3da522 100644 --- a/src/rpc/rpcupgrades.cpp +++ b/src/rpc/rpcupgrades.cpp @@ -113,6 +113,13 @@ Value createupgradefromcmd(const Array& params, bool fHelp) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid protocol version, cannot downgrade to this version"); } + if( mc_gState->m_NetworkParams->ProtocolVersion() >= mc_gState->MinProtocolForbiddenDowngradeVersion() ) + { + if(protocol_version < mc_gState->m_NetworkParams->ProtocolVersion()) + { + throw JSONRPCError(RPC_NOT_ALLOWED, "Invalid protocol version, cannot downgrade from current version"); + } + } lpDetails->SetSpecialParamValue(MC_ENT_SPRM_UPGRADE_PROTOCOL_VERSION,(unsigned char*)&protocol_version,4); } else @@ -267,6 +274,14 @@ Value approvefrom(const json_spirit::Array& params, bool fHelp) mc_EntityDetails entity; entity.Zero(); ParseEntityIdentifier(entity_identifier,&entity, MC_ENT_TYPE_UPGRADE); + + if( mc_gState->m_NetworkParams->ProtocolVersion() >= mc_gState->MinProtocolForbiddenDowngradeVersion() ) + { + if(entity.UpgradeProtocolVersion() < mc_gState->m_NetworkParams->ProtocolVersion()) + { + throw JSONRPCError(RPC_NOT_ALLOWED, "Invalid protocol version, cannot downgrade from current version"); + } + } if(mc_gState->m_Permissions->IsApproved(entity.GetTxID()+MC_AST_SHORT_TXID_OFFSET,0)) { @@ -337,6 +352,7 @@ Value listupgrades(const json_spirit::Array& params, bool fHelp) Array results; mc_Buffer *upgrades; + int latest_version; upgrades=NULL; @@ -420,6 +436,7 @@ Value listupgrades(const json_spirit::Array& params, bool fHelp) } } + latest_version=(int)mc_gState->m_NetworkParams->GetInt64Param("protocolversion"); BOOST_FOREACH(PAIRTYPE(const uint64_t, int)& item, map_sorted) { int i=item.second; @@ -454,7 +471,16 @@ Value listupgrades(const json_spirit::Array& params, bool fHelp) } if(current_height >=applied_height) { - entry.push_back(Pair("appliedblock",(int64_t)applied_height)); + if((latest_version < mc_gState->MinProtocolForbiddenDowngradeVersion()) || (upgrade_entity.UpgradeProtocolVersion() >= latest_version)) + { + latest_version=upgrade_entity.UpgradeProtocolVersion(); + entry.push_back(Pair("appliedblock",(int64_t)applied_height)); + } + else + { + Value null_value; + entry.push_back(Pair("appliedblock",null_value)); + } } else { diff --git a/src/version/version.cpp b/src/version/version.cpp index 7f89846f..f1d80351 100644 --- a/src/version/version.cpp +++ b/src/version/version.cpp @@ -25,6 +25,8 @@ int mc_State::VersionInfo(int version) return 10004; // first supported version case MULTICHAIN_VERSION_CODE_PROTOCOL_MIN_DOWNGRADE: return 10008; // cannot downgrade below this version + case MULTICHAIN_VERSION_CODE_PROTOCOL_MIN_NO_DOWNGRADE: + return 20002; // if we are on this version or above, downgrades are forbidden } return 0; } @@ -102,6 +104,10 @@ int mc_State::MinProtocolDowngradeVersion() return VersionInfo(MULTICHAIN_VERSION_CODE_PROTOCOL_MIN_DOWNGRADE); } +int mc_State::MinProtocolForbiddenDowngradeVersion() +{ + return VersionInfo(MULTICHAIN_VERSION_CODE_PROTOCOL_MIN_NO_DOWNGRADE); +} int mc_State::GetWalletDBVersion() diff --git a/src/version/version.h b/src/version/version.h index 70b5e9a1..9c71a94f 100644 --- a/src/version/version.h +++ b/src/version/version.h @@ -53,6 +53,7 @@ #define MULTICHAIN_VERSION_CODE_PROTOCOL_THIS 0 #define MULTICHAIN_VERSION_CODE_PROTOCOL_MIN 1 #define MULTICHAIN_VERSION_CODE_PROTOCOL_MIN_DOWNGRADE 2 +#define MULTICHAIN_VERSION_CODE_PROTOCOL_MIN_NO_DOWNGRADE 3 #define MULTICHAIN_VERSION_CODE_BUILD 16 #define MULTICHAIN_VERSION_CODE_MIN_VALID 10000 From 98abdc7c9f5ec3f505c6bb0ea47c5e513539684a Mon Sep 17 00:00:00 2001 From: mike31 Date: Wed, 22 Nov 2017 16:42:31 +0200 Subject: [PATCH 17/71] Fixed checking full branch when accepting new headers in inital download --- src/core/main.cpp | 28 +++++++++++++++++----------- src/core/main.h | 4 ++-- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/src/core/main.cpp b/src/core/main.cpp index a9863d63..83d4414b 100644 --- a/src/core/main.cpp +++ b/src/core/main.cpp @@ -4155,7 +4155,7 @@ bool CheckBranchForInvalidBlocks(CBlockIndex * const pindexPrev) -bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex * const pindexPrev) +bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex * const pindexPrev, CBlockIndex *pindexChecked) { uint256 hash = block.GetHash(); if (hash == Params().HashGenesisBlock()) @@ -4228,11 +4228,14 @@ bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& sta } } } - - if(!CheckBranchForInvalidBlocks(pindexPrev)) + + if(pindexChecked != pindexPrev) { - return state.Invalid(error("%s : %s rejected - invalid branch", __func__,block.GetHash().ToString().c_str()), - REJECT_INVALID, "reorg-invalid branch"); + if(!CheckBranchForInvalidBlocks(pindexPrev)) + { + return state.Invalid(error("%s : %s rejected - invalid branch", __func__,block.GetHash().ToString().c_str()), + REJECT_INVALID, "reorg-invalid branch"); + } } @@ -4285,7 +4288,7 @@ bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIn return true; } -bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex** ppindex, int node_id) +bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex** ppindex, int node_id, CBlockIndex *pindexChecked) { AssertLockHeld(cs_main); // Check for duplicate @@ -4299,10 +4302,13 @@ bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state, CBloc *ppindex = pindex; if (pindex->nStatus & BLOCK_FAILED_MASK) return state.Invalid(error("%s : block is marked invalid", __func__), 0, "duplicate"); - if(!CheckBranchForInvalidBlocks(pindex->pprev)) + if(pindexChecked != pindex->pprev) { - return state.Invalid(error("%s : %s rejected - invalid branch", __func__,block.GetHash().ToString().c_str()), - REJECT_INVALID, "reorg-invalid branch"); + if(!CheckBranchForInvalidBlocks(pindex->pprev)) + { + return state.Invalid(error("%s : %s rejected - invalid branch", __func__,block.GetHash().ToString().c_str()), + REJECT_INVALID, "reorg-invalid branch"); + } } return true; } @@ -4321,7 +4327,7 @@ bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state, CBloc return state.DoS(10, error("%s : prev block invalid", __func__), REJECT_INVALID, "bad-prevblk");// MCHN was 100 before, softened for reorgs due to mining diversity change } - if (!ContextualCheckBlockHeader(block, state, pindexPrev)) + if (!ContextualCheckBlockHeader(block, state, pindexPrev, pindexChecked)) return false; int successor=0; @@ -6226,7 +6232,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, Misbehaving(pfrom->GetId(), 20); return error("non-continuous headers sequence"); } - if (!AcceptBlockHeader(header, state, &pindexLast, pfrom->GetId())) { + if (!AcceptBlockHeader(header, state, &pindexLast, pfrom->GetId(),pindexLast)) { int nDoS; if (state.IsInvalid(nDoS)) { if (nDoS > 0) diff --git a/src/core/main.h b/src/core/main.h index f5316228..4cccc4b7 100644 --- a/src/core/main.h +++ b/src/core/main.h @@ -397,7 +397,7 @@ bool CheckBlockHeader(const CBlockHeader& block, CValidationState& state, bool f bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW = true, bool fCheckMerkleRoot = true); /** Context-dependent validity checks */ -bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex *pindexPrev); +bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex *pindexPrev, CBlockIndex *pindexChecked = NULL); bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIndex *pindexPrev); /** Check a block is completely valid from start to finish (only works on top of our current best block, with cs_main held) */ @@ -405,7 +405,7 @@ bool TestBlockValidity(CValidationState &state, const CBlock& block, CBlockIndex /** Store block on disk. If dbp is provided, the file is known to already reside on disk */ bool AcceptBlock(CBlock& block, CValidationState& state, CBlockIndex **pindex, CDiskBlockPos* dbp = NULL, int node_id = 0); -bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex **ppindex= NULL, int node_id = 0); +bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex **ppindex= NULL, int node_id = 0, CBlockIndex *pindexChecked = NULL); From c2535c559aa86ebec324f2731297b7162ffdd5e0 Mon Sep 17 00:00:00 2001 From: mike31 Date: Thu, 23 Nov 2017 10:22:44 +0200 Subject: [PATCH 18/71] Fixed decoderawesxchange crash on p2sh output --- src/rpc/rpcexchange.cpp | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/rpc/rpcexchange.cpp b/src/rpc/rpcexchange.cpp index d2c84c77..c9415947 100644 --- a/src/rpc/rpcexchange.cpp +++ b/src/rpc/rpcexchange.cpp @@ -114,6 +114,13 @@ Object ExchangeAssetEntry(uint256 hash,const CTxOut txout,mc_Script *lpScript,mc { address=CBitcoinAddress(*lpKeyID); address_found=true; + if(mc_gState->m_Permissions->CanReceive(NULL,(unsigned char*)(lpKeyID)) == 0) + { + if(strError.size() == 0) + { + strError="Address doesn't have receive permission"; + } + } } else { @@ -122,16 +129,14 @@ Object ExchangeAssetEntry(uint256 hash,const CTxOut txout,mc_Script *lpScript,mc strError="Only pay-to-keyhash addresses are supported in exchange"; } } - if(mc_gState->m_Permissions->CanReceive(NULL,(unsigned char*)(lpKeyID)) == 0) - { - if(strError.size() == 0) - { - strError="Address doesn't have receive permission"; - } - } } } + if(strError.size()) + { + return result; + } + Array assets; asset_amounts->Clear(); From b5a7470f613d5387d64a7c5b2e426afd1e2bdcd3 Mon Sep 17 00:00:00 2001 From: mike31 Date: Thu, 23 Nov 2017 10:59:54 +0200 Subject: [PATCH 19/71] Fixed per-asset receive check for multisigs --- src/utils/utilparse.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/utilparse.cpp b/src/utils/utilparse.cpp index 10dc9469..aa05a598 100644 --- a/src/utils/utilparse.cpp +++ b/src/utils/utilparse.cpp @@ -91,7 +91,7 @@ bool mc_VerifyAssetPermissions(mc_Buffer *assets, vector address int found=required_permissions; for(int j=0;j<(int)addressRets.size();j++) { - if(mc_gState->m_Permissions->GetPermission(entity.GetTxID(),GetAddressIDPtr(addressRets[i]),permission)) + if(mc_gState->m_Permissions->GetPermission(entity.GetTxID(),GetAddressIDPtr(addressRets[j]),permission)) { found--; } From a0fb5aaa8645e2075a6aaa5ac04b1884c8d424c3 Mon Sep 17 00:00:00 2001 From: mike31 Date: Thu, 23 Nov 2017 13:51:48 +0200 Subject: [PATCH 20/71] Fixed checkin receive permission in coin selection --- src/wallet/walletcoins.cpp | 75 +++++++++++++++++++++----------------- 1 file changed, 42 insertions(+), 33 deletions(-) diff --git a/src/wallet/walletcoins.cpp b/src/wallet/walletcoins.cpp index 69dc8017..b96e65ff 100644 --- a/src/wallet/walletcoins.cpp +++ b/src/wallet/walletcoins.cpp @@ -2001,42 +2001,51 @@ bool CheckOutputPermissions(const vector >& vecSend,mc_Bu fIsMaybePurePermission=false; } - if( (s.second > 0) || - !fIsMaybePurePermission || - (mc_gState->m_Features->AnyoneCanReceiveEmpty() == 0) ) - { - for(int a=0;a<(int)addressRets.size();a++) - { - CKeyID *lpKeyID=boost::get (&addressRets[a]); - CScriptID *lpScriptID=boost::get (&addressRets[a]); - if((lpKeyID == NULL) && (lpScriptID == NULL)) - { - strFailReason="Wrong destination type"; - *eErrorCode=RPC_INTERNAL_ERROR; - return false; - } - unsigned char* ptr=NULL; - if(lpKeyID != NULL) - { - ptr=(unsigned char*)(lpKeyID); - } - else - { - ptr=(unsigned char*)(lpScriptID); - } + if(s.second > 0) + { + fIsMaybePurePermission=false; + } + + if(!fIsMaybePurePermission) + + { + if( (s.second > 0) || + (tmp_amounts->GetCount() > 0) || + (mc_gState->m_Features->AnyoneCanReceiveEmpty() == 0) ) + { + for(int a=0;a<(int)addressRets.size();a++) + { + CKeyID *lpKeyID=boost::get (&addressRets[a]); + CScriptID *lpScriptID=boost::get (&addressRets[a]); + if((lpKeyID == NULL) && (lpScriptID == NULL)) + { + strFailReason="Wrong destination type"; + *eErrorCode=RPC_INTERNAL_ERROR; + return false; + } + unsigned char* ptr=NULL; + if(lpKeyID != NULL) + { + ptr=(unsigned char*)(lpKeyID); + } + else + { + ptr=(unsigned char*)(lpScriptID); + } - bool fCanReceive=mc_gState->m_Permissions->CanReceive(NULL,ptr); + bool fCanReceive=mc_gState->m_Permissions->CanReceive(NULL,ptr); - if(fCanReceive) + if(fCanReceive) + { + receive_required--; + } + } + if(receive_required>0) { - receive_required--; - } - } - if(receive_required>0) - { - strFailReason="One of the outputs doesn't have receive permission"; - *eErrorCode=RPC_INSUFFICIENT_PERMISSIONS; - return false; + strFailReason="One of the outputs doesn't have receive permission"; + *eErrorCode=RPC_INSUFFICIENT_PERMISSIONS; + return false; + } } } } From 655f3f93c9cfec0a7c799452dc2474d6a00dba75 Mon Sep 17 00:00:00 2001 From: mike31 Date: Thu, 23 Nov 2017 15:13:42 +0200 Subject: [PATCH 21/71] Forbidden sending restricted assets to non-standard and multisigs --- src/utils/utilparse.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/utils/utilparse.cpp b/src/utils/utilparse.cpp index aa05a598..67da1063 100644 --- a/src/utils/utilparse.cpp +++ b/src/utils/utilparse.cpp @@ -60,6 +60,11 @@ bool mc_VerifyAssetPermissions(mc_Buffer *assets, vector address { if( entity.Permissions() & (MC_PTP_SEND | MC_PTP_RECEIVE) ) { + if( (addressRets.size() != 1) || (required_permissions > 1) ) + { + reason="Sending restricted asset to non-standard and multisig addresses not allowed"; + return false; + } if(assets->GetCount() > 1) { if(asset_count < 0) From 0d61a9951ec029725f31186cae784c8ecdf08ac5 Mon Sep 17 00:00:00 2001 From: mike31 Date: Tue, 28 Nov 2017 15:18:57 +0200 Subject: [PATCH 22/71] Custom plugins --- src/Makefile.am | 4 ++++ src/chainparams/params.cpp | 7 ++++++- src/protocol/multichaintx.cpp | 2 ++ src/utils/declare.h | 1 + src/utils/utilwrapper.cpp | 3 +++ src/version/version.cpp | 9 ++++++++- 6 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index f183bfe9..95a980ec 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -252,6 +252,8 @@ multichain_libbitcoin_multichain_a_SOURCES = \ utils/tools.cpp \ utils/utilwrapper.cpp \ version/version.cpp \ + custom/custom.cpp \ + custom/custom_multichain.cpp \ chainparams/params.cpp \ protocol/multichainscript.cpp \ utils/dbwrapper.cpp \ @@ -513,6 +515,8 @@ libbitcoinconsensus_la_SOURCES = \ utils/utilwrapper.cpp \ chainparams/buildgenesis.cpp \ version/version.cpp \ + custom/custom.cpp \ + custom/custom_multichain.cpp \ chainparams/chainparams.cpp \ protocol/multichainscript.cpp \ utils/dbwrapper.cpp \ diff --git a/src/chainparams/params.cpp b/src/chainparams/params.cpp index ed80a5af..8dd3da2f 100644 --- a/src/chainparams/params.cpp +++ b/src/chainparams/params.cpp @@ -694,7 +694,12 @@ int mc_MultichainParams::Read(const char* name,int argc, char* argv[],int create ptrData=m_lpData+offset+MC_PRM_PARAM_SIZE_BYTES; - ptr=(char*)lpDefaultParams->GetParam(param->m_Name,&size); + ptr=(char*)custom_get_blockchain_default(param->m_Name,&size); + if(ptr == NULL) + { + ptr=(char*)lpDefaultParams->GetParam(param->m_Name,&size); + } + if(size) { memcpy(ptrData,ptr,size); diff --git a/src/protocol/multichaintx.cpp b/src/protocol/multichaintx.cpp index 9479b62c..23b24c74 100644 --- a/src/protocol/multichaintx.cpp +++ b/src/protocol/multichaintx.cpp @@ -9,6 +9,7 @@ #include "utils/utilparse.h" #include "multichain/multichain.h" #include "structs/base58.h" +#include "custom/custom.h" using namespace std; @@ -1940,6 +1941,7 @@ bool AcceptMultiChainTransaction(const CTransaction& tx, } } + fReject=!custom_accept_transacton(tx,inputs,offset,accept,reason,replay); exitlbl: diff --git a/src/utils/declare.h b/src/utils/declare.h index e52b7394..cc802187 100644 --- a/src/utils/declare.h +++ b/src/utils/declare.h @@ -243,6 +243,7 @@ void mc_SetDataDirArg(char *buf); void mc_ExpandDataDirParam(); void mc_CheckDataDirInConfFile(); void mc_AdjustStartAndCount(int *count,int *start,int size); +void* custom_get_blockchain_default(const char *param,int* size); int mc_TestScenario(char* scenario_file); diff --git a/src/utils/utilwrapper.cpp b/src/utils/utilwrapper.cpp index 4ea68afd..fce40580 100644 --- a/src/utils/utilwrapper.cpp +++ b/src/utils/utilwrapper.cpp @@ -47,6 +47,7 @@ #include "structs/hash.h" #include "core/main.h" #include "net/net.h" +#include "custom/custom.h" #define MC_DCT_SEED_NODE_MAX_SIZE 32 @@ -77,6 +78,8 @@ void mc_Params::Parse(int argc, const char* const argv[],int exe_type) ParseParameters(argc,argv); mc_ExpandDataDirParam(); + custom_set_runtime_defaults(exe_type); + m_NumArguments=0; length=MC_DCT_SEED_NODE_MAX_SIZE+1; for (i = 1; i < argc; i++) diff --git a/src/version/version.cpp b/src/version/version.cpp index f1d80351..e651f5b1 100644 --- a/src/version/version.cpp +++ b/src/version/version.cpp @@ -3,12 +3,19 @@ #include "multichain/multichain.h" #include "version/version.h" - +#include "custom/custom.h" int mc_State::VersionInfo(int version) { int this_build=20000102; int this_protocol=20002; + + int custom_version=custom_version_info(version); + if(custom_version != 0) + { + return custom_version; + } + if(version < 0) { return 0; From c2039a08b863dcfdd223273175715b4db70b5802 Mon Sep 17 00:00:00 2001 From: mike31 Date: Tue, 28 Nov 2017 15:25:07 +0200 Subject: [PATCH 23/71] Custom plugins new files --- src/custom/custom.cpp | 28 ++++++++++++++++++++++++++ src/custom/custom.h | 34 ++++++++++++++++++++++++++++++++ src/custom/custom_multichain.cpp | 12 +++++++++++ src/utils/utilwrapper.cpp | 3 +++ 4 files changed, 77 insertions(+) create mode 100644 src/custom/custom.cpp create mode 100644 src/custom/custom.h create mode 100644 src/custom/custom_multichain.cpp diff --git a/src/custom/custom.cpp b/src/custom/custom.cpp new file mode 100644 index 00000000..1454721d --- /dev/null +++ b/src/custom/custom.cpp @@ -0,0 +1,28 @@ +// Copyright (c) 2014-2017 Coin Sciences Ltd +// MultiChain code distributed under the GPLv3 license, see COPYING file. + +#include "custom/custom.h" + +using namespace std; + +int custom_version_info(int version) +{ + return 0; +} + +void custom_set_runtime_defaults(int exe_type) +{ + +} + + +bool custom_accept_transacton(const CTransaction& tx, + const CCoinsViewCache &inputs, + int offset, + bool accept, + string& reason, + uint32_t *replay) +{ + return true; +} + diff --git a/src/custom/custom.h b/src/custom/custom.h new file mode 100644 index 00000000..3135386e --- /dev/null +++ b/src/custom/custom.h @@ -0,0 +1,34 @@ +// Copyright (c) 2014-2017 Coin Sciences Ltd +// MultiChain code distributed under the GPLv3 license, see COPYING file. + +#include "core/main.h" +#include "utils/util.h" +#include "utils/utilparse.h" +#include "multichain/multichain.h" +#include "structs/base58.h" + + + +#ifndef CUSTOM_H +#define CUSTOM_H + +#ifdef __cplusplus +extern "C" { +#endif + +int custom_version_info(int version); +bool custom_accept_transacton(const CTransaction& tx, + const CCoinsViewCache &inputs, + int offset, + bool accept, + std::string& reason, + uint32_t *replay); + +void custom_set_runtime_defaults(int exe_type); + +#ifdef __cplusplus +} +#endif + +#endif /* CUSTOM_H */ + diff --git a/src/custom/custom_multichain.cpp b/src/custom/custom_multichain.cpp new file mode 100644 index 00000000..73bfd43d --- /dev/null +++ b/src/custom/custom_multichain.cpp @@ -0,0 +1,12 @@ +// Copyright (c) 2014-2017 Coin Sciences Ltd +// MultiChain code distributed under the GPLv3 license, see COPYING file. + +#include "multichain/multichain.h" + +void* custom_get_blockchain_default(const char *param,int* size) +{ + *size=0; + + return NULL; +} + diff --git a/src/utils/utilwrapper.cpp b/src/utils/utilwrapper.cpp index fce40580..d66795a9 100644 --- a/src/utils/utilwrapper.cpp +++ b/src/utils/utilwrapper.cpp @@ -718,6 +718,9 @@ int mc_BuildDescription(int build, char *desc) case 2: sprintf(desc+strlen(desc)," beta "); break; + case 7: + sprintf(desc+strlen(desc)," build "); + break; case 9: if(c[4] != 1)return MC_ERR_INVALID_PARAMETER_VALUE; break; From 50402a8b8454f0f6baea40b53becfd202be44971 Mon Sep 17 00:00:00 2001 From: mike31 Date: Tue, 28 Nov 2017 15:52:05 +0200 Subject: [PATCH 24/71] Setting relevant protocol version for custom builds --- src/chainparams/params.cpp | 10 ++++++++-- src/chainparams/state.h | 1 + src/custom/custom.h | 1 + src/version/version.cpp | 12 +++++++++--- src/version/version.h | 3 ++- 5 files changed, 21 insertions(+), 6 deletions(-) diff --git a/src/chainparams/params.cpp b/src/chainparams/params.cpp index 8dd3da2f..d68c4b9a 100644 --- a/src/chainparams/params.cpp +++ b/src/chainparams/params.cpp @@ -18,14 +18,20 @@ int mc_OneMultichainParam::IsRelevant(int version) { int ret=1; - if(m_ProtocolVersion > version) + int relevant_version=mc_gState->RelevantParamProtocolVersion(); + if(relevant_version == 0) + { + relevant_version=version; + } + + if(m_ProtocolVersion > relevant_version) { ret=0; } if(m_Removed > 0) { - if(m_Removed <= version) + if(m_Removed <= relevant_version) { ret=0; } diff --git a/src/chainparams/state.h b/src/chainparams/state.h index 02a6197f..ba85229d 100644 --- a/src/chainparams/state.h +++ b/src/chainparams/state.h @@ -263,6 +263,7 @@ typedef struct mc_State int MinProtocolVersion(); int MinProtocolDowngradeVersion(); int MinProtocolForbiddenDowngradeVersion(); + int RelevantParamProtocolVersion(); int IsSupported(int version); int IsDeprecated(int version); const char* GetSeedNode(); diff --git a/src/custom/custom.h b/src/custom/custom.h index 3135386e..9cf45427 100644 --- a/src/custom/custom.h +++ b/src/custom/custom.h @@ -6,6 +6,7 @@ #include "utils/utilparse.h" #include "multichain/multichain.h" #include "structs/base58.h" +#include "version/version.h" diff --git a/src/version/version.cpp b/src/version/version.cpp index e651f5b1..ac342acf 100644 --- a/src/version/version.cpp +++ b/src/version/version.cpp @@ -7,15 +7,15 @@ int mc_State::VersionInfo(int version) { - int this_build=20000102; - int this_protocol=20002; - int custom_version=custom_version_info(version); if(custom_version != 0) { return custom_version; } + int this_build=20000102; + int this_protocol=20002; + if(version < 0) { return 0; @@ -34,6 +34,8 @@ int mc_State::VersionInfo(int version) return 10008; // cannot downgrade below this version case MULTICHAIN_VERSION_CODE_PROTOCOL_MIN_NO_DOWNGRADE: return 20002; // if we are on this version or above, downgrades are forbidden + case MULTICHAIN_VERSION_CODE_PROTOCOL_FOR_RELEVANCE: + return 0; // If not 0, defines relevant parameter set } return 0; } @@ -116,6 +118,10 @@ int mc_State::MinProtocolForbiddenDowngradeVersion() return VersionInfo(MULTICHAIN_VERSION_CODE_PROTOCOL_MIN_NO_DOWNGRADE); } +int mc_State::RelevantParamProtocolVersion() +{ + return VersionInfo(MULTICHAIN_VERSION_CODE_PROTOCOL_FOR_RELEVANCE); +} int mc_State::GetWalletDBVersion() { diff --git a/src/version/version.h b/src/version/version.h index 9c71a94f..06886129 100644 --- a/src/version/version.h +++ b/src/version/version.h @@ -54,8 +54,9 @@ #define MULTICHAIN_VERSION_CODE_PROTOCOL_MIN 1 #define MULTICHAIN_VERSION_CODE_PROTOCOL_MIN_DOWNGRADE 2 #define MULTICHAIN_VERSION_CODE_PROTOCOL_MIN_NO_DOWNGRADE 3 +#define MULTICHAIN_VERSION_CODE_PROTOCOL_FOR_RELEVANCE 4 #define MULTICHAIN_VERSION_CODE_BUILD 16 -#define MULTICHAIN_VERSION_CODE_MIN_VALID 10000 +#define MULTICHAIN_VERSION_CODE_MIN_VALID 1000 #endif /* MULTICHAINVERSION_H */ From e9e99abfa84ed24efa86b583e5695bb091641820 Mon Sep 17 00:00:00 2001 From: mike31 Date: Wed, 29 Nov 2017 09:57:20 +0200 Subject: [PATCH 25/71] ubjson compilation fix for Mac --- src/json/json_spirit_ubjson.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/json/json_spirit_ubjson.cpp b/src/json/json_spirit_ubjson.cpp index 2b6f28f5..04a2f941 100644 --- a/src/json/json_spirit_ubjson.cpp +++ b/src/json/json_spirit_ubjson.cpp @@ -355,7 +355,7 @@ int ubjson_write_internal(Value json_value,int known_type,mc_Script *lpScript,in ssize=usize; } } - value=array_value.size(); + value=(int)array_value.size(); ubj_type=ubjson_best_type(value,0,NULL,NULL,NULL); if(ssize+(int64_t)array_value.size()+1 <= (int64_t)array_value.size()*UBJ_SIZE[last_type]+UBJ_SIZE[ubj_type]+4) { @@ -443,7 +443,7 @@ int ubjson_write_internal(Value json_value,int known_type,mc_Script *lpScript,in ssize=usize; } } - value=obj_value.size(); + value=(int)obj_value.size(); ubj_type=ubjson_best_type(value,0,NULL,NULL,NULL); if(ssize+(int64_t)obj_value.size()+1 <= (int64_t)obj_value.size()*UBJ_SIZE[last_type]+UBJ_SIZE[ubj_type]+4) { From fd52db1963a8a4d3f13c17da37045c2ef594ec5c Mon Sep 17 00:00:00 2001 From: mike31 Date: Wed, 29 Nov 2017 10:41:08 +0200 Subject: [PATCH 26/71] Fixed max value for reward-halving-interval --- src/chainparams/paramlist.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/chainparams/paramlist.h b/src/chainparams/paramlist.h index 0293322c..183190fb 100644 --- a/src/chainparams/paramlist.h +++ b/src/chainparams/paramlist.h @@ -159,7 +159,7 @@ static const mc_OneMultichainParam MultichainParamArray[] = "firstblockreward","Native blockchain currency (likely not required)", "Initial block mining reward in raw native currency units."}, { "rewardhalvinginterval" , "reward-halving-interval" , - MC_PRM_UINT32 | MC_PRM_USER | MC_PRM_CLONE , -1, 52560000, 60,4294967295U, 0.0, 10001, 0, "-mc-rewardhalvinginterval", + MC_PRM_UINT32 | MC_PRM_USER | MC_PRM_CLONE , -1, 52560000, 60,1000000000, 0.0, 10001, 0, "-mc-rewardhalvinginterval", "rewardspendabledelay","", "Interval for halving of mining rewards, in blocks."}, { "rewardspendabledelay" , "reward-spendable-delay" , From 7c631c98c5c448cc95cd0a9fbb3b2abf94d58ab8 Mon Sep 17 00:00:00 2001 From: mike31 Date: Wed, 29 Nov 2017 10:43:05 +0200 Subject: [PATCH 27/71] Fixed custom blockchain parameter setting procedure --- src/chainparams/params.cpp | 3 ++- src/custom/custom_multichain.cpp | 2 +- src/utils/declare.h | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/chainparams/params.cpp b/src/chainparams/params.cpp index d68c4b9a..7defe5fc 100644 --- a/src/chainparams/params.cpp +++ b/src/chainparams/params.cpp @@ -466,6 +466,7 @@ int mc_MultichainParams::Read(const char* name,int argc, char* argv[],int create mc_OneMultichainParam *param; char *ptrData; const char *ptr; + unsigned char custom_param[8]; if(name == NULL) { @@ -700,7 +701,7 @@ int mc_MultichainParams::Read(const char* name,int argc, char* argv[],int create ptrData=m_lpData+offset+MC_PRM_PARAM_SIZE_BYTES; - ptr=(char*)custom_get_blockchain_default(param->m_Name,&size); + ptr=(char*)custom_get_blockchain_default(param->m_Name,&size,custom_param); if(ptr == NULL) { ptr=(char*)lpDefaultParams->GetParam(param->m_Name,&size); diff --git a/src/custom/custom_multichain.cpp b/src/custom/custom_multichain.cpp index 73bfd43d..b67933ce 100644 --- a/src/custom/custom_multichain.cpp +++ b/src/custom/custom_multichain.cpp @@ -3,7 +3,7 @@ #include "multichain/multichain.h" -void* custom_get_blockchain_default(const char *param,int* size) +void* custom_get_blockchain_default(const char *param,int* size,void *param_in) { *size=0; diff --git a/src/utils/declare.h b/src/utils/declare.h index cc802187..ac6e15a0 100644 --- a/src/utils/declare.h +++ b/src/utils/declare.h @@ -243,7 +243,7 @@ void mc_SetDataDirArg(char *buf); void mc_ExpandDataDirParam(); void mc_CheckDataDirInConfFile(); void mc_AdjustStartAndCount(int *count,int *start,int size); -void* custom_get_blockchain_default(const char *param,int* size); +void* custom_get_blockchain_default(const char *param,int* size,void *param_in); int mc_TestScenario(char* scenario_file); From 11887019a39155fd4f6cc761d27e03df0e0e6fe6 Mon Sep 17 00:00:00 2001 From: mike31 Date: Thu, 30 Nov 2017 09:16:32 +0200 Subject: [PATCH 28/71] Cached burn address --- src/chainparams/state.h | 2 + src/structs/base58.cpp | 127 +++++++++++++++++++++------------------- 2 files changed, 70 insertions(+), 59 deletions(-) diff --git a/src/chainparams/state.h b/src/chainparams/state.h index ba85229d..018174bd 100644 --- a/src/chainparams/state.h +++ b/src/chainparams/state.h @@ -166,6 +166,7 @@ typedef struct mc_State void *m_pSeedNode; uint32_t m_Compatibility; uint32_t m_SessionFlags; + unsigned char m_BurnAddress[20]; mc_Script *m_TmpScript; mc_Script *m_TmpScript1; @@ -188,6 +189,7 @@ typedef struct mc_State m_NodePausedState=MC_NPS_NONE; m_ProtocolVersionToUpgrade=0; m_SessionFlags=MC_SSF_DEFAULT; + memset(m_BurnAddress,0,20); m_IPv4Address=0; m_WalletMode=0; diff --git a/src/structs/base58.cpp b/src/structs/base58.cpp index 9e117bc3..bbe4b3d8 100644 --- a/src/structs/base58.cpp +++ b/src/structs/base58.cpp @@ -262,81 +262,90 @@ std::string BurnAddress(const std::vector& vchVersion) char res[100]; int shift=nDataBytes / nVersionBytes; - vch.resize(nDataBytes + nVersionBytes + nHashBytes); + CKeyID kBurn; int p; - for(int i=2;i nDataBytes + nVersionBytes + nHashBytes) + if(*(uint160*)(mc_gState->m_BurnAddress) == 0) { - res[strlen(res)-1]=0x00; + vch.resize(nDataBytes + nVersionBytes + nHashBytes); + for(int i=2;i nDataBytes + nVersionBytes + nHashBytes) + { + res[strlen(res)-1]=0x00; + DecodeBase58(res,vch); + } - p=0; - while(p strlen(res)) + memset(&vch[p+2],0x00,vch.size()-p-2); + vch[p] = vchVersion[p / (shift+1)]; + vch[p+1] = 0x80; + strcpy(test,EncodeBase58(vch).c_str()); + if(strlen(test) != strlen(res)) { - res[strlen(res)+1]=0x00; - res[strlen(res)]='X'; - } - if(strlen(test) < strlen(res)) + if(strlen(test) > strlen(res)) + { + res[strlen(res)+1]=0x00; + res[strlen(res)]='X'; + } + if(strlen(test) < strlen(res)) + { + res[strlen(res)-1]=0x00; + } + } + int j=0; + while( (j<(int)strlen(res)) && (res[j] == test[j]) ) { - res[strlen(res)-1]=0x00; - } - } - int j=0; - while( (j<(int)strlen(res)) && (res[j] == test[j]) ) - { - j++; + j++; + } + int k=0; + while( (k<3) && (j<(int)strlen(res)) && ((vch[p] != vchVersion[p / (shift+1)]) || (k ==0))) + { + res[j]=test[j]; + DecodeBase58(res,vch); + k++; + j++; + } } - int k=0; - while( (k<3) && (j<(int)strlen(res)) && ((vch[p] != vchVersion[p / (shift+1)]) || (k ==0))) - { - res[j]=test[j]; - DecodeBase58(res,vch); - k++; - j++; - } } + p++; } - p++; - } - -// strcpy(test,EncodeBase58(vch).c_str()); - - - for(int i=0;i<(int)nVersionBytes;i++) - { - int size=shift; - if(i == (int)(nVersionBytes-1)) + + // strcpy(test,EncodeBase58(vch).c_str()); + + + for(int i=0;i<(int)nVersionBytes;i++) { - size=nDataBytes-i*shift; + int size=shift; + if(i == (int)(nVersionBytes-1)) + { + size=nDataBytes-i*shift; + } + memcpy(data+i*shift,&vch[i*(shift+1)+1],size); } - memcpy(data+i*shift,&vch[i*(shift+1)+1],size); + + memcpy(&kBurn,data,nDataBytes); + memcpy(mc_gState->m_BurnAddress,data,nDataBytes); + } + else + { + memcpy(&kBurn,mc_gState->m_BurnAddress,nDataBytes); } - - CKeyID kBurn; - memcpy(&kBurn,data,nDataBytes); CBitcoinAddress ba; ba.Set(kBurn,vchVersion); From 9546645ce8726d984d95de82dd4e60b799d6eec1 Mon Sep 17 00:00:00 2001 From: mike31 Date: Thu, 30 Nov 2017 11:11:21 +0200 Subject: [PATCH 29/71] Custom build refactoring and burn address initialization --- src/Makefile.am | 1 + src/core/init.cpp | 3 +++ src/custom/custom.cpp | 9 --------- src/custom/custom_server.cpp | 18 ++++++++++++++++++ 4 files changed, 22 insertions(+), 9 deletions(-) create mode 100644 src/custom/custom_server.cpp diff --git a/src/Makefile.am b/src/Makefile.am index 95a980ec..95ab04dc 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -179,6 +179,7 @@ libbitcoin_server_a_SOURCES = \ core/main.cpp \ protocol/multichaintx.cpp \ protocol/multichainblock.cpp \ + custom/custom_server.cpp \ protocol/handshake.cpp \ chain/merkleblock.cpp \ miner/miner.cpp \ diff --git a/src/core/init.cpp b/src/core/init.cpp index 2f1d16b1..9a033031 100644 --- a/src/core/init.cpp +++ b/src/core/init.cpp @@ -1334,6 +1334,9 @@ bool AppInit2(boost::thread_group& threadGroup,int OutputPipe) return InitError(_(seed_error.c_str())); } + string strBurnAddress=BurnAddress(Params().Base58Prefix(CChainParams::PUBKEY_ADDRESS)); // Caching burn address + LogPrint("mchn","mchn: Burn address: %s\n",strBurnAddress.c_str()); + int64_t wallet_mode=GetArg("-walletdbversion",0); bool wallet_mode_valid=false; if(wallet_mode == 0) diff --git a/src/custom/custom.cpp b/src/custom/custom.cpp index 1454721d..c759d078 100644 --- a/src/custom/custom.cpp +++ b/src/custom/custom.cpp @@ -16,13 +16,4 @@ void custom_set_runtime_defaults(int exe_type) } -bool custom_accept_transacton(const CTransaction& tx, - const CCoinsViewCache &inputs, - int offset, - bool accept, - string& reason, - uint32_t *replay) -{ - return true; -} diff --git a/src/custom/custom_server.cpp b/src/custom/custom_server.cpp new file mode 100644 index 00000000..820ee6d1 --- /dev/null +++ b/src/custom/custom_server.cpp @@ -0,0 +1,18 @@ +// Copyright (c) 2014-2017 Coin Sciences Ltd +// MultiChain code distributed under the GPLv3 license, see COPYING file. + +#include "custom/custom.h" + +using namespace std; + + +bool custom_accept_transacton(const CTransaction& tx, + const CCoinsViewCache &inputs, + int offset, + bool accept, + string& reason, + uint32_t *replay) +{ + return true; +} + From ce1f2dab0948d681dfc7649d9cc0814059c8694e Mon Sep 17 00:00:00 2001 From: mike31 Date: Thu, 30 Nov 2017 17:18:07 +0200 Subject: [PATCH 30/71] Custom builds, fixing relevant version and coin selection --- src/chainparams/params.cpp | 5 +++++ src/chainparams/params.h | 1 + src/core/init.cpp | 1 + src/custom/custom.h | 1 + src/custom/custom_server.cpp | 4 ++++ src/wallet/walletcoins.cpp | 4 +++- 6 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/chainparams/params.cpp b/src/chainparams/params.cpp index 7defe5fc..d4b85d63 100644 --- a/src/chainparams/params.cpp +++ b/src/chainparams/params.cpp @@ -50,6 +50,7 @@ void mc_MultichainParams::Zero() m_Size=0; m_IsProtocolMultiChain=1; m_ProtocolVersion=0; + m_RelevantProtocolVersion=0; m_AssetRefSize=MC_AST_SHORT_TXID_SIZE; } @@ -1555,6 +1556,10 @@ const unsigned char* mc_MultichainParams::AddressCheckumValue() int mc_MultichainParams::ProtocolVersion() { + if(mc_gState->m_NetworkParams->m_RelevantProtocolVersion) + { + return mc_gState->m_NetworkParams->m_RelevantProtocolVersion; + } if(m_ProtocolVersion) { return m_ProtocolVersion; diff --git a/src/chainparams/params.h b/src/chainparams/params.h index 11b08a1c..fa61eaef 100644 --- a/src/chainparams/params.h +++ b/src/chainparams/params.h @@ -96,6 +96,7 @@ typedef struct mc_MultichainParams int m_Count; int m_IsProtocolMultiChain; int m_ProtocolVersion; + int m_RelevantProtocolVersion; int m_AssetRefSize; diff --git a/src/core/init.cpp b/src/core/init.cpp index 9a033031..3246e60c 100644 --- a/src/core/init.cpp +++ b/src/core/init.cpp @@ -1334,6 +1334,7 @@ bool AppInit2(boost::thread_group& threadGroup,int OutputPipe) return InitError(_(seed_error.c_str())); } + mc_gState->m_NetworkParams->m_RelevantProtocolVersion=mc_gState->RelevantParamProtocolVersion(); // Caching relevant protocol version string strBurnAddress=BurnAddress(Params().Base58Prefix(CChainParams::PUBKEY_ADDRESS)); // Caching burn address LogPrint("mchn","mchn: Burn address: %s\n",strBurnAddress.c_str()); diff --git a/src/custom/custom.h b/src/custom/custom.h index 9cf45427..9d134eb6 100644 --- a/src/custom/custom.h +++ b/src/custom/custom.h @@ -18,6 +18,7 @@ extern "C" { #endif int custom_version_info(int version); +bool custom_good_for_coin_selection(const CScript& script); bool custom_accept_transacton(const CTransaction& tx, const CCoinsViewCache &inputs, int offset, diff --git a/src/custom/custom_server.cpp b/src/custom/custom_server.cpp index 820ee6d1..7fac2277 100644 --- a/src/custom/custom_server.cpp +++ b/src/custom/custom_server.cpp @@ -5,6 +5,10 @@ using namespace std; +bool custom_good_for_coin_selection(const CScript& script) +{ + return true; +} bool custom_accept_transacton(const CTransaction& tx, const CCoinsViewCache &inputs, diff --git a/src/wallet/walletcoins.cpp b/src/wallet/walletcoins.cpp index b96e65ff..ad8d3dc5 100644 --- a/src/wallet/walletcoins.cpp +++ b/src/wallet/walletcoins.cpp @@ -11,6 +11,7 @@ #include "script/sign.h" #include "utils/utilmoneystr.h" #include "rpc/rpcprotocol.h" +#include "custom/custom.h" extern mc_WalletTxs* pwalletTxsMain; @@ -815,7 +816,8 @@ bool FindRelevantCoins(CWallet *lpWallet, out_i=out.i; tmp_amounts->Clear(); - if(ParseMultichainTxOutToBuffer(hash,txout,tmp_amounts,lpScript,&allowed,&required,mapSpecialEntity,strError)) + if(custom_good_for_coin_selection(txout.scriptPubKey) && + ParseMultichainTxOutToBuffer(hash,txout,tmp_amounts,lpScript,&allowed,&required,mapSpecialEntity,strError)) { // All coins are taken, possible future optimization /* From f37b15f641bfd9935e1f765b2ea8603dd55f0f58 Mon Sep 17 00:00:00 2001 From: mike31 Date: Thu, 30 Nov 2017 18:53:29 +0200 Subject: [PATCH 31/71] Fixed setting of relevant version for genesis block --- src/core/init.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/init.cpp b/src/core/init.cpp index 3246e60c..9f7ffd47 100644 --- a/src/core/init.cpp +++ b/src/core/init.cpp @@ -1049,6 +1049,8 @@ bool AppInit2(boost::thread_group& threadGroup,int OutputPipe) bool fFirstRunForBuild; string init_privkey=GetArg("-initprivkey",""); + + mc_gState->m_NetworkParams->m_RelevantProtocolVersion=mc_gState->RelevantParamProtocolVersion(); // Caching relevant protocol version pwalletMain=NULL; if(mc_gState->m_NetworkParams->m_Status != MC_PRM_STATUS_VALID) @@ -1334,7 +1336,6 @@ bool AppInit2(boost::thread_group& threadGroup,int OutputPipe) return InitError(_(seed_error.c_str())); } - mc_gState->m_NetworkParams->m_RelevantProtocolVersion=mc_gState->RelevantParamProtocolVersion(); // Caching relevant protocol version string strBurnAddress=BurnAddress(Params().Base58Prefix(CChainParams::PUBKEY_ADDRESS)); // Caching burn address LogPrint("mchn","mchn: Burn address: %s\n",strBurnAddress.c_str()); From 799d594c5370978b54b90785f4e66c6b82d0c1d4 Mon Sep 17 00:00:00 2001 From: mike31 Date: Mon, 4 Dec 2017 15:20:33 +0200 Subject: [PATCH 32/71] Fixed crash when passing empty address in raw transactions --- src/rpc/rpcutils.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/rpc/rpcutils.cpp b/src/rpc/rpcutils.cpp index 7907c874..4b968aa6 100644 --- a/src/rpc/rpcutils.cpp +++ b/src/rpc/rpcutils.cpp @@ -1942,6 +1942,11 @@ CScript GetScriptForString(string source) destinations.push_back(tok); } + if(destinations.size() == 0) + { + throw runtime_error(" Address cannot be empty"); + } + if(destinations.size() == 1) { CBitcoinAddress address(destinations[0]); From fa88731cea7b247b8c12a3d81b608493ad1f5941 Mon Sep 17 00:00:00 2001 From: mike31 Date: Tue, 5 Dec 2017 10:20:02 +0200 Subject: [PATCH 33/71] Custom filter for combining outputs --- src/wallet/walletcoins.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/wallet/walletcoins.cpp b/src/wallet/walletcoins.cpp index ad8d3dc5..41232796 100644 --- a/src/wallet/walletcoins.cpp +++ b/src/wallet/walletcoins.cpp @@ -944,7 +944,6 @@ bool FindCoinsToCombine(CWallet *lpWallet, int full_count,this_count,pure_native_count; CAmount total_native; int total_native_hit; - vector > active_groups; // Groups found in UTXOs group_count=lpWallet->lpAssetGroups->GroupCount(); @@ -969,7 +968,8 @@ bool FindCoinsToCombine(CWallet *lpWallet, uint256 hash=out.GetHashAndTxOut(txout); out_i=out.i; tmp_amounts->Clear(); - if(ParseMultichainTxOutToBuffer(hash,txout,tmp_amounts,lpScript,&allowed,&required,strError)) + if(custom_good_for_coin_selection(txout.scriptPubKey) && + ParseMultichainTxOutToBuffer(hash,txout,tmp_amounts,lpScript,&allowed,&required,strError)) { if( (required & MC_PTP_ISSUE) == 0 ) // Ignore txouts containing unconfirmed geneses { @@ -1079,7 +1079,8 @@ bool FindCoinsToCombine(CWallet *lpWallet, uint256 hash=out.GetHashAndTxOut(txout); out_i=out.i; tmp_amounts->Clear(); - if(ParseMultichainTxOutToBuffer(hash,txout,tmp_amounts,lpScript,&allowed,&required,strError)) + if(custom_good_for_coin_selection(txout.scriptPubKey) && + ParseMultichainTxOutToBuffer(hash,txout,tmp_amounts,lpScript,&allowed,&required,strError)) { if( (required & MC_PTP_ISSUE) == 0 ) // Ignore txouts containing unconfirmed geneses { From 54ecc673cc2797d47e15d9317cd8af5c842faf69 Mon Sep 17 00:00:00 2001 From: mike31 Date: Wed, 6 Dec 2017 10:49:59 +0200 Subject: [PATCH 34/71] Fixed method field for curl help messages --- src/rpc/rpcserver.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rpc/rpcserver.cpp b/src/rpc/rpcserver.cpp index 83a886fd..6f888414 100644 --- a/src/rpc/rpcserver.cpp +++ b/src/rpc/rpcserver.cpp @@ -1232,7 +1232,7 @@ std::string HelpExampleCli(string methodname, string args){ std::string HelpExampleRpc(string methodname, string args){ return "> curl --user myusername --data-binary '{\"jsonrpc\": \"1.0\", \"id\":\"curltest\", " - "\"method\": \"" + std::string(mc_gState->m_NetworkParams->Name()) + " " + methodname + "\", \"params\": [" + args + "] }' -H 'content-type: text/plain;' http://127.0.0.1:"+ + "\"method\": \"" + methodname + "\", \"params\": [" + args + "] }' -H 'content-type: text/plain;' http://127.0.0.1:"+ strprintf("%d",(int)mc_gState->m_NetworkParams->GetInt64Param("defaultrpcport")) + "\n";// MCHN was hard-coded 8332 before } From 50e3059e8f392276b043c21305c983e5f4623cc0 Mon Sep 17 00:00:00 2001 From: mike31 Date: Wed, 6 Dec 2017 10:56:52 +0200 Subject: [PATCH 35/71] Fixed -cold param help message for multichain-cli --- src/multichain/multichain-cli.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/multichain/multichain-cli.cpp b/src/multichain/multichain-cli.cpp index a975b491..22b0fb19 100644 --- a/src/multichain/multichain-cli.cpp +++ b/src/multichain/multichain-cli.cpp @@ -36,7 +36,7 @@ std::string HelpMessageCli() strUsage += " -? " + _("This help message") + "\n"; strUsage += " -conf= " + strprintf(_("Specify configuration file (default: %s)"), "multichain.conf") + "\n"; strUsage += " -datadir= " + _("Specify data directory") + "\n"; - strUsage += " -cold= " + _("Connect to multichaind-cold: use multichaind-cold default directory if -datadir is not set") + "\n"; + strUsage += " -cold " + _("Connect to multichaind-cold: use multichaind-cold default directory if -datadir is not set") + "\n"; /* MCHN START */ strUsage += " -requestout= " + _("Send request to stderr, stdout or null (not print it at all), default stderr") + "\n"; strUsage += " -saveclilog= " + _("If =0 multichain-cli history is not saved, default 1") + "\n"; From 5e567b2ac0449a4a5cb9b2c9304766b594db0dec Mon Sep 17 00:00:00 2001 From: mike31 Date: Wed, 6 Dec 2017 14:59:18 +0200 Subject: [PATCH 36/71] Fixed error messages when multiple keys and formatted data are not supported --- src/rpc/rpcrawdata.cpp | 4 ++++ src/rpc/rpcstreams.cpp | 8 ++++++++ 2 files changed, 12 insertions(+) diff --git a/src/rpc/rpcrawdata.cpp b/src/rpc/rpcrawdata.cpp index 8ff9a43d..61f5f78b 100644 --- a/src/rpc/rpcrawdata.cpp +++ b/src/rpc/rpcrawdata.cpp @@ -368,6 +368,10 @@ vector ParseRawFormattedData(const Value *value,uint32_t *data_fo else { *strError=string("data should be hexadecimal string"); + if(mc_gState->m_Features->FormattedData() == 0) + { + *strError+=" for this protocol version"; + } } } diff --git a/src/rpc/rpcstreams.cpp b/src/rpc/rpcstreams.cpp index af25338c..aabf8416 100644 --- a/src/rpc/rpcstreams.cpp +++ b/src/rpc/rpcstreams.cpp @@ -642,6 +642,14 @@ Value publishfrom(const Array& params, bool fHelp) } } + if(keys.size() > 1) + { + if( mc_gState->m_Features->MultipleStreamKeys() == 0 ) + { + throw JSONRPCError(RPC_NOT_SUPPORTED, "Multiple keys are not supported by this protocol version"); + } + } + mc_Script *lpDetailsScript; lpDetailsScript=NULL; From fbcfd15e5eed1f1cbc55e2272d9b43eadaf631f9 Mon Sep 17 00:00:00 2001 From: mike31 Date: Wed, 6 Dec 2017 15:41:27 +0200 Subject: [PATCH 37/71] Fixed chain description length issue --- src/chainparams/paramlist.h | 2 +- src/chainparams/params.cpp | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/chainparams/paramlist.h b/src/chainparams/paramlist.h index 183190fb..da71186e 100644 --- a/src/chainparams/paramlist.h +++ b/src/chainparams/paramlist.h @@ -13,7 +13,7 @@ static const mc_OneMultichainParam MultichainParamArray[] = { "chaindescription" , "chain-description" , MC_PRM_STRING | MC_PRM_USER | MC_PRM_CLONE | MC_PRM_SPECIAL ,256, 0, 0, 0, 0.0, 10001, 0, "-mc-chaindescription", "rootstreamname","", - "Chain description, embedded in genesis block coinbase, max 256 chars."}, + "Chain description, embedded in genesis block coinbase, max 90 chars."}, { "rootstreamname" , "root-stream-name" , MC_PRM_STRING | MC_PRM_USER | MC_PRM_CLONE | MC_PRM_SPECIAL,256, 0, 0, 0, 0.0, 10006, 0, "-mc-rootstreamname", "rootstreamopen","", diff --git a/src/chainparams/params.cpp b/src/chainparams/params.cpp index d4b85d63..18c8b27e 100644 --- a/src/chainparams/params.cpp +++ b/src/chainparams/params.cpp @@ -1117,6 +1117,12 @@ int mc_MultichainParams::Validate() return MC_ERR_INVALID_PARAMETER_VALUE; } } + GetParam("chaindescription",&size); + if(size-1 > 90) + { + printf("Invalid parameter value for chain-description - too long: %d\n",size-1); + return MC_ERR_INVALID_PARAMETER_VALUE; + } } else { From 4ed82d4f4ebad22cfd747ec0538e2628ad6bd374 Mon Sep 17 00:00:00 2001 From: mike31 Date: Thu, 7 Dec 2017 10:05:31 +0200 Subject: [PATCH 38/71] Fixed height mismatch in coinbase --- src/miner/miner.cpp | 14 +++++++++----- src/miner/miner.h | 2 +- src/rpc/rpcmining.cpp | 5 +++-- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/miner/miner.cpp b/src/miner/miner.cpp index 4f5e3948..6b2d5377 100644 --- a/src/miner/miner.cpp +++ b/src/miner/miner.cpp @@ -261,7 +261,7 @@ bool CreateBlockSignature(CBlock *block,uint32_t hash_type,CWallet *pwallet) /* MCHN START */ //CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) -CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn,CWallet *pwallet,CPubKey *ppubkey,int *canMine) +CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn,CWallet *pwallet,CPubKey *ppubkey,int *canMine,CBlockIndex** ppPrev) /* MCHN END */ { // Create new block @@ -322,6 +322,10 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn,CWallet *pwallet,CP CBlockIndex* pindexPrev = chainActive.Tip(); const int nHeight = pindexPrev->nHeight + 1; + if(ppPrev) + { + *ppPrev=pindexPrev; + } CCoinsViewCache view(pcoinsTip); // Priority order to process transactions @@ -678,7 +682,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn,CWallet *pwallet,CP /* MCHN START */ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) { - return CreateNewBlock(scriptPubKeyIn,NULL,NULL,NULL); + return CreateNewBlock(scriptPubKeyIn,NULL,NULL,NULL,NULL); } /* MCHN END */ @@ -769,7 +773,7 @@ CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey) // Block should be mined for specific keys, not just any from pool -CBlockTemplate* CreateNewBlockWithDefaultKey(CWallet *pwallet,int *canMine,const set* addresses) +CBlockTemplate* CreateNewBlockWithDefaultKey(CWallet *pwallet,int *canMine,const set* addresses,CBlockIndex** ppPrev) { CPubKey pubkey; bool key_found; @@ -795,7 +799,7 @@ CBlockTemplate* CreateNewBlockWithDefaultKey(CWallet *pwallet,int *canMine,const CScript scriptPubKey = CScript() << OP_DUP << OP_HASH160 << vector(pubkey_hash, pubkey_hash + 20) << OP_EQUALVERIFY << OP_CHECKSIG; - return CreateNewBlock(scriptPubKey,pwallet,&pubkey,canMine); + return CreateNewBlock(scriptPubKey,pwallet,&pubkey,canMine,ppPrev); } /* MCHN END */ @@ -1422,7 +1426,7 @@ void static BitcoinMiner(CWallet *pwallet) const unsigned char *pubkey_hash=(unsigned char *)Hash160(kMiner.begin(),kMiner.end()).begin(); CScript scriptPubKey = CScript() << OP_DUP << OP_HASH160 << vector(pubkey_hash, pubkey_hash + 20) << OP_EQUALVERIFY << OP_CHECKSIG; canMine=prevCanMine; - auto_ptr pblocktemplate(CreateNewBlock(scriptPubKey,pwallet,&kMiner,&canMine)); + auto_ptr pblocktemplate(CreateNewBlock(scriptPubKey,pwallet,&kMiner,&canMine,&pindexPrev)); prevCanMine=canMine; /* MCHN END */ if (!pblocktemplate.get()) diff --git a/src/miner/miner.h b/src/miner/miner.h index abe4db1a..fff4a3bd 100644 --- a/src/miner/miner.h +++ b/src/miner/miner.h @@ -27,7 +27,7 @@ void GenerateBitcoins(bool fGenerate, CWallet* pwallet, int nThreads); /** Generate a new block, without valid proof-of-work */ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn); CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey); -CBlockTemplate* CreateNewBlockWithDefaultKey(CWallet *pwallet,int *canMine, const std::set* addresses = NULL); +CBlockTemplate* CreateNewBlockWithDefaultKey(CWallet *pwallet,int *canMine, const std::set* addresses = NULL,CBlockIndex** ppPrev = NULL); /** Modify the extranonce in a block */ /* MCHN START */ void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce,CWallet *pwallet); diff --git a/src/rpc/rpcmining.cpp b/src/rpc/rpcmining.cpp index def05c13..e6789920 100644 --- a/src/rpc/rpcmining.cpp +++ b/src/rpc/rpcmining.cpp @@ -171,7 +171,8 @@ Value setgenerate(const Array& params, bool fHelp) while (nHeight < nHeightEnd) { int canMine=0; - auto_ptr pblocktemplate(CreateNewBlockWithDefaultKey(pwalletMain,&canMine,lpMinerAddresses)); + CBlockIndex *pindexPrev; + auto_ptr pblocktemplate(CreateNewBlockWithDefaultKey(pwalletMain,&canMine,lpMinerAddresses,&pindexPrev)); // auto_ptr pblocktemplate(CreateNewBlockWithKey(reservekey)); if (!pblocktemplate.get()) { @@ -196,7 +197,7 @@ Value setgenerate(const Array& params, bool fHelp) { LOCK(cs_main); /* MCHN START */ - IncrementExtraNonce(pblock, chainActive.Tip(), nExtraNonce,pwalletMain); + IncrementExtraNonce(pblock, pindexPrev, nExtraNonce,pwalletMain); // IncrementExtraNonce(pblock, chainActive.Tip(), nExtraNonce); /* MCHN START */ } From 6016b7a37cf414c152309708959c89ff479c5788 Mon Sep 17 00:00:00 2001 From: mike31 Date: Thu, 7 Dec 2017 17:21:44 +0200 Subject: [PATCH 39/71] Fixed getstreamkeysummary without ignore for single non-json item --- src/rpc/rpcstreams.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/rpc/rpcstreams.cpp b/src/rpc/rpcstreams.cpp index aabf8416..1fe7c3c2 100644 --- a/src/rpc/rpcstreams.cpp +++ b/src/rpc/rpcstreams.cpp @@ -1506,6 +1506,10 @@ Value getstreamsummary(const Array& params, bool fPublisher) } else { + if( (mode & MC_VMM_IGNORE) == 0) + { + err=MC_ERR_INVALID_PARAMETER_VALUE; + } obj.push_back(Pair("json", empty_object)); } result=obj; From 41cbef3867540afc819f984b1549d9e1ff20183e Mon Sep 17 00:00:00 2001 From: mike31 Date: Sun, 10 Dec 2017 17:35:18 +0200 Subject: [PATCH 40/71] Startup message tweaks --- src/core/init-cold.cpp | 13 ++++++++++--- src/core/init.cpp | 16 +++++++++++----- src/multichain/multichaind-cold.cpp | 2 +- src/multichain/multichaind.cpp | 2 +- 4 files changed, 23 insertions(+), 10 deletions(-) diff --git a/src/core/init-cold.cpp b/src/core/init-cold.cpp index f237d404..e1d36b81 100644 --- a/src/core/init-cold.cpp +++ b/src/core/init-cold.cpp @@ -1013,6 +1013,13 @@ bool AppInit2_Cold(boost::thread_group& threadGroup,int OutputPipe) return false; } LogPrintf(" block index %15dms\n", GetTimeMillis() - nStart); + + if(mapMultiArgs.count("-rpcallowip") == 0) + { + sprintf(bufOutput,"Listening for API requests on port %d (local only - see rpcallowip setting)\n\n",(int)GetArg("-rpcport", BaseParams().RPCPort())); + bytes_written=write(OutputPipe,bufOutput,strlen(bufOutput)); + } + int version=mc_gState->m_NetworkParams->ProtocolVersion(); LogPrintf("MultiChain protocol version: %d\n",version); @@ -1024,11 +1031,11 @@ bool AppInit2_Cold(boost::thread_group& threadGroup,int OutputPipe) if(version != original_protocol_version) { - sprintf(bufOutput,"Protocol version %d (chain created with %d)\n\n",version,original_protocol_version); + sprintf(bufOutput,"Chain running protocol version %d (chain created with %d)\n\n",version,original_protocol_version); } else { - sprintf(bufOutput,"Protocol version %d\n\n",version); + sprintf(bufOutput,"Chain running protocol version %d\n\n",version); } bytes_written=write(OutputPipe,bufOutput,strlen(bufOutput)); } @@ -1236,7 +1243,7 @@ bool AppInit2_Cold(boost::thread_group& threadGroup,int OutputPipe) /* MCHN START */ if(!GetBoolArg("-shortoutput", false)) { - sprintf(bufOutput,"Node started\n"); + sprintf(bufOutput,"Node ready.\n\n"); bytes_written=write(OutputPipe,bufOutput,strlen(bufOutput)); } mc_InitRPCHelpMap(); diff --git a/src/core/init.cpp b/src/core/init.cpp index 9f7ffd47..e7eebbbd 100644 --- a/src/core/init.cpp +++ b/src/core/init.cpp @@ -1870,7 +1870,7 @@ bool AppInit2(boost::thread_group& threadGroup,int OutputPipe) bytes_written=write(OutputPipe,bufOutput,strlen(bufOutput)); if(found_ips > 1) { - sprintf(bufOutput,"\nThis host has multiple IP addresses, so from some networks:\n\n"); + sprintf(bufOutput,"This host has multiple IP addresses, so from some networks:\n"); bytes_written=write(OutputPipe,bufOutput,strlen(bufOutput)); for(int i_ips=0;i_ipsm_NetworkParams->GetInt64Param("protocolversion"); int version=mc_gState->m_NetworkParams->ProtocolVersion(); LogPrintf("MultiChain protocol version: %d\n",version); @@ -2149,11 +2155,11 @@ bool AppInit2(boost::thread_group& threadGroup,int OutputPipe) if(version != original_protocol_version) { - sprintf(bufOutput,"Protocol version %d (chain created with %d)\n\n",version,original_protocol_version); + sprintf(bufOutput,"Chain running protocol version %d (chain created with %d)\n\n",version,original_protocol_version); } else { - sprintf(bufOutput,"Protocol version %d\n\n",version); + sprintf(bufOutput,"Chain running protocol version %d\n\n",version); } bytes_written=write(OutputPipe,bufOutput,strlen(bufOutput)); } @@ -2411,7 +2417,7 @@ bool AppInit2(boost::thread_group& threadGroup,int OutputPipe) /* MCHN START */ if(!GetBoolArg("-shortoutput", false)) { - sprintf(bufOutput,"Node started\n"); + sprintf(bufOutput,"Node ready.\n\n"); bytes_written=write(OutputPipe,bufOutput,strlen(bufOutput)); } mc_InitRPCHelpMap(); diff --git a/src/multichain/multichaind-cold.cpp b/src/multichain/multichaind-cold.cpp index 3df8ae19..cc3a01ee 100644 --- a/src/multichain/multichaind-cold.cpp +++ b/src/multichain/multichaind-cold.cpp @@ -147,7 +147,7 @@ bool AppInit(int argc, char* argv[]) if(!GetBoolArg("-shortoutput", false)) { - fprintf(stdout, "MultiChain server starting\n"); + fprintf(stdout, "Starting up node...\n"); } if (pipe(pipes)) diff --git a/src/multichain/multichaind.cpp b/src/multichain/multichaind.cpp index 9285d77f..93d63b49 100644 --- a/src/multichain/multichaind.cpp +++ b/src/multichain/multichaind.cpp @@ -142,7 +142,7 @@ bool AppInit(int argc, char* argv[]) if(!GetBoolArg("-shortoutput", false)) { - fprintf(stdout, "MultiChain server starting\n"); + fprintf(stdout, "Starting up node...\n\n"); } if (pipe(pipes)) From 42d6ea4fd8308d4359f0382e57b49c9af53da8e8 Mon Sep 17 00:00:00 2001 From: mike31 Date: Sun, 10 Dec 2017 17:35:53 +0200 Subject: [PATCH 41/71] Miner starting nonce randomization --- src/miner/miner.cpp | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/src/miner/miner.cpp b/src/miner/miner.cpp index 6b2d5377..43d46769 100644 --- a/src/miner/miner.cpp +++ b/src/miner/miner.cpp @@ -88,6 +88,11 @@ class TxPriorityCompare } }; +uint32_t RandomStartNonce() +{ + return mc_RandomInRange(0,0x4fffffff); +} + bool UpdateTime(CBlockHeader* pblock, const CBlockIndex* pindexPrev) { /* MCHN START */ @@ -693,7 +698,7 @@ void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& static uint256 hashPrevBlock; if (hashPrevBlock != pblock->hashPrevBlock) { - nExtraNonce = 0; + nExtraNonce = RandomStartNonce(); hashPrevBlock = pblock->hashPrevBlock; } ++nExtraNonce; @@ -1201,7 +1206,7 @@ void static BitcoinMiner(CWallet *pwallet) // Each thread has its own key and counter CReserveKey reservekey(pwallet); - unsigned int nExtraNonce = 0; + unsigned int nExtraNonce = RandomStartNonce();//0; /* MCHN START */ int canMine; @@ -1437,8 +1442,6 @@ void static BitcoinMiner(CWallet *pwallet) CBlock *pblock = &pblocktemplate->block; IncrementExtraNonce(pblock, pindexPrev, nExtraNonce,pwallet); - LogPrint("mcminer","mchn-miner: Running MultiChainMiner with %u transactions in block (%u bytes)\n", pblock->vtx.size(), - ::GetSerializeSize(*pblock, SER_NETWORK, PROTOCOL_VERSION)); // // Search @@ -1446,9 +1449,11 @@ void static BitcoinMiner(CWallet *pwallet) int64_t nStart = GetTime(); uint256 hashTarget = uint256().SetCompact(pblock->nBits); uint256 hash; - uint32_t nNonce = 0; + uint32_t nNonce = RandomStartNonce(); + uint32_t nStartNonce=nNonce; uint32_t nOldNonce = 0; - + LogPrint("mcminer","mchn-miner: Running MultiChainMiner with %u transactions in block (%u bytes). Starting nonce: %08x/%08x\n", pblock->vtx.size(), + ::GetSerializeSize(*pblock, SER_NETWORK, PROTOCOL_VERSION),nNonce,nExtraNonce); double wStartTime=mc_TimeNowAsDouble(); uint64_t wThisCount=0; while (true) { @@ -1554,8 +1559,12 @@ void static BitcoinMiner(CWallet *pwallet) // if (vNodes.empty() && Params().MiningRequiresPeers() && not_setup_period) break; } - if (nNonce >= 0xffff0000) +// if (nNonce >= 0xffff0000) + if ( (nNonce-nStartNonce) >= 0x8fffffff/GetArg("-genproclimit", 1)) + { + LogPrint("mcminer","Too many nonces tried for %08x, switching timestamp\n",nStartNonce); break; + } if (mempool.GetTransactionsUpdated() != nTransactionsUpdatedLast && GetTime() - nStart > 60) break; if (pindexPrev != chainActive.Tip()) From 44101759c6c4e3ad7fb0f78eba6401d2d0bf357d Mon Sep 17 00:00:00 2001 From: mike31 Date: Mon, 18 Dec 2017 16:24:13 +0200 Subject: [PATCH 42/71] Parameter upgrades, not applied --- src/chainparams/params.cpp | 82 +++++++++++++ src/chainparams/params.h | 3 +- src/chainparams/state.h | 1 + src/entities/asset.cpp | 51 +++++--- src/entities/asset.h | 3 + src/rpc/rpcrawdata.cpp | 113 ++++++++++++++++-- src/rpc/rpcupgrades.cpp | 233 ++++++++++++++++++++++++------------- src/rpc/rpcutils.cpp | 64 +++++++++- 8 files changed, 441 insertions(+), 109 deletions(-) diff --git a/src/chainparams/params.cpp b/src/chainparams/params.cpp index 18c8b27e..cf62ee90 100644 --- a/src/chainparams/params.cpp +++ b/src/chainparams/params.cpp @@ -137,6 +137,55 @@ void* mc_MultichainParams::GetParam(const char *param,int* size) return m_lpData+offset; } +int mc_MultichainParams::CanBeUpgradedByVersion(const char *param,int version,int size) +{ + if(m_lpIndex == NULL) + { + return -1; + } + int index=m_lpIndex->Get(param); + if(index<0) + { + return -2; + } + int offset=m_lpCoord[2 * index + 0]; + if(offset<0) + { + return -3; + } + + if(size) + { + if(size != m_lpCoord[2 * index + 1]) + { + return -4; + } + } + + if(version == 0) + { + return m_lpCoord[2 * index + 1]; + } + + if(strcmp(param,"maximumblocksize") == 0) + { + if(version >= 20002) + { + return m_lpCoord[2 * index + 1]; + } + } + + if(strcmp(param,"targetblocktime") == 0) + { + if(version >= 20002) + { + return m_lpCoord[2 * index + 1]; + } + } + + return 0; +} + int mc_MultichainParams::SetParam(const char *param,const char* value,int size) { @@ -454,6 +503,19 @@ double mc_MultichainParams::ParamAccuracy() } +const mc_OneMultichainParam *mc_MultichainParams::FindParam(const char* param) +{ + int i; + for(i=0;im_Name,param) == 0) + { + return MultichainParamArray+i; + } + } + return NULL; +} + int mc_MultichainParams::Read(const char* name) { return Read(name,0,NULL,0); @@ -2003,3 +2065,23 @@ int mc_Features::PerAssetPermissions() return ret; } +int mc_Features::ParameterUpgrades() +{ + int ret=0; + if(mc_gState->m_NetworkParams->IsProtocolMultichain() == 0) + { + return 0; + } + int protocol=mc_gState->m_NetworkParams->ProtocolVersion(); + + if(protocol) + { + if(protocol >= 20002) + { + ret=1; + } + } + + return ret; +} + diff --git a/src/chainparams/params.h b/src/chainparams/params.h index fa61eaef..9236ebd3 100644 --- a/src/chainparams/params.h +++ b/src/chainparams/params.h @@ -127,7 +127,7 @@ typedef struct mc_MultichainParams int Import(const char *name,const char *source_address); int Set(const char *name,const char *source,int source_size); - int FindParam(const char *param); + const mc_OneMultichainParam *FindParam(const char *param); void* GetParam(const char *param,int* size); int64_t GetInt64Param(const char *param); double GetDoubleParam(const char *param); @@ -135,6 +135,7 @@ typedef struct mc_MultichainParams int SetParam(const char *param,const char* value,int size); int SetParam(const char *param,int64_t value); + int CanBeUpgradedByVersion(const char *param,int version,int size); const char* Name(); const unsigned char* DefaultMessageStart(); diff --git a/src/chainparams/state.h b/src/chainparams/state.h index 018174bd..4b1584df 100644 --- a/src/chainparams/state.h +++ b/src/chainparams/state.h @@ -131,6 +131,7 @@ typedef struct mc_Features int MultipleStreamKeys(); int FixedIsUnspendable(); int PerAssetPermissions(); + int ParameterUpgrades(); } mc_Features; typedef struct mc_BlockHeaderInfo diff --git a/src/entities/asset.cpp b/src/entities/asset.cpp index bef46f15..89b26090 100644 --- a/src/entities/asset.cpp +++ b/src/entities/asset.cpp @@ -675,18 +675,21 @@ int mc_AssetDB::InsertEntity(const void* txid, int offset, int entity_type, cons { if(script) { - value_offset=mc_FindSpecialParamInDetailsScript((unsigned char*)script,script_size,MC_ENT_SPRM_UPGRADE_PROTOCOL_VERSION,&value_size); - if(value_offset == script_size) + if(mc_gState->m_Features->ParameterUpgrades() == 0) { - return MC_ERR_ERROR_IN_SCRIPT; - } - if( (value_size <=0) || (value_size > 4) ) - { - return MC_ERR_ERROR_IN_SCRIPT; - } - if((int)mc_GetLE((unsigned char*)script+value_offset,value_size) < 0) - { - return MC_ERR_ERROR_IN_SCRIPT; + value_offset=mc_FindSpecialParamInDetailsScript((unsigned char*)script,script_size,MC_ENT_SPRM_UPGRADE_PROTOCOL_VERSION,&value_size); + if(value_offset == script_size) + { + return MC_ERR_ERROR_IN_SCRIPT; + } + if( (value_size <=0) || (value_size > 4) ) + { + return MC_ERR_ERROR_IN_SCRIPT; + } + if((int)mc_GetLE((unsigned char*)script+value_offset,value_size) < 0) + { + return MC_ERR_ERROR_IN_SCRIPT; + } } value_offset=mc_FindSpecialParamInDetailsScript((unsigned char*)script,script_size,MC_ENT_SPRM_UPGRADE_START_BLOCK,&value_size); if(value_offset != script_size) @@ -1619,7 +1622,24 @@ int mc_AssetDB::FindEntityByFollowOn(mc_EntityDetails *entity,const unsigned cha return 0; } - +const unsigned char* mc_EntityDetails::GetParamUpgrades(int *size) +{ + uint32_t value_offset; + size_t value_size; + + if(m_LedgerRow.m_ScriptSize) + { + value_offset=mc_FindSpecialParamInDetailsScript(m_LedgerRow.m_Script,m_LedgerRow.m_ScriptSize,MC_ENT_SPRM_UPGRADE_CHAIN_PARAMS,&value_size); + if(value_offset != m_LedgerRow.m_ScriptSize) + { + *size=(int)value_size; + return m_LedgerRow.m_Script+value_offset; + } + } + + *size=0; + return NULL; +} const char* mc_EntityDetails::GetName() { @@ -1784,12 +1804,17 @@ int mc_EntityDetails::UpgradeProtocolVersion() { unsigned char *ptr; size_t bytes; + int version; ptr=(unsigned char *)GetSpecialParam(MC_ENT_SPRM_UPGRADE_PROTOCOL_VERSION,&bytes); if(ptr) { if((bytes>0) && (bytes<=4)) { - return (int)mc_GetLE(ptr,bytes); + version=(int)mc_GetLE(ptr,bytes); + if(version > 0) + { + return version; + } } } return 0; diff --git a/src/entities/asset.h b/src/entities/asset.h index 2a36fac2..60fa458c 100644 --- a/src/entities/asset.h +++ b/src/entities/asset.h @@ -60,6 +60,7 @@ #define MC_ENT_SPRM_ASSET_MULTIPLE 0x41 #define MC_ENT_SPRM_UPGRADE_PROTOCOL_VERSION 0x42 #define MC_ENT_SPRM_UPGRADE_START_BLOCK 0x43 +#define MC_ENT_SPRM_UPGRADE_CHAIN_PARAMS 0x44 #define MC_ENT_FLAG_OFFSET_IS_SET 0x00000001 #define MC_ENT_FLAG_NAME_IS_SET 0x00000010 @@ -147,6 +148,8 @@ typedef struct mc_EntityDetails const unsigned char* GetFullRef(); const unsigned char* GetShortRef(); const unsigned char* GetScript(); + const unsigned char* GetParamUpgrades(int *size); + int IsUnconfirmedGenesis(); int GetAssetMultiple(); int IsFollowOn(); diff --git a/src/rpc/rpcrawdata.cpp b/src/rpc/rpcrawdata.cpp index 61f5f78b..e5cb13ef 100644 --- a/src/rpc/rpcrawdata.cpp +++ b/src/rpc/rpcrawdata.cpp @@ -894,6 +894,73 @@ CScript RawDataScriptCreateStream(Value *param,mc_Script *lpDetails,mc_Script *l return scriptOpReturn; } +bool AddParamNameValueToScript(const string param_name,const Value param_value,mc_Script *lpDetailsScript,int version,int *errorCode,string *strError) +{ + int64_t value; + string name=param_name; + + int size=-1; + unsigned char zero=0; + if(param_value.type() == bool_type) + { + value=param_value.get_bool() ? 1 : 0; + size=1; + } + if(param_value.type() == int_type) + { + value=param_value.get_int64(); + size=0; + } + if(size < 0) + { + *errorCode=RPC_INVALID_PARAMETER; + *strError=string("Invalid parameter type"); + return false; + } + + name.erase(std::remove(name.begin(), name.end(), '-'), name.end()); + size=mc_gState->m_NetworkParams->CanBeUpgradedByVersion(name.c_str(),version,size); + + if(size == 1) + { + if(param_value.type() != bool_type) + { + *errorCode=RPC_INVALID_PARAMETER; + *strError=string("Invalid parameter type"); + return false; + } + } + + if(size == -4) + { + *errorCode=RPC_INVALID_PARAMETER; + *strError=string("Invalid parameter type"); + return false; + } + + if(size < 0) + { + *errorCode=RPC_INVALID_PARAMETER; + *strError=string("Invalid parameter name"); + return false; + } + + if(size == 0) + { + *errorCode=RPC_NOT_SUPPORTED; + *strError=string("One of parameters cannot be upgraded by this protocol version"); + return false; + } + + lpDetailsScript->SetData((unsigned char*)name.c_str(),name.size()); + lpDetailsScript->SetData((unsigned char*)&zero,1); + lpDetailsScript->SetData((unsigned char*)&size,MC_PRM_PARAM_SIZE_BYTES); + lpDetailsScript->SetData((unsigned char*)&value,size); + + return true; +} + + CScript RawDataScriptCreateUpgrade(Value *param,mc_Script *lpDetails,mc_Script *lpDetailsScript,int *errorCode,string *strError) { CScript scriptOpReturn=CScript(); @@ -906,10 +973,14 @@ CScript RawDataScriptCreateUpgrade(Value *param,mc_Script *lpDetails,mc_Script * bool missing_name=true; bool missing_startblock=true; + bool missing_details=true; lpDetails->Clear(); lpDetails->AddElement(); - + + lpDetailsScript->Clear(); + lpDetailsScript->AddElement(); + protocol_version=-1; BOOST_FOREACH(const Pair& d, param->get_obj()) @@ -966,7 +1037,7 @@ CScript RawDataScriptCreateUpgrade(Value *param,mc_Script *lpDetails,mc_Script * } if(d.name_ == "details") { - if(protocol_version > 0) + if(!missing_details) { *strError=string("details field can appear only once in the object"); } @@ -979,7 +1050,10 @@ CScript RawDataScriptCreateUpgrade(Value *param,mc_Script *lpDetails,mc_Script * { if( (p.value_.type() == int_type) && (p.value_.get_int() > 0) ) { - protocol_version=p.value_.get_int(); + if(protocol_version < 0) + { + protocol_version=p.value_.get_int(); + } } else { @@ -988,21 +1062,39 @@ CScript RawDataScriptCreateUpgrade(Value *param,mc_Script *lpDetails,mc_Script * } else { - *strError=string("Invalid details"); + if(mc_gState->m_Features->ParameterUpgrades()) + { + AddParamNameValueToScript(p.name_,p.value_,lpDetailsScript,0,errorCode,strError); + } + else + { + *strError=string("Invalid details"); + } + } + } + + script = lpDetailsScript->GetData(0,&bytes); + if(strError->size() == 0) + { + if( (protocol_version <= 0) && (bytes == 0) ) + { + *strError=string("Missing protocol-version"); } } + if(strError->size() == 0) { if(protocol_version > 0) { lpDetails->SetSpecialParamValue(MC_ENT_SPRM_UPGRADE_PROTOCOL_VERSION,(unsigned char*)&protocol_version,4); } - else + if(bytes) { - *strError=string("Missing protocol-version"); - } + lpDetails->SetSpecialParamValue(MC_ENT_SPRM_UPGRADE_CHAIN_PARAMS,script,bytes); + } } - } + } + missing_details=false; field_parsed=true; } if(d.name_ == "create")field_parsed=true; @@ -1014,9 +1106,9 @@ CScript RawDataScriptCreateUpgrade(Value *param,mc_Script *lpDetails,mc_Script * if(strError->size() == 0) { - if(protocol_version < 0) + if(missing_details) { - *strError=string("Missing protocol-version"); + *strError=string("Missing details"); } } @@ -1024,6 +1116,7 @@ CScript RawDataScriptCreateUpgrade(Value *param,mc_Script *lpDetails,mc_Script * { int err; script=lpDetails->GetData(0,&bytes); + lpDetailsScript->Clear(); err=lpDetailsScript->SetNewEntityType(MC_ENT_TYPE_UPGRADE,0,script,bytes); if(err) { diff --git a/src/rpc/rpcupgrades.cpp b/src/rpc/rpcupgrades.cpp index 3c3da522..ea65b881 100644 --- a/src/rpc/rpcupgrades.cpp +++ b/src/rpc/rpcupgrades.cpp @@ -6,6 +6,7 @@ #include "rpc/rpcwallet.h" +bool AddParamNameValueToScript(const string param_name,const Value param_value,mc_Script *lpDetailsScript,int version,int *errorCode,string *strError); Value createupgradefromcmd(const Array& params, bool fHelp) { @@ -23,15 +24,19 @@ Value createupgradefromcmd(const Array& params, bool fHelp) CWalletTx wtx; mc_Script *lpScript; + lpScript=NULL; mc_Script *lpDetailsScript; lpDetailsScript=NULL; mc_Script *lpDetails; + lpDetails=NULL; int ret,type; string upgrade_name=""; - + string strError=""; + int errorCode=RPC_INVALID_PARAMETER; + if (params[2].type() != str_type) throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid upgrade name, should be string"); @@ -71,6 +76,65 @@ Value createupgradefromcmd(const Array& params, bool fHelp) } } + vector addresses; + + vector fromaddresses; + + if(params[0].get_str() != "*") + { + fromaddresses=ParseAddresses(params[0].get_str(),false,false); + + if(fromaddresses.size() != 1) + { + throw JSONRPCError(RPC_INVALID_PARAMETER, "Single from-address should be specified"); + } + + if( (IsMine(*pwalletMain, fromaddresses[0]) & ISMINE_SPENDABLE) != ISMINE_SPENDABLE ) + { + throw JSONRPCError(RPC_WALLET_ADDRESS_NOT_FOUND, "Private key for from-address is not found in this wallet"); + } + + set thisFromAddresses; + + BOOST_FOREACH(const CTxDestination& fromaddress, fromaddresses) + { + thisFromAddresses.insert(fromaddress); + } + + CPubKey pkey; + if(!pwalletMain->GetKeyFromAddressBook(pkey,MC_PTP_CREATE | MC_PTP_ADMIN,&thisFromAddresses)) + { + throw JSONRPCError(RPC_INSUFFICIENT_PERMISSIONS, "from-address doesn't have create or admin permission"); + } + } + else + { + BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, CAddressBookData)& item, pwalletMain->mapAddressBook) + { + const CBitcoinAddress& address = item.first; + CKeyID keyID; + + if(address.GetKeyID(keyID)) + { + if( IsMine(*pwalletMain, keyID) & ISMINE_SPENDABLE ) + { + if(mc_gState->m_Permissions->CanCreate(NULL,(unsigned char*)(&keyID))) + { + if(mc_gState->m_Permissions->CanAdmin(NULL,(unsigned char*)(&keyID))) + { + fromaddresses.push_back(keyID); + } + } + } + } + } + CPubKey pkey; + if(fromaddresses.size() == 0) + { + throw JSONRPCError(RPC_INSUFFICIENT_PERMISSIONS, "This wallet doesn't have keys with create and admin permission"); + } + } + lpScript=new mc_Script; lpDetails=new mc_Script; @@ -89,6 +153,10 @@ Value createupgradefromcmd(const Array& params, bool fHelp) bool protocol_version_found=false; int protocol_version; int start_block; + CScript scriptOpReturn=CScript(); + + lpDetailsScript=new mc_Script; + lpDetailsScript->AddElement(); if(params[4].type() == obj_type) { @@ -99,25 +167,30 @@ Value createupgradefromcmd(const Array& params, bool fHelp) { if(s.value_.type() != int_type) { - throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid protocol version, expecting integer"); + strError="Invalid protocol version, expecting integer"; + goto exitlbl; } protocol_version_found=true; protocol_version=s.value_.get_int(); if( (protocol_version < mc_gState->MinProtocolVersion()) || ( -mc_gState->VersionInfo(protocol_version) != mc_gState->GetNumericVersion() ) ) { - throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid value for protocol version. Valid range: %s\n",mc_SupportedProtocols().c_str())); + strError=strprintf("Invalid value for protocol version. Valid range: %s\n",mc_SupportedProtocols().c_str()); + goto exitlbl; } if( protocol_version < mc_gState->MinProtocolDowngradeVersion() ) { - throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid protocol version, cannot downgrade to this version"); + strError="Invalid protocol version, cannot downgrade to this version"; + goto exitlbl; } if( mc_gState->m_NetworkParams->ProtocolVersion() >= mc_gState->MinProtocolForbiddenDowngradeVersion() ) { if(protocol_version < mc_gState->m_NetworkParams->ProtocolVersion()) { - throw JSONRPCError(RPC_NOT_ALLOWED, "Invalid protocol version, cannot downgrade from current version"); + strError="Invalid protocol version, cannot downgrade from current version"; + errorCode=RPC_NOT_ALLOWED; + goto exitlbl; } } lpDetails->SetSpecialParamValue(MC_ENT_SPRM_UPGRADE_PROTOCOL_VERSION,(unsigned char*)&protocol_version,4); @@ -128,122 +201,104 @@ Value createupgradefromcmd(const Array& params, bool fHelp) { if(s.value_.type() != int_type) { - throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid start block, expecting integer"); + strError="Invalid start block, expecting integer"; + goto exitlbl; } start_block=s.value_.get_int(); lpDetails->SetSpecialParamValue(MC_ENT_SPRM_UPGRADE_START_BLOCK,(unsigned char*)&start_block,4); } else { - throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter name"); + if(mc_gState->m_Features->ParameterUpgrades()) + { + if(!AddParamNameValueToScript(s.name_,s.value_,lpDetailsScript,0,&errorCode,&strError)) + { + goto exitlbl; + } + } + else + { + strError="Invalid parameter name"; + goto exitlbl; + } // lpDetails->SetParamValue(s.name_.c_str(),s.name_.size(),(unsigned char*)s.value_.get_str().c_str(),s.value_.get_str().size()); } } } + } else { - throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid custom fields, expecting object"); + strError="Invalid custom fields, expecting object"; + goto exitlbl; } - if(!protocol_version_found) + size_t bytes; + const unsigned char *script; + + script = lpDetailsScript->GetData(0,&bytes); + if( !protocol_version_found && (bytes == 0) ) + { + strError="Missing protocol-version"; + if(mc_gState->m_Features->ParameterUpgrades()) + { + strError+=" or other parameters"; + } + + goto exitlbl; + } + + if(bytes) { - throw JSONRPCError(RPC_INVALID_PARAMETER, "protocol-version is required"); + lpDetails->SetSpecialParamValue(MC_ENT_SPRM_UPGRADE_CHAIN_PARAMS,script,bytes); } - size_t bytes; - const unsigned char *script; script=lpDetails->GetData(0,&bytes); - lpDetailsScript=new mc_Script; int err; size_t elem_size; const unsigned char *elem; - CScript scriptOpReturn=CScript(); + lpDetailsScript->Clear(); err=lpDetailsScript->SetNewEntityType(MC_ENT_TYPE_UPGRADE,0,script,bytes); if(err) { - throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid custom fields or upgrade name, too long"); + strError="Invalid custom fields or upgrade name, too long"; + goto exitlbl; } elem = lpDetailsScript->GetData(0,&elem_size); scriptOpReturn << vector(elem, elem + elem_size) << OP_DROP << OP_RETURN; - vector addresses; - - vector fromaddresses; - if(params[0].get_str() != "*") + EnsureWalletIsUnlocked(); { - fromaddresses=ParseAddresses(params[0].get_str(),false,false); - - if(fromaddresses.size() != 1) - { - throw JSONRPCError(RPC_INVALID_PARAMETER, "Single from-address should be specified"); - } + LOCK (pwalletMain->cs_wallet_send); - if( (IsMine(*pwalletMain, fromaddresses[0]) & ISMINE_SPENDABLE) != ISMINE_SPENDABLE ) - { - throw JSONRPCError(RPC_WALLET_ADDRESS_NOT_FOUND, "Private key for from-address is not found in this wallet"); - } + SendMoneyToSeveralAddresses(addresses, 0, wtx, lpScript, scriptOpReturn,fromaddresses); + } - set thisFromAddresses; - - BOOST_FOREACH(const CTxDestination& fromaddress, fromaddresses) - { - thisFromAddresses.insert(fromaddress); - } +exitlbl: - CPubKey pkey; - if(!pwalletMain->GetKeyFromAddressBook(pkey,MC_PTP_CREATE | MC_PTP_ADMIN,&thisFromAddresses)) - { - throw JSONRPCError(RPC_INSUFFICIENT_PERMISSIONS, "from-address doesn't have create or admin permission"); - } - } - else + if(lpDetailsScript) { - BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, CAddressBookData)& item, pwalletMain->mapAddressBook) - { - const CBitcoinAddress& address = item.first; - CKeyID keyID; - - if(address.GetKeyID(keyID)) - { - if( IsMine(*pwalletMain, keyID) & ISMINE_SPENDABLE ) - { - if(mc_gState->m_Permissions->CanCreate(NULL,(unsigned char*)(&keyID))) - { - if(mc_gState->m_Permissions->CanAdmin(NULL,(unsigned char*)(&keyID))) - { - fromaddresses.push_back(keyID); - } - } - } - } - } - CPubKey pkey; - if(fromaddresses.size() == 0) - { - throw JSONRPCError(RPC_INSUFFICIENT_PERMISSIONS, "This wallet doesn't have keys with create and admin permission"); - } + delete lpDetailsScript; } - - - EnsureWalletIsUnlocked(); - LOCK (pwalletMain->cs_wallet_send); - - SendMoneyToSeveralAddresses(addresses, 0, wtx, lpScript, scriptOpReturn,fromaddresses); - if(lpDetailsScript) { - delete lpDetailsScript; + delete lpDetails; + } + if(lpScript) + { + delete lpScript; } - delete lpDetails; - delete lpScript; + if(strError.size()) + { + throw JSONRPCError(errorCode, strError); + } return wtx.GetHash().GetHex(); } @@ -277,10 +332,13 @@ Value approvefrom(const json_spirit::Array& params, bool fHelp) if( mc_gState->m_NetworkParams->ProtocolVersion() >= mc_gState->MinProtocolForbiddenDowngradeVersion() ) { - if(entity.UpgradeProtocolVersion() < mc_gState->m_NetworkParams->ProtocolVersion()) + if(entity.UpgradeProtocolVersion()) { - throw JSONRPCError(RPC_NOT_ALLOWED, "Invalid protocol version, cannot downgrade from current version"); - } + if(entity.UpgradeProtocolVersion() < mc_gState->m_NetworkParams->ProtocolVersion()) + { + throw JSONRPCError(RPC_NOT_ALLOWED, "Invalid protocol version, cannot downgrade from current version"); + } + } } if(mc_gState->m_Permissions->IsApproved(entity.GetTxID()+MC_AST_SHORT_TXID_OFFSET,0)) @@ -471,15 +529,22 @@ Value listupgrades(const json_spirit::Array& params, bool fHelp) } if(current_height >=applied_height) { - if((latest_version < mc_gState->MinProtocolForbiddenDowngradeVersion()) || (upgrade_entity.UpgradeProtocolVersion() >= latest_version)) + if(upgrade_entity.UpgradeProtocolVersion()) { - latest_version=upgrade_entity.UpgradeProtocolVersion(); - entry.push_back(Pair("appliedblock",(int64_t)applied_height)); + if((latest_version < mc_gState->MinProtocolForbiddenDowngradeVersion()) || (upgrade_entity.UpgradeProtocolVersion() >= latest_version)) + { + latest_version=upgrade_entity.UpgradeProtocolVersion(); + entry.push_back(Pair("appliedblock",(int64_t)applied_height)); + } + else + { + Value null_value; + entry.push_back(Pair("appliedblock",null_value)); + } } else { - Value null_value; - entry.push_back(Pair("appliedblock",null_value)); + entry.push_back(Pair("appliedblock",(int64_t)applied_height)); } } else diff --git a/src/rpc/rpcutils.cpp b/src/rpc/rpcutils.cpp index 4b968aa6..b79e6ba3 100644 --- a/src/rpc/rpcutils.cpp +++ b/src/rpc/rpcutils.cpp @@ -752,6 +752,60 @@ Object StreamEntry(const unsigned char *txid,uint32_t output_level) return entry; } +map ParamsToUpgrade(mc_EntityDetails *entity,int version) +{ + map result; + int size=0; + const mc_OneMultichainParam *param; + char* ptr=(char*)entity->GetParamUpgrades(&size); + char* ptrEnd; + string param_name; + int param_size,given_size; + int64_t param_value; + if(ptr) + { + ptrEnd=ptr+size; + while(ptrm_NetworkParams->FindParam(ptr); + ptr+=strlen(ptr)+1; + if(param) + { + param_size=mc_gState->m_NetworkParams->CanBeUpgradedByVersion(param->m_Name,version,0); + given_size=(int)mc_GetLE(ptr,MC_PRM_PARAM_SIZE_BYTES); + ptr+=MC_PRM_PARAM_SIZE_BYTES; + if( (param_size > 0) && (param_size == given_size) ) + { + param_name=string(param->m_DisplayName); + param_value=mc_GetLE(ptr,param_size); + if(result.find(param_name) == result.end()) + { + switch(param->m_Type & MC_PRM_DATA_TYPE_MASK) + { + case MC_PRM_BOOLEAN: + result.insert(make_pair(param_name, (param_value != 0) )); + break; + case MC_PRM_INT32: + result.insert(make_pair(param_name, (int)param_value)); + case MC_PRM_UINT32: + case MC_PRM_INT64: + result.insert(make_pair(param_name, param_value)); + break; + } + } + } + ptr+=given_size; + } + } + } + } + + return result; +} + + Object UpgradeEntry(const unsigned char *txid) { Object entry; @@ -777,7 +831,15 @@ Object UpgradeEntry(const unsigned char *txid) } entry.push_back(Pair("createtxid", hash.GetHex())); Object fields; - fields.push_back(Pair("protocol-version",entity.UpgradeProtocolVersion())); + map params_to_upgrade=ParamsToUpgrade(&entity,0); + if(entity.UpgradeProtocolVersion()) + { + fields.push_back(Pair("protocol-version",entity.UpgradeProtocolVersion())); + } + for(map::iterator it = params_to_upgrade.begin(); it != params_to_upgrade.end(); ++it) + { + fields.push_back(Pair(it->first, it->second)); + } entry.push_back(Pair("params",fields)); entry.push_back(Pair("startblock",(int64_t)entity.UpgradeStartBlock())); From 014d35441640a0f27f18bb54f89ff7dc1b9a1566 Mon Sep 17 00:00:00 2001 From: mike31 Date: Tue, 19 Dec 2017 16:40:48 +0200 Subject: [PATCH 43/71] Applied parameters in listupgrades --- src/chainparams/params.cpp | 40 ++++++- src/chainparams/params.h | 4 + src/chainparams/state.h | 15 +++ src/protocol/multichainblock.cpp | 162 ++++++++++++++++++++++++++++ src/rpc/rpcrawdata.cpp | 93 ++++++++++------ src/rpc/rpcupgrades.cpp | 180 +++++++++++++++++++++++++++++++ src/rpc/rpcutils.cpp | 38 ++++--- 7 files changed, 480 insertions(+), 52 deletions(-) diff --git a/src/chainparams/params.cpp b/src/chainparams/params.cpp index cf62ee90..5bc45284 100644 --- a/src/chainparams/params.cpp +++ b/src/chainparams/params.cpp @@ -102,6 +102,32 @@ int64_t mc_MultichainParams::GetInt64Param(const char *param) return mc_GetLE(ptr,size); } +double mc_MultichainParams::Int64ToDecimal(int64_t value) +{ + if(value < 0) + { + return -((double)(-value) / MC_PRM_DECIMAL_GRANULARITY); + } + return (double)value / MC_PRM_DECIMAL_GRANULARITY; +} + +int64_t mc_MultichainParams::DecimalToInt64(double value) +{ + return (int64_t)(value*MC_PRM_DECIMAL_GRANULARITY+mc_gState->m_NetworkParams->ParamAccuracy()); +} + +int mc_MultichainParams::GetParamFromScript(char* script,int64_t *value,int *size) +{ + char *ptr; + ptr=script; + ptr+=strlen(ptr)+1; + *size=(int)mc_GetLE(ptr,MC_PRM_PARAM_SIZE_BYTES); + ptr+=MC_PRM_PARAM_SIZE_BYTES; + *value=mc_GetLE(ptr,*size); + ptr+=*size; + return ptr-script; +} + double mc_MultichainParams::GetDoubleParam(const char *param) { int n=(int)mc_gState->m_NetworkParams->GetInt64Param(param); @@ -137,6 +163,18 @@ void* mc_MultichainParams::GetParam(const char *param,int* size) return m_lpData+offset; } +int mc_MultichainParams::IsParamUpgradeValueInRange(const mc_OneMultichainParam *param,int version,int64_t value) +{ + if(value >= param->m_MinIntegerValue) + { + if(value <= param->m_MaxIntegerValue) + { + return 1; + } + } + return 0; +} + int mc_MultichainParams::CanBeUpgradedByVersion(const char *param,int version,int size) { if(m_lpIndex == NULL) @@ -154,7 +192,7 @@ int mc_MultichainParams::CanBeUpgradedByVersion(const char *param,int version,in return -3; } - if(size) + if(size > 0) { if(size != m_lpCoord[2 * index + 1]) { diff --git a/src/chainparams/params.h b/src/chainparams/params.h index 9236ebd3..2be4028b 100644 --- a/src/chainparams/params.h +++ b/src/chainparams/params.h @@ -131,11 +131,15 @@ typedef struct mc_MultichainParams void* GetParam(const char *param,int* size); int64_t GetInt64Param(const char *param); double GetDoubleParam(const char *param); + double Int64ToDecimal(int64_t value); + int64_t DecimalToInt64(double value); + int GetParamFromScript(char* ptr,int64_t *value,int *size); int SetParam(const char *param,const char* value,int size); int SetParam(const char *param,int64_t value); int CanBeUpgradedByVersion(const char *param,int version,int size); + int IsParamUpgradeValueInRange(const mc_OneMultichainParam *param,int version,int64_t value); const char* Name(); const unsigned char* DefaultMessageStart(); diff --git a/src/chainparams/state.h b/src/chainparams/state.h index 4b1584df..34f1a38b 100644 --- a/src/chainparams/state.h +++ b/src/chainparams/state.h @@ -106,6 +106,21 @@ typedef struct mc_Params } mc_Params; +typedef struct mc_UpgradeStatus +{ + unsigned char m_EntityShortTxID[MC_ENT_KEY_SIZE]; + uint32_t m_ApprovedBlock; + uint32_t m_AppliedBlock; + uint32_t m_FirstParam; + uint32_t m_LastParam; +} mc_UpgradeStatus; + +typedef struct mc_UpgradedParameter +{ + const mc_OneMultichainParam *m_Param; + int64_t m_Value; +} mc_UpgradedParameter; + typedef struct mc_Features { int MinProtocolVersion(); diff --git a/src/protocol/multichainblock.cpp b/src/protocol/multichainblock.cpp index d5ec0fd1..4b3588fe 100644 --- a/src/protocol/multichainblock.cpp +++ b/src/protocol/multichainblock.cpp @@ -9,6 +9,8 @@ #include "multichain/multichain.h" #include "wallet/wallettxs.h" +#include + extern mc_WalletTxs* pwalletTxsMain; @@ -31,6 +33,166 @@ bool AcceptPermissionsAndCheckForDust(const CTransaction &tx,bool accept,string& bool IsTxBanned(uint256 txid); +int CreateUpgradeLists(int current_height,vector *vParams,vector *vUpgrades) +{ + mc_EntityDetails entity; + mc_Buffer *upgrades; + mc_UpgradeStatus upgrade; + mc_UpgradedParameter param; + + upgrades=NULL; + set stored_upgrades; + map map_sorted; + uint160 hash; + + int OriginalProtocolVersion=(int)mc_gState->m_NetworkParams->GetInt64Param("protocolversion"); + int NewProtocolVersion=OriginalProtocolVersion; + int version; + int err=MC_ERR_NOERROR; + + if(vUpgrades) + { + vUpgrades->clear(); + } + vParams->clear(); + + upgrades=mc_gState->m_Permissions->GetUpgradeList(NULL,NULL); + + + for(int i=0;iGetCount();i++) + { + mc_PermissionDetails *plsRow; + plsRow=(mc_PermissionDetails *)(upgrades->GetRow(i)); + if(plsRow->m_Type == MC_PTP_UPGRADE) + { + if(vParams) + { + memcpy(&hash,plsRow->m_Address,sizeof(uint160)); + stored_upgrades.insert(hash); + } + map_sorted.insert(std::make_pair(plsRow->m_LastRow,i)); + } + } + + if(vParams) + { + for(int i=0;iGetCount();i++) + { + mc_PermissionDetails *plsRow; + plsRow=(mc_PermissionDetails *)(upgrades->GetRow(i)); + if(plsRow->m_Type != MC_PTP_UPGRADE) + { + memcpy(&hash,plsRow->m_Address,sizeof(uint160)); + if(stored_upgrades.count(hash) == 0) + { + plsRow->m_BlockTo = 0; + map_sorted.insert(std::make_pair(plsRow->m_LastRow,i)); + } + } + } + } + +/* + for(int i=0;iGetCount();i++) + { + mc_PermissionDetails *plsRow; + plsRow=(mc_PermissionDetails *)(permissions->GetRow(i)); + if(plsRow->m_Type == MC_PTP_UPGRADE) + { + map_sorted.insert(std::make_pair(plsRow->m_LastRow,i)); + } + } +*/ + BOOST_FOREACH(PAIRTYPE(const uint64_t, int)& item, map_sorted) + { + int i=item.second; + mc_PermissionDetails *plsRow; + plsRow=(mc_PermissionDetails *)(upgrades->GetRow(i)); +// if(plsRow->m_Type == MC_PTP_UPGRADE) + { + memset(&upgrade,0,sizeof(mc_UpgradeStatus)); + memcpy(upgrade.m_EntityShortTxID,plsRow->m_Address,MC_AST_SHORT_TXID_SIZE); + upgrade.m_ApprovedBlock=current_height+2; + upgrade.m_AppliedBlock=current_height+2; + upgrade.m_FirstParam=(int)vParams->size(); + if(plsRow->m_BlockFrom < plsRow->m_BlockTo) + { + upgrade.m_ApprovedBlock=plsRow->m_BlockReceived; + if(mc_gState->m_Assets->FindEntityByShortTxID(&entity,plsRow->m_Address)) + { + int applied_height=entity.UpgradeStartBlock(); + if((int)plsRow->m_BlockReceived > applied_height) + { + applied_height=plsRow->m_BlockReceived; + } + upgrade.m_AppliedBlock=applied_height; + if(current_height >=applied_height) + { + version=entity.UpgradeProtocolVersion(); + if(version >= mc_gState->MinProtocolDowngradeVersion()) + { + if((NewProtocolVersion < mc_gState->MinProtocolForbiddenDowngradeVersion()) || (version >= NewProtocolVersion)) + { + NewProtocolVersion=version; + if( mc_gState->IsSupported(version) == 0 ) + { + err=MC_ERR_NOT_SUPPORTED; + } + memset(¶m,0,sizeof(mc_UpgradedParameter)); + param.m_Param=mc_gState->m_NetworkParams->FindParam("protocolversion"); + param.m_Value=version; + vParams->push_back(param); + } + } + + if(err == MC_ERR_NOERROR) + { + int size=0; + char* ptr=(char*)entity.GetParamUpgrades(&size); + char* ptrEnd; + int param_size,given_size; + int64_t param_value; + if(ptr) + { + ptrEnd=ptr+size; + while(ptrm_NetworkParams->FindParam(ptr); + ptr+=mc_gState->m_NetworkParams->GetParamFromScript(ptr,¶m_value,&given_size); + if(param.m_Param) + { + param_size=mc_gState->m_NetworkParams->CanBeUpgradedByVersion(param.m_Param->m_Name,NewProtocolVersion,0); + if( (param_size > 0) && (param_size == given_size) ) + { + if(mc_gState->m_NetworkParams->IsParamUpgradeValueInRange(param.m_Param,NewProtocolVersion,param_value)) + { + param.m_Value=param_value; + vParams->push_back(param); + } + } + } + } + } + } + } + } + } + upgrade.m_LastParam=(int)vParams->size(); + if(vUpgrades) + { + vUpgrades->push_back(upgrade); + } + } + } + + +exitlbl: + mc_gState->m_Permissions->FreePermissionList(upgrades); + mc_gState->m_ProtocolVersionToUpgrade=NewProtocolVersion; + + return err; +} + bool ReplayMemPool(CTxMemPool& pool, int from,bool accept) { int pos; diff --git a/src/rpc/rpcrawdata.cpp b/src/rpc/rpcrawdata.cpp index e5cb13ef..686531be 100644 --- a/src/rpc/rpcrawdata.cpp +++ b/src/rpc/rpcrawdata.cpp @@ -896,47 +896,72 @@ CScript RawDataScriptCreateStream(Value *param,mc_Script *lpDetails,mc_Script *l bool AddParamNameValueToScript(const string param_name,const Value param_value,mc_Script *lpDetailsScript,int version,int *errorCode,string *strError) { + int64_t value; - string name=param_name; + string name=param_name; + name.erase(std::remove(name.begin(), name.end(), '-'), name.end()); + const mc_OneMultichainParam *param=mc_gState->m_NetworkParams->FindParam(name.c_str()); - int size=-1; - unsigned char zero=0; - if(param_value.type() == bool_type) - { - value=param_value.get_bool() ? 1 : 0; - size=1; - } - if(param_value.type() == int_type) - { - value=param_value.get_int64(); - size=0; - } - if(size < 0) + if(param == NULL) { *errorCode=RPC_INVALID_PARAMETER; - *strError=string("Invalid parameter type"); - return false; - } - - name.erase(std::remove(name.begin(), name.end(), '-'), name.end()); - size=mc_gState->m_NetworkParams->CanBeUpgradedByVersion(name.c_str(),version,size); - - if(size == 1) - { - if(param_value.type() != bool_type) - { - *errorCode=RPC_INVALID_PARAMETER; - *strError=string("Invalid parameter type"); - return false; - } - } + *strError=string("Invalid parameter name"); + return false; + } - if(size == -4) + int size; + unsigned char zero=0; + switch(param->m_Type & MC_PRM_DATA_TYPE_MASK) { - *errorCode=RPC_INVALID_PARAMETER; - *strError=string("Invalid parameter type"); - return false; + case MC_PRM_BOOLEAN: + if(param_value.type() == bool_type) + { + value=param_value.get_bool() ? 1 : 0; + } + else + { + *errorCode=RPC_INVALID_PARAMETER; + *strError=string("Invalid parameter type, should be boolean"); + return false; + } + break; + case MC_PRM_INT32: + case MC_PRM_INT64: + case MC_PRM_UINT32: + if(param->m_Type & MC_PRM_DECIMAL) + { + if(param_value.type() == real_type) + { + value=mc_gState->m_NetworkParams->DecimalToInt64(param_value.get_real()); + } + else + { + *errorCode=RPC_INVALID_PARAMETER; + *strError=string("Invalid parameter type, should be numeric"); + return false; + } + } + else + { + if(param_value.type() == int_type) + { + value=param_value.get_int64(); + } + else + { + *errorCode=RPC_INVALID_PARAMETER; + *strError=string("Invalid parameter type, should be integer"); + return false; + } + } + break; + default: + *errorCode=RPC_NOT_SUPPORTED; + *strError=string("One of parameters cannot be upgraded by this protocol version"); + return false; } + + size=mc_gState->m_NetworkParams->CanBeUpgradedByVersion(name.c_str(),version,0); if(size < 0) { diff --git a/src/rpc/rpcupgrades.cpp b/src/rpc/rpcupgrades.cpp index ea65b881..b44705f2 100644 --- a/src/rpc/rpcupgrades.cpp +++ b/src/rpc/rpcupgrades.cpp @@ -7,6 +7,7 @@ #include "rpc/rpcwallet.h" bool AddParamNameValueToScript(const string param_name,const Value param_value,mc_Script *lpDetailsScript,int version,int *errorCode,string *strError); +int CreateUpgradeLists(int current_height,vector *vParams,vector *vUpgrades); Value createupgradefromcmd(const Array& params, bool fHelp) { @@ -436,6 +437,185 @@ Value listupgrades(const json_spirit::Array& params, bool fHelp) } } +/* + if(inputStrings.size()) + { + { + LOCK(cs_main); + for(int is=0;is<(int)inputStrings.size();is++) + { + string param=inputStrings[is]; + + mc_EntityDetails upgrade_entity; + ParseEntityIdentifier(param,&upgrade_entity, MC_ENT_TYPE_UPGRADE); + + upgrades=mc_gState->m_Permissions->GetUpgradeList(upgrade_entity.GetTxID() + MC_AST_SHORT_TXID_OFFSET,upgrades); + } + } + } + else + { + { + LOCK(cs_main); + upgrades=mc_gState->m_Permissions->GetUpgradeList(NULL,upgrades); + } + } + */ + vector vParams; + vector vUpgrades; + int current_height=chainActive.Height(); + + CreateUpgradeLists(chainActive.Height(),&vParams,&vUpgrades); + + for(int u=0;u<(int)vUpgrades.size();u++) + { + Object entry; + Object applied_params; + mc_PermissionDetails *plsRow; + mc_PermissionDetails *plsDet; + mc_EntityDetails upgrade_entity; + bool take_it,approved; + int flags,consensus,remaining; + Value null_value; + string param_name; + + upgrade_entity.Zero(); + mc_gState->m_Assets->FindEntityByShortTxID(&upgrade_entity,vUpgrades[u].m_EntityShortTxID); + entry=UpgradeEntry(upgrade_entity.GetTxID()); + + entry.push_back(Pair("approved", (vUpgrades[u].m_ApprovedBlock <= current_height+1))); + + for(int p=vUpgrades[u].m_FirstParam;pm_DisplayName); + if(vParams[p].m_Param->m_Type & MC_PRM_DECIMAL) + { + applied_params.push_back(Pair(param_name,mc_gState->m_NetworkParams->Int64ToDecimal(vParams[p].m_Value))); + } + else + { + switch(vParams[p].m_Param->m_Type & MC_PRM_DATA_TYPE_MASK) + { + case MC_PRM_BOOLEAN: + applied_params.push_back(Pair(param_name,(vParams[p].m_Value != 0))); + break; + case MC_PRM_INT32: + applied_params.push_back(Pair(param_name,(int)vParams[p].m_Value)); + case MC_PRM_UINT32: + case MC_PRM_INT64: + applied_params.push_back(Pair(param_name,vParams[p].m_Value)); + break; + } + } + } + + if(vUpgrades[u].m_ApprovedBlock <= current_height) + { + entry.push_back(Pair("appliedblock", (int64_t)vUpgrades[u].m_ApprovedBlock)); + entry.push_back(Pair("appliedparams", applied_params)); + } + else + { + entry.push_back(Pair("appliedblock", null_value)); + entry.push_back(Pair("appliedparams", null_value)); + } + + upgrades=mc_gState->m_Permissions->GetUpgradeList(upgrade_entity.GetTxID() + MC_AST_SHORT_TXID_OFFSET,upgrades); + if(upgrades->GetCount()) + { + plsRow=(mc_PermissionDetails *)(upgrades->GetRow(upgrades->GetCount()-1)); + flags=plsRow->m_Flags; + consensus=plsRow->m_RequiredAdmins; + if(plsRow->m_Type != MC_PTP_UPGRADE) + { + plsRow->m_BlockTo=0; + } + + Array admins; + Array pending; + mc_Buffer *details; + + if(plsRow->m_Type == MC_PTP_UPGRADE) + { + details=mc_gState->m_Permissions->GetPermissionDetails(plsRow); + } + else + { + details=NULL; + } + + if(details) + { + for(int j=0;jGetCount();j++) + { + plsDet=(mc_PermissionDetails *)(details->GetRow(j)); + remaining=plsDet->m_RequiredAdmins; + if(plsDet->m_BlockFrom < plsDet->m_BlockTo) + { + uint160 addr; + memcpy(&addr,plsDet->m_LastAdmin,sizeof(uint160)); + CKeyID lpKeyID=CKeyID(addr); + admins.push_back(CBitcoinAddress(lpKeyID).ToString()); + } + } + consensus=plsRow->m_RequiredAdmins; + } + if(admins.size() == 0) + { + if(plsRow->m_BlockFrom < plsRow->m_BlockTo) + { + uint160 addr; + memcpy(&addr,plsRow->m_LastAdmin,sizeof(uint160)); + CKeyID lpKeyID=CKeyID(addr); + admins.push_back(CBitcoinAddress(lpKeyID).ToString()); + } + } + + entry.push_back(Pair("admins", admins)); + entry.push_back(Pair("required", (int64_t)(consensus-admins.size()))); + } + upgrades->Clear(); + results.push_back(entry); + } + + mc_gState->m_Permissions->FreePermissionList(upgrades); + + return results; +} + +Value listupgrades_old(const json_spirit::Array& params, bool fHelp) +{ + if (fHelp || params.size() > 1) + throw runtime_error("Help message not found\n"); + + Array results; + mc_Buffer *upgrades; + int latest_version; + + upgrades=NULL; + + + vector inputStrings; + if (params.size() > 0 && params[0].type() != null_type && ((params[0].type() != str_type) || (params[0].get_str() !="*" ) ) ) + { + if(params[0].type() == str_type) + { + inputStrings.push_back(params[0].get_str()); + if(params[0].get_str() == "") + { + return results; + } + } + else + { + inputStrings=ParseStringList(params[0]); + if(inputStrings.size() == 0) + { + return results; + } + } + } + if(inputStrings.size()) { diff --git a/src/rpc/rpcutils.cpp b/src/rpc/rpcutils.cpp index b79e6ba3..66ea22ff 100644 --- a/src/rpc/rpcutils.cpp +++ b/src/rpc/rpcutils.cpp @@ -767,36 +767,40 @@ map ParamsToUpgrade(mc_EntityDetails *entity,int version) ptrEnd=ptr+size; while(ptrm_NetworkParams->FindParam(ptr); + ptr+=mc_gState->m_NetworkParams->GetParamFromScript(ptr,¶m_value,&given_size); + if(strcmp(ptr,"protocolversion")) { - param=mc_gState->m_NetworkParams->FindParam(ptr); - ptr+=strlen(ptr)+1; if(param) { param_size=mc_gState->m_NetworkParams->CanBeUpgradedByVersion(param->m_Name,version,0); - given_size=(int)mc_GetLE(ptr,MC_PRM_PARAM_SIZE_BYTES); - ptr+=MC_PRM_PARAM_SIZE_BYTES; if( (param_size > 0) && (param_size == given_size) ) { param_name=string(param->m_DisplayName); - param_value=mc_GetLE(ptr,param_size); if(result.find(param_name) == result.end()) { - switch(param->m_Type & MC_PRM_DATA_TYPE_MASK) + if(param->m_Type & MC_PRM_DECIMAL) + { + result.insert(make_pair(param_name, mc_gState->m_NetworkParams->Int64ToDecimal(param_value))); + } + else { - case MC_PRM_BOOLEAN: - result.insert(make_pair(param_name, (param_value != 0) )); - break; - case MC_PRM_INT32: - result.insert(make_pair(param_name, (int)param_value)); - case MC_PRM_UINT32: - case MC_PRM_INT64: - result.insert(make_pair(param_name, param_value)); - break; - } + switch(param->m_Type & MC_PRM_DATA_TYPE_MASK) + { + case MC_PRM_BOOLEAN: + result.insert(make_pair(param_name, (param_value != 0) )); + break; + case MC_PRM_INT32: + result.insert(make_pair(param_name, (int)param_value)); + case MC_PRM_UINT32: + case MC_PRM_INT64: + result.insert(make_pair(param_name, param_value)); + break; + } + } } } - ptr+=given_size; } } } From 862926ee095003680bfcf8ecbb8302758e832cf9 Mon Sep 17 00:00:00 2001 From: mike31 Date: Tue, 19 Dec 2017 17:32:16 +0200 Subject: [PATCH 44/71] Applied parameters in protocol with stubs --- src/chainparams/params.h | 2 ++ src/core/main.cpp | 51 +++++++++++++++++++++++++++++++++++++++ src/utils/utilwrapper.cpp | 31 +++++++++++++++++++++--- 3 files changed, 81 insertions(+), 3 deletions(-) diff --git a/src/chainparams/params.h b/src/chainparams/params.h index 2be4028b..2ab03f65 100644 --- a/src/chainparams/params.h +++ b/src/chainparams/params.h @@ -124,6 +124,8 @@ typedef struct mc_MultichainParams int Write(int overwrite); int Print(FILE *); int SetGlobals(); + int SetProtocolGlobals(); + int SetUpgradedParamValue(const mc_OneMultichainParam *param,int64_t value); int Import(const char *name,const char *source_address); int Set(const char *name,const char *source,int source_size); diff --git a/src/core/main.cpp b/src/core/main.cpp index 83d4414b..1739e149 100644 --- a/src/core/main.cpp +++ b/src/core/main.cpp @@ -72,6 +72,7 @@ bool MultichainNode_AcceptData(CNode *pnode); bool MultichainNode_IgnoreIncoming(CNode *pnode); bool MultichainNode_IsLocal(CNode *pnode); bool IsTxBanned(uint256 txid); +int CreateUpgradeLists(int current_height,vector *vParams,vector *vUpgrades); @@ -348,6 +349,56 @@ map mapNodeState; /* MCHN START */ int MultichainNode_ApplyUpgrades(int current_height) +{ + vector vParams; + int err=MC_ERR_NOERROR; + + CreateUpgradeLists(chainActive.Height(),&vParams,NULL); + + int OriginalProtocolVersion=(int)mc_gState->m_NetworkParams->GetInt64Param("protocolversion"); + int CurrentProtocolVersion=mc_gState->m_NetworkParams->ProtocolVersion();//mc_gState->m_ProtocolVersionToUpgrade; + int NewProtocolVersion=OriginalProtocolVersion; + + mc_gState->m_NetworkParams->SetGlobals(); + for(int p=0;p<(int)vParams.size();p++) + { + if(strcmp(vParams[p].m_Param->m_Name,"protocolversion") == 0) + { + err=mc_gState->m_NetworkParams->m_ProtocolVersion=mc_gState->m_ProtocolVersionToUpgrade;// UPGRADE CODE HERE + mc_gState->m_NetworkParams->SetProtocolGlobals(); + } + else + { + mc_gState->m_NetworkParams->SetUpgradedParamValue(vParams[p].m_Param,vParams[p].m_Value); + } + } + SetMultiChainParams(); + + if(mc_gState->m_ProtocolVersionToUpgrade != CurrentProtocolVersion) + { + LogPrintf("New protocol upgrade version: %d (was %d)\n",mc_gState->m_ProtocolVersionToUpgrade,CurrentProtocolVersion); + if( (err == MC_ERR_NOT_SUPPORTED) || ((mc_gState->m_ProtocolVersionToUpgrade > 0) && (mc_gState->IsSupported(mc_gState->m_ProtocolVersionToUpgrade) == 0)) ) + { + LogPrintf("NODE SHOULD BE UPGRADED FROM %d TO %d\n",mc_gState->GetProtocolVersion(),mc_gState->m_ProtocolVersionToUpgrade); + } + else + { + if(mc_gState->m_ProtocolVersionToUpgrade != mc_gState->m_NetworkParams->ProtocolVersion()) + { + LogPrintf("NODE IS UPGRADED FROM %d TO %d\n",mc_gState->m_NetworkParams->ProtocolVersion(),mc_gState->m_ProtocolVersionToUpgrade); + } + } + } + else + { + mc_gState->m_ProtocolVersionToUpgrade=0; + } + + return MC_ERR_NOERROR; +} + + +int MultichainNode_ApplyUpgrades_Old(int current_height) { mc_EntityDetails entity; mc_Buffer *permissions; diff --git a/src/utils/utilwrapper.cpp b/src/utils/utilwrapper.cpp index d66795a9..3dddf337 100644 --- a/src/utils/utilwrapper.cpp +++ b/src/utils/utilwrapper.cpp @@ -735,6 +735,29 @@ int mc_BuildDescription(int build, char *desc) return MC_ERR_NOERROR; } +int mc_MultichainParams::SetUpgradedParamValue(const mc_OneMultichainParam *param,int64_t value) +{ + return MC_ERR_NOERROR; +} + +int mc_MultichainParams::SetProtocolGlobals() +{ + if(mc_gState->m_Features->ShortTxIDInTx() == 0) + { + m_AssetRefSize=MC_AST_ASSET_REF_SIZE; + } + MCP_ALLOW_ARBITRARY_OUTPUTS=1; + if(mc_gState->m_Features->FixedDestinationExtraction() != 0) + { + int aao=mc_gState->m_NetworkParams->GetInt64Param("allowarbitraryoutputs"); + if(aao>=0) + { + MCP_ALLOW_ARBITRARY_OUTPUTS=aao; + } + } + return MC_ERR_NOERROR; +} + int mc_MultichainParams::SetGlobals() { m_IsProtocolMultiChain=1; @@ -773,12 +796,12 @@ int mc_MultichainParams::SetGlobals() CENT=0; MAX_MONEY=0; } - +/* if(mc_gState->m_Features->ShortTxIDInTx() == 0) { m_AssetRefSize=MC_AST_ASSET_REF_SIZE; } - +*/ MCP_MAX_STD_OP_RETURN_COUNT=mc_gState->m_NetworkParams->GetInt64Param("maxstdopreturnscount"); MCP_INITIAL_BLOCK_REWARD=mc_gState->m_NetworkParams->GetInt64Param("initialblockreward"); MCP_FIRST_BLOCK_REWARD=mc_gState->m_NetworkParams->GetInt64Param("firstblockreward"); @@ -790,6 +813,7 @@ int mc_MultichainParams::SetGlobals() MCP_ANYONE_CAN_RECEIVE=mc_gState->m_NetworkParams->GetInt64Param("anyonecanreceive"); MCP_ANYONE_CAN_ACTIVATE=mc_gState->m_NetworkParams->GetInt64Param("anyonecanactivate"); MCP_MINIMUM_PER_OUTPUT=mc_gState->m_NetworkParams->GetInt64Param("minimumperoutput"); +/* MCP_ALLOW_ARBITRARY_OUTPUTS=1; if(mc_gState->m_Features->FixedDestinationExtraction() != 0) { @@ -799,6 +823,7 @@ int mc_MultichainParams::SetGlobals() MCP_ALLOW_ARBITRARY_OUTPUTS=aao; } } + */ MCP_ALLOW_MULTISIG_OUTPUTS=mc_gState->m_NetworkParams->GetInt64Param("allowmultisigoutputs"); MCP_ALLOW_P2SH_OUTPUTS=mc_gState->m_NetworkParams->GetInt64Param("allowp2shoutputs"); MCP_WITH_NATIVE_CURRENCY=0; @@ -809,7 +834,7 @@ int mc_MultichainParams::SetGlobals() MCP_STD_OP_DROP_COUNT=mc_gState->m_NetworkParams->GetInt64Param("maxstdopdropscount"); MCP_STD_OP_DROP_SIZE=mc_gState->m_NetworkParams->GetInt64Param("maxstdopdropsize"); MCP_ANYONE_CAN_RECEIVE_EMPTY=mc_gState->m_NetworkParams->GetInt64Param("anyonecanreceiveempty"); - return MC_ERR_NOERROR; + return SetProtocolGlobals(); } From 01050cc53ad60caaab6309c6332997a6281fe505 Mon Sep 17 00:00:00 2001 From: mike31 Date: Tue, 19 Dec 2017 17:52:02 +0200 Subject: [PATCH 45/71] listupgrades - upgrade-identifier(s) --- src/protocol/multichainblock.cpp | 2 +- src/rpc/rpcupgrades.cpp | 198 +++++++++++++++---------------- 2 files changed, 97 insertions(+), 103 deletions(-) diff --git a/src/protocol/multichainblock.cpp b/src/protocol/multichainblock.cpp index 4b3588fe..38b0a429 100644 --- a/src/protocol/multichainblock.cpp +++ b/src/protocol/multichainblock.cpp @@ -43,7 +43,7 @@ int CreateUpgradeLists(int current_height,vector *vParams, upgrades=NULL; set stored_upgrades; map map_sorted; - uint160 hash; + uint160 hash=0; int OriginalProtocolVersion=(int)mc_gState->m_NetworkParams->GetInt64Param("protocolversion"); int NewProtocolVersion=OriginalProtocolVersion; diff --git a/src/rpc/rpcupgrades.cpp b/src/rpc/rpcupgrades.cpp index b44705f2..3d451b80 100644 --- a/src/rpc/rpcupgrades.cpp +++ b/src/rpc/rpcupgrades.cpp @@ -411,7 +411,8 @@ Value listupgrades(const json_spirit::Array& params, bool fHelp) Array results; mc_Buffer *upgrades; - int latest_version; + + set inputUpgrades; upgrades=NULL; @@ -437,30 +438,18 @@ Value listupgrades(const json_spirit::Array& params, bool fHelp) } } -/* - if(inputStrings.size()) + for(int is=0;is<(int)inputStrings.size();is++) { - { - LOCK(cs_main); - for(int is=0;is<(int)inputStrings.size();is++) - { - string param=inputStrings[is]; + string param=inputStrings[is]; - mc_EntityDetails upgrade_entity; - ParseEntityIdentifier(param,&upgrade_entity, MC_ENT_TYPE_UPGRADE); - - upgrades=mc_gState->m_Permissions->GetUpgradeList(upgrade_entity.GetTxID() + MC_AST_SHORT_TXID_OFFSET,upgrades); - } - } - } - else - { - { - LOCK(cs_main); - upgrades=mc_gState->m_Permissions->GetUpgradeList(NULL,upgrades); - } + mc_EntityDetails upgrade_entity; + ParseEntityIdentifier(param,&upgrade_entity, MC_ENT_TYPE_UPGRADE); + + uint160 hash=0; + memcpy(&hash,upgrade_entity.GetTxID() + MC_AST_SHORT_TXID_OFFSET,MC_AST_SHORT_TXID_SIZE); + inputUpgrades.insert(hash); } - */ + vector vParams; vector vUpgrades; int current_height=chainActive.Height(); @@ -474,108 +463,113 @@ Value listupgrades(const json_spirit::Array& params, bool fHelp) mc_PermissionDetails *plsRow; mc_PermissionDetails *plsDet; mc_EntityDetails upgrade_entity; - bool take_it,approved; int flags,consensus,remaining; Value null_value; string param_name; - upgrade_entity.Zero(); - mc_gState->m_Assets->FindEntityByShortTxID(&upgrade_entity,vUpgrades[u].m_EntityShortTxID); - entry=UpgradeEntry(upgrade_entity.GetTxID()); + uint160 hash=0; + memcpy(&hash,vUpgrades[u].m_EntityShortTxID,sizeof(uint160)); - entry.push_back(Pair("approved", (vUpgrades[u].m_ApprovedBlock <= current_height+1))); - - for(int p=vUpgrades[u].m_FirstParam;p 0) ) { - param_name=string(vParams[p].m_Param->m_DisplayName); - if(vParams[p].m_Param->m_Type & MC_PRM_DECIMAL) - { - applied_params.push_back(Pair(param_name,mc_gState->m_NetworkParams->Int64ToDecimal(vParams[p].m_Value))); - } - else + upgrade_entity.Zero(); + mc_gState->m_Assets->FindEntityByShortTxID(&upgrade_entity,vUpgrades[u].m_EntityShortTxID); + entry=UpgradeEntry(upgrade_entity.GetTxID()); + + entry.push_back(Pair("approved", (vUpgrades[u].m_ApprovedBlock <= current_height+1))); + + for(int p=vUpgrades[u].m_FirstParam;pm_Type & MC_PRM_DATA_TYPE_MASK) + param_name=string(vParams[p].m_Param->m_DisplayName); + if(vParams[p].m_Param->m_Type & MC_PRM_DECIMAL) { - case MC_PRM_BOOLEAN: - applied_params.push_back(Pair(param_name,(vParams[p].m_Value != 0))); - break; - case MC_PRM_INT32: - applied_params.push_back(Pair(param_name,(int)vParams[p].m_Value)); - case MC_PRM_UINT32: - case MC_PRM_INT64: - applied_params.push_back(Pair(param_name,vParams[p].m_Value)); - break; - } - } - } - - if(vUpgrades[u].m_ApprovedBlock <= current_height) - { - entry.push_back(Pair("appliedblock", (int64_t)vUpgrades[u].m_ApprovedBlock)); - entry.push_back(Pair("appliedparams", applied_params)); - } - else - { - entry.push_back(Pair("appliedblock", null_value)); - entry.push_back(Pair("appliedparams", null_value)); - } - - upgrades=mc_gState->m_Permissions->GetUpgradeList(upgrade_entity.GetTxID() + MC_AST_SHORT_TXID_OFFSET,upgrades); - if(upgrades->GetCount()) - { - plsRow=(mc_PermissionDetails *)(upgrades->GetRow(upgrades->GetCount()-1)); - flags=plsRow->m_Flags; - consensus=plsRow->m_RequiredAdmins; - if(plsRow->m_Type != MC_PTP_UPGRADE) - { - plsRow->m_BlockTo=0; + applied_params.push_back(Pair(param_name,mc_gState->m_NetworkParams->Int64ToDecimal(vParams[p].m_Value))); + } + else + { + switch(vParams[p].m_Param->m_Type & MC_PRM_DATA_TYPE_MASK) + { + case MC_PRM_BOOLEAN: + applied_params.push_back(Pair(param_name,(vParams[p].m_Value != 0))); + break; + case MC_PRM_INT32: + applied_params.push_back(Pair(param_name,(int)vParams[p].m_Value)); + case MC_PRM_UINT32: + case MC_PRM_INT64: + applied_params.push_back(Pair(param_name,vParams[p].m_Value)); + break; + } + } } - Array admins; - Array pending; - mc_Buffer *details; - - if(plsRow->m_Type == MC_PTP_UPGRADE) + if(vUpgrades[u].m_ApprovedBlock <= current_height) { - details=mc_gState->m_Permissions->GetPermissionDetails(plsRow); + entry.push_back(Pair("appliedblock", (int64_t)vUpgrades[u].m_ApprovedBlock)); + entry.push_back(Pair("appliedparams", applied_params)); } else { - details=NULL; + entry.push_back(Pair("appliedblock", null_value)); + entry.push_back(Pair("appliedparams", null_value)); } - if(details) - { - for(int j=0;jGetCount();j++) + upgrades=mc_gState->m_Permissions->GetUpgradeList(upgrade_entity.GetTxID() + MC_AST_SHORT_TXID_OFFSET,upgrades); + if(upgrades->GetCount()) + { + plsRow=(mc_PermissionDetails *)(upgrades->GetRow(upgrades->GetCount()-1)); + flags=plsRow->m_Flags; + consensus=plsRow->m_RequiredAdmins; + if(plsRow->m_Type != MC_PTP_UPGRADE) { - plsDet=(mc_PermissionDetails *)(details->GetRow(j)); - remaining=plsDet->m_RequiredAdmins; - if(plsDet->m_BlockFrom < plsDet->m_BlockTo) + plsRow->m_BlockTo=0; + } + + Array admins; + Array pending; + mc_Buffer *details; + + if(plsRow->m_Type == MC_PTP_UPGRADE) + { + details=mc_gState->m_Permissions->GetPermissionDetails(plsRow); + } + else + { + details=NULL; + } + + if(details) + { + for(int j=0;jGetCount();j++) + { + plsDet=(mc_PermissionDetails *)(details->GetRow(j)); + remaining=plsDet->m_RequiredAdmins; + if(plsDet->m_BlockFrom < plsDet->m_BlockTo) + { + uint160 addr; + memcpy(&addr,plsDet->m_LastAdmin,sizeof(uint160)); + CKeyID lpKeyID=CKeyID(addr); + admins.push_back(CBitcoinAddress(lpKeyID).ToString()); + } + } + consensus=plsRow->m_RequiredAdmins; + } + if(admins.size() == 0) + { + if(plsRow->m_BlockFrom < plsRow->m_BlockTo) { uint160 addr; - memcpy(&addr,plsDet->m_LastAdmin,sizeof(uint160)); + memcpy(&addr,plsRow->m_LastAdmin,sizeof(uint160)); CKeyID lpKeyID=CKeyID(addr); - admins.push_back(CBitcoinAddress(lpKeyID).ToString()); - } - } - consensus=plsRow->m_RequiredAdmins; - } - if(admins.size() == 0) - { - if(plsRow->m_BlockFrom < plsRow->m_BlockTo) - { - uint160 addr; - memcpy(&addr,plsRow->m_LastAdmin,sizeof(uint160)); - CKeyID lpKeyID=CKeyID(addr); - admins.push_back(CBitcoinAddress(lpKeyID).ToString()); - } + admins.push_back(CBitcoinAddress(lpKeyID).ToString()); + } + } + + entry.push_back(Pair("admins", admins)); + entry.push_back(Pair("required", (int64_t)(consensus-admins.size()))); } - - entry.push_back(Pair("admins", admins)); - entry.push_back(Pair("required", (int64_t)(consensus-admins.size()))); + upgrades->Clear(); + results.push_back(entry); } - upgrades->Clear(); - results.push_back(entry); } mc_gState->m_Permissions->FreePermissionList(upgrades); From e09d67edef5083626b718bf8f169d65c485d4e2b Mon Sep 17 00:00:00 2001 From: mike31 Date: Thu, 21 Dec 2017 17:20:14 +0200 Subject: [PATCH 46/71] maximum-block-size upgrade --- src/chainparams/globals.h | 2 ++ src/core/init.cpp | 1 + src/core/main.cpp | 4 +++- src/core/main.h | 6 +++--- src/miner/miner.cpp | 2 +- src/rpc/rpcmisc.cpp | 7 +++++++ src/utils/utilwrapper.cpp | 26 ++++++++++++++++++++++++++ 7 files changed, 43 insertions(+), 5 deletions(-) diff --git a/src/chainparams/globals.h b/src/chainparams/globals.h index 81e3471c..ec35d0ee 100644 --- a/src/chainparams/globals.h +++ b/src/chainparams/globals.h @@ -11,6 +11,8 @@ unsigned int MAX_BLOCK_SIZE = 1000000; unsigned int DEFAULT_BLOCK_MAX_SIZE = 750000; // main.h unsigned int MAX_BLOCKFILE_SIZE = 0x8000000; // main.h unsigned int MAX_STANDARD_TX_SIZE = 100000; // main.h +unsigned int MAX_BLOCK_SIGOPS = 20000; // main.h +unsigned int MAX_TX_SIGOPS = 4000; // main.h int COINBASE_MATURITY = 100; // main.h unsigned int MAX_SIZE = 0x02000000; // serialize,h int64_t COIN = 100000000; // amount.h diff --git a/src/core/init.cpp b/src/core/init.cpp index e7eebbbd..d5dbb3a3 100644 --- a/src/core/init.cpp +++ b/src/core/init.cpp @@ -318,6 +318,7 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += " -datadir= " + _("Specify data directory") + "\n"; strUsage += " -dbcache= " + strprintf(_("Set database cache size in megabytes (%d to %d, default: %d)"), nMinDbCache, nMaxDbCache, nDefaultDbCache) + "\n"; strUsage += " -loadblock= " + _("Imports blocks from external blk000??.dat file") + " " + _("on startup") + "\n"; + strUsage += " -loadblockmaxsize= " + _("Maximal block size in the files specified in -loadblock") + "\n"; strUsage += " -maxorphantx= " + strprintf(_("Keep at most unconnectable transactions in memory (default: %u)"), DEFAULT_MAX_ORPHAN_TRANSACTIONS) + "\n"; strUsage += " -par= " + strprintf(_("Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)"), -(int)boost::thread::hardware_concurrency(), MAX_SCRIPTCHECK_THREADS, DEFAULT_SCRIPTCHECK_THREADS) + "\n"; #ifndef WIN32 diff --git a/src/core/main.cpp b/src/core/main.cpp index 1739e149..761810ab 100644 --- a/src/core/main.cpp +++ b/src/core/main.cpp @@ -5159,10 +5159,12 @@ bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp) static std::multimap mapBlocksUnknownParent; int64_t nStart = GetTimeMillis(); + uint32_t effective_max_block_size=GetArg("-loadblockmaxsize",2*MAX_BLOCK_SIZE); + int nLoaded = 0; try { // This takes over fileIn and calls fclose() on it in the CBufferedFile destructor - CBufferedFile blkdat(fileIn, 2*MAX_BLOCK_SIZE, MAX_BLOCK_SIZE+8, SER_DISK, CLIENT_VERSION); + CBufferedFile blkdat(fileIn, 2*effective_max_block_size, effective_max_block_size+8, SER_DISK, CLIENT_VERSION); uint64_t nRewind = blkdat.GetPos(); while (!blkdat.eof()) { boost::this_thread::interruption_point(); diff --git a/src/core/main.h b/src/core/main.h index 4cccc4b7..f3788330 100644 --- a/src/core/main.h +++ b/src/core/main.h @@ -58,11 +58,11 @@ static const unsigned int DEFAULT_BLOCK_MIN_SIZE = 0; /** The maximum size for transactions we're willing to relay/mine */ extern unsigned int MAX_STANDARD_TX_SIZE; // MCHN global /** The maximum allowed number of signature check operations in a block (network rule) */ -static const unsigned int MAX_BLOCK_SIGOPS = MAX_BLOCK_SIZE/50; +extern unsigned int MAX_BLOCK_SIGOPS; // MCHN global +/** The maximum number of sigops we're willing to relay/mine in a single tx */ +extern unsigned int MAX_TX_SIGOPS; // MCHN global /** Maximum number of signature check operations in an IsStandard() P2SH script */ static const unsigned int MAX_P2SH_SIGOPS = 15; -/** The maximum number of sigops we're willing to relay/mine in a single tx */ -static const unsigned int MAX_TX_SIGOPS = MAX_BLOCK_SIGOPS/5; /** Default for -maxorphantx, maximum number of orphan transactions kept in memory */ /* MCHN START */ //static const unsigned int DEFAULT_MAX_ORPHAN_TRANSACTIONS = 100; diff --git a/src/miner/miner.cpp b/src/miner/miner.cpp index 43d46769..06d53bf3 100644 --- a/src/miner/miner.cpp +++ b/src/miner/miner.cpp @@ -478,7 +478,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn,CWallet *pwallet,CP // Collect transactions into block uint64_t nBlockSize = 1000; uint64_t nBlockTx = 0; - int nBlockSigOps = 100; + int nBlockSigOps = 40; // bool fSortedByFee = (nBlockPrioritySize <= 0); /* MCHN START */ diff --git a/src/rpc/rpcmisc.cpp b/src/rpc/rpcmisc.cpp index 50e76b87..4a55d745 100644 --- a/src/rpc/rpcmisc.cpp +++ b/src/rpc/rpcmisc.cpp @@ -669,6 +669,13 @@ Value getblockchainparams(const json_spirit::Array& params, bool fHelp) param_value=mc_gState->m_NetworkParams->m_ProtocolVersion; } } + if(strcmp("maximumblocksize",(mc_gState->m_NetworkParams->m_lpParams+i)->m_Name) == 0) + { + if(nHeight) + { + param_value=(int)MAX_BLOCK_SIZE; + } + } obj.push_back(Pair(param_name,param_value)); } diff --git a/src/utils/utilwrapper.cpp b/src/utils/utilwrapper.cpp index 3dddf337..06176080 100644 --- a/src/utils/utilwrapper.cpp +++ b/src/utils/utilwrapper.cpp @@ -737,6 +737,27 @@ int mc_BuildDescription(int build, char *desc) int mc_MultichainParams::SetUpgradedParamValue(const mc_OneMultichainParam *param,int64_t value) { + if(mc_gState->m_Features->ParameterUpgrades() == 0) + { + return MC_ERR_NOERROR; + } + + if(strcmp(param->m_Name,"maximumblocksize") == 0) + { + MAX_BLOCK_SIZE=(unsigned int)value; + DEFAULT_BLOCK_MAX_SIZE=MAX_BLOCK_SIZE; + while(MAX_BLOCK_SIZE>MAX_BLOCKFILE_SIZE) + { + MAX_BLOCKFILE_SIZE *= 2; + } + while(MAX_BLOCK_SIZE>MAX_SIZE) + { + MAX_SIZE *= 2; + } + MAX_BLOCK_SIGOPS = MAX_BLOCK_SIZE/50; + MAX_TX_SIGOPS = MAX_BLOCK_SIGOPS/5; + } + return MC_ERR_NOERROR; } @@ -755,6 +776,11 @@ int mc_MultichainParams::SetProtocolGlobals() MCP_ALLOW_ARBITRARY_OUTPUTS=aao; } } + if(mc_gState->m_Features->ParameterUpgrades()) + { + MAX_BLOCK_SIGOPS = MAX_BLOCK_SIZE/50; + MAX_TX_SIGOPS = MAX_BLOCK_SIGOPS/5; + } return MC_ERR_NOERROR; } From 50ad03c56f11ad3a5b0feeb9debb80307b2539e3 Mon Sep 17 00:00:00 2001 From: mike31 Date: Sun, 24 Dec 2017 15:24:10 +0200 Subject: [PATCH 47/71] Fixed default min value for maximum-block-size --- src/chainparams/paramlist.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/chainparams/paramlist.h b/src/chainparams/paramlist.h index da71186e..0cfd39c7 100644 --- a/src/chainparams/paramlist.h +++ b/src/chainparams/paramlist.h @@ -31,7 +31,7 @@ static const mc_OneMultichainParam MultichainParamArray[] = "maximumblocksize","", "Target time between blocks (transaction confirmation delay), seconds."}, { "maximumblocksize" , "maximum-block-size" , - MC_PRM_UINT32 | MC_PRM_USER | MC_PRM_CLONE , -1, 8388608, 1000,1000000000, 0.0, 10001, 0, "-mc-maximumblocksize", + MC_PRM_UINT32 | MC_PRM_USER | MC_PRM_CLONE , -1, 8388608, 5000,1000000000, 0.0, 10001, 0, "-mc-maximumblocksize", "defaultnetworkport","", "Maximum block size in bytes."}, { "defaultnetworkport" , "default-network-port" , From 53cb1e09fefbd1076da405292fb70fbdf611be4c Mon Sep 17 00:00:00 2001 From: mike31 Date: Sun, 24 Dec 2017 17:05:04 +0200 Subject: [PATCH 48/71] Parameter upgrades --- src/chainparams/chainparams.cpp | 14 ++++ src/chainparams/chainparams.h | 1 + src/chainparams/params.cpp | 44 ++++++------ src/chainparams/params.h | 14 ++++ src/chainparams/state.h | 2 + src/core/main.cpp | 49 ++++++++++++-- src/protocol/multichainblock.cpp | 111 +++++++++++++++++++++++++++---- src/rpc/rpcupgrades.cpp | 52 +++++++++++---- src/utils/utilwrapper.cpp | 25 ------- 9 files changed, 230 insertions(+), 82 deletions(-) diff --git a/src/chainparams/chainparams.cpp b/src/chainparams/chainparams.cpp index 4f3d3059..8ea27db7 100644 --- a/src/chainparams/chainparams.cpp +++ b/src/chainparams/chainparams.cpp @@ -554,6 +554,14 @@ class CMultiChainParams : public CMainParams { } } + void SetMultiChainParam(const char*param_name,int64_t value) + { + if(strcmp(param_name,"targetblocktime") == 0) + { + nTargetSpacing=value; + } + } + void SetMultiChainRuntimeParams() { fMineBlocksOnDemand = GetBoolArg("-mineblocksondemand", false); @@ -781,6 +789,12 @@ void SetMultiChainParams() multiChainParams.SetMultiChainParams(); } +void SetMultiChainParam(const char*param_name,int64_t value) +{ + multiChainParams.SetMultiChainParam(param_name,value); +} + + void SetMultiChainRuntimeParams() { multiChainParams.SetMultiChainRuntimeParams(); diff --git a/src/chainparams/chainparams.h b/src/chainparams/chainparams.h index 51319d92..bd463178 100644 --- a/src/chainparams/chainparams.h +++ b/src/chainparams/chainparams.h @@ -166,6 +166,7 @@ bool SelectParamsFromCommandLine(); bool SelectMultiChainParams(const char *NetworkName); bool InitializeMultiChainParams(); void SetMultiChainParams(); +void SetMultiChainParam(const char*param_name,int64_t value); void SetMultiChainRuntimeParams(); diff --git a/src/chainparams/params.cpp b/src/chainparams/params.cpp index 5bc45284..66ec8c4e 100644 --- a/src/chainparams/params.cpp +++ b/src/chainparams/params.cpp @@ -179,24 +179,24 @@ int mc_MultichainParams::CanBeUpgradedByVersion(const char *param,int version,in { if(m_lpIndex == NULL) { - return -1; + return -MC_PSK_INTERNAL_ERROR; } int index=m_lpIndex->Get(param); if(index<0) { - return -2; + return -MC_PSK_NOT_FOUND; } int offset=m_lpCoord[2 * index + 0]; if(offset<0) { - return -3; + return -MC_PSK_NOT_FOUND; } if(size > 0) { if(size != m_lpCoord[2 * index + 1]) { - return -4; + return -MC_PSK_WRONG_SIZE; } } @@ -215,9 +215,12 @@ int mc_MultichainParams::CanBeUpgradedByVersion(const char *param,int version,in if(strcmp(param,"targetblocktime") == 0) { - if(version >= 20002) + if(GetInt64Param("targetadjustfreq") >= 0) { - return m_lpCoord[2 * index + 1]; + if(version >= 20002) + { + return m_lpCoord[2 * index + 1]; + } } } @@ -1200,23 +1203,20 @@ int mc_MultichainParams::Validate() if(isGenerated) { m_Status=MC_PRM_STATUS_GENERATED; - iv=GetInt64Param("targetblocktime"); - if(iv>0) + dv=2*(double)GetInt64Param("rewardhalvinginterval"); + dv*=(double)GetInt64Param("initialblockreward"); + iv=GetInt64Param("firstblockreward"); + if(iv<0) { - dv=2*(double)GetInt64Param("rewardhalvinginterval")/(double)iv; - dv*=(double)GetInt64Param("initialblockreward"); - iv=GetInt64Param("firstblockreward"); - if(iv<0) - { - iv=GetInt64Param("initialblockreward"); - } - dv+=(double)iv; - if(dv > 9.e+18) - { - printf("Total mining reward over blockchain's history is more than 2^63 raw units. Please reduce initial-block-reward or reward-halving-interval.\n"); - return MC_ERR_INVALID_PARAMETER_VALUE; - } - } + iv=GetInt64Param("initialblockreward"); + } + dv+=(double)iv; + if(dv > 9.e+18) + { + printf("Total mining reward over blockchain's history is more than 2^63 raw units. Please reduce initial-block-reward or reward-halving-interval.\n"); + return MC_ERR_INVALID_PARAMETER_VALUE; + } + GetParam("chaindescription",&size); if(size-1 > 90) { diff --git a/src/chainparams/params.h b/src/chainparams/params.h index 2ab03f65..c4c4378f 100644 --- a/src/chainparams/params.h +++ b/src/chainparams/params.h @@ -46,6 +46,20 @@ #define MC_PRM_STATUS_INVALID 4 #define MC_PRM_STATUS_VALID 5 +#define MC_PSK_APPLIED 0 +#define MC_PSK_INTERNAL_ERROR 1 +#define MC_PSK_NOT_FOUND 2 +#define MC_PSK_WRONG_SIZE 3 +#define MC_PSK_OUT_OF_RANGE 4 +#define MC_PSK_FRESH_UPGRADE 5 +#define MC_PSK_DOUBLE_RANGE 6 +#define MC_PSK_NOT_SUPPORTED 7 +#define MC_PSK_NEW_NOT_DOWNGRADABLE 8 +#define MC_PSK_OLD_NOT_DOWNGRADABLE 9 + + + + extern int MCP_MAX_STD_OP_RETURN_COUNT; extern int64_t MCP_INITIAL_BLOCK_REWARD; extern int64_t MCP_FIRST_BLOCK_REWARD; diff --git a/src/chainparams/state.h b/src/chainparams/state.h index 34f1a38b..1141df10 100644 --- a/src/chainparams/state.h +++ b/src/chainparams/state.h @@ -119,6 +119,8 @@ typedef struct mc_UpgradedParameter { const mc_OneMultichainParam *m_Param; int64_t m_Value; + uint32_t m_Block; + int32_t m_Skipped; } mc_UpgradedParameter; typedef struct mc_Features diff --git a/src/core/main.cpp b/src/core/main.cpp index 761810ab..bea3561b 100644 --- a/src/core/main.cpp +++ b/src/core/main.cpp @@ -348,6 +348,38 @@ map mapNodeState; /* MCHN START */ +int SetUpgradedParamValue(const mc_OneMultichainParam *param,int64_t value) +{ + if(mc_gState->m_Features->ParameterUpgrades() == 0) + { + return MC_ERR_NOERROR; + } + + if(strcmp(param->m_Name,"maximumblocksize") == 0) + { + MAX_BLOCK_SIZE=(unsigned int)value; + DEFAULT_BLOCK_MAX_SIZE=MAX_BLOCK_SIZE; + while(MAX_BLOCK_SIZE>MAX_BLOCKFILE_SIZE) + { + MAX_BLOCKFILE_SIZE *= 2; + } + while(MAX_BLOCK_SIZE>MAX_SIZE) + { + MAX_SIZE *= 2; + } + MAX_BLOCK_SIGOPS = MAX_BLOCK_SIZE/50; + MAX_TX_SIGOPS = MAX_BLOCK_SIGOPS/5; + } + + if(strcmp(param->m_Name,"targetblocktime") == 0) + { + MCP_TARGET_BLOCK_TIME=value; + SetMultiChainParam("targetblocktime",value); + } + + return MC_ERR_NOERROR; +} + int MultichainNode_ApplyUpgrades(int current_height) { vector vParams; @@ -362,14 +394,17 @@ int MultichainNode_ApplyUpgrades(int current_height) mc_gState->m_NetworkParams->SetGlobals(); for(int p=0;p<(int)vParams.size();p++) { - if(strcmp(vParams[p].m_Param->m_Name,"protocolversion") == 0) - { - err=mc_gState->m_NetworkParams->m_ProtocolVersion=mc_gState->m_ProtocolVersionToUpgrade;// UPGRADE CODE HERE - mc_gState->m_NetworkParams->SetProtocolGlobals(); - } - else + if(vParams[p].m_Skipped == MC_PSK_APPLIED) { - mc_gState->m_NetworkParams->SetUpgradedParamValue(vParams[p].m_Param,vParams[p].m_Value); + if(strcmp(vParams[p].m_Param->m_Name,"protocolversion") == 0) + { + err=mc_gState->m_NetworkParams->m_ProtocolVersion=mc_gState->m_ProtocolVersionToUpgrade;// UPGRADE CODE HERE + mc_gState->m_NetworkParams->SetProtocolGlobals(); + } + else + { + SetUpgradedParamValue(vParams[p].m_Param,vParams[p].m_Value); + } } } SetMultiChainParams(); diff --git a/src/protocol/multichainblock.cpp b/src/protocol/multichainblock.cpp index 38b0a429..31dc162a 100644 --- a/src/protocol/multichainblock.cpp +++ b/src/protocol/multichainblock.cpp @@ -43,6 +43,7 @@ int CreateUpgradeLists(int current_height,vector *vParams, upgrades=NULL; set stored_upgrades; map map_sorted; + map map_last_upgrade; uint160 hash=0; int OriginalProtocolVersion=(int)mc_gState->m_NetworkParams->GetInt64Param("protocolversion"); @@ -129,21 +130,33 @@ int CreateUpgradeLists(int current_height,vector *vParams, if(current_height >=applied_height) { version=entity.UpgradeProtocolVersion(); - if(version >= mc_gState->MinProtocolDowngradeVersion()) + if(version > 0) { - if((NewProtocolVersion < mc_gState->MinProtocolForbiddenDowngradeVersion()) || (version >= NewProtocolVersion)) + param.m_Param=mc_gState->m_NetworkParams->FindParam("protocolversion"); + param.m_Value=version; + param.m_Block=upgrade.m_AppliedBlock; + if(version >= mc_gState->MinProtocolDowngradeVersion()) { - NewProtocolVersion=version; - if( mc_gState->IsSupported(version) == 0 ) + if((NewProtocolVersion < mc_gState->MinProtocolForbiddenDowngradeVersion()) || (version >= NewProtocolVersion)) { - err=MC_ERR_NOT_SUPPORTED; + NewProtocolVersion=version; + if( mc_gState->IsSupported(version) == 0 ) + { + err=MC_ERR_NOT_SUPPORTED; + } + memset(¶m,0,sizeof(mc_UpgradedParameter)); + } + else + { + param.m_Skipped = MC_PSK_OLD_NOT_DOWNGRADABLE; } - memset(¶m,0,sizeof(mc_UpgradedParameter)); - param.m_Param=mc_gState->m_NetworkParams->FindParam("protocolversion"); - param.m_Value=version; - vParams->push_back(param); } - } + else + { + param.m_Skipped = MC_PSK_NEW_NOT_DOWNGRADABLE; + } + vParams->push_back(param); + } if(err == MC_ERR_NOERROR) { @@ -159,6 +172,9 @@ int CreateUpgradeLists(int current_height,vector *vParams, { param.m_Param=mc_gState->m_NetworkParams->FindParam(ptr); ptr+=mc_gState->m_NetworkParams->GetParamFromScript(ptr,¶m_value,&given_size); + param.m_Value=param_value; + param.m_Block=upgrade.m_AppliedBlock; + param.m_Skipped=MC_PSK_APPLIED; if(param.m_Param) { param_size=mc_gState->m_NetworkParams->CanBeUpgradedByVersion(param.m_Param->m_Name,NewProtocolVersion,0); @@ -166,12 +182,79 @@ int CreateUpgradeLists(int current_height,vector *vParams, { if(mc_gState->m_NetworkParams->IsParamUpgradeValueInRange(param.m_Param,NewProtocolVersion,param_value)) { - param.m_Value=param_value; - vParams->push_back(param); + bool take_it=true; + string param_name=string(param.m_Param->m_Name); + map ::iterator it = map_last_upgrade.find(param_name); + + if (it != map_last_upgrade.end()) + { + take_it=false; + if((*vParams)[it->second].m_Block + 100 <= upgrade.m_AppliedBlock) + { + int64_t old_value=(*vParams)[it->second].m_Value; + if(param.m_Value >= old_value) + { + if(param_value <= 2*old_value) + { + take_it=true; + } + } + else + { + if(old_value <= 2*param_value) + { + take_it=true; + } + } + if(!take_it) + { + param.m_Skipped =MC_PSK_DOUBLE_RANGE; + } + } + else + { + param.m_Skipped = MC_PSK_FRESH_UPGRADE; + } + if(take_it) + { + it->second=(int)vParams->size(); + } + } + else + { + map_last_upgrade.insert(std::make_pair(param_name,(int)vParams->size())); + } + } + else + { + param.m_Skipped = MC_PSK_OUT_OF_RANGE; } - } + } + else + { + if(param_size > 0) + { + param.m_Skipped = MC_PSK_WRONG_SIZE; + } + else + { + if(param_size < 0) + { + param.m_Skipped = -param_size; + } + else + { + param.m_Skipped = MC_PSK_NOT_SUPPORTED; + } + } + } } - } + else + { + param.m_Skipped = MC_PSK_NOT_FOUND; + } + vParams->push_back(param); + } } } } diff --git a/src/rpc/rpcupgrades.cpp b/src/rpc/rpcupgrades.cpp index 3d451b80..06b65abd 100644 --- a/src/rpc/rpcupgrades.cpp +++ b/src/rpc/rpcupgrades.cpp @@ -460,6 +460,7 @@ Value listupgrades(const json_spirit::Array& params, bool fHelp) { Object entry; Object applied_params; + Object skipped_params; mc_PermissionDetails *plsRow; mc_PermissionDetails *plsDet; mc_EntityDetails upgrade_entity; @@ -481,24 +482,45 @@ Value listupgrades(const json_spirit::Array& params, bool fHelp) for(int p=vUpgrades[u].m_FirstParam;pm_DisplayName); - if(vParams[p].m_Param->m_Type & MC_PRM_DECIMAL) - { - applied_params.push_back(Pair(param_name,mc_gState->m_NetworkParams->Int64ToDecimal(vParams[p].m_Value))); + if(vParams[p].m_Skipped == MC_PSK_APPLIED) + { + if(vParams[p].m_Param->m_Type & MC_PRM_DECIMAL) + { + applied_params.push_back(Pair(param_name,mc_gState->m_NetworkParams->Int64ToDecimal(vParams[p].m_Value))); + } + else + { + switch(vParams[p].m_Param->m_Type & MC_PRM_DATA_TYPE_MASK) + { + case MC_PRM_BOOLEAN: + applied_params.push_back(Pair(param_name,(vParams[p].m_Value != 0))); + break; + case MC_PRM_INT32: + applied_params.push_back(Pair(param_name,(int)vParams[p].m_Value)); + case MC_PRM_UINT32: + case MC_PRM_INT64: + applied_params.push_back(Pair(param_name,vParams[p].m_Value)); + break; + } + } } else { - switch(vParams[p].m_Param->m_Type & MC_PRM_DATA_TYPE_MASK) + string param_err; + switch(vParams[p].m_Skipped) { - case MC_PRM_BOOLEAN: - applied_params.push_back(Pair(param_name,(vParams[p].m_Value != 0))); - break; - case MC_PRM_INT32: - applied_params.push_back(Pair(param_name,(int)vParams[p].m_Value)); - case MC_PRM_UINT32: - case MC_PRM_INT64: - applied_params.push_back(Pair(param_name,vParams[p].m_Value)); - break; - } + case MC_PSK_INTERNAL_ERROR: param_err="Parameter not applied because of internal error, please report this"; break; + case MC_PSK_NOT_FOUND: param_err="Parameter name not recognized"; break; + case MC_PSK_WRONG_SIZE: param_err="Parameter is encoded with wrong size"; break; + case MC_PSK_OUT_OF_RANGE: param_err="Parameter value is out of range"; break; + case MC_PSK_FRESH_UPGRADE: param_err="Parameter is upgraded less than 100 blocks ago"; break; + case MC_PSK_DOUBLE_RANGE: param_err="New pparameter value must be between half and double preview time"; break; + case MC_PSK_NOT_SUPPORTED: param_err="This parameter cannot be upgraded in this protocol version"; break; + case MC_PSK_NEW_NOT_DOWNGRADABLE: param_err="Cannot downgrade to this version"; break; + case MC_PSK_OLD_NOT_DOWNGRADABLE: param_err="Downgrades are not allowed in this protocol version"; break; + default: param_err="Parameter not applied because of internal error, please report this"; break; + } + skipped_params.push_back(Pair(param_name,param_err)); } } @@ -506,11 +528,13 @@ Value listupgrades(const json_spirit::Array& params, bool fHelp) { entry.push_back(Pair("appliedblock", (int64_t)vUpgrades[u].m_ApprovedBlock)); entry.push_back(Pair("appliedparams", applied_params)); + entry.push_back(Pair("skippedparams", skipped_params)); } else { entry.push_back(Pair("appliedblock", null_value)); entry.push_back(Pair("appliedparams", null_value)); + entry.push_back(Pair("skippedparams", null_value)); } upgrades=mc_gState->m_Permissions->GetUpgradeList(upgrade_entity.GetTxID() + MC_AST_SHORT_TXID_OFFSET,upgrades); diff --git a/src/utils/utilwrapper.cpp b/src/utils/utilwrapper.cpp index 06176080..8e900715 100644 --- a/src/utils/utilwrapper.cpp +++ b/src/utils/utilwrapper.cpp @@ -735,31 +735,6 @@ int mc_BuildDescription(int build, char *desc) return MC_ERR_NOERROR; } -int mc_MultichainParams::SetUpgradedParamValue(const mc_OneMultichainParam *param,int64_t value) -{ - if(mc_gState->m_Features->ParameterUpgrades() == 0) - { - return MC_ERR_NOERROR; - } - - if(strcmp(param->m_Name,"maximumblocksize") == 0) - { - MAX_BLOCK_SIZE=(unsigned int)value; - DEFAULT_BLOCK_MAX_SIZE=MAX_BLOCK_SIZE; - while(MAX_BLOCK_SIZE>MAX_BLOCKFILE_SIZE) - { - MAX_BLOCKFILE_SIZE *= 2; - } - while(MAX_BLOCK_SIZE>MAX_SIZE) - { - MAX_SIZE *= 2; - } - MAX_BLOCK_SIGOPS = MAX_BLOCK_SIZE/50; - MAX_TX_SIGOPS = MAX_BLOCK_SIGOPS/5; - } - - return MC_ERR_NOERROR; -} int mc_MultichainParams::SetProtocolGlobals() { From 81546a346f65c29a94d30f1888a84f0e58811e64 Mon Sep 17 00:00:00 2001 From: mike31 Date: Mon, 25 Dec 2017 09:35:47 +0200 Subject: [PATCH 49/71] Fixed listupgrades bugs --- src/protocol/multichainblock.cpp | 4 ++-- src/rpc/rpcupgrades.cpp | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/protocol/multichainblock.cpp b/src/protocol/multichainblock.cpp index 31dc162a..58183873 100644 --- a/src/protocol/multichainblock.cpp +++ b/src/protocol/multichainblock.cpp @@ -189,7 +189,7 @@ int CreateUpgradeLists(int current_height,vector *vParams, if (it != map_last_upgrade.end()) { take_it=false; - if((*vParams)[it->second].m_Block + 100 <= upgrade.m_AppliedBlock) + if((*vParams)[it->second].m_Block + 5 <= upgrade.m_AppliedBlock) { int64_t old_value=(*vParams)[it->second].m_Value; if(param.m_Value >= old_value) @@ -248,12 +248,12 @@ int CreateUpgradeLists(int current_height,vector *vParams, } } } + vParams->push_back(param); } else { param.m_Skipped = MC_PSK_NOT_FOUND; } - vParams->push_back(param); } } } diff --git a/src/rpc/rpcupgrades.cpp b/src/rpc/rpcupgrades.cpp index 06b65abd..614b7563 100644 --- a/src/rpc/rpcupgrades.cpp +++ b/src/rpc/rpcupgrades.cpp @@ -453,7 +453,6 @@ Value listupgrades(const json_spirit::Array& params, bool fHelp) vector vParams; vector vUpgrades; int current_height=chainActive.Height(); - CreateUpgradeLists(chainActive.Height(),&vParams,&vUpgrades); for(int u=0;u<(int)vUpgrades.size();u++) @@ -514,7 +513,7 @@ Value listupgrades(const json_spirit::Array& params, bool fHelp) case MC_PSK_WRONG_SIZE: param_err="Parameter is encoded with wrong size"; break; case MC_PSK_OUT_OF_RANGE: param_err="Parameter value is out of range"; break; case MC_PSK_FRESH_UPGRADE: param_err="Parameter is upgraded less than 100 blocks ago"; break; - case MC_PSK_DOUBLE_RANGE: param_err="New pparameter value must be between half and double preview time"; break; + case MC_PSK_DOUBLE_RANGE: param_err="New parameter value must be between half and double preview time"; break; case MC_PSK_NOT_SUPPORTED: param_err="This parameter cannot be upgraded in this protocol version"; break; case MC_PSK_NEW_NOT_DOWNGRADABLE: param_err="Cannot downgrade to this version"; break; case MC_PSK_OLD_NOT_DOWNGRADABLE: param_err="Downgrades are not allowed in this protocol version"; break; From fc03c788eba71e5a4f1dae0ea84bd94b416e0778 Mon Sep 17 00:00:00 2001 From: mike31 Date: Mon, 25 Dec 2017 15:29:45 +0200 Subject: [PATCH 50/71] Upgraded target-block-time in getblockchainparams --- src/protocol/multichainblock.cpp | 2 +- src/rpc/rpcmisc.cpp | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/protocol/multichainblock.cpp b/src/protocol/multichainblock.cpp index 58183873..156d4d0b 100644 --- a/src/protocol/multichainblock.cpp +++ b/src/protocol/multichainblock.cpp @@ -189,7 +189,7 @@ int CreateUpgradeLists(int current_height,vector *vParams, if (it != map_last_upgrade.end()) { take_it=false; - if((*vParams)[it->second].m_Block + 5 <= upgrade.m_AppliedBlock) + if((*vParams)[it->second].m_Block + 100 <= upgrade.m_AppliedBlock) { int64_t old_value=(*vParams)[it->second].m_Value; if(param.m_Value >= old_value) diff --git a/src/rpc/rpcmisc.cpp b/src/rpc/rpcmisc.cpp index 4a55d745..7097261d 100644 --- a/src/rpc/rpcmisc.cpp +++ b/src/rpc/rpcmisc.cpp @@ -676,6 +676,13 @@ Value getblockchainparams(const json_spirit::Array& params, bool fHelp) param_value=(int)MAX_BLOCK_SIZE; } } + if(strcmp("targetblocktime",(mc_gState->m_NetworkParams->m_lpParams+i)->m_Name) == 0) + { + if(nHeight) + { + param_value=(int)MCP_TARGET_BLOCK_TIME; + } + } obj.push_back(Pair(param_name,param_value)); } From d555fa23ba6abccaa89362e125b765fb4bce6cf3 Mon Sep 17 00:00:00 2001 From: mike31 Date: Tue, 26 Dec 2017 15:25:30 +0200 Subject: [PATCH 51/71] Fixed compilation warnings --- src/protocol/multichainblock.cpp | 1 - src/rpc/rpcupgrades.cpp | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/protocol/multichainblock.cpp b/src/protocol/multichainblock.cpp index 156d4d0b..0f19d970 100644 --- a/src/protocol/multichainblock.cpp +++ b/src/protocol/multichainblock.cpp @@ -269,7 +269,6 @@ int CreateUpgradeLists(int current_height,vector *vParams, } -exitlbl: mc_gState->m_Permissions->FreePermissionList(upgrades); mc_gState->m_ProtocolVersionToUpgrade=NewProtocolVersion; diff --git a/src/rpc/rpcupgrades.cpp b/src/rpc/rpcupgrades.cpp index 614b7563..efbfec6a 100644 --- a/src/rpc/rpcupgrades.cpp +++ b/src/rpc/rpcupgrades.cpp @@ -452,7 +452,7 @@ Value listupgrades(const json_spirit::Array& params, bool fHelp) vector vParams; vector vUpgrades; - int current_height=chainActive.Height(); + uint32_t current_height=chainActive.Height(); CreateUpgradeLists(chainActive.Height(),&vParams,&vUpgrades); for(int u=0;u<(int)vUpgrades.size();u++) From fcd4f496fcec93ec64cec7c046db032d90c1bcff Mon Sep 17 00:00:00 2001 From: mike31 Date: Wed, 27 Dec 2017 15:35:51 +0200 Subject: [PATCH 52/71] Checking upgradable constraints when connection block --- src/chainparams/globals.h | 1 + src/core/main.cpp | 52 ++++++++++++++++++++++++++++++-- src/core/main.h | 2 ++ src/protocol/multichainblock.cpp | 2 +- src/rpc/rpcupgrades.cpp | 2 +- 5 files changed, 55 insertions(+), 4 deletions(-) diff --git a/src/chainparams/globals.h b/src/chainparams/globals.h index ec35d0ee..f3feff15 100644 --- a/src/chainparams/globals.h +++ b/src/chainparams/globals.h @@ -19,6 +19,7 @@ int64_t COIN = 100000000; int64_t CENT = 1000000; // amount.h int64_t MAX_MONEY = 21000000 * COIN; // amount.h unsigned int MAX_SCRIPT_ELEMENT_SIZE=520; // script.h +int MIN_BLOCKS_BETWEEN_UPGRADES = 100; int MAX_OP_RETURN_SHOWN=16384; int MAX_FORMATTED_DATA_DEPTH=100; unsigned int MAX_OP_RETURN_OP_DROP_COUNT=100000000; diff --git a/src/core/main.cpp b/src/core/main.cpp index bea3561b..69fc75e4 100644 --- a/src/core/main.cpp +++ b/src/core/main.cpp @@ -2314,6 +2314,15 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin return false; } + if(!CheckBlockForUpgardableConstraints(block,state,"maximum-block-size",true)) + { + return false; + } + if(!CheckBlockForUpgardableConstraints(block,state,"maximum-block-sigops",true)) + { + return false; + } + /* MCHN START */ uint256 block_hash; unsigned char miner_address[20]; @@ -4135,6 +4144,34 @@ bool CheckBlockHeader(const CBlockHeader& block, CValidationState& state, bool f } /* MCHN START */ + +bool CheckBlockForUpgardableConstraints(const CBlock& block, CValidationState& state, string parameter, bool in_sync) +{ + if(!in_sync) + { + return true; + } + + if(parameter == "maximum-block-size") + { + if (block.vtx.empty() || block.vtx.size() > MAX_BLOCK_SIZE || ::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION) > MAX_BLOCK_SIZE) + return state.DoS(100, error("CheckBlock() : size limits failed"), + REJECT_INVALID, "bad-blk-length"); + } + if(parameter == "maximum-block-sigops") + { + unsigned int nSigOps = 0; + BOOST_FOREACH(const CTransaction& tx, block.vtx) + { + nSigOps += GetLegacySigOpCount(tx); + } + if (nSigOps > MAX_BLOCK_SIGOPS) + return state.DoS(100, error("CheckBlock() : out-of-bounds SigOpCount"), + REJECT_INVALID, "bad-blk-sigops", true); + } + return true; +} + //bool CheckBlock(CBlock& block, CValidationState& state, bool fCheckPOW, bool fCheckMerkleRoot) bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bool fCheckMerkleRoot) /* MCHN END */ @@ -4167,10 +4204,16 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo // because we receive the wrong transactions for it. // Size limits + if(!CheckBlockForUpgardableConstraints(block,state,"maximum-block-size",false)) + { + return false; + } +/* if (block.vtx.empty() || block.vtx.size() > MAX_BLOCK_SIZE || ::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION) > MAX_BLOCK_SIZE) return state.DoS(100, error("CheckBlock() : size limits failed"), REJECT_INVALID, "bad-blk-length"); - +*/ + // First transaction must be coinbase, the rest must not be if (block.vtx.empty() || !block.vtx[0].IsCoinBase()) return state.DoS(100, error("CheckBlock() : first tx is not coinbase"), @@ -4200,7 +4243,12 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo } } + if(!CheckBlockForUpgardableConstraints(block,state,"maximum-block-sigops",false)) + { + return false; + } +/* unsigned int nSigOps = 0; BOOST_FOREACH(const CTransaction& tx, block.vtx) { @@ -4209,7 +4257,7 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo if (nSigOps > MAX_BLOCK_SIGOPS) return state.DoS(100, error("CheckBlock() : out-of-bounds SigOpCount"), REJECT_INVALID, "bad-blk-sigops", true); - +*/ return true; } diff --git a/src/core/main.h b/src/core/main.h index f3788330..9eca8043 100644 --- a/src/core/main.h +++ b/src/core/main.h @@ -73,6 +73,7 @@ static const unsigned int DEFAULT_MAX_SUCCESSORS_FROM_ONE_NODE = 10; /* MCHN END */ extern int MAX_OP_RETURN_SHOWN; extern int MAX_FORMATTED_DATA_DEPTH; +extern int MIN_BLOCKS_BETWEEN_UPGRADES; /* MCHN END */ /** The maximum size of a blk?????.dat file (since 0.8) */ extern unsigned int MAX_BLOCKFILE_SIZE; // MCHN global @@ -395,6 +396,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin /** Context-independent validity checks */ bool CheckBlockHeader(const CBlockHeader& block, CValidationState& state, bool fCheckPOW = true); bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW = true, bool fCheckMerkleRoot = true); +bool CheckBlockForUpgardableConstraints(const CBlock& block, CValidationState& state, std::string parameter, bool in_sync); /** Context-dependent validity checks */ bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex *pindexPrev, CBlockIndex *pindexChecked = NULL); diff --git a/src/protocol/multichainblock.cpp b/src/protocol/multichainblock.cpp index 0f19d970..5aa1e7c1 100644 --- a/src/protocol/multichainblock.cpp +++ b/src/protocol/multichainblock.cpp @@ -189,7 +189,7 @@ int CreateUpgradeLists(int current_height,vector *vParams, if (it != map_last_upgrade.end()) { take_it=false; - if((*vParams)[it->second].m_Block + 100 <= upgrade.m_AppliedBlock) + if((*vParams)[it->second].m_Block + MIN_BLOCKS_BETWEEN_UPGRADES <= upgrade.m_AppliedBlock) { int64_t old_value=(*vParams)[it->second].m_Value; if(param.m_Value >= old_value) diff --git a/src/rpc/rpcupgrades.cpp b/src/rpc/rpcupgrades.cpp index efbfec6a..093b7072 100644 --- a/src/rpc/rpcupgrades.cpp +++ b/src/rpc/rpcupgrades.cpp @@ -512,7 +512,7 @@ Value listupgrades(const json_spirit::Array& params, bool fHelp) case MC_PSK_NOT_FOUND: param_err="Parameter name not recognized"; break; case MC_PSK_WRONG_SIZE: param_err="Parameter is encoded with wrong size"; break; case MC_PSK_OUT_OF_RANGE: param_err="Parameter value is out of range"; break; - case MC_PSK_FRESH_UPGRADE: param_err="Parameter is upgraded less than 100 blocks ago"; break; + case MC_PSK_FRESH_UPGRADE: param_err=strprintf("Parameter is upgraded less than %d blocks ago",MIN_BLOCKS_BETWEEN_UPGRADES); break; case MC_PSK_DOUBLE_RANGE: param_err="New parameter value must be between half and double preview time"; break; case MC_PSK_NOT_SUPPORTED: param_err="This parameter cannot be upgraded in this protocol version"; break; case MC_PSK_NEW_NOT_DOWNGRADABLE: param_err="Cannot downgrade to this version"; break; From 807dda76eed22fab5c85fcf5e4f1d1b18bffbcc6 Mon Sep 17 00:00:00 2001 From: mike31 Date: Wed, 27 Dec 2017 15:50:38 +0200 Subject: [PATCH 53/71] Logging parameter upgrades --- src/protocol/multichainblock.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/protocol/multichainblock.cpp b/src/protocol/multichainblock.cpp index 5aa1e7c1..4b2d424a 100644 --- a/src/protocol/multichainblock.cpp +++ b/src/protocol/multichainblock.cpp @@ -127,7 +127,7 @@ int CreateUpgradeLists(int current_height,vector *vParams, applied_height=plsRow->m_BlockReceived; } upgrade.m_AppliedBlock=applied_height; - if(current_height >=applied_height) + if(current_height >= applied_height) { version=entity.UpgradeProtocolVersion(); if(version > 0) @@ -248,6 +248,16 @@ int CreateUpgradeLists(int current_height,vector *vParams, } } } + if(vUpgrades == NULL) // Called from MultichainNode_ApplyUpgrades + { + if(param.m_Block == current_height) + { + if(param.m_Skipped == MC_PSK_APPLIED) + { + LogPrintf("PARAMETER UPGRADE: %s = %ld\n",param.m_Param->m_DisplayName,param.m_Value); + } + } + } vParams->push_back(param); } else From 6b45900c24a167de67aa64f9d5bd72cc5bdf0515 Mon Sep 17 00:00:00 2001 From: mike31 Date: Wed, 27 Dec 2017 16:23:40 +0200 Subject: [PATCH 54/71] walletnotifynew --- src/core/init.cpp | 1 + src/wallet/wallettxs.cpp | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/core/init.cpp b/src/core/init.cpp index d5dbb3a3..a8b6a7f2 100644 --- a/src/core/init.cpp +++ b/src/core/init.cpp @@ -385,6 +385,7 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += " -upgradewallet " + _("Upgrade wallet to latest format") + " " + _("on startup") + "\n"; strUsage += " -wallet= " + _("Specify wallet file (within data directory)") + " " + strprintf(_("(default: %s)"), "wallet.dat") + "\n"; strUsage += " -walletnotify= " + _("Execute this command when a transaction is first seen or confirmed, if it relates to an address in the wallet or a subscribed asset or stream. ") + "\n"; + strUsage += " -walletnotifynew= " + _("Execute this command when a transaction is first seen, if it relates to an address in the wallet or a subscribed asset or stream. ") + "\n"; strUsage += " " + _("(more details and % substitutions online)") + "\n"; /* MCHN START */ strUsage += " -walletdbversion=1|2 " + _("Specify wallet version, 1 - not scalable, 2 (default) - scalable") + "\n"; diff --git a/src/wallet/wallettxs.cpp b/src/wallet/wallettxs.cpp index cb358288..1d69efc0 100644 --- a/src/wallet/wallettxs.cpp +++ b/src/wallet/wallettxs.cpp @@ -25,7 +25,8 @@ using namespace std; void WalletTxNotify(mc_TxImport *imp,const CWalletTx& tx,int block,bool fFound,uint256 block_hash) { - std::string strNotifyCmd = GetArg("-walletnotify", ""); +// std::string strNotifyCmd = GetArg("-walletnotify", ""); + std::string strNotifyCmd = GetArg("-walletnotify", fFound ? "" : GetArg("-walletnotifynew", "")); if ( strNotifyCmd.empty() ) { return; @@ -2610,7 +2611,7 @@ int mc_WalletTxs::AddTx(mc_TxImport *import,const CWalletTx& tx,int block,CDiskT } fAlreadyInTheWalletForNotify=false; - if(!GetArg("-walletnotify", "").empty()) + if(!GetArg("-walletnotify", "").empty() || !GetArg("-walletnotifynew", "").empty()) { mc_TxDefRow StoredTxDef; if(m_Database->GetTx(&StoredTxDef,(unsigned char*)&hash) == 0) From 37a8c5a1075d2c6f3679d6054beab02ab707021b Mon Sep 17 00:00:00 2001 From: mike31 Date: Mon, 8 Jan 2018 16:15:12 +0200 Subject: [PATCH 55/71] Fixed protocol version upgrade and setlastblock --- src/core/main.cpp | 27 ++++++++++++++++++--------- src/protocol/multichainblock.cpp | 3 ++- src/rpc/rpcupgrades.cpp | 4 ++-- 3 files changed, 22 insertions(+), 12 deletions(-) diff --git a/src/core/main.cpp b/src/core/main.cpp index 69fc75e4..75659219 100644 --- a/src/core/main.cpp +++ b/src/core/main.cpp @@ -385,12 +385,12 @@ int MultichainNode_ApplyUpgrades(int current_height) vector vParams; int err=MC_ERR_NOERROR; - CreateUpgradeLists(chainActive.Height(),&vParams,NULL); + err=CreateUpgradeLists(current_height,&vParams,NULL); int OriginalProtocolVersion=(int)mc_gState->m_NetworkParams->GetInt64Param("protocolversion"); int CurrentProtocolVersion=mc_gState->m_NetworkParams->ProtocolVersion();//mc_gState->m_ProtocolVersionToUpgrade; - int NewProtocolVersion=OriginalProtocolVersion; + mc_gState->m_NetworkParams->m_ProtocolVersion=OriginalProtocolVersion; mc_gState->m_NetworkParams->SetGlobals(); for(int p=0;p<(int)vParams.size();p++) { @@ -398,7 +398,7 @@ int MultichainNode_ApplyUpgrades(int current_height) { if(strcmp(vParams[p].m_Param->m_Name,"protocolversion") == 0) { - err=mc_gState->m_NetworkParams->m_ProtocolVersion=mc_gState->m_ProtocolVersionToUpgrade;// UPGRADE CODE HERE + mc_gState->m_NetworkParams->m_ProtocolVersion=(int)vParams[p].m_Value; mc_gState->m_NetworkParams->SetProtocolGlobals(); } else @@ -408,20 +408,26 @@ int MultichainNode_ApplyUpgrades(int current_height) } } SetMultiChainParams(); + mc_gState->m_ProtocolVersionToUpgrade=mc_gState->m_NetworkParams->m_ProtocolVersion; + if(mc_gState->m_ProtocolVersionToUpgrade != CurrentProtocolVersion) { LogPrintf("New protocol upgrade version: %d (was %d)\n",mc_gState->m_ProtocolVersionToUpgrade,CurrentProtocolVersion); if( (err == MC_ERR_NOT_SUPPORTED) || ((mc_gState->m_ProtocolVersionToUpgrade > 0) && (mc_gState->IsSupported(mc_gState->m_ProtocolVersionToUpgrade) == 0)) ) { + mc_gState->m_NetworkParams->m_ProtocolVersion=CurrentProtocolVersion; LogPrintf("NODE SHOULD BE UPGRADED FROM %d TO %d\n",mc_gState->GetProtocolVersion(),mc_gState->m_ProtocolVersionToUpgrade); } else { + LogPrintf("NODE IS UPGRADED FROM %d TO %d\n",CurrentProtocolVersion,mc_gState->m_ProtocolVersionToUpgrade); +/* if(mc_gState->m_ProtocolVersionToUpgrade != mc_gState->m_NetworkParams->ProtocolVersion()) { LogPrintf("NODE IS UPGRADED FROM %d TO %d\n",mc_gState->m_NetworkParams->ProtocolVersion(),mc_gState->m_ProtocolVersionToUpgrade); } + */ } } else @@ -3569,7 +3575,6 @@ string SetLastBlock(uint256 hash,bool *fNotFound) CBlockIndex *pindex; pindex=pblockindex; - while(pindex != pindexFork) { if (pblockindex->nStatus & BLOCK_FAILED_MASK) @@ -3601,12 +3606,16 @@ string SetLastBlock(uint256 hash,bool *fNotFound) pindex=pindex->pprev; } - if(!ActivateBestChainStep(state,pblockindex,&block)) + while(pblockindex != chainActive.Tip()) { - string error=state.GetRejectReason(); - ActivateBestChain(state); - return error; - } + if(!ActivateBestChainStep(state,pblockindex,NULL)) + { + string error=state.GetRejectReason(); + ActivateBestChain(state); + return error; + } + } + setBlockIndexCandidates.insert(pblockindex); LogPrintf("Set active chain tip: %s\n",hash.GetHex().c_str()); diff --git a/src/protocol/multichainblock.cpp b/src/protocol/multichainblock.cpp index 4b2d424a..c2a2b8c9 100644 --- a/src/protocol/multichainblock.cpp +++ b/src/protocol/multichainblock.cpp @@ -110,6 +110,7 @@ int CreateUpgradeLists(int current_height,vector *vParams, mc_PermissionDetails *plsRow; plsRow=(mc_PermissionDetails *)(upgrades->GetRow(i)); // if(plsRow->m_Type == MC_PTP_UPGRADE) + if(err == MC_ERR_NOERROR) { memset(&upgrade,0,sizeof(mc_UpgradeStatus)); memcpy(upgrade.m_EntityShortTxID,plsRow->m_Address,MC_AST_SHORT_TXID_SIZE); @@ -135,6 +136,7 @@ int CreateUpgradeLists(int current_height,vector *vParams, param.m_Param=mc_gState->m_NetworkParams->FindParam("protocolversion"); param.m_Value=version; param.m_Block=upgrade.m_AppliedBlock; + param.m_Skipped=MC_PSK_APPLIED; if(version >= mc_gState->MinProtocolDowngradeVersion()) { if((NewProtocolVersion < mc_gState->MinProtocolForbiddenDowngradeVersion()) || (version >= NewProtocolVersion)) @@ -144,7 +146,6 @@ int CreateUpgradeLists(int current_height,vector *vParams, { err=MC_ERR_NOT_SUPPORTED; } - memset(¶m,0,sizeof(mc_UpgradedParameter)); } else { diff --git a/src/rpc/rpcupgrades.cpp b/src/rpc/rpcupgrades.cpp index 093b7072..284b5960 100644 --- a/src/rpc/rpcupgrades.cpp +++ b/src/rpc/rpcupgrades.cpp @@ -523,9 +523,9 @@ Value listupgrades(const json_spirit::Array& params, bool fHelp) } } - if(vUpgrades[u].m_ApprovedBlock <= current_height) + if(vUpgrades[u].m_AppliedBlock <= current_height) { - entry.push_back(Pair("appliedblock", (int64_t)vUpgrades[u].m_ApprovedBlock)); + entry.push_back(Pair("appliedblock", (int64_t)vUpgrades[u].m_AppliedBlock)); entry.push_back(Pair("appliedparams", applied_params)); entry.push_back(Pair("skippedparams", skipped_params)); } From ba3b71fddce33e94a8d958b8aa410553736226b0 Mon Sep 17 00:00:00 2001 From: mike31 Date: Tue, 9 Jan 2018 08:35:35 +0200 Subject: [PATCH 56/71] Help messages for per-asset permissions --- src/rpc/rpchelp.cpp | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/rpc/rpchelp.cpp b/src/rpc/rpchelp.cpp index 8504b30f..38aad2b1 100644 --- a/src/rpc/rpchelp.cpp +++ b/src/rpc/rpchelp.cpp @@ -2025,7 +2025,7 @@ void mc_InitRPCHelpMap09() "1. \"address(es)\" (string, required) The multichain addresses to send to (comma delimited)\n" "2. \"permission(s)\" (string, required) Permission strings, comma delimited. \n" " Global: " + AllowedPermissions() + " \n" - " or per-asset: asset-identifier.issue,admin \n" + " or per-asset: asset-identifier.issue,admin,activate,send,receive \n" " or per-stream: stream-identifier.write,activate,admin \n" "3. native-amount (numeric, optional) Native currency amount to send. eg 0.1. Default - 0.0\n" "4. startblock (numeric, optional) Block to apply permissions from (inclusive). Default - 0\n" @@ -2054,7 +2054,7 @@ void mc_InitRPCHelpMap09() "2. \"to-address(es)\" (string, required) The multichain addresses to grant permissions to\n" "3. \"permission(s)\" (string, required) Permission strings, comma delimited. \n" " Global: " + AllowedPermissions() + " \n" - " or per-asset: asset-identifier.issue,admin \n" + " or per-asset: asset-identifier.issue,admin,activate,send,receive \n" " or per-stream: stream-identifier.write,activate,admin \n" "4. native-amount (numeric, optional) Native currency amount to send. eg 0.1. Default - 0.0\n" "5. startblock (numeric, optional) Block to apply permissions from (inclusive). Default - 0\n" @@ -2080,7 +2080,7 @@ void mc_InitRPCHelpMap09() "1. \"address(es)\" (string, required) The multichain addresses to send to (comma delimited)\n" "2. \"permission(s)\" (string, required) Permission strings, comma delimited. \n" " Global: " + AllowedPermissions() + " \n" - " or per-asset: asset-identifier.issue,admin \n" + " or per-asset: asset-identifier.issue,admin,activate,send,receive \n" " or per-stream: stream-identifier.write,activate,admin \n" "3. data|publish-new-stream-item (string or object, required) Data, see help data-with for details. \n" "4. native-amount (numeric, optional) Native currency amount to send. eg 0.1. Default - 0.0\n" @@ -2106,7 +2106,7 @@ void mc_InitRPCHelpMap10() "1. \"address(es)\" (string, required) The multichain addresses to send to (comma delimited)\n" "2. \"permission(s)\" (string, required) Permission strings, comma delimited. \n" " Global: " + AllowedPermissions() + " \n" - " or per-asset: asset-identifier.issue,admin \n" + " or per-asset: asset-identifier.issue,admin,activate,send,receive \n" " or per-stream: stream-identifier.write,activate,admin \n" "3. data|publish-new-stream-item (string or object, required) Data, see help data-with for details. \n" "4. native-amount (numeric, optional) Native currency amount to send. eg 0.1. Default - 0.0\n" @@ -2130,7 +2130,7 @@ void mc_InitRPCHelpMap10() "2. \"address(es)\" (string, required) The multichain addresses to send to (comma delimited)\n" "3. \"permission(s)\" (string, required) Permission strings, comma delimited. \n" " Global: " + AllowedPermissions() + " \n" - " or per-asset: asset-identifier.issue,admin \n" + " or per-asset: asset-identifier.issue,admin,activate,send,receive \n" " or per-stream: stream-identifier.write,activate,admin \n" "4. data|publish-new-stream-item (string or object, required) Data, see help data-with for details. \n" "5. native-amount (numeric, optional) Native currency amount to send. eg 0.1. Default - 0.0\n" @@ -2154,7 +2154,7 @@ void mc_InitRPCHelpMap10() "2. \"address(es)\" (string, required) The multichain addresses to send to (comma delimited)\n" "3. \"permission(s)\" (string, required) Permission strings, comma delimited. \n" " Global: " + AllowedPermissions() + " \n" - " or per-asset: asset-identifier.issue,admin \n" + " or per-asset: asset-identifier.issue,admin,activate,send,receive \n" " or per-stream: stream-identifier.write,activate,admin \n" "4. data|publish-new-stream-item (string or object, required) Data, see help data-with for details. \n" "5. native-amount (numeric, optional) Native currency amount to send. eg 0.1. Default - 0.0\n" @@ -2237,6 +2237,7 @@ void mc_InitRPCHelpMap10() " {\n" " \"name\" : \"asset-name\" (string, optional) Asset name\n" " \"open\" : true|false (boolean, optional, default false) True if follow-on issues are allowed\n" + " \"restrict\" : \"restrictions\" (string, optional) Permission strings, comma delimited. Possible values: send,receive\n" " ,...\n" " }\n" "3. quantity (numeric, required) The asset total amount in display units. eg. 1234.56\n" @@ -2268,6 +2269,7 @@ void mc_InitRPCHelpMap10() " {\n" " \"name\" : \"asset-name\" (string, optional) Asset name\n" " \"open\" : true|false (boolean, optional, default false) True if follow-on issues are allowed\n" + " \"restrict\" : \"restrictions\" (string, optional) Permission strings, comma delimited. Possible values: send,receive\n" " ,...\n" " }\n" "4. quantity (numeric, required) The asset total amount in display units. eg. 1234.56\n" @@ -2998,7 +3000,7 @@ void mc_InitRPCHelpMap13() "1. \"address(es)\" (string, required) The addresses(es) to revoke permissions from\n" "2. \"permission(s)\" (string, required) Permission strings, comma delimited. \n" " Global: " + AllowedPermissions() + " \n" - " or per-asset: asset-identifier.issue,admin \n" + " or per-asset: asset-identifier.issue,admin,activate,send,receive \n" " or per-stream: stream-identifier.write,activate,admin \n" "3. native-amount (numeric, optional) native currency amount to send. eg 0.1. Default - 0\n" "4. \"comment\" (string, optional) A comment used to store what the transaction is for. \n" @@ -3023,7 +3025,7 @@ void mc_InitRPCHelpMap13() "2. \"to-address(es)\" (string, required) The addresses(es) to revoke permissions from. Comma delimited\n" "3. \"permission(s)\" (string, required) Permission strings, comma delimited. \n" " Global: " + AllowedPermissions() + " \n" - " or per-asset: asset-identifier.issue,admin \n" + " or per-asset: asset-identifier.issue,admin,activate,send,receive \n" " or per-stream: stream-identifier.write,activate,admin \n" "4. native-amount (numeric, optional) native currency amount to send. eg 0.1. Default - 0\n" "5. \"comment\" (string, optional) A comment used to store what the transaction is for. \n" @@ -3686,6 +3688,7 @@ void mc_InitRPCHelpMap16() " \"name\" : \"asset-name\" (string, optional) Asset name\n" " \"multiple\" : n (numeric, optional, default 1) Number of raw units in one displayed unit\n" " \"open\" : true|false (boolean, optional, default false) True if follow-on issues are allowed\n" + " \"restrict\" : \"restrictions\" (string, optional) Permission strings, comma delimited. Possible values: send,receive\n" " \"details\" : (object, optional) A json object with custom fields\n" " {\n" " \"param-name\": \"param-value\" (strings, required) The key is the parameter name, the value is parameter value\n" From ac5c8f7a4ec373b342ce2963b9e6253d90d01b44 Mon Sep 17 00:00:00 2001 From: mike31 Date: Tue, 9 Jan 2018 10:21:48 +0200 Subject: [PATCH 57/71] Compilation warnings --- src/protocol/multichainblock.cpp | 2 +- src/rpc/rpcupgrades.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/protocol/multichainblock.cpp b/src/protocol/multichainblock.cpp index c2a2b8c9..35562345 100644 --- a/src/protocol/multichainblock.cpp +++ b/src/protocol/multichainblock.cpp @@ -251,7 +251,7 @@ int CreateUpgradeLists(int current_height,vector *vParams, } if(vUpgrades == NULL) // Called from MultichainNode_ApplyUpgrades { - if(param.m_Block == current_height) + if((int)param.m_Block == current_height) { if(param.m_Skipped == MC_PSK_APPLIED) { diff --git a/src/rpc/rpcupgrades.cpp b/src/rpc/rpcupgrades.cpp index 284b5960..7a628f56 100644 --- a/src/rpc/rpcupgrades.cpp +++ b/src/rpc/rpcupgrades.cpp @@ -478,7 +478,7 @@ Value listupgrades(const json_spirit::Array& params, bool fHelp) entry.push_back(Pair("approved", (vUpgrades[u].m_ApprovedBlock <= current_height+1))); - for(int p=vUpgrades[u].m_FirstParam;pm_DisplayName); if(vParams[p].m_Skipped == MC_PSK_APPLIED) From 179d220bdb83eaf37c9e24e3084693b61634d1dc Mon Sep 17 00:00:00 2001 From: mike31 Date: Tue, 9 Jan 2018 18:07:44 +0200 Subject: [PATCH 58/71] -rpcallowmethod --- src/core/init-cold.cpp | 1 + src/core/init.cpp | 1 + src/rpc/rpcserver.cpp | 40 +++++++++++++++++++++++++++++++++++++++- src/rpc/rpcserver.h | 1 + 4 files changed, 42 insertions(+), 1 deletion(-) diff --git a/src/core/init-cold.cpp b/src/core/init-cold.cpp index e1d36b81..45ec7255 100644 --- a/src/core/init-cold.cpp +++ b/src/core/init-cold.cpp @@ -218,6 +218,7 @@ std::string HelpMessage_Cold() strUsage += " -rpcport= " + strprintf(_("Listen for JSON-RPC connections on (default: %u or testnet: %u)"), 8332, 18332) + "\n"; strUsage += " -rpcallowip= " + _("Allow JSON-RPC connections from specified source. Valid for are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24).") + "\n"; strUsage += " " + _("This option can be specified multiple times") + "\n"; + strUsage += " -rpcallowmethod= " + _("If specified, allow only comma delimited list of JSON-RPC . This option can be specified multiple times.") + "\n"; strUsage += " -rpcthreads= " + strprintf(_("Set the number of threads to service RPC calls (default: %d)"), 4) + "\n"; strUsage += " -rpckeepalive " + strprintf(_("RPC support for HTTP persistent connections (default: %d)"), 0) + "\n"; diff --git a/src/core/init.cpp b/src/core/init.cpp index a8b6a7f2..fd907707 100644 --- a/src/core/init.cpp +++ b/src/core/init.cpp @@ -466,6 +466,7 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += " -rpcport= " + strprintf(_("Listen for JSON-RPC connections on (default: %u or testnet: %u)"), 8332, 18332) + "\n"; strUsage += " -rpcallowip= " + _("Allow JSON-RPC connections from specified source. Valid for are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24).") + "\n"; strUsage += " " + _("This option can be specified multiple times") + "\n"; + strUsage += " -rpcallowmethod= " + _("If specified, allow only comma delimited list of JSON-RPC . This option can be specified multiple times.") + "\n"; strUsage += " -rpcthreads= " + strprintf(_("Set the number of threads to service RPC calls (default: %d)"), 4) + "\n"; strUsage += " -rpckeepalive " + strprintf(_("RPC support for HTTP persistent connections (default: %d)"), 0) + "\n"; diff --git a/src/rpc/rpcserver.cpp b/src/rpc/rpcserver.cpp index 6f888414..d8bf9273 100644 --- a/src/rpc/rpcserver.cpp +++ b/src/rpc/rpcserver.cpp @@ -311,7 +311,18 @@ Value help(const Array& params, bool fHelp) string strCommand; if (params.size() > 0) strCommand = params[0].get_str(); - + + if(strCommand.size()) + { + if(setAllowedWhenLimited.size()) + { + if( setAllowedWhenLimited.count(strCommand) == 0 ) + { + throw JSONRPCError(RPC_NOT_ALLOWED, "Method not allowed with current setting of -rpcallowmethod runtime parameter"); + } + } + } + return tableRPC.help(strCommand); } @@ -622,9 +633,27 @@ static ip::tcp::endpoint ParseEndpoint(const std::string &strEndpoint, int defau return ip::tcp::endpoint(asio::ip::address::from_string(addr), port); } +void mc_InitRPCListIfLimited() +{ + if (mapArgs.count("-rpcallowmethod")) + { + setAllowedWhenLimited.insert("help"); + BOOST_FOREACH(const std::string& methods, mapMultiArgs["-rpcallowmethod"]) + { + stringstream ss(methods); + string tok; + while(getline(ss, tok, ',')) + { + setAllowedWhenLimited.insert(tok); + } + } + } +} + void StartRPCThreads() { mc_InitRPCList(vStaticRPCCommands,vStaticRPCWalletReadCommands); + mc_InitRPCListIfLimited(); tableRPC.initialize(); rpc_allow_subnets.clear(); @@ -1134,6 +1163,14 @@ json_spirit::Value CRPCTable::execute(const std::string &strMethod, const json_s } } + if(setAllowedWhenLimited.size()) + { + if( setAllowedWhenLimited.count(strMethod) == 0 ) + { + throw JSONRPCError(RPC_NOT_ALLOWED, "Method not allowed with current setting of -rpcallowmethod runtime parameter"); + } + } + // Observe safe mode string strWarning = GetWarnings("rpc"); if (strWarning != "" && !GetBoolArg("-disablesafemode", false) && @@ -1241,6 +1278,7 @@ std::map mapHelpStrings; std::map mapLogParamCounts; std::set setAllowedWhenWaitingForUpgrade; std::set setAllowedWhenOffline; +std::set setAllowedWhenLimited; std::vector vStaticRPCCommands; std::vector vStaticRPCWalletReadCommands; diff --git a/src/rpc/rpcserver.h b/src/rpc/rpcserver.h index e9e4a9ea..a0401fbc 100644 --- a/src/rpc/rpcserver.h +++ b/src/rpc/rpcserver.h @@ -124,6 +124,7 @@ extern std::map mapHelpStrings; extern std::map mapLogParamCounts; extern std::set setAllowedWhenWaitingForUpgrade; extern std::set setAllowedWhenOffline; +extern std::set setAllowedWhenLimited; extern std::vector vStaticRPCCommands; extern std::vector vStaticRPCWalletReadCommands; void mc_InitRPCHelpMap(); From 10e7013b8fbcf8774f5c953fed826601dd1905a6 Mon Sep 17 00:00:00 2001 From: mike31 Date: Thu, 11 Jan 2018 21:12:51 +0200 Subject: [PATCH 59/71] Avoiding buffer allocation in RPC calls --- src/chainparams/state.h | 67 +++++++++++++++++ src/rpc/rpcassets.cpp | 131 +++++++++++----------------------- src/rpc/rpcexchange.cpp | 52 ++++---------- src/rpc/rpcpermissions.cpp | 5 +- src/rpc/rpcrawdata.cpp | 40 ++--------- src/rpc/rpcrawtransaction.cpp | 43 ++++------- src/rpc/rpcstreams.cpp | 94 ++++++++---------------- src/rpc/rpcupgrades.cpp | 38 +++------- src/rpc/rpcutils.cpp | 19 ++--- src/rpc/rpcwallet.cpp | 30 -------- src/rpc/rpcwalletsend.cpp | 65 +++++------------ src/rpc/rpcwallettxs.cpp | 64 ++++++----------- 12 files changed, 231 insertions(+), 417 deletions(-) diff --git a/src/chainparams/state.h b/src/chainparams/state.h index 1141df10..ac6b9aa6 100644 --- a/src/chainparams/state.h +++ b/src/chainparams/state.h @@ -9,6 +9,7 @@ #include "protocol/multichainscript.h" #include "permissions/permission.h" #include "entities/asset.h" +#include "wallet/wallettxdb.h" #define MC_FAT_UNKNOWN 1 #define MC_FAT_COMMAND 2 @@ -159,6 +160,64 @@ typedef struct mc_BlockHeaderInfo } mc_BlockHeaderInfo; +typedef struct mc_TmpBuffers +{ + mc_TmpBuffers() + { + Init(); + } + + ~mc_TmpBuffers() + { + Destroy(); + } + + mc_Script *m_RpcScript1; + mc_Script *m_RpcScript2; + mc_Script *m_RpcScript3; + mc_Script *m_RpcScript4; + mc_Buffer *m_RpcABBuffer1; + mc_Buffer *m_RpcABBuffer2; + mc_Buffer *m_RpcBuffer1; + mc_Buffer *m_RpcABNoMapBuffer1; + mc_Buffer *m_RpcABNoMapBuffer2; + mc_Buffer *m_RpcEntityRows; + + void Init() + { + m_RpcScript1=new mc_Script(); + m_RpcScript2=new mc_Script(); + m_RpcScript3=new mc_Script(); + m_RpcScript4=new mc_Script(); + m_RpcABBuffer1=new mc_Buffer; + mc_InitABufferMap(m_RpcABBuffer1); + m_RpcABBuffer2=new mc_Buffer; + mc_InitABufferMap(m_RpcABBuffer2); + m_RpcBuffer1=new mc_Buffer; + m_RpcABNoMapBuffer1=new mc_Buffer; + mc_InitABufferDefault(m_RpcABNoMapBuffer1); + m_RpcABNoMapBuffer2=new mc_Buffer; + mc_InitABufferDefault(m_RpcABNoMapBuffer2); + m_RpcEntityRows=new mc_Buffer; + m_RpcEntityRows->Initialize(MC_TDB_ENTITY_KEY_SIZE,MC_TDB_ROW_SIZE,MC_BUF_MODE_DEFAULT); + } + + void Destroy() + { + delete m_RpcScript1; + delete m_RpcScript2; + delete m_RpcScript3; + delete m_RpcScript4; + delete m_RpcABBuffer1; + delete m_RpcABBuffer2; + delete m_RpcBuffer1; + delete m_RpcABNoMapBuffer1; + delete m_RpcABNoMapBuffer2; + delete m_RpcEntityRows; + } + +} mc_TmpBuffers; + typedef struct mc_State { mc_State() @@ -194,6 +253,8 @@ typedef struct mc_State mc_Buffer *m_BlockHeaderSuccessors; + mc_TmpBuffers *m_TmpBuffers; + void InitDefaults() { m_Params=new mc_Params; @@ -225,6 +286,8 @@ typedef struct mc_State memset(&bhi,0,sizeof(mc_BlockHeaderInfo)); m_BlockHeaderSuccessors->Add(&bhi); + m_TmpBuffers=new mc_TmpBuffers; + m_pSeedNode=NULL; } @@ -274,6 +337,10 @@ typedef struct mc_State { delete m_BlockHeaderSuccessors; } + if(m_TmpBuffers) + { + delete m_TmpBuffers; + } } int VersionInfo(int version); diff --git a/src/rpc/rpcassets.cpp b/src/rpc/rpcassets.cpp index 57972963..7d3f87e3 100644 --- a/src/rpc/rpcassets.cpp +++ b/src/rpc/rpcassets.cpp @@ -60,8 +60,8 @@ Value issuefromcmd(const Array& params, bool fHelp) // Wallet comments CWalletTx wtx; - mc_Script *lpScript; - lpScript=new mc_Script; + mc_Script *lpScript=mc_gState->m_TmpBuffers->m_RpcScript3; + lpScript->Clear(); int64_t quantity; int multiple; @@ -123,11 +123,10 @@ Value issuefromcmd(const Array& params, bool fHelp) lpScript->SetAssetGenesis(quantity); - mc_Script *lpDetailsScript; - lpDetailsScript=NULL; - - mc_Script *lpDetails; - lpDetails=NULL; + mc_Script *lpDetailsScript=mc_gState->m_TmpBuffers->m_RpcScript1; + lpDetailsScript->Clear(); + mc_Script *lpDetails=mc_gState->m_TmpBuffers->m_RpcScript2; + lpDetails->Clear(); int ret,type; string asset_name=""; @@ -220,7 +219,7 @@ Value issuefromcmd(const Array& params, bool fHelp) } } - lpDetails=new mc_Script; + lpDetails->Clear(); lpDetails->AddElement(); if(mc_gState->m_Features->OpDropDetailsScripts()) @@ -273,7 +272,7 @@ Value issuefromcmd(const Array& params, bool fHelp) vector fromaddresses; int errorCode=RPC_INVALID_PARAMETER; string strError; - lpDetailsScript=new mc_Script; + lpDetailsScript->Clear(); if (params.size() > 6) { ParseRawDetails(&(params[6]),lpDetails,lpDetailsScript,&errorCode,&strError); @@ -375,13 +374,6 @@ Value issuefromcmd(const Array& params, bool fHelp) exitlbl: - if(lpDetailsScript) - { - delete lpDetailsScript; - } - delete lpDetails; - delete lpScript; - if(strError.size()) { throw JSONRPCError(errorCode, strError); @@ -425,8 +417,8 @@ Value issuemorefromcmd(const Array& params, bool fHelp) throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid amount"); } - mc_Script *lpScript; - lpScript=new mc_Script; + mc_Script *lpScript=mc_gState->m_TmpBuffers->m_RpcScript3; + lpScript->Clear(); unsigned char buf[MC_AST_ASSET_FULLREF_BUF_SIZE]; memset(buf,0,MC_AST_ASSET_FULLREF_BUF_SIZE); int multiple=1; @@ -460,19 +452,13 @@ Value issuemorefromcmd(const Array& params, bool fHelp) mc_SetABQuantity(buf,quantity); - mc_Buffer *lpBuffer; - lpBuffer=new mc_Buffer; - - mc_InitABufferDefault(lpBuffer); + mc_Buffer *lpBuffer=mc_gState->m_TmpBuffers->m_RpcABNoMapBuffer2; + lpBuffer->Clear(); lpBuffer->Add(buf); lpScript->SetAssetQuantities(lpBuffer,MC_SCR_ASSET_SCRIPT_TYPE_FOLLOWON); - delete lpBuffer; - - - // Wallet comments CWalletTx wtx; @@ -484,11 +470,12 @@ Value issuemorefromcmd(const Array& params, bool fHelp) } - mc_Script *lpDetailsScript; - lpDetailsScript=NULL; + mc_Script *lpDetailsScript=mc_gState->m_TmpBuffers->m_RpcScript1; + lpDetailsScript->Clear(); + + mc_Script *lpDetails=mc_gState->m_TmpBuffers->m_RpcScript2; + lpDetails->Clear(); - mc_Script *lpDetails; - lpDetails=new mc_Script; lpDetails->AddElement(); vector addresses; @@ -668,13 +655,6 @@ Value issuemorefromcmd(const Array& params, bool fHelp) exitlbl: - if(lpDetailsScript) - { - delete lpDetailsScript; - } - delete lpDetails; - delete lpScript; - if(strError.size()) { throw JSONRPCError(errorCode, strError); @@ -791,8 +771,10 @@ Value getmultibalances(const Array& params, bool fHelp) } } - mc_Buffer *asset_amounts; - mc_Buffer *addresstxid_amounts; + mc_Buffer *asset_amounts=mc_gState->m_TmpBuffers->m_RpcABBuffer1; + asset_amounts->Clear(); + mc_Buffer *addresstxid_amounts=mc_gState->m_TmpBuffers->m_RpcBuffer1; + addresstxid_amounts->Clear(); unsigned char buf[80+MC_AST_ASSET_QUANTITY_SIZE]; unsigned char totbuf[80+MC_AST_ASSET_QUANTITY_SIZE]; int64_t quantity; @@ -805,14 +787,11 @@ Value getmultibalances(const Array& params, bool fHelp) { LOCK(cs_main); - mc_Script *lpScript; - lpScript=new mc_Script; + mc_Script *lpScript=mc_gState->m_TmpBuffers->m_RpcScript3; + lpScript->Clear(); - asset_amounts=new mc_Buffer; - mc_InitABufferMap(asset_amounts); asset_amounts->Clear(); - addresstxid_amounts=new mc_Buffer; addresstxid_amounts->Initialize(80,80+MC_AST_ASSET_QUANTITY_SIZE,MC_BUF_MODE_MAP); addresstxid_amounts->Clear(); @@ -1065,9 +1044,6 @@ Value getmultibalances(const Array& params, bool fHelp) } - delete addresstxid_amounts; - delete asset_amounts; - delete lpScript; } return balances; @@ -1112,18 +1088,15 @@ Value getaddressbalances(const Array& params, bool fHelp) if (params.size() > 1) nMinDepth = params[1].get_int(); - mc_Buffer *asset_amounts; - asset_amounts=new mc_Buffer; - mc_InitABufferMap(asset_amounts); + mc_Buffer *asset_amounts=mc_gState->m_TmpBuffers->m_RpcABBuffer1; asset_amounts->Clear(); - mc_Buffer *genesis_amounts; - genesis_amounts=new mc_Buffer; + mc_Buffer *genesis_amounts=mc_gState->m_TmpBuffers->m_RpcBuffer1; genesis_amounts->Initialize(32,32+MC_AST_ASSET_QUANTITY_SIZE,MC_BUF_MODE_MAP); genesis_amounts->Clear(); - mc_Script *lpScript; - lpScript=new mc_Script; + mc_Script *lpScript=mc_gState->m_TmpBuffers->m_RpcScript3; + lpScript->Clear(); int last_size=0; Array assets; @@ -1300,10 +1273,6 @@ Value getaddressbalances(const Array& params, bool fHelp) } - delete lpScript; - delete asset_amounts; - delete genesis_amounts; - /* MCHN END */ return assets; } @@ -1359,18 +1328,15 @@ Value getassetbalances(const Array& params, bool fHelp) if (params.size() > 1) nMinDepth = params[1].get_int(); - mc_Buffer *asset_amounts; - asset_amounts=new mc_Buffer; - mc_InitABufferMap(asset_amounts); + mc_Buffer *asset_amounts=mc_gState->m_TmpBuffers->m_RpcABBuffer1; asset_amounts->Clear(); - mc_Buffer *genesis_amounts; - genesis_amounts=new mc_Buffer; + mc_Buffer *genesis_amounts=mc_gState->m_TmpBuffers->m_RpcBuffer1; genesis_amounts->Initialize(32,32+MC_AST_ASSET_QUANTITY_SIZE,MC_BUF_MODE_MAP); genesis_amounts->Clear(); - mc_Script *lpScript; - lpScript=new mc_Script; + mc_Script *lpScript=mc_gState->m_TmpBuffers->m_RpcScript3; + lpScript->Clear(); int last_size=0; Array assets; @@ -1521,11 +1487,7 @@ Value getassetbalances(const Array& params, bool fHelp) asset_entry=AssetEntry(ptr,mc_GetLE(ptr+32,MC_AST_ASSET_QUANTITY_SIZE),0x00); assets.push_back(asset_entry); } - - delete lpScript; - delete asset_amounts; - delete genesis_amounts; - + /* MCHN END */ return assets; } @@ -1992,12 +1954,11 @@ Value getassettransaction(const Array& params, bool fHelp) } const CWalletTx& wtx=pwalletTxsMain->GetWalletTx(hash,NULL,NULL); - mc_Buffer *asset_amounts; - asset_amounts=new mc_Buffer; - mc_InitABufferMap(asset_amounts); + mc_Buffer *asset_amounts=mc_gState->m_TmpBuffers->m_RpcABBuffer1; + asset_amounts->Clear(); - mc_Script *lpScript; - lpScript=new mc_Script; + mc_Script *lpScript=mc_gState->m_TmpBuffers->m_RpcScript3; + lpScript->Clear(); Object entry=ListAssetTransactions(wtx, &asset_entity, verbose, asset_amounts, lpScript); @@ -2006,8 +1967,6 @@ Value getassettransaction(const Array& params, bool fHelp) throw JSONRPCError(RPC_TX_NOT_FOUND, "This transaction was not found for this asset"); } - delete asset_amounts; - delete lpScript; return entry; } @@ -2071,16 +2030,14 @@ Value listassettransactions(const Array& params, bool fHelp) throw JSONRPCError(RPC_NOT_SUBSCRIBED, "Not subscribed to this asset"); } - mc_Buffer *entity_rows; - entity_rows=new mc_Buffer; - entity_rows->Initialize(MC_TDB_ENTITY_KEY_SIZE,MC_TDB_ROW_SIZE,MC_BUF_MODE_DEFAULT); + mc_Buffer *entity_rows=mc_gState->m_TmpBuffers->m_RpcEntityRows; + entity_rows->Clear(); - mc_Buffer *asset_amounts; - asset_amounts=new mc_Buffer; - mc_InitABufferMap(asset_amounts); + mc_Buffer *asset_amounts=mc_gState->m_TmpBuffers->m_RpcABBuffer1; + asset_amounts->Clear(); - mc_Script *lpScript; - lpScript=new mc_Script; + mc_Script *lpScript=mc_gState->m_TmpBuffers->m_RpcScript3; + lpScript->Clear(); pwalletTxsMain->GetList(&entStat.m_Entity,1,1,entity_rows); shift=1; @@ -2135,9 +2092,5 @@ Value listassettransactions(const Array& params, bool fHelp) } } - delete entity_rows; - delete asset_amounts; - delete lpScript; - return retArray; } diff --git a/src/rpc/rpcexchange.cpp b/src/rpc/rpcexchange.cpp index c9415947..b30f9860 100644 --- a/src/rpc/rpcexchange.cpp +++ b/src/rpc/rpcexchange.cpp @@ -219,13 +219,11 @@ Object DecodeExchangeTransaction(const CTransaction tx,int verbose,int64_t& nati vector input_txouts; vector input_errors; - mc_Buffer *asset_amounts; - asset_amounts=new mc_Buffer; - mc_InitABufferMap(asset_amounts); + mc_Buffer *asset_amounts=mc_gState->m_TmpBuffers->m_RpcABBuffer2; asset_amounts->Clear(); - mc_Script *lpScript; - lpScript=new mc_Script; + mc_Script *lpScript=mc_gState->m_TmpBuffers->m_RpcScript4; + lpScript->Clear(); AcceptExchange(tx, input_txouts, input_errors,strError); @@ -345,9 +343,6 @@ Object DecodeExchangeTransaction(const CTransaction tx,int verbose,int64_t& nati } - delete lpScript; - delete asset_amounts; - is_complete=true; if(lpAssets != NULL) { @@ -492,8 +487,8 @@ Object DecodeExchangeTransaction(const CTransaction tx,int verbose,int64_t& nati { CTxDestination address=CTxDestination(pkey.GetID()); - mc_Script *lpScript; - lpScript=new mc_Script; + mc_Script *lpScript=mc_gState->m_TmpBuffers->m_RpcScript4; + lpScript->Clear(); Value param=tocomplete; uint256 offer_hash; @@ -542,8 +537,6 @@ Object DecodeExchangeTransaction(const CTransaction tx,int verbose,int64_t& nati result.push_back(Pair("cancomplete", true)); } } - - delete lpScript; } } @@ -620,8 +613,8 @@ Value createrawexchange(const json_spirit::Array& params, bool fHelp) COutPoint offer_input; - mc_Script *lpScript; - lpScript=new mc_Script; + mc_Script *lpScript=mc_gState->m_TmpBuffers->m_RpcScript3; + lpScript->Clear(); CAmount nAmount=0; int eErrorCode; string strError=FindExchangeOutPoint(params,0,offer_input,nAmount,lpScript,&eErrorCode); @@ -717,9 +710,6 @@ Value createrawexchange(const json_spirit::Array& params, bool fHelp) } } - delete lpScript; - - return EncodeHexTx(tx); } @@ -730,8 +720,8 @@ Value appendrawexchange(const json_spirit::Array& params, bool fHelp) throw runtime_error("Help message not found\n"); COutPoint offer_input; - mc_Script *lpScript; - lpScript=new mc_Script; + mc_Script *lpScript=mc_gState->m_TmpBuffers->m_RpcScript3; + lpScript->Clear(); CAmount nAmount=0; int eErrorCode; @@ -830,14 +820,11 @@ Value appendrawexchange(const json_spirit::Array& params, bool fHelp) throw JSONRPCError(RPC_WALLET_ERROR, "Signing transaction failed"); } } - delete lpScript; bool is_complete=true; int64_t native_balance; - mc_Buffer *asset_amounts; - asset_amounts=new mc_Buffer; - mc_InitABufferMap(asset_amounts); + mc_Buffer *asset_amounts=mc_gState->m_TmpBuffers->m_RpcABBuffer1; asset_amounts->Clear(); { @@ -847,8 +834,6 @@ Value appendrawexchange(const json_spirit::Array& params, bool fHelp) decode_result=DecodeExchangeTransaction(tx,0,native_balance,asset_amounts,is_complete,false,strError); } - delete asset_amounts; - Object result; result.push_back(Pair("hex", EncodeHexTx(tx))); result.push_back(Pair("complete", is_complete)); @@ -862,8 +847,8 @@ Value completerawexchange(const json_spirit::Array& params, bool fHelp) throw runtime_error("Help message not found\n"); COutPoint offer_input; - mc_Script *lpScript; - lpScript=new mc_Script; + mc_Script *lpScript=mc_gState->m_TmpBuffers->m_RpcScript3; + lpScript->Clear(); CAmount nAmount=0; int eErrorCode; @@ -989,14 +974,11 @@ Value completerawexchange(const json_spirit::Array& params, bool fHelp) throw JSONRPCError(RPC_WALLET_ERROR, "Signing transaction failed"); } } - delete lpScript; bool is_complete=true; int64_t native_balance; - mc_Buffer *asset_amounts; - asset_amounts=new mc_Buffer; - mc_InitABufferMap(asset_amounts); + mc_Buffer *asset_amounts=mc_gState->m_TmpBuffers->m_RpcABBuffer1; asset_amounts->Clear(); { @@ -1005,8 +987,6 @@ Value completerawexchange(const json_spirit::Array& params, bool fHelp) decode_result=DecodeExchangeTransaction(tx,0,native_balance,asset_amounts,is_complete,true,strError); } - - delete asset_amounts; if(!is_complete) { @@ -1041,9 +1021,7 @@ Value decoderawexchange(const json_spirit::Array& params, bool fHelp) int64_t native_balance; string strError; - mc_Buffer *asset_amounts; - asset_amounts=new mc_Buffer; - mc_InitABufferMap(asset_amounts); + mc_Buffer *asset_amounts=mc_gState->m_TmpBuffers->m_RpcABBuffer1; asset_amounts->Clear(); { @@ -1051,8 +1029,6 @@ Value decoderawexchange(const json_spirit::Array& params, bool fHelp) result=DecodeExchangeTransaction(tx,verbose,native_balance,asset_amounts,is_complete,true,strError); } - - delete asset_amounts; return result; } diff --git a/src/rpc/rpcpermissions.cpp b/src/rpc/rpcpermissions.cpp index 31552c68..8e6e688e 100644 --- a/src/rpc/rpcpermissions.cpp +++ b/src/rpc/rpcpermissions.cpp @@ -52,8 +52,8 @@ Value grantoperation(const Array& params) if (params.size() > 8 && params[8].type() != null_type && !params[8].get_str().empty()) wtx.mapValue["to"] = params[8].get_str(); - mc_Script *lpScript; - lpScript=new mc_Script; + mc_Script *lpScript=mc_gState->m_TmpBuffers->m_RpcScript3; + lpScript->Clear(); uint32_t type,from,to,timestamp; @@ -302,7 +302,6 @@ Value grantoperation(const Array& params) SendMoneyToSeveralAddresses(addresses, nAmount, wtx, lpScript, scriptOpReturn, fromaddresses); - delete lpScript; return wtx.GetHash().GetHex(); } diff --git a/src/rpc/rpcrawdata.cpp b/src/rpc/rpcrawdata.cpp index 686531be..6562ce2f 100644 --- a/src/rpc/rpcrawdata.cpp +++ b/src/rpc/rpcrawdata.cpp @@ -1484,12 +1484,10 @@ CScript ParseRawMetadata(Value param,uint32_t allowed_objects,mc_EntityDetails * uint32_t data_format; mc_EntityDetails entity; CScript scriptOpReturn=CScript(); - mc_Script *lpDetailsScript; - mc_Script *lpDetails; - - lpDetailsScript=NULL; - lpDetails=NULL; - + mc_Script *lpDetailsScript=mc_gState->m_TmpBuffers->m_RpcScript1; + lpDetailsScript->Clear(); + mc_Script *lpDetails=mc_gState->m_TmpBuffers->m_RpcScript2; + lpDetails->Clear(); uint32_t param_type=ParseRawDataParamType(¶m,given_entity,&entity,&data_format,&errorCode,&strError); if(strError.size()) @@ -1517,28 +1515,6 @@ CScript ParseRawMetadata(Value param,uint32_t allowed_objects,mc_EntityDetails * memcpy(found_entity,&entity,sizeof(mc_EntityDetails)); } - switch(param_type) - { - case MC_DATA_API_PARAM_TYPE_EMPTY_RAW: - case MC_DATA_API_PARAM_TYPE_RAW: - break; - default: - lpDetailsScript=new mc_Script; - break; - } - - switch(param_type) - { - case MC_DATA_API_PARAM_TYPE_ISSUE: - case MC_DATA_API_PARAM_TYPE_FOLLOWON: - case MC_DATA_API_PARAM_TYPE_CREATE_STREAM: - case MC_DATA_API_PARAM_TYPE_CREATE_UPGRADE: - lpDetails=new mc_Script; - break; - default: - break; - } - switch(param_type) { case MC_DATA_API_PARAM_TYPE_EMPTY_RAW: @@ -1573,14 +1549,6 @@ CScript ParseRawMetadata(Value param,uint32_t allowed_objects,mc_EntityDetails * exitlbl: - if(lpDetailsScript) - { - delete lpDetailsScript; - } - if(lpDetails) - { - delete lpDetails; - } if(strError.size()) { throw JSONRPCError(errorCode, strError); diff --git a/src/rpc/rpcrawtransaction.cpp b/src/rpc/rpcrawtransaction.cpp index 508613fc..e25fb8b2 100644 --- a/src/rpc/rpcrawtransaction.cpp +++ b/src/rpc/rpcrawtransaction.cpp @@ -102,12 +102,11 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, Object& entry) entry.push_back(Pair("vin", vin)); /* MCHN START */ - mc_Buffer *asset_amounts; - asset_amounts=new mc_Buffer; - mc_InitABufferMap(asset_amounts); + mc_Buffer *asset_amounts=mc_gState->m_TmpBuffers->m_RpcABBuffer2; + asset_amounts->Clear(); - mc_Script *lpScript; - lpScript=new mc_Script; + mc_Script *lpScript=mc_gState->m_TmpBuffers->m_RpcScript4; + lpScript->Clear(); /* MCHN END */ Array vdata; @@ -487,10 +486,6 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, Object& entry) entry.push_back(Pair("data", aFullFormatMetaData)); } - delete lpScript; - delete asset_amounts; - - if (hashBlock != 0) { entry.push_back(Pair("blockhash", hashBlock.GetHex())); BlockMap::iterator mi = mapBlockIndex.find(hashBlock); @@ -577,12 +572,11 @@ Value listunspent(const Array& params, bool fHelp) } /* MCHN START */ - mc_Buffer *asset_amounts; - asset_amounts=new mc_Buffer; - mc_InitABufferMap(asset_amounts); + mc_Buffer *asset_amounts=mc_gState->m_TmpBuffers->m_RpcABBuffer1; + asset_amounts->Clear(); - mc_Script *lpScript; - lpScript=new mc_Script; + mc_Script *lpScript=mc_gState->m_TmpBuffers->m_RpcScript3; + lpScript->Clear(); { LOCK(pwalletMain->cs_wallet); @@ -708,9 +702,6 @@ Value listunspent(const Array& params, bool fHelp) /* MCHN START */ - delete lpScript; - delete asset_amounts; - /* MCHN END */ return results; } @@ -761,15 +752,13 @@ Value appendrawchange(const Array& params, bool fHelp) } } - mc_Buffer *asset_amounts; - asset_amounts=new mc_Buffer; - mc_InitABufferMap(asset_amounts); - mc_Buffer *amounts; - amounts=new mc_Buffer; - mc_InitABufferMap(amounts); + mc_Buffer *asset_amounts=mc_gState->m_TmpBuffers->m_RpcABBuffer1; + asset_amounts->Clear(); + mc_Buffer *amounts=mc_gState->m_TmpBuffers->m_RpcABBuffer2; + amounts->Clear(); - mc_Script *lpScript; - lpScript=new mc_Script; + mc_Script *lpScript=mc_gState->m_TmpBuffers->m_RpcScript3; + lpScript->Clear(); int allowed=0; int required=0; @@ -945,10 +934,6 @@ Value appendrawchange(const Array& params, bool fHelp) } } - delete lpScript; - delete asset_amounts; - delete amounts; - return EncodeHexTx(txNew); } diff --git a/src/rpc/rpcstreams.cpp b/src/rpc/rpcstreams.cpp index 1fe7c3c2..84dd298b 100644 --- a/src/rpc/rpcstreams.cpp +++ b/src/rpc/rpcstreams.cpp @@ -270,12 +270,12 @@ Value createstreamfromcmd(const Array& params, bool fHelp) CWalletTx wtx; - mc_Script *lpScript; - - mc_Script *lpDetailsScript; - lpDetailsScript=NULL; - - mc_Script *lpDetails; + mc_Script *lpScript=mc_gState->m_TmpBuffers->m_RpcScript3; + lpScript->Clear(); + mc_Script *lpDetailsScript=mc_gState->m_TmpBuffers->m_RpcScript1; + lpDetailsScript->Clear(); + mc_Script *lpDetails=mc_gState->m_TmpBuffers->m_RpcScript2; + lpDetails->Clear(); int ret,type; string stream_name=""; @@ -322,9 +322,9 @@ Value createstreamfromcmd(const Array& params, bool fHelp) } } - lpScript=new mc_Script; + lpScript->Clear(); - lpDetails=new mc_Script; + lpDetails->Clear(); lpDetails->AddElement(); if(params[3].get_bool()) { @@ -361,7 +361,7 @@ Value createstreamfromcmd(const Array& params, bool fHelp) int errorCode=RPC_INVALID_PARAMETER; string strError; - lpDetailsScript=new mc_Script; + lpDetailsScript->Clear(); if (params.size() > 4) { ParseRawDetails(&(params[4]),lpDetails,lpDetailsScript,&errorCode,&strError); @@ -488,13 +488,6 @@ Value createstreamfromcmd(const Array& params, bool fHelp) exitlbl: - if(lpDetailsScript) - { - delete lpDetailsScript; - } - delete lpDetails; - delete lpScript; - if(strError.size()) { throw JSONRPCError(errorCode, strError); @@ -575,7 +568,9 @@ Value publishfrom(const Array& params, bool fHelp) throw JSONRPCError(RPC_NOT_SUPPORTED, "API is not supported for this protocol version"); } - mc_Script *lpScript; + mc_Script *lpScript=mc_gState->m_TmpBuffers->m_RpcScript3; + lpScript->Clear(); + mc_EntityDetails stream_entity; parseStreamIdentifier(params[1],&stream_entity); @@ -650,13 +645,13 @@ Value publishfrom(const Array& params, bool fHelp) } } - mc_Script *lpDetailsScript; - lpDetailsScript=NULL; - + mc_Script *lpDetailsScript=mc_gState->m_TmpBuffers->m_RpcScript1; + lpDetailsScript->Clear(); + uint32_t data_format=MC_SCR_DATA_FORMAT_UNKNOWN; vector dataData; - lpDetailsScript=new mc_Script; + lpDetailsScript->Clear(); string strError; int errorCode=RPC_INVALID_PARAMETER; @@ -664,7 +659,6 @@ Value publishfrom(const Array& params, bool fHelp) if(strError.size()) { - delete lpDetailsScript; throw JSONRPCError(errorCode, strError); } @@ -713,16 +707,13 @@ Value publishfrom(const Array& params, bool fHelp) } - lpScript=new mc_Script; + lpScript->Clear(); EnsureWalletIsUnlocked(); LOCK (pwalletMain->cs_wallet_send); SendMoneyToSeveralAddresses(addresses, 0, wtx, lpScript, scriptOpReturn,fromaddresses); - delete lpDetailsScript; - delete lpScript; - return wtx.GetHash().GetHex(); } @@ -849,8 +840,7 @@ Value unsubscribe(const Array& params, bool fHelp) inputEntities.push_back(entity_to_subscribe); } - mc_Buffer *streams; - streams=new mc_Buffer; + mc_Buffer *streams=mc_gState->m_TmpBuffers->m_RpcBuffer1; streams->Initialize(sizeof(mc_TxEntity),sizeof(mc_TxEntity),MC_BUF_MODE_DEFAULT); @@ -896,12 +886,10 @@ Value unsubscribe(const Array& params, bool fHelp) { if(pwalletTxsMain->Unsubscribe(streams)) { - delete streams; throw JSONRPCError(RPC_INTERNAL_ERROR, "Couldn't unsubscribe from stream"); } } - delete streams; return Value::null; } @@ -1067,9 +1055,8 @@ Value liststreamitems(const Array& params, bool fHelp) throw JSONRPCError(RPC_NOT_SUBSCRIBED, "Not subscribed to this stream"); } - mc_Buffer *entity_rows; - entity_rows=new mc_Buffer; - entity_rows->Initialize(MC_TDB_ENTITY_KEY_SIZE,MC_TDB_ROW_SIZE,MC_BUF_MODE_DEFAULT); + mc_Buffer *entity_rows=mc_gState->m_TmpBuffers->m_RpcEntityRows; + entity_rows->Clear(); mc_AdjustStartAndCount(&count,&start,entStat.m_LastPos); @@ -1090,8 +1077,6 @@ Value liststreamitems(const Array& params, bool fHelp) } } - delete entity_rows; - return retArray; } @@ -1184,9 +1169,8 @@ Value liststreamblockitems(const Array& params, bool fHelp) height_from=heights[0]; height_to=heights[0]; - mc_Buffer *entity_rows; - entity_rows=new mc_Buffer; - entity_rows->Initialize(MC_TDB_ENTITY_KEY_SIZE,MC_TDB_ROW_SIZE,MC_BUF_MODE_DEFAULT); + mc_Buffer *entity_rows=mc_gState->m_TmpBuffers->m_RpcEntityRows; + entity_rows->Clear(); for(unsigned int i=1;iInitialize(MC_TDB_ENTITY_KEY_SIZE,MC_TDB_ROW_SIZE,MC_BUF_MODE_DEFAULT); + mc_Buffer *entity_rows=mc_gState->m_TmpBuffers->m_RpcEntityRows; + entity_rows->Clear(); Object empty_object; Object obj; @@ -1516,8 +1498,6 @@ Value getstreamsummary(const Array& params, bool fPublisher) exitlbl: - delete entity_rows; - if(err) { throw JSONRPCError(RPC_NOT_ALLOWED, "Some items to be merged are in the wrong format (try using \'ignore\')" ); @@ -1622,9 +1602,8 @@ Value liststreamkeyitems(const Array& params, bool fHelp) getSubKeyEntityFromKey(params[1].get_str(),entStat,&entity); - mc_Buffer *entity_rows; - entity_rows=new mc_Buffer; - entity_rows->Initialize(MC_TDB_ENTITY_KEY_SIZE,MC_TDB_ROW_SIZE,MC_BUF_MODE_DEFAULT); + mc_Buffer *entity_rows=mc_gState->m_TmpBuffers->m_RpcEntityRows; + entity_rows->Clear(); mc_AdjustStartAndCount(&count,&start,pwalletTxsMain->GetListSize(&entity,entStat.m_Generation,NULL)); @@ -1645,8 +1624,6 @@ Value liststreamkeyitems(const Array& params, bool fHelp) } } - delete entity_rows; - return retArray; } @@ -1731,9 +1708,8 @@ Value liststreampublisheritems(const Array& params, bool fHelp) const char *key_ptr=key_string.c_str(); getSubKeyEntityFromPublisher(params[1].get_str(),entStat,&entity); - mc_Buffer *entity_rows; - entity_rows=new mc_Buffer; - entity_rows->Initialize(MC_TDB_ENTITY_KEY_SIZE,MC_TDB_ROW_SIZE,MC_BUF_MODE_DEFAULT); + mc_Buffer *entity_rows=mc_gState->m_TmpBuffers->m_RpcEntityRows; + entity_rows->Clear(); mc_AdjustStartAndCount(&count,&start,pwalletTxsMain->GetListSize(&entity,entStat.m_Generation,NULL)); @@ -1754,8 +1730,6 @@ Value liststreampublisheritems(const Array& params, bool fHelp) } } - delete entity_rows; - return retArray; } @@ -1772,20 +1746,19 @@ Value liststreammap_operation(mc_TxEntity *parent_entity,vector& in mc_TxEntity entity; mc_TxEntityStat entStat; Array retArray; - mc_Buffer *entity_rows; + mc_Buffer *entity_rows=mc_gState->m_TmpBuffers->m_RpcEntityRows; mc_TxEntityRow erow; uint160 stream_subkey_hash; int row,enitity_count; const char **given_key; const char **given_publisher; - entity_rows=NULL; + entity_rows->Clear(); enitity_count=inputEntities.size(); if(enitity_count == 0) { mc_AdjustStartAndCount(&count,&start,pwalletTxsMain->GetListSize(parent_entity,NULL)); - entity_rows=new mc_Buffer; - entity_rows->Initialize(MC_TDB_ENTITY_KEY_SIZE,MC_TDB_ROW_SIZE,MC_BUF_MODE_DEFAULT); + entity_rows->Clear(); pwalletTxsMain->GetList(parent_entity,start+1,count,entity_rows); enitity_count=entity_rows->GetCount(); } @@ -1882,11 +1855,6 @@ Value liststreammap_operation(mc_TxEntity *parent_entity,vector& in retArray.push_back(all_entry); } - if(entity_rows) - { - delete entity_rows; - } - return retArray; } diff --git a/src/rpc/rpcupgrades.cpp b/src/rpc/rpcupgrades.cpp index 7a628f56..15283ac1 100644 --- a/src/rpc/rpcupgrades.cpp +++ b/src/rpc/rpcupgrades.cpp @@ -24,14 +24,12 @@ Value createupgradefromcmd(const Array& params, bool fHelp) CWalletTx wtx; - mc_Script *lpScript; - lpScript=NULL; - - mc_Script *lpDetailsScript; - lpDetailsScript=NULL; - - mc_Script *lpDetails; - lpDetails=NULL; + mc_Script *lpScript=mc_gState->m_TmpBuffers->m_RpcScript3; + lpScript->Clear(); + mc_Script *lpDetailsScript=mc_gState->m_TmpBuffers->m_RpcScript1; + lpDetailsScript->Clear(); + mc_Script *lpDetails=mc_gState->m_TmpBuffers->m_RpcScript2; + lpDetails->Clear(); int ret,type; string upgrade_name=""; @@ -136,9 +134,9 @@ Value createupgradefromcmd(const Array& params, bool fHelp) } } - lpScript=new mc_Script; + lpScript->Clear(); - lpDetails=new mc_Script; + lpDetails->Clear(); lpDetails->AddElement(); if(upgrade_name.size()) { @@ -156,7 +154,7 @@ Value createupgradefromcmd(const Array& params, bool fHelp) int start_block; CScript scriptOpReturn=CScript(); - lpDetailsScript=new mc_Script; + lpDetailsScript->Clear(); lpDetailsScript->AddElement(); if(params[4].type() == obj_type) @@ -283,19 +281,6 @@ Value createupgradefromcmd(const Array& params, bool fHelp) exitlbl: - if(lpDetailsScript) - { - delete lpDetailsScript; - } - if(lpDetailsScript) - { - delete lpDetails; - } - if(lpScript) - { - delete lpScript; - } - if(strError.size()) { throw JSONRPCError(errorCode, strError); @@ -372,8 +357,8 @@ Value approvefrom(const json_spirit::Array& params, bool fHelp) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Please use raw transactions to approve upgrades from P2SH addresses"); } - mc_Script *lpScript; - lpScript=new mc_Script; + mc_Script *lpScript=mc_gState->m_TmpBuffers->m_RpcScript3; + lpScript->Clear(); lpScript->SetEntity(entity.GetTxID()+MC_AST_SHORT_TXID_OFFSET); lpScript->SetApproval(approval, timestamp); @@ -399,7 +384,6 @@ Value approvefrom(const json_spirit::Array& params, bool fHelp) SendMoneyToSeveralAddresses(addresses, 0, wtx, lpScript, scriptOpReturn, fromaddresses); - delete lpScript; return wtx.GetHash().GetHex(); } diff --git a/src/rpc/rpcutils.cpp b/src/rpc/rpcutils.cpp index 66ea22ff..e2b3ae9f 100644 --- a/src/rpc/rpcutils.cpp +++ b/src/rpc/rpcutils.cpp @@ -1396,10 +1396,10 @@ string ParseRawOutputObject(Value param,CAmount& nAmount,mc_Script *lpScript, in { string strError=""; unsigned char buf[MC_AST_ASSET_FULLREF_BUF_SIZE]; - mc_Buffer *lpBuffer; - mc_Buffer *lpFollowonBuffer; - lpBuffer=new mc_Buffer; - lpFollowonBuffer=new mc_Buffer; + mc_Buffer *lpBuffer=mc_gState->m_TmpBuffers->m_RpcABNoMapBuffer1; + lpBuffer->Clear(); + mc_Buffer *lpFollowonBuffer=mc_gState->m_TmpBuffers->m_RpcABNoMapBuffer2; + lpFollowonBuffer->Clear(); int assets_per_opdrop=(MAX_STANDARD_TX_SIZE)/(mc_gState->m_NetworkParams->m_AssetRefSize+MC_AST_ASSET_QUANTITY_SIZE); int32_t verify_level=-1; int asset_error=0; @@ -1416,9 +1416,6 @@ string ParseRawOutputObject(Value param,CAmount& nAmount,mc_Script *lpScript, in memset(buf,0,MC_AST_ASSET_FULLREF_BUF_SIZE); - mc_InitABufferDefault(lpBuffer); - mc_InitABufferDefault(lpFollowonBuffer); - if(mc_gState->m_Features->VerifySizeOfOpDropElements()) { if(mc_gState->m_Features->VerifySizeOfOpDropElements()) @@ -1863,9 +1860,6 @@ string ParseRawOutputObject(Value param,CAmount& nAmount,mc_Script *lpScript, in break; } - delete lpBuffer; - delete lpFollowonBuffer; - return strError; } @@ -2083,8 +2077,8 @@ vector > ParseRawOutputMultiObject(Object sendTo,int *re } else { - mc_Script *lpScript; - lpScript=new mc_Script; + mc_Script *lpScript=mc_gState->m_TmpBuffers->m_RpcScript4; + lpScript->Clear(); // uint256 offer_hash; size_t elem_size; const unsigned char *elem; @@ -2113,7 +2107,6 @@ vector > ParseRawOutputMultiObject(Object sendTo,int *re else throw JSONRPCError(RPC_INTERNAL_ERROR, "Invalid script"); } - delete lpScript; } vecSend.push_back(make_pair(scriptPubKey, nAmount)); diff --git a/src/rpc/rpcwallet.cpp b/src/rpc/rpcwallet.cpp index c7dffac2..aefa80c7 100644 --- a/src/rpc/rpcwallet.cpp +++ b/src/rpc/rpcwallet.cpp @@ -1483,36 +1483,6 @@ Value listtransactions(const Array& params, bool fHelp) if(mc_gState->m_WalletMode & MC_WMD_ADDRESS_TXS) { throw JSONRPCError(RPC_NOT_SUPPORTED, "Not supported with scalable wallet - if you need listtransactions, run multichaind -walletdbversion=1 -rescan, but the wallet will perform worse"); -/* - mc_Buffer *entity_rows; - entity_rows=new mc_Buffer; - entity_rows->Initialize(MC_TDB_ENTITY_KEY_SIZE,MC_TDB_ROW_SIZE,MC_BUF_MODE_DEFAULT); - - mc_TxEntity wallet_by_time; - mc_TxEntityRow *lpEntTx; - wallet_by_time.Zero(); - wallet_by_time.m_EntityType=MC_TET_TIMERECEIVED; - if(filter & ISMINE_WATCH_ONLY) - { - wallet_by_time.m_EntityType |= MC_TET_WALLET_ALL; - } - else - { - wallet_by_time.m_EntityType |= MC_TET_WALLET_SPENDABLE; - } - pwalletTxsMain->GetList(&wallet_by_time,-nFrom,nCount,entity_rows); - for(int i=entity_rows->GetCount()-1;i>=0;i--) - { - lpEntTx=(mc_TxEntityRow*)entity_rows->GetRow(i); - uint256 hash; - mc_TxDefRow txdef; - memcpy(&hash,lpEntTx->m_TxId,MC_TDB_TXID_SIZE); - const CWalletTx& wtx=pwalletTxsMain->GetWalletTx(hash,&txdef,NULL); - ListTransactions(wtx, strAccount, 0, true, ret, filter,&txdef); - } - delete entity_rows; - std::reverse(ret.begin(), ret.end()); // Return oldest to newest -*/ } else { diff --git a/src/rpc/rpcwalletsend.cpp b/src/rpc/rpcwalletsend.cpp index be1c3187..8cb2497e 100644 --- a/src/rpc/rpcwalletsend.cpp +++ b/src/rpc/rpcwalletsend.cpp @@ -201,13 +201,12 @@ Value sendfromaddress(const Array& params, bool fHelp) vector addresses; addresses.push_back(address.Get()); - mc_Script *lpScript; - - lpScript=NULL; + mc_Script *lpScript=mc_gState->m_TmpBuffers->m_RpcScript3; + lpScript->Clear(); if (params[2].type() == obj_type) { - lpScript=new mc_Script; + lpScript->Clear(); uint256 offer_hash; if (params[2].type() != obj_type) @@ -275,11 +274,6 @@ Value sendfromaddress(const Array& params, bool fHelp) SendMoneyToSeveralAddresses(addresses, nAmount, wtx, lpScript, CScript(), fromaddresses); - if(lpScript) - { - delete lpScript; - } - return wtx.GetHash().GetHex(); } @@ -307,13 +301,12 @@ Value sendwithmetadatafrom(const Array& params, bool fHelp) vector addresses; addresses.push_back(address.Get()); - mc_Script *lpScript; - - lpScript=NULL; + mc_Script *lpScript=mc_gState->m_TmpBuffers->m_RpcScript3; + lpScript->Clear(); if (params[2].type() == obj_type) { - lpScript=new mc_Script; + lpScript->Clear(); uint256 offer_hash; if (params[2].type() != obj_type) @@ -402,11 +395,6 @@ Value sendwithmetadatafrom(const Array& params, bool fHelp) SendMoneyToSeveralAddresses(addresses, nAmount, wtx, lpScript, scriptOpReturn, fromaddresses); - if(lpScript) - { - delete lpScript; - } - return wtx.GetHash().GetHex(); } @@ -623,8 +611,9 @@ Value preparelockunspentfrom(const json_spirit::Array& params, bool fHelp) vector addresses; addresses.push_back(CTxDestination(pkey.GetID())); - mc_Script *lpScript; - lpScript=new mc_Script; + mc_Script *lpScript=mc_gState->m_TmpBuffers->m_RpcScript3; + lpScript->Clear(); + CAmount nAmount=0; uint256 offer_hash; bool lock_it=true; @@ -703,8 +692,6 @@ Value preparelockunspentfrom(const json_spirit::Array& params, bool fHelp) } } - delete lpScript; - if(lock_it) { @@ -737,8 +724,9 @@ Value preparelockunspent(const json_spirit::Array& params, bool fHelp) vector addresses; addresses.push_back(CTxDestination(pkey.GetID())); - mc_Script *lpScript; + mc_Script *lpScript=mc_gState->m_TmpBuffers->m_RpcScript3; lpScript=new mc_Script; + CAmount nAmount=0; uint256 offer_hash; bool lock_it=true; @@ -820,9 +808,6 @@ Value preparelockunspent(const json_spirit::Array& params, bool fHelp) } } - delete lpScript; - - if(lock_it) { COutPoint outpt(wtx.GetHash(),vout); @@ -866,8 +851,8 @@ Value sendassetfrom(const Array& params, bool fHelp) throw JSONRPCError(RPC_INSUFFICIENT_PERMISSIONS, "Destination address doesn't have receive permission"); } - mc_Script *lpScript; - lpScript=new mc_Script; + mc_Script *lpScript=mc_gState->m_TmpBuffers->m_RpcScript3; + lpScript->Clear(); unsigned char buf[MC_AST_ASSET_FULLREF_BUF_SIZE]; memset(buf,0,MC_AST_ASSET_FULLREF_BUF_SIZE); @@ -902,18 +887,13 @@ Value sendassetfrom(const Array& params, bool fHelp) mc_SetABQuantity(buf,quantity); - mc_Buffer *lpBuffer; - lpBuffer=new mc_Buffer; - - mc_InitABufferDefault(lpBuffer); + mc_Buffer *lpBuffer=mc_gState->m_TmpBuffers->m_RpcABNoMapBuffer1; + lpBuffer->Clear(); lpBuffer->Add(buf); lpScript->SetAssetQuantities(lpBuffer,MC_SCR_ASSET_SCRIPT_TYPE_TRANSFER); - delete lpBuffer; - - vector addresses; addresses.push_back(address.Get()); @@ -961,8 +941,6 @@ Value sendassetfrom(const Array& params, bool fHelp) SendMoneyToSeveralAddresses(addresses, nAmount, wtx, lpScript, CScript(),fromaddresses); - delete lpScript; - return wtx.GetHash().GetHex(); } @@ -1004,8 +982,8 @@ Value sendassettoaddress(const Array& params, bool fHelp) throw JSONRPCError(RPC_INSUFFICIENT_PERMISSIONS, "Destination address doesn't have receive permission"); } - mc_Script *lpScript; - lpScript=new mc_Script; + mc_Script *lpScript=mc_gState->m_TmpBuffers->m_RpcScript3; + lpScript->Clear(); unsigned char buf[MC_AST_ASSET_FULLREF_BUF_SIZE]; memset(buf,0,MC_AST_ASSET_FULLREF_BUF_SIZE); @@ -1040,8 +1018,8 @@ Value sendassettoaddress(const Array& params, bool fHelp) mc_SetABQuantity(buf,quantity); - mc_Buffer *lpBuffer; - lpBuffer=new mc_Buffer; + mc_Buffer *lpBuffer=mc_gState->m_TmpBuffers->m_RpcABNoMapBuffer1; + lpBuffer->Clear(); mc_InitABufferDefault(lpBuffer); @@ -1049,9 +1027,6 @@ Value sendassettoaddress(const Array& params, bool fHelp) lpScript->SetAssetQuantities(lpBuffer,MC_SCR_ASSET_SCRIPT_TYPE_TRANSFER); - delete lpBuffer; - - vector addresses; addresses.push_back(address.Get()); @@ -1062,7 +1037,5 @@ Value sendassettoaddress(const Array& params, bool fHelp) SendMoneyToSeveralAddresses(addresses, nAmount, wtx, lpScript, CScript(),fromaddresses); - delete lpScript; - return wtx.GetHash().GetHex(); } diff --git a/src/rpc/rpcwallettxs.cpp b/src/rpc/rpcwallettxs.cpp index 65bd7a2c..a20507bd 100644 --- a/src/rpc/rpcwallettxs.cpp +++ b/src/rpc/rpcwallettxs.cpp @@ -497,16 +497,14 @@ Value listwallettransactions(const Array& params, bool fHelp) throw JSONRPCError(RPC_INVALID_PARAMETER, "Negative from"); - mc_Buffer *asset_amounts; - asset_amounts=new mc_Buffer; - mc_InitABufferMap(asset_amounts); + mc_Buffer *asset_amounts=mc_gState->m_TmpBuffers->m_RpcABBuffer1; + asset_amounts->Clear(); - mc_Script *lpScript; - lpScript=new mc_Script; + mc_Script *lpScript=mc_gState->m_TmpBuffers->m_RpcScript3; + lpScript->Clear(); - mc_Buffer *entity_rows; - entity_rows=new mc_Buffer; - entity_rows->Initialize(MC_TDB_ENTITY_KEY_SIZE,MC_TDB_ROW_SIZE,MC_BUF_MODE_DEFAULT); + mc_Buffer *entity_rows=mc_gState->m_TmpBuffers->m_RpcEntityRows; + entity_rows->Clear(); Array ret; if(mc_gState->m_WalletMode & MC_WMD_ADDRESS_TXS) @@ -574,11 +572,6 @@ Value listwallettransactions(const Array& params, bool fHelp) } - delete lpScript; - delete asset_amounts; - delete entity_rows; - - return ret; } @@ -605,12 +598,11 @@ Value listaddresstransactions(const Array& params, bool fHelp) throw JSONRPCError(RPC_INVALID_PARAMETER, "Negative from"); - mc_Buffer *asset_amounts; - asset_amounts=new mc_Buffer; - mc_InitABufferMap(asset_amounts); + mc_Buffer *asset_amounts=mc_gState->m_TmpBuffers->m_RpcABBuffer1; + asset_amounts->Clear(); - mc_Script *lpScript; - lpScript=new mc_Script; + mc_Script *lpScript=mc_gState->m_TmpBuffers->m_RpcScript3; + lpScript->Clear(); vector fromaddresses; @@ -639,10 +631,9 @@ Value listaddresstransactions(const Array& params, bool fHelp) } - mc_Buffer *entity_rows; - entity_rows=new mc_Buffer; - entity_rows->Initialize(MC_TDB_ENTITY_KEY_SIZE,MC_TDB_ROW_SIZE,MC_BUF_MODE_DEFAULT); - + mc_Buffer *entity_rows=mc_gState->m_TmpBuffers->m_RpcEntityRows; + entity_rows->Clear(); + Array ret; if(mc_gState->m_WalletMode & MC_WMD_ADDRESS_TXS) { @@ -712,11 +703,6 @@ Value listaddresstransactions(const Array& params, bool fHelp) std::reverse(ret.begin(), ret.end()); // Return oldest to newest } - delete lpScript; - delete asset_amounts; - delete entity_rows; - - return ret; } @@ -750,12 +736,11 @@ Value getwallettransaction(const Array& params, bool fHelp) throw JSONRPCError(RPC_TX_NOT_FOUND, "Invalid or non-wallet transaction id"); } - mc_Buffer *asset_amounts; - asset_amounts=new mc_Buffer; - mc_InitABufferMap(asset_amounts); + mc_Buffer *asset_amounts=mc_gState->m_TmpBuffers->m_RpcABBuffer1; + asset_amounts->Clear(); - mc_Script *lpScript; - lpScript=new mc_Script; + mc_Script *lpScript=mc_gState->m_TmpBuffers->m_RpcScript3; + lpScript->Clear(); Object entry; @@ -770,9 +755,6 @@ Value getwallettransaction(const Array& params, bool fHelp) entry=ListWalletTransactions(wtx,fLong,filter,NULL,asset_amounts,lpScript); } - delete lpScript; - delete asset_amounts; - if(entry.size() == 0) { throw JSONRPCError(RPC_TX_NOT_FOUND, "Wallet addresses with specified criteria are not involved in transaction"); @@ -809,12 +791,11 @@ Value getaddresstransaction(const Array& params, bool fHelp) } - mc_Buffer *asset_amounts; - asset_amounts=new mc_Buffer; - mc_InitABufferMap(asset_amounts); + mc_Buffer *asset_amounts=mc_gState->m_TmpBuffers->m_RpcABBuffer1; + asset_amounts->Clear(); - mc_Script *lpScript; - lpScript=new mc_Script; + mc_Script *lpScript=mc_gState->m_TmpBuffers->m_RpcScript3; + lpScript->Clear(); vector fromaddresses; @@ -859,9 +840,6 @@ Value getaddresstransaction(const Array& params, bool fHelp) throw JSONRPCError(RPC_TX_NOT_FOUND, "This transaction was not found for this address"); } - delete lpScript; - delete asset_amounts; - return entry; } From b16d8e02f7d6796773c23b74ab9e144320072452 Mon Sep 17 00:00:00 2001 From: mike31 Date: Sun, 14 Jan 2018 16:40:47 +0200 Subject: [PATCH 60/71] Avoiding buffer allocations in RPC calls - fixed --- src/rpc/rpcassets.cpp | 1 - src/rpc/rpcblockchain.cpp | 10 ++++------ src/rpc/rpcrawtransaction.cpp | 4 +--- src/rpc/rpcwalletsend.cpp | 2 +- 4 files changed, 6 insertions(+), 11 deletions(-) diff --git a/src/rpc/rpcassets.cpp b/src/rpc/rpcassets.cpp index 7d3f87e3..f11326e8 100644 --- a/src/rpc/rpcassets.cpp +++ b/src/rpc/rpcassets.cpp @@ -483,7 +483,6 @@ Value issuemorefromcmd(const Array& params, bool fHelp) CScript scriptOpReturn=CScript(); int errorCode=RPC_INVALID_PARAMETER; string strError; - lpDetailsScript=new mc_Script; if (params.size() > 5) { ParseRawDetails(&(params[5]),lpDetails,lpDetailsScript,&errorCode,&strError); diff --git a/src/rpc/rpcblockchain.cpp b/src/rpc/rpcblockchain.cpp index 92650790..f80fb3a1 100644 --- a/src/rpc/rpcblockchain.cpp +++ b/src/rpc/rpcblockchain.cpp @@ -515,12 +515,10 @@ Value gettxout(const Array& params, bool fHelp) /* MCHN START */ - mc_Buffer *asset_amounts; - asset_amounts=new mc_Buffer; - mc_InitABufferMap(asset_amounts); - - mc_Script *lpScript; - lpScript=new mc_Script; + mc_Buffer *asset_amounts=mc_gState->m_TmpBuffers->m_RpcABBuffer1; + + mc_Script *lpScript=mc_gState->m_TmpBuffers->m_RpcScript3; + lpScript->Clear(); asset_amounts->Clear(); CTxOut txout=coins.vout[n]; diff --git a/src/rpc/rpcrawtransaction.cpp b/src/rpc/rpcrawtransaction.cpp index e25fb8b2..2c17b740 100644 --- a/src/rpc/rpcrawtransaction.cpp +++ b/src/rpc/rpcrawtransaction.cpp @@ -1090,9 +1090,7 @@ void AddCacheInputScriptIfNeeded(CMutableTransaction& rawTx,Array inputs, bool f if(fNewOutputs) { - mc_Script *lpDetails; - lpDetails=new mc_Script; - + mc_Script *lpDetails=mc_gState->m_TmpBuffers->m_RpcScript4; lpDetails->Clear(); for(int i=0;i<(int)cache_array.size();i++) { diff --git a/src/rpc/rpcwalletsend.cpp b/src/rpc/rpcwalletsend.cpp index 8cb2497e..c2f3e925 100644 --- a/src/rpc/rpcwalletsend.cpp +++ b/src/rpc/rpcwalletsend.cpp @@ -725,7 +725,7 @@ Value preparelockunspent(const json_spirit::Array& params, bool fHelp) addresses.push_back(CTxDestination(pkey.GetID())); mc_Script *lpScript=mc_gState->m_TmpBuffers->m_RpcScript3; - lpScript=new mc_Script; + lpScript->Clear(); CAmount nAmount=0; uint256 offer_hash; From c2bc57bd8f6d09abe1070d465c68361242f1fe08 Mon Sep 17 00:00:00 2001 From: mike31 Date: Sun, 14 Jan 2018 17:37:21 +0200 Subject: [PATCH 61/71] Hidden chain parameters and timing-upgrade-min-gap --- src/chainparams/paramlist.h | 8 +- src/chainparams/params.cpp | 123 +++++++++++++++++-------------- src/chainparams/params.h | 2 + src/protocol/multichainblock.cpp | 3 +- src/rpc/rpcmisc.cpp | 14 +++- src/utils/utilwrapper.cpp | 1 + 6 files changed, 90 insertions(+), 61 deletions(-) diff --git a/src/chainparams/paramlist.h b/src/chainparams/paramlist.h index 0cfd39c7..52035c70 100644 --- a/src/chainparams/paramlist.h +++ b/src/chainparams/paramlist.h @@ -27,13 +27,17 @@ static const mc_OneMultichainParam MultichainParamArray[] = "targetblocktime","", "Content of the 'testnet' field of API responses, for compatibility."}, { "targetblocktime" , "target-block-time" , - MC_PRM_UINT32 | MC_PRM_USER | MC_PRM_CLONE , -1, 15, 2, 86400, 0.0, 10001, 0, "-mc-targetblocktime", + MC_PRM_UINT32 | MC_PRM_USER | MC_PRM_CLONE | MC_PRM_TIME , -1, 15, 2, 86400, 0.0, 10001, 0, "-mc-targetblocktime", "maximumblocksize","", "Target time between blocks (transaction confirmation delay), seconds."}, { "maximumblocksize" , "maximum-block-size" , MC_PRM_UINT32 | MC_PRM_USER | MC_PRM_CLONE , -1, 8388608, 5000,1000000000, 0.0, 10001, 0, "-mc-maximumblocksize", - "defaultnetworkport","", + "timingupgrademingap","", "Maximum block size in bytes."}, + { "timingupgrademingap" , "timing-upgrade-min-gap" , + MC_PRM_UINT32 | MC_PRM_USER | MC_PRM_CLONE | MC_PRM_HIDDEN , -1, 100, 1, 31536000, 0.0, 20002, 0, "-mc-timingupgrademingap", + "defaultnetworkport","", + "Minimal gap between time-related parameter upgrades. In blocks."}, { "defaultnetworkport" , "default-network-port" , MC_PRM_UINT32 | MC_PRM_GENERATED | MC_PRM_CLONE , -1, MC_DEFAULT_NETWORK_PORT, 1024, 65535, 0.0, 10001, 0, "-mc-defaultnetworkport", "defaultrpcport","", diff --git a/src/chainparams/params.cpp b/src/chainparams/params.cpp index 66ec8c4e..63dfd8ec 100644 --- a/src/chainparams/params.cpp +++ b/src/chainparams/params.cpp @@ -1245,7 +1245,7 @@ int mc_MultichainParams::Print(FILE* fileHan) int i,c,size; int version; int header_printed; - int set,chars_remaining; + int set,chars_remaining,hidden; void *ptr; char line[MC_PRM_DAT_FILE_LINE_SIZE+1+100]; char *cptr; @@ -1303,6 +1303,7 @@ int mc_MultichainParams::Print(FILE* fileHan) if( (((m_lpParams+i)->m_Type & MC_PRM_SOURCE_MASK) == param_sets[set]) && ((m_lpParams+i)->IsRelevant(version) > 0)) { + hidden=0; if(header_printed == 0) { fprintf(fileHan,"\n"); @@ -1463,6 +1464,13 @@ int mc_MultichainParams::Print(FILE* fileHan) else { sprintf(line+strlen(line),"%ld",mc_GetLE(ptr,4)); + if((m_lpParams+i)->m_Type & MC_PRM_HIDDEN) + { + if(mc_GetLE(ptr,4) == (m_lpParams+i)->m_DefaultIntegerValue) + { + hidden=1; + } + } } break; case MC_PRM_INT64: @@ -1477,76 +1485,79 @@ int mc_MultichainParams::Print(FILE* fileHan) { sprintf(line+strlen(line),"[null]"); } - if(chars_remaining == 0) - { - fprintf(fileHan,"%s",line); - chars_remaining=MC_PRM_DAT_FILE_LINE_SIZE-strlen(line)+1; - } - for(c=0;cm_Description; - while(*cptr) - { - c=0; - - while((c<(int)strlen(cptr)) && (cptr[c]!='\n')) + if(chars_remaining == 0) { - c++; + fprintf(fileHan,"%s",line); + chars_remaining=MC_PRM_DAT_FILE_LINE_SIZE-strlen(line)+1; } - - if(c<(int)strlen(cptr)) + for(c=0;cm_Description; + while(*cptr) { - fprintf(fileHan,"# %s",cptr); - cptr+=c; - } - } + c=0; - switch((m_lpParams+i)->m_Type & MC_PRM_DATA_TYPE_MASK) - { - case MC_PRM_INT32: - case MC_PRM_INT64: - case MC_PRM_UINT32: - switch(param_sets[set]) + while((c<(int)strlen(cptr)) && (cptr[c]!='\n')) { - case MC_PRM_COMMENT: - case MC_PRM_USER: - if((m_lpParams+i)->m_MinIntegerValue <= (m_lpParams+i)->m_MaxIntegerValue) - { - if((m_lpParams+i)->m_Type & MC_PRM_DECIMAL) + c++; + } + + if(c<(int)strlen(cptr)) + { + cptr[c]=0x00; + fprintf(fileHan,"# %s",cptr); + memset(line,0x20,MC_PRM_DAT_FILE_LINE_SIZE); + line[MC_PRM_DAT_FILE_LINE_SIZE]=0x00; + fprintf(fileHan,"\n%s ",line); + cptr+=c+1; + } + else + { + fprintf(fileHan,"# %s",cptr); + cptr+=c; + } + } + + switch((m_lpParams+i)->m_Type & MC_PRM_DATA_TYPE_MASK) + { + case MC_PRM_INT32: + case MC_PRM_INT64: + case MC_PRM_UINT32: + switch(param_sets[set]) + { + case MC_PRM_COMMENT: + case MC_PRM_USER: + if((m_lpParams+i)->m_MinIntegerValue <= (m_lpParams+i)->m_MaxIntegerValue) { - d1=0; - if((m_lpParams+i)->m_MinIntegerValue) + if((m_lpParams+i)->m_Type & MC_PRM_DECIMAL) { - d1=((double)((m_lpParams+i)->m_MinIntegerValue)+ParamAccuracy())/MC_PRM_DECIMAL_GRANULARITY; + d1=0; + if((m_lpParams+i)->m_MinIntegerValue) + { + d1=((double)((m_lpParams+i)->m_MinIntegerValue)+ParamAccuracy())/MC_PRM_DECIMAL_GRANULARITY; + } + d2=0; + if((m_lpParams+i)->m_MaxIntegerValue) + { + d2=((double)((m_lpParams+i)->m_MaxIntegerValue)+ParamAccuracy())/MC_PRM_DECIMAL_GRANULARITY; + } + fprintf(fileHan," (%0.6g - %0.6g)",d1,d2); } - d2=0; - if((m_lpParams+i)->m_MaxIntegerValue) + else { - d2=((double)((m_lpParams+i)->m_MaxIntegerValue)+ParamAccuracy())/MC_PRM_DECIMAL_GRANULARITY; + fprintf(fileHan," (%ld - %ld)",(m_lpParams+i)->m_MinIntegerValue,(m_lpParams+i)->m_MaxIntegerValue); } - fprintf(fileHan," (%0.6g - %0.6g)",d1,d2); } - else - { - fprintf(fileHan," (%ld - %ld)",(m_lpParams+i)->m_MinIntegerValue,(m_lpParams+i)->m_MaxIntegerValue); - } - } - break; - } - break; + break; + } + break; + } + fprintf(fileHan,"\n"); } - fprintf(fileHan,"\n"); } if(strlen((m_lpParams+i)->m_Next)) diff --git a/src/chainparams/params.h b/src/chainparams/params.h index c4c4378f..08ee0d62 100644 --- a/src/chainparams/params.h +++ b/src/chainparams/params.h @@ -37,6 +37,8 @@ #define MC_PRM_NOHASH 0x00040000 #define MC_PRM_MINIMAL 0x00080000 #define MC_PRM_DECIMAL 0x00100000 +#define MC_PRM_HIDDEN 0x00200000 +#define MC_PRM_TIME 0x00400000 #define MC_PRM_STATUS_EMPTY 0 diff --git a/src/protocol/multichainblock.cpp b/src/protocol/multichainblock.cpp index 35562345..f6ed69ef 100644 --- a/src/protocol/multichainblock.cpp +++ b/src/protocol/multichainblock.cpp @@ -190,7 +190,8 @@ int CreateUpgradeLists(int current_height,vector *vParams, if (it != map_last_upgrade.end()) { take_it=false; - if((*vParams)[it->second].m_Block + MIN_BLOCKS_BETWEEN_UPGRADES <= upgrade.m_AppliedBlock) + if( ( (param.m_Param->m_Type & MC_PRM_TIME) == 0 ) || + ((*vParams)[it->second].m_Block + MIN_BLOCKS_BETWEEN_UPGRADES <= upgrade.m_AppliedBlock) ) { int64_t old_value=(*vParams)[it->second].m_Value; if(param.m_Value >= old_value) diff --git a/src/rpc/rpcmisc.cpp b/src/rpc/rpcmisc.cpp index 7097261d..69487312 100644 --- a/src/rpc/rpcmisc.cpp +++ b/src/rpc/rpcmisc.cpp @@ -516,7 +516,6 @@ Value getblockchainparams(const json_spirit::Array& params, bool fHelp) if (fHelp || params.size() > 2) // MCHN throw runtime_error("Help message not found\n"); - bool fDisplay = true; if (params.size() > 0) fDisplay = params[0].get_bool(); @@ -569,6 +568,7 @@ Value getblockchainparams(const json_spirit::Array& params, bool fHelp) Value param_value; unsigned char* ptr; int size; + bool hidden=false; string param_string="";; ptr=(unsigned char*)mc_gState->m_NetworkParams->GetParam((mc_gState->m_NetworkParams->m_lpParams+i)->m_Name,&size); @@ -648,6 +648,13 @@ Value getblockchainparams(const json_spirit::Array& params, bool fHelp) else { param_value=mc_GetLE(ptr,4); + if((mc_gState->m_NetworkParams->m_lpParams+i)->m_Type & MC_PRM_HIDDEN) + { + if(mc_GetLE(ptr,4) == (mc_gState->m_NetworkParams->m_lpParams+i)->m_DefaultIntegerValue) + { + hidden=true; + } + } } break; case MC_PRM_INT64: @@ -684,7 +691,10 @@ Value getblockchainparams(const json_spirit::Array& params, bool fHelp) } } - obj.push_back(Pair(param_name,param_value)); + if(!hidden) + { + obj.push_back(Pair(param_name,param_value)); + } } } diff --git a/src/utils/utilwrapper.cpp b/src/utils/utilwrapper.cpp index 8e900715..53223018 100644 --- a/src/utils/utilwrapper.cpp +++ b/src/utils/utilwrapper.cpp @@ -785,6 +785,7 @@ int mc_MultichainParams::SetGlobals() { MAX_SIZE *= 2; } + MIN_BLOCKS_BETWEEN_UPGRADES=(unsigned int)GetInt64Param("timingupgrademingap"); MAX_STANDARD_TX_SIZE=(unsigned int)GetInt64Param("maxstdtxsize"); MAX_SCRIPT_ELEMENT_SIZE=(unsigned int)GetInt64Param("maxstdelementsize"); COINBASE_MATURITY=(int)GetInt64Param("rewardspendabledelay"); From e91c2a5941d5a40d1473abdc4e6b7e0cb0d16f81 Mon Sep 17 00:00:00 2001 From: pawel <30689354+pawel-conjoule@users.noreply.github.com> Date: Thu, 10 Aug 2017 13:08:03 +0200 Subject: [PATCH 62/71] Added missing `./autogen.sh` to the "Compile MultiChain for Mac" section --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 92917391..c3a7db25 100644 --- a/README.md +++ b/README.md @@ -116,6 +116,7 @@ Compile MultiChain for Mac (64-bit) export LDFLAGS=-L/usr/local/opt/openssl/lib export CPPFLAGS=-I/usr/local/opt/openssl/include + ./autogen.sh ./configure --with-gui=no --with-libs=no --with-miniupnpc=no make From a2a0d753acbea6eb4405a06003f482656aaefabc Mon Sep 17 00:00:00 2001 From: mike31 Date: Mon, 15 Jan 2018 17:31:15 +0200 Subject: [PATCH 63/71] Upgradable max-std-* parameters --- src/chainparams/params.cpp | 42 ++++++++++++++++++++++++++++++++ src/core/main.cpp | 28 +++++++++++++++++++++ src/protocol/multichainblock.cpp | 26 +++++++++++++++++++- src/rpc/rpchelp.cpp | 30 ++++++++++++++++++++--- 4 files changed, 122 insertions(+), 4 deletions(-) diff --git a/src/chainparams/params.cpp b/src/chainparams/params.cpp index 63dfd8ec..14807a3f 100644 --- a/src/chainparams/params.cpp +++ b/src/chainparams/params.cpp @@ -224,6 +224,48 @@ int mc_MultichainParams::CanBeUpgradedByVersion(const char *param,int version,in } } + if(strcmp(param,"maxstdtxsize") == 0) + { + if(version >= 20002) + { + return m_lpCoord[2 * index + 1]; + } + } + + if(strcmp(param,"maxstdopreturnscount") == 0) + { + if(version >= 20002) + { + return m_lpCoord[2 * index + 1]; + } + } + + if(strcmp(param,"maxstdopreturnsize") == 0) + { + if(version >= 20002) + { + return m_lpCoord[2 * index + 1]; + } + } + + if(strcmp(param,"maxstdopdropscount") == 0) + { + if(version >= 20002) + { + return m_lpCoord[2 * index + 1]; + } + } + + if(strcmp(param,"maxstdelementsize") == 0) + { + if(version >= 20002) + { + return m_lpCoord[2 * index + 1]; + } + } + + + return 0; } diff --git a/src/core/main.cpp b/src/core/main.cpp index 75659219..a144163d 100644 --- a/src/core/main.cpp +++ b/src/core/main.cpp @@ -377,6 +377,34 @@ int SetUpgradedParamValue(const mc_OneMultichainParam *param,int64_t value) SetMultiChainParam("targetblocktime",value); } + if(strcmp(param->m_Name,"maxstdtxsize") == 0) + { + MAX_STANDARD_TX_SIZE=value; + } + + if(strcmp(param->m_Name,"maxstdopreturnscount") == 0) + { + MCP_MAX_STD_OP_RETURN_COUNT=value; + } + + if(strcmp(param->m_Name,"maxstdopreturnsize") == 0) + { + MAX_OP_RETURN_RELAY=value; + MAX_OP_RETURN_RELAY=GetArg("-datacarriersize", MAX_OP_RETURN_RELAY); + } + + if(strcmp(param->m_Name,"maxstdopdropscount") == 0) + { + MCP_STD_OP_DROP_COUNT=value; + pwalletMain->InitializeUnspentList(); + } + + if(strcmp(param->m_Name,"maxstdelementsize") == 0) + { + MAX_SCRIPT_ELEMENT_SIZE=value; + pwalletMain->InitializeUnspentList(); + } + return MC_ERR_NOERROR; } diff --git a/src/protocol/multichainblock.cpp b/src/protocol/multichainblock.cpp index f6ed69ef..90f11268 100644 --- a/src/protocol/multichainblock.cpp +++ b/src/protocol/multichainblock.cpp @@ -224,7 +224,31 @@ int CreateUpgradeLists(int current_height,vector *vParams, } else { - map_last_upgrade.insert(std::make_pair(param_name,(int)vParams->size())); + take_it=false; + int64_t old_value=mc_gState->m_NetworkParams->GetInt64Param(param.m_Param->m_Name); + + if(param.m_Value >= old_value) + { + if(param_value <= 2*old_value) + { + take_it=true; + } + } + else + { + if(old_value <= 2*param_value) + { + take_it=true; + } + } + if(!take_it) + { + param.m_Skipped =MC_PSK_DOUBLE_RANGE; + } + else + { + map_last_upgrade.insert(std::make_pair(param_name,(int)vParams->size())); + } } } else diff --git a/src/rpc/rpchelp.cpp b/src/rpc/rpchelp.cpp index 38aad2b1..23ab4bb4 100644 --- a/src/rpc/rpchelp.cpp +++ b/src/rpc/rpchelp.cpp @@ -1404,7 +1404,15 @@ void mc_InitRPCHelpMap06() "3. open (boolean, required ) Should be false\n" "4 custom-fields (object, required) a json object with custom fields\n" " {\n" - " \"protocol-version\": version (numeric, required) Protocol version to upgrade to\n" + " \"protocol-version\": version (numeric, optional) Protocol version to upgrade to\n" + " \"parameter-name\": value (numeric, optional) New value for upgradable parameter, one of the following: \n" + " target-block-time,\n" + " maximum-block-size,\n" + " max-std-tx-size,\n" + " max-std-op-returns-count,\n" + " max-std-op-return-size,\n" + " max-std-op-drops-count,\n" + " max-std-element-size\n" " \"startblock\": block (numeric, optional, default 0) Block to apply from \n" // " \"param-name\": \"param-value\" (strings, required) The key is the parameter name, the value is parameter value\n" " ,...\n" @@ -1439,7 +1447,15 @@ void mc_InitRPCHelpMap06() "4. open (boolean, required ) Should be false\n" "5 custom-fields (object, required) a json object with custom fields\n" " {\n" - " \"protocol-version\": version (numeric, required) Protocol version to upgrade to \n" + " \"protocol-version\": version (numeric, optional) Protocol version to upgrade to \n" + " \"parameter-name\": value (numeric, optional) New value for upgradable parameter, one of the following: \n" + " target-block-time,\n" + " maximum-block-size,\n" + " max-std-tx-size,\n" + " max-std-op-returns-count,\n" + " max-std-op-return-size,\n" + " max-std-op-drops-count,\n" + " max-std-element-size\n" " \"start-block\": block (numeric, optional, default 0) Block to apply from \n" // " \"param-name\": \"param-value\" (strings, required) The key is the parameter name, the value is parameter value\n" " ,...\n" @@ -3744,7 +3760,15 @@ void mc_InitRPCHelpMap16() " \"startblock\" : n (numeric, optional, default: 0) Block to apply upgrade from (inclusive).\n" " \"details\" : (object, optional) A json object with custom fields\n" " {\n" - " \"protocol-version\": version (numeric, required) Protocol version to upgrade to \n" + " \"protocol-version\": version (numeric, optional) Protocol version to upgrade to \n" + " \"parameter-name\": value (numeric, optional) New value for upgradable parameter, one of the following: \n" + " target-block-time,\n" + " maximum-block-size,\n" + " max-std-tx-size,\n" + " max-std-op-returns-count,\n" + " max-std-op-return-size,\n" + " max-std-op-drops-count,\n" + " max-std-element-size\n" " }\n" " }\n" " or\n" From 572745bc509686f3a9987024586bf72425672a5b Mon Sep 17 00:00:00 2001 From: mike31 Date: Wed, 17 Jan 2018 11:36:08 +0200 Subject: [PATCH 64/71] Upgrade parameter error message tweaks --- src/rpc/rpcupgrades.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rpc/rpcupgrades.cpp b/src/rpc/rpcupgrades.cpp index 15283ac1..3fb04023 100644 --- a/src/rpc/rpcupgrades.cpp +++ b/src/rpc/rpcupgrades.cpp @@ -217,7 +217,7 @@ Value createupgradefromcmd(const Array& params, bool fHelp) } else { - strError="Invalid parameter name"; + strError="Some upgrade parameters are not supported by the current protocol, please upgrade protocol separately first."; goto exitlbl; } // lpDetails->SetParamValue(s.name_.c_str(),s.name_.size(),(unsigned char*)s.value_.get_str().c_str(),s.value_.get_str().size()); @@ -497,7 +497,7 @@ Value listupgrades(const json_spirit::Array& params, bool fHelp) case MC_PSK_WRONG_SIZE: param_err="Parameter is encoded with wrong size"; break; case MC_PSK_OUT_OF_RANGE: param_err="Parameter value is out of range"; break; case MC_PSK_FRESH_UPGRADE: param_err=strprintf("Parameter is upgraded less than %d blocks ago",MIN_BLOCKS_BETWEEN_UPGRADES); break; - case MC_PSK_DOUBLE_RANGE: param_err="New parameter value must be between half and double preview time"; break; + case MC_PSK_DOUBLE_RANGE: param_err="New parameter value must be between half and double previous value"; break; case MC_PSK_NOT_SUPPORTED: param_err="This parameter cannot be upgraded in this protocol version"; break; case MC_PSK_NEW_NOT_DOWNGRADABLE: param_err="Cannot downgrade to this version"; break; case MC_PSK_OLD_NOT_DOWNGRADABLE: param_err="Downgrades are not allowed in this protocol version"; break; From 1d7faf7fbe4132140800e920278710706915b2f6 Mon Sep 17 00:00:00 2001 From: mike31 Date: Wed, 17 Jan 2018 17:07:40 +0200 Subject: [PATCH 65/71] listunspent/getmultibalances optimization if addresses are specified --- src/rpc/rpcassets.cpp | 30 +++++++++++++++++++++++++++++- src/rpc/rpcrawtransaction.cpp | 27 +++++++++++++++++++++++++-- src/wallet/wallet.cpp | 9 ++++++--- src/wallet/wallet.h | 2 +- src/wallet/walletcoins.cpp | 2 +- 5 files changed, 62 insertions(+), 8 deletions(-) diff --git a/src/rpc/rpcassets.cpp b/src/rpc/rpcassets.cpp index f11326e8..52721c19 100644 --- a/src/rpc/rpcassets.cpp +++ b/src/rpc/rpcassets.cpp @@ -718,6 +718,10 @@ Value getmultibalances(const Array& params, bool fHelp) set setAddresses; set setAddressesWithBalances; + set setAddressUints; + set *lpSetAddressUint=NULL; + CTxDestination dest; + if(params.size() > 0) { if( (params[0].type() != str_type) || (params[0].get_str() != "*") ) @@ -729,6 +733,30 @@ Value getmultibalances(const Array& params, bool fHelp) { return balances; } + + BOOST_FOREACH(string str_addr, setAddresses) + { + CBitcoinAddress address(str_addr); + dest=address.Get(); + const CKeyID *lpKeyID=boost::get (&dest); + const CScriptID *lpScriptID=boost::get (&dest); + if(lpKeyID) + { + setAddressUints.insert(*(uint160*)lpKeyID); + } + else + { + if(lpScriptID) + { + setAddressUints.insert(*(uint160*)lpScriptID); + } + } + } + + if(setAddressUints.size()) + { + lpSetAddressUint=&setAddressUints; + } } } @@ -799,7 +827,7 @@ Value getmultibalances(const Array& params, bool fHelp) vector vecOutputs; - pwalletMain->AvailableCoins(vecOutputs, false, NULL, fUnlockedOnly,true); + pwalletMain->AvailableCoins(vecOutputs, false, NULL, fUnlockedOnly,true, 0, lpSetAddressUint); BOOST_FOREACH(const COutput& out, vecOutputs) { if(!out.IsTrustedNoDepth()) diff --git a/src/rpc/rpcrawtransaction.cpp b/src/rpc/rpcrawtransaction.cpp index 2c17b740..2d5fe3b2 100644 --- a/src/rpc/rpcrawtransaction.cpp +++ b/src/rpc/rpcrawtransaction.cpp @@ -559,6 +559,9 @@ Value listunspent(const Array& params, bool fHelp) nMaxDepth = params[1].get_int64(); set setAddress; + set setAddressUints; + set *lpSetAddressUint=NULL; + CTxDestination dest; if (params.size() > 2) { Array inputs = params[2].get_array(); BOOST_FOREACH(Value& input, inputs) { @@ -567,7 +570,27 @@ Value listunspent(const Array& params, bool fHelp) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid address: ")+input.get_str()); if (setAddress.count(address)) throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ")+input.get_str()); - setAddress.insert(address); + setAddress.insert(address); + + dest=address.Get(); + const CKeyID *lpKeyID=boost::get (&dest); + const CScriptID *lpScriptID=boost::get (&dest); + if(lpKeyID) + { + setAddressUints.insert(*(uint160*)lpKeyID); + } + else + { + if(lpScriptID) + { + setAddressUints.insert(*(uint160*)lpScriptID); + } + } + } + + if(setAddressUints.size()) + { + lpSetAddressUint=&setAddressUints; } } /* MCHN START */ @@ -588,7 +611,7 @@ Value listunspent(const Array& params, bool fHelp) vector vecOutputs; assert(pwalletMain != NULL); // pwalletMain->AvailableCoins(vecOutputs, false); - pwalletMain->AvailableCoins(vecOutputs, false, NULL, true, true); + pwalletMain->AvailableCoins(vecOutputs, false, NULL, true, true, 0, lpSetAddressUint); BOOST_FOREACH(const COutput& out, vecOutputs) { if (out.nDepth < nMinDepth || out.nDepth > nMaxDepth) continue; diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index b377ce6a..cce28d7b 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1944,7 +1944,8 @@ CAmount CWallet::GetImmatureWatchOnlyBalance() const /** * populate vCoins with vector of available COutputs. */ -void CWallet::AvailableCoins(vector& vCoins, bool fOnlyConfirmed, const CCoinControl *coinControl, bool fOnlyUnlocked, bool fOnlyCoinsNoTxs, uint160 addr, uint32_t flags) const +void CWallet::AvailableCoins(vector& vCoins, bool fOnlyConfirmed, const CCoinControl *coinControl, bool fOnlyUnlocked, bool fOnlyCoinsNoTxs, + uint160 addr, const set* addresses, uint32_t flags) const { vCoins.clear(); @@ -1960,10 +1961,12 @@ void CWallet::AvailableCoins(vector& vCoins, bool fOnlyConfirmed, const for (map::const_iterator it = pwalletTxsMain->m_UTXOs[0].begin(); it != pwalletTxsMain->m_UTXOs[0].end(); ++it) { const mc_Coin& coin = it->second; - if((addr == 0) || (addr == coin.m_EntityID)) + if( ( (addresses == NULL) && (addr == 0) ) || + (addr == coin.m_EntityID) || + ( (addresses != NULL) && (addresses->count(coin.m_EntityID) != 0)) ) { isminetype mine; - bool is_p2sh=false;; + bool is_p2sh=false; if(coin.m_EntityType) { if(coin.m_Flags & MC_TFL_IS_SPENDABLE) diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 811fe57b..7c0dddb0 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -386,7 +386,7 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface /* MCHN START */ // void AvailableCoins(std::vector& vCoins, bool fOnlyConfirmed=true, const CCoinControl *coinControl = NULL) const; void AvailableCoins(std::vector& vCoins, bool fOnlyConfirmed=true, const CCoinControl *coinControl = NULL, bool fOnlyUnlocked=true, - bool fOnlyCoinsNoTxs=false, uint160 addr=0, uint32_t flags=MC_CSF_ALLOW_SPENDABLE_P2SH) const; + bool fOnlyCoinsNoTxs=false, uint160 addr=0, const std::set* addresses=NULL, uint32_t flags=MC_CSF_ALLOW_SPENDABLE_P2SH) const; /* MCHN END */ bool SelectCoinsMinConf(const CAmount& nTargetValue, int nConfMine, int nConfTheirs, std::vector vCoins, std::set >& setCoinsRet, CAmount& nValueRet) const; diff --git a/src/wallet/walletcoins.cpp b/src/wallet/walletcoins.cpp index 41232796..9636ae6e 100644 --- a/src/wallet/walletcoins.cpp +++ b/src/wallet/walletcoins.cpp @@ -670,7 +670,7 @@ void AvalableCoinsForAddress(CWallet *lpWallet,vector& vCoins, const CC } } - lpWallet->AvailableCoins(vCoins, true, coinControl,true,true,addr,flags); + lpWallet->AvailableCoins(vCoins, true, coinControl,true,true,addr,NULL,flags); this_time=mc_TimeNowAsDouble(); if(fDebug)LogPrint("mcperf","mcperf: AvailableCoins: Time: %8.6f \n", this_time-last_time); last_time=this_time; From 2e6705a75fcf9492f71cea8e1aa6014576b6de53 Mon Sep 17 00:00:00 2001 From: mike31 Date: Sun, 21 Jan 2018 17:32:39 +0200 Subject: [PATCH 66/71] Fixed. Setting Invalid flag for coinbases on rollback --- src/wallet/wallettxs.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/wallet/wallettxs.cpp b/src/wallet/wallettxs.cpp index 1d69efc0..fd600e84 100644 --- a/src/wallet/wallettxs.cpp +++ b/src/wallet/wallettxs.cpp @@ -817,6 +817,7 @@ int mc_WalletTxs::RollBack(mc_TxImport *import,int block) mc_Buffer *lpSubKeyEntRowBuffer; bool fInBlocks; std::vector txouts; + std::vector removed_coinbases; if((m_Mode & MC_WMD_TXS) == 0) { @@ -1070,6 +1071,10 @@ int mc_WalletTxs::RollBack(mc_TxImport *import,int block) } } if(fDebug)LogPrint("wallet","wtxs: Removing tx %s, block %d, flags: %08X, import %d\n",hash.ToString().c_str(),entrow->m_Block,entrow->m_Flags,imp->m_ImportID); + if(wtx.IsCoinBase()) + { + removed_coinbases.push_back(hash); + } } } else @@ -1121,6 +1126,11 @@ int mc_WalletTxs::RollBack(mc_TxImport *import,int block) if(err == MC_ERR_NOERROR) { err=m_Database->RollBack(import,block); // Database rollback + for(i=0;i<(int)removed_coinbases.size();i++) + { + uint256 hash=removed_coinbases[i]; + m_Database->SaveTxFlag((unsigned char*)&hash,MC_TFL_INVALID,1); + } } if(err) { From c31bcdd3d9e9bf02a98c0863ab37fe295cef3bf1 Mon Sep 17 00:00:00 2001 From: mike31 Date: Tue, 23 Jan 2018 17:05:33 +0200 Subject: [PATCH 67/71] pausing reaccepting --- src/chainparams/state.h | 1 + src/core/main.cpp | 5 ++++- src/rpc/rpcserver.cpp | 10 ++++++++-- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/chainparams/state.h b/src/chainparams/state.h index ac6b9aa6..98920cea 100644 --- a/src/chainparams/state.h +++ b/src/chainparams/state.h @@ -33,6 +33,7 @@ #define MC_NPS_NETWORK 0x00000001 #define MC_NPS_INCOMING 0x00000002 #define MC_NPS_MINING 0x00000004 +#define MC_NPS_REACCEPT 0x00000008 #define MC_NPS_ALL 0xFFFFFFFF #define MC_WMD_NONE 0x00000000 diff --git a/src/core/main.cpp b/src/core/main.cpp index a144163d..292bd9e2 100644 --- a/src/core/main.cpp +++ b/src/core/main.cpp @@ -3390,8 +3390,11 @@ static bool ActivateBestChainStep(CValidationState &state, CBlockIndex *pindexMo if(fDebug)LogPrint("mcblockperf","mchn-block-perf: Reaccepting wallet transactions\n"); if(pwalletMain) { - pwalletMain->ReacceptWalletTransactions(); // Some wallet transactions may become invalid in reorg + if( (mc_gState->m_NodePausedState & MC_NPS_REACCEPT) == 0 ) + { + pwalletMain->ReacceptWalletTransactions(); // Some wallet transactions may become invalid in reorg // Some may become invalid if not confirmed in time + } } if(fDebug)LogPrint("mcblockperf","mchn-block-perf: Best chain activation completed\n"); diff --git a/src/rpc/rpcserver.cpp b/src/rpc/rpcserver.cpp index d8bf9273..5a18fc28 100644 --- a/src/rpc/rpcserver.cpp +++ b/src/rpc/rpcserver.cpp @@ -368,8 +368,9 @@ uint32_t GetPausedServices(const char *str) if(ptr > start) { type=0; - if(memcmp(start,"incoming", ptr-start) == 0)type = MC_NPS_INCOMING; - if(memcmp(start,"mining", ptr-start) == 0)type = MC_NPS_MINING; + if(memcmp(start,"incoming", ptr-start) == 0)type = MC_NPS_INCOMING; + if(memcmp(start,"mining", ptr-start) == 0)type = MC_NPS_MINING; + if(memcmp(start,"reaccepting", ptr-start) == 0)type = MC_NPS_REACCEPT; if(type == 0) { @@ -427,6 +428,11 @@ Value resumecmd(const Array& params, bool fHelp) mc_gState->m_NodePausedState &= (MC_NPS_ALL ^ type); + if( type & MC_NPS_REACCEPT ) + { + pwalletMain->ReacceptWalletTransactions(); + } + LogPrintf("Node paused state is set to %08X\n",mc_gState->m_NodePausedState); return "Resumed"; From 0ca9aa3d376b07d20cd208691ec5b2fa1caa1f43 Mon Sep 17 00:00:00 2001 From: mike31 Date: Wed, 24 Jan 2018 09:11:18 +0200 Subject: [PATCH 68/71] Revert "Miner starting nonce randomization" This reverts commit 42d6ea4fd8308d4359f0382e57b49c9af53da8e8. --- src/miner/miner.cpp | 23 +++++++---------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/src/miner/miner.cpp b/src/miner/miner.cpp index 06d53bf3..6c0ae8a8 100644 --- a/src/miner/miner.cpp +++ b/src/miner/miner.cpp @@ -88,11 +88,6 @@ class TxPriorityCompare } }; -uint32_t RandomStartNonce() -{ - return mc_RandomInRange(0,0x4fffffff); -} - bool UpdateTime(CBlockHeader* pblock, const CBlockIndex* pindexPrev) { /* MCHN START */ @@ -698,7 +693,7 @@ void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& static uint256 hashPrevBlock; if (hashPrevBlock != pblock->hashPrevBlock) { - nExtraNonce = RandomStartNonce(); + nExtraNonce = 0; hashPrevBlock = pblock->hashPrevBlock; } ++nExtraNonce; @@ -1206,7 +1201,7 @@ void static BitcoinMiner(CWallet *pwallet) // Each thread has its own key and counter CReserveKey reservekey(pwallet); - unsigned int nExtraNonce = RandomStartNonce();//0; + unsigned int nExtraNonce = 0; /* MCHN START */ int canMine; @@ -1442,6 +1437,8 @@ void static BitcoinMiner(CWallet *pwallet) CBlock *pblock = &pblocktemplate->block; IncrementExtraNonce(pblock, pindexPrev, nExtraNonce,pwallet); + LogPrint("mcminer","mchn-miner: Running MultiChainMiner with %u transactions in block (%u bytes)\n", pblock->vtx.size(), + ::GetSerializeSize(*pblock, SER_NETWORK, PROTOCOL_VERSION)); // // Search @@ -1449,11 +1446,9 @@ void static BitcoinMiner(CWallet *pwallet) int64_t nStart = GetTime(); uint256 hashTarget = uint256().SetCompact(pblock->nBits); uint256 hash; - uint32_t nNonce = RandomStartNonce(); - uint32_t nStartNonce=nNonce; + uint32_t nNonce = 0; uint32_t nOldNonce = 0; - LogPrint("mcminer","mchn-miner: Running MultiChainMiner with %u transactions in block (%u bytes). Starting nonce: %08x/%08x\n", pblock->vtx.size(), - ::GetSerializeSize(*pblock, SER_NETWORK, PROTOCOL_VERSION),nNonce,nExtraNonce); + double wStartTime=mc_TimeNowAsDouble(); uint64_t wThisCount=0; while (true) { @@ -1559,12 +1554,8 @@ void static BitcoinMiner(CWallet *pwallet) // if (vNodes.empty() && Params().MiningRequiresPeers() && not_setup_period) break; } -// if (nNonce >= 0xffff0000) - if ( (nNonce-nStartNonce) >= 0x8fffffff/GetArg("-genproclimit", 1)) - { - LogPrint("mcminer","Too many nonces tried for %08x, switching timestamp\n",nStartNonce); + if (nNonce >= 0xffff0000) break; - } if (mempool.GetTransactionsUpdated() != nTransactionsUpdatedLast && GetTime() - nStart > 60) break; if (pindexPrev != chainActive.Tip()) From 1a78af12c0b48f5e4a126592713798d44307445e Mon Sep 17 00:00:00 2001 From: mike31 Date: Wed, 24 Jan 2018 15:00:28 +0200 Subject: [PATCH 69/71] Fixed representation of upgraded std- params in getblockchainparams --- src/rpc/rpcmisc.cpp | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/src/rpc/rpcmisc.cpp b/src/rpc/rpcmisc.cpp index 69487312..b7f4ca98 100644 --- a/src/rpc/rpcmisc.cpp +++ b/src/rpc/rpcmisc.cpp @@ -669,26 +669,40 @@ Value getblockchainparams(const json_spirit::Array& params, bool fHelp) { param_value=Value::null; } - if(strcmp("protocolversion",(mc_gState->m_NetworkParams->m_lpParams+i)->m_Name) == 0) + if(nHeight) { - if(nHeight) + if(strcmp("protocolversion",(mc_gState->m_NetworkParams->m_lpParams+i)->m_Name) == 0) { param_value=mc_gState->m_NetworkParams->m_ProtocolVersion; } - } - if(strcmp("maximumblocksize",(mc_gState->m_NetworkParams->m_lpParams+i)->m_Name) == 0) - { - if(nHeight) + if(strcmp("maximumblocksize",(mc_gState->m_NetworkParams->m_lpParams+i)->m_Name) == 0) { param_value=(int)MAX_BLOCK_SIZE; } - } - if(strcmp("targetblocktime",(mc_gState->m_NetworkParams->m_lpParams+i)->m_Name) == 0) - { - if(nHeight) + if(strcmp("targetblocktime",(mc_gState->m_NetworkParams->m_lpParams+i)->m_Name) == 0) { param_value=(int)MCP_TARGET_BLOCK_TIME; } + if(strcmp("maxstdtxsize",(mc_gState->m_NetworkParams->m_lpParams+i)->m_Name) == 0) + { + param_value=(int)MAX_STANDARD_TX_SIZE; + } + if(strcmp("maxstdopreturnscount",(mc_gState->m_NetworkParams->m_lpParams+i)->m_Name) == 0) + { + param_value=(int)MCP_MAX_STD_OP_RETURN_COUNT; + } + if(strcmp("maxstdopreturnsize",(mc_gState->m_NetworkParams->m_lpParams+i)->m_Name) == 0) + { + param_value=(int)MAX_OP_RETURN_RELAY; + } + if(strcmp("maxstdopdropscount",(mc_gState->m_NetworkParams->m_lpParams+i)->m_Name) == 0) + { + param_value=(int)MCP_STD_OP_DROP_COUNT; + } + if(strcmp("maxstdelementsize",(mc_gState->m_NetworkParams->m_lpParams+i)->m_Name) == 0) + { + param_value=(int)MAX_SCRIPT_ELEMENT_SIZE; + } } if(!hidden) From aa7e696f22828bc0cf0f538ec69416d3b4c6eacb Mon Sep 17 00:00:00 2001 From: mike31 Date: Thu, 25 Jan 2018 17:45:47 +0200 Subject: [PATCH 70/71] Inline data help message --- src/rpc/rpchelp.cpp | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/rpc/rpchelp.cpp b/src/rpc/rpchelp.cpp index 23ab4bb4..f4ca707e 100644 --- a/src/rpc/rpchelp.cpp +++ b/src/rpc/rpchelp.cpp @@ -3851,7 +3851,25 @@ void mc_InitRPCHelpMap16() " \"timestamp\" : n (numeric, optional) This helps resolve conflicts between\n" " permissions assigned by the same administrator. Default - current time\n" " }\n" - " }\n" + " }\n" + " or \n" + " { (object) A json object describing inline data\n" + " \"data\" : \n" + " {\n" + " \"data-hex\" (string, required) Data hex string\n" + " or\n" + " data-json (object, required) JSON data object\n" + " {\n" + " \"json\" : data-json (object, required) Valid JSON object\n" + " }\n" + " or\n" + " data-text (object, required) Text data object\n" + " {\n" + " \"text\" : \"data-text\" (string, required) Data string\n" + " }\n" + " }\n" + " }\n" + " ,...\n" "}\n" )); From c10bc361704fc8e6cc078591466cb3a76d4965ab Mon Sep 17 00:00:00 2001 From: mike31 Date: Fri, 26 Jan 2018 08:59:54 +0200 Subject: [PATCH 71/71] Fixed liststreamkeys for single key --- src/rpc/rpcstreams.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rpc/rpcstreams.cpp b/src/rpc/rpcstreams.cpp index 84dd298b..d93db3ae 100644 --- a/src/rpc/rpcstreams.cpp +++ b/src/rpc/rpcstreams.cpp @@ -1779,7 +1779,7 @@ Value liststreammap_operation(mc_TxEntity *parent_entity,vector& in { mc_TxEntityRow *lpEntTx; string key_string; - if(entity_rows) + if(entity_rows->GetCount()) { lpEntTx=(mc_TxEntityRow*)entity_rows->GetRow(i); key_string=pwalletTxsMain->GetSubKey(lpEntTx->m_TxId, NULL,NULL);