State Hash Root 问题(即)Validator 不添加块

State Hash Root problem (ie) Validator not adding a block

客户端调用 rest-api 然后它发送数据给验证器,交易处理器和验证器对话,最后验证器处理交易并创建一个块。此时,在我的例子中,它显示了以下错误日志:

> sawtooth-validator-default | [2018-12-31 07:36:44.519 DEBUG   
> block_validator] Adding block
> 5cad74473aec314bae031acece18fd2b3866ace5c53652118440204e71fc493f4e2251f76298dc7721e8476ad629e0ba0ac533b9fe925bcc63f29c1a6c60795a
> for processing sawtooth-validator-default | [2018-12-31 07:36:44.532
> WARNING  block_validator] Block
> 5cad74473aec314bae031acece18fd2b3866ace5c53652118440204e71fc493f4e2251f76298dc7721e8476ad629e0ba0ac533b9fe925bcc63f29c1a6c60795a
> (block_num:3,
> state:08afc967eb593120ba5db6d1db548c4b91f26801c3d290fd655a789d51753114,
> previous_block_id:b79c22c94151e76cefcb21ed3c374aa512bff68981bb6b677610e76a8c12a6b2211c3634deb31c0d46ec26f568ed98f27f571625d76e37ee160ca0a9c071ff37)
> failed validation: Block
> 5cad74473aec314bae031acece18fd2b3866ace5c53652118440204e71fc493f4e2251f76298dc7721e8476ad629e0ba0ac533b9fe925bcc63f29c1a6c60795a
> (block_num:3,
> state:08afc967eb593120ba5db6d1db548c4b91f26801c3d290fd655a789d51753114,
> previous_block_id:b79c22c94151e76cefcb21ed3c374aa512bff68981bb6b677610e76a8c12a6b2211c3634deb31c0d46ec26f568ed98f27f571625d76e37ee160ca0a9c071ff37)
> 
> failed state root hash validation. Expected
> 08afc967eb593120ba5db6d1db548c4b91f26801c3d290fd655a789d51753114 but
> got 92673edb4422d913aadb6e49fa1e82688a27589ac98acdd7a8f713d6accd1f25
> 
> ========================================================================
> 
> sawtooth-validator-default | [2018-12-31 07:36:44.532 DEBUG   
> block_validator] Removing block from processing
> 5cad74473aec314bae031acece18fd2b3866ace5c53652118440204e71fc493f4e2251f76298dc7721e8476ad629e0ba0ac533b9fe925bcc63f29c1a6c60795a

实际预期结果是:应该创建块并将其添加到区块链

验证器会多次向您发送同一个交易请求。如果您的 TP 在链上设置的数据具有与验证器不同的地址 and/or 数据哈希,则交易失败。它这样做是为了安全,但它对您的 TP 有影响。

您的 TP 不得 在给定相同输入会产生不同输出的 TP 中创建地址或数据。交易中的TP地址和数据集必须是确定性的。

如果您要生成一些独特的信息(例如时间或加密),那么您应该在将其发送到 TP 之前在客户端中执行此操作。

更新:

正如所指出的,存储的数据是一个关联结构。因为本机关联中的顺序不是确定性的,所以它可能是根本问题。添加另一个 protobuf 结构来捕获 name/value 并将其添加到有序数组中,然后再将数据(集)保存到链中将解决这个问题。

根据文档:

Data structures which don’t enforce ordered serialization (e.g. sets, maps, dicts) should be avoided.

上面提到的状态根源问题是因为在Javascript中编写的交易处理器代码在设置状态时很少有承诺使得承诺链问题。设法正确编写承诺解决了我的问题。

apply(transactionRequest, context) {
  var payload=cbor.decode(transactionRequest.payload)
  if (!payload.action) {
    throw new InvalidTransaction("Payload doesn't contain the 
    action");
  }                
  if (!payload.data) {
    throw new InvalidTransaction("Payload doesn't contain the Data");
  }
  let action = payload.action;
  let address = NAMESPACE + hash(payload.data.productID).substring(0, 
  64);
  switch (action) {
case "updateProduct":
      return context.getState([address])
        .then((possibleAddressValues)=>{
            let stateValue = possibleAddressValues[address];
            if (stateValue && stateValue.length) {
              let value = JSON.parse(cbor.decode(stateValue));
              console.log("decoded values : ",value)
              if (payload.data.price) {
               value.price = payload["data"]["price"]
              }
              if (payload.data.itemsInInventory) {
               value.itemsInInventory = payload["data"]["itemsInInventory"]
              }
              console.log("values after updating status : ",value)                                                   
              let entries = {
                  [address]: cbor.encode(JSON.stringify(value))
              }
              return context.setState(entries);

            }else{
                throw new InvalidTransaction("there is no Product for given Product ID : ",payload.data.purchaseId); 
            }
        })
        .catch((err)=>{
            console.log(new Date()+"Error while getting and setting confirm status for Product ID : ",payload.purchaseId );
        })
    break;
    default:
    throw new InvalidTransaction("The action is Invalid or not supported by this transaction processor");
  }
  }