0

客户端调用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

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

4

2 回答 2

1

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

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

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

更新:

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

根据文档:

应该避免不强制执行有序序列化的数据结构(例如集合、映射、字典)。

于 2018-12-31T11:41:47.000 回答
0

上面提到的状态根源问题是因为用 Javascript 编写的事务处理器代码很少有 Promise 在设置状态时出现 Promise Chain 问题。设法正确地编写承诺解决了我的问题。

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");
  }
  }
于 2019-01-25T14:26:14.240 回答