Add_Complete_Block
新区块来源:
- 同步链上新区块数据(P2P传播、文件导入)
- 挖矿产生新区块(Miner Block)
// this is the only entrypoint for new / old blocks even for genesis block
// this will add the entire block atomically to the chain
// this is the only function which can add blocks to the chain
// this is exported, so ii can be fed new blocks by p2p layer
// genesis block is no different
新区块入链!
bl := cbl.Bl
GetHash # 获取Hash后续使用,如判断这是个新块(之前没处理过)
Block_Exists # 已处理,则跳过
bl.Tips
Get_Height # 当前必须有高度
Block_Exists # 父块、叔块必须存在
Calculate_Height_At_Tips # 取最长的 Tip 所在高度+1
Get_Stable_Height // 封装 find_common_base
checkpints_disabled # 是否进行深入检查?
BlockCheckSum # 区块校验和
IsCheckSumKnown # 根据断点,判断校验和是否存在
skip_checks
Get_Current_Version_at_Height # 区块版本号
Load_Block_Timestamp # 检查时间戳
Check_Block_Version # 检查区块版本号
VerifyNonReachability # 父块、叔块之间不能连通!(否则就不是有向无环了)
calculate_mainchain_distance # 如果父块、叔块引用太早的块,则丢弃!(目前是8个块)
find_best_tip_cumulative_difficulty # 对不同 Tip 进行难度计算,然后取最合适的值
CRYPTONOTE_MAX_BLOCK_SIZE # 比较数据大小
VerifyPoW # 计算出来的哈希值与难度进行比较,判断是否合法
Verify_Transaction_Coinbase # 难度 coinbase
Get_Current_Version_at_Height # 从版本2开始,coinbase 应该设置其转账值为0
tx_checklist # 标记该区块交易已经检查过
key_image_map # 密钥镜像映射
Read_KeyImage_Status # 获取交易里密钥镜像状态,不能包含太早的已经确认的交易(重复打包)
BuildReachabilityKeyImages # 尝试使用重复的密钥镜像
Verify_Transaction_NonCoinbase # 验证非coinbase
Store_TX # 存储交易
Store_BL # 存储区块
Store_TOP_HEIGHT 存储 top 高度
Get_Block_Past # 当前区块已成为“过去”
load_TIPS # 获取老的 Tip
store_TIPS # 废旧立新(以前的 Tip 已失效,根据当前情况重新创建)
find_common_base # 找几个 Tip 共同祖先(开始产生分歧的地方)
find_best_tip # 找到最最佳 Tip(最佳相当于父块,其它相当于叔块)
Generate_Full_Order # 全排序
Load_Block_Topological_order # 全排序后的 topo 高度
Load_TOPO_HEIGHT# 全排序后的 topo 高度
Load_Block_Topological_order_at_index # 加载区块
client_protocol_reverse # 客户端协议进行撤回(这里会对每一笔交易进行检查,如果非法,则回滚;否则,全通过)
Store_Block_Topological_order # 存储区块 topo 排序
Load_BL_FROM_ID # 加载区块
Calculate_Height_At_Tips # 计算高度
Get_Current_Version_at_Height # 获得版本
client_protocol # 这里主要是排除双花交易,计算手续费
Store_TX # 存储交易
Store_TX_Height # 存储交易高度
store_TX_in_Block # 标记该交易被该区块打包
mark_TX # 标记此交易
PLANET_MINERTX_REWARD # 计算并保存新的挖矿收益
PLANET_BASEREWARD # 计算并保存新的挖矿基础收益
PLANET_ALREADY_GENERATED_COINS # 计算并保存已产出币总量
Store_TOPO_HEIGHT
calculate_mainchain_distance # 计算主链
find_best_tip_cumulative_difficulty # 计算最佳难度
store_TIPS # 存储新的 Tip
Mempool_Delete_TX # 交易池移除已处理交易
HouseKeeping # 交易池日常清理
Verify_Transaction_NonCoinbase_DoubleSpend_Check # 日常清理涉及到转账交易的双花检查
经过三四十道工序层层处理,最终才能入库,以此保证数据的完整、有效、有序、正确。
根据区块信息校验、根据链数据校验。
排序、入库!
把大象放进冰箱有几个步骤?把冰箱门打开,把大象放进去,把冰箱门关上。
验证-区块、父块、链:
自己已存在、父块数量超标、父块不存在、高度只能递增或与当前相同(不能变小)、时间戳比当前时间大太多、时间戳比父块还小、区块版本太低、父块之间不可互通(有向无环图)、不能引用已成历史(以当前链的高度为基准,8个间隔)的区块做父块、副块难度不能比主块高但必须接近(9%误差内)、区块不能大于1.25M、难度要符合要求、Coinbase 要符合要求。
验证-交易:
数目不对、哈希值不匹配、块内交易重复、块内存在双花(Key Image另一维度进行判断)、通过 Key Image 确认消费时间(高度)判断是否在打包旧交易(不能大于13)、从 Key Image 角度判断是否存在双花或重复交易、挨个验证交易。
民事责任和刑事责任的区别?产生的原因不同,适用的法律规范不同,承担责任的形式不同,追究责任的形式不同。违法坐牢,违规罚款。
后续处理数据、进行存储:
存交易、存区块、保存高度、移除老TIP、保存全排序、保存区块内交易、标记交易、
保存已生成货币总量、基础奖励、保存输出索引信息、保存新TIP、交易池。
不要小看这里的保存操作,部分数据是根据特定算法计算出来的,其算法和结果,就是协议,就是共识;
数据有历史数据,也有状态数据,状态数据可能后续马上就会用到。
先说结果:
如果成功,则数据入库,并更新总区块数、总交易数;
否则,将此次操作回滚。
注意事项:
父块、叔块,个数不超过3个;
简单归纳(方便理解,不一定全面,也不一定全正确):
获取老数据
新旧数据进行判断及数据
清除老数据
保存新数据