diff --git a/account_create_transaction.go b/account_create_transaction.go index 4bffbee65..86cac24ad 100644 --- a/account_create_transaction.go +++ b/account_create_transaction.go @@ -40,6 +40,13 @@ func NewAccountCreateTransaction() *AccountCreateTransaction { return &transaction } +func accountCreateTransactionFromProtobuf(transactions map[TransactionID]map[AccountID]*proto.Transaction, pb *proto.TransactionBody) AccountCreateTransaction { + return AccountCreateTransaction{ + Transaction: transactionFromProtobuf(transactions, pb), + pb: pb.GetCryptoCreateAccount(), + } +} + // SetKey sets the key that must sign each transfer out of the account. If RecieverSignatureRequired is true, then it // must also sign any transfer into the account. func (transaction *AccountCreateTransaction) SetKey(key Key) *AccountCreateTransaction { diff --git a/account_delete_transaction.go b/account_delete_transaction.go index 20e68adfd..dfb285a0d 100644 --- a/account_delete_transaction.go +++ b/account_delete_transaction.go @@ -18,6 +18,13 @@ type AccountDeleteTransaction struct { pb *proto.CryptoDeleteTransactionBody } +func accountDeleteTransactionFromProtobuf(transactions map[TransactionID]map[AccountID]*proto.Transaction, pb *proto.TransactionBody) AccountDeleteTransaction { + return AccountDeleteTransaction{ + Transaction: transactionFromProtobuf(transactions, pb), + pb: pb.GetCryptoDelete(), + } +} + func NewAccountDeleteTransaction() *AccountDeleteTransaction { pb := &proto.CryptoDeleteTransactionBody{} diff --git a/account_update_transaction.go b/account_update_transaction.go index 537338e06..955e2df76 100644 --- a/account_update_transaction.go +++ b/account_update_transaction.go @@ -20,6 +20,13 @@ func NewAccountUpdateTransaction() *AccountUpdateTransaction { return &transaction } +func accountUpdateTransactionFromProtobuf(transactions map[TransactionID]map[AccountID]*proto.Transaction, pb *proto.TransactionBody) AccountUpdateTransaction { + return AccountUpdateTransaction{ + Transaction: transactionFromProtobuf(transactions, pb), + pb: pb.GetCryptoUpdateAccount(), + } +} + func (transaction *AccountUpdateTransaction) SetKey(key Key) *AccountUpdateTransaction { transaction.requireNotFrozen() transaction.pb.Key = key.toProtoKey() diff --git a/contract_create_transaction.go b/contract_create_transaction.go index 0f865a2fa..53fb667bf 100644 --- a/contract_create_transaction.go +++ b/contract_create_transaction.go @@ -24,6 +24,13 @@ func NewContractCreateTransaction() *ContractCreateTransaction { return &transaction } +func contractCreateTransactionFromProtobuf(transactions map[TransactionID]map[AccountID]*proto.Transaction, pb *proto.TransactionBody) ContractCreateTransaction { + return ContractCreateTransaction{ + Transaction: transactionFromProtobuf(transactions, pb), + pb: pb.GetContractCreateInstance(), + } +} + func (transaction *ContractCreateTransaction) SetBytecodeFileID(bytecodeFileID FileID) *ContractCreateTransaction { transaction.requireNotFrozen() transaction.pb.FileID = bytecodeFileID.toProtobuf() diff --git a/contract_delete_transaction.go b/contract_delete_transaction.go index e26fce65c..e429818d9 100644 --- a/contract_delete_transaction.go +++ b/contract_delete_transaction.go @@ -21,6 +21,13 @@ func NewContractDeleteTransaction() *ContractDeleteTransaction { return &transaction } +func contractDeleteTransactionFromProtobuf(transactions map[TransactionID]map[AccountID]*proto.Transaction, pb *proto.TransactionBody) ContractDeleteTransaction { + return ContractDeleteTransaction{ + Transaction: transactionFromProtobuf(transactions, pb), + pb: pb.GetContractDeleteInstance(), + } +} + func (transaction *ContractDeleteTransaction) SetContractID(contractID ContractID) *ContractDeleteTransaction { transaction.requireNotFrozen() transaction.pb.ContractID = contractID.toProtobuf() diff --git a/contract_execute_transaction.go b/contract_execute_transaction.go index f14a4db17..d543333b6 100644 --- a/contract_execute_transaction.go +++ b/contract_execute_transaction.go @@ -30,6 +30,13 @@ func NewContractExecuteTransaction() *ContractExecuteTransaction { return &transaction } +func contractExecuteTransactionFromProtobuf(transactions map[TransactionID]map[AccountID]*proto.Transaction, pb *proto.TransactionBody) ContractExecuteTransaction { + return ContractExecuteTransaction{ + Transaction: transactionFromProtobuf(transactions, pb), + pb: pb.GetContractCall(), + } +} + // SetContractID sets the contract instance to call. func (transaction *ContractExecuteTransaction) SetContractID(ID ContractID) *ContractExecuteTransaction { transaction.requireNotFrozen() diff --git a/contract_update_transaction.go b/contract_update_transaction.go index 97b24992a..7fdc9c7fa 100644 --- a/contract_update_transaction.go +++ b/contract_update_transaction.go @@ -37,6 +37,13 @@ func NewContractUpdateTransaction() *ContractUpdateTransaction { return &transaction } +func contractUpdateTransactionFromProtobuf(transactions map[TransactionID]map[AccountID]*proto.Transaction, pb *proto.TransactionBody) ContractUpdateTransaction { + return ContractUpdateTransaction{ + Transaction: transactionFromProtobuf(transactions, pb), + pb: pb.GetContractUpdateInstance(), + } +} + // SetContractID sets The Contract ID instance to update (this can't be changed on the contract) func (transaction *ContractUpdateTransaction) SetContractID(contractID ContractID) *ContractUpdateTransaction { transaction.pb.ContractID = contractID.toProtobuf() diff --git a/errors.go b/errors.go index e7897ee46..4f9fa74b0 100644 --- a/errors.go +++ b/errors.go @@ -20,6 +20,8 @@ var errNoClientOrTransactionIDOrNodeId = errors.New("`client` must be provided o var errClientOperatorSigning = errors.New("`client` must have an `operator` to sign with the operator") var errNoClientProvided = errors.New("`client` must be provided and have an operator") var errTransactionIsNotFrozen = errors.New("transaction is not frozen") +var errFailedToDeserializeBytes = errors.New("Failed to deserialize bytes") +var errNoTransactionInBytes = errors.New("No transaction was found in bytes") type ErrInvalidNodeAccountIDSet struct { NodeAccountID AccountID diff --git a/file_append_transaction.go b/file_append_transaction.go index 7a3b2530a..76d0ae3bb 100644 --- a/file_append_transaction.go +++ b/file_append_transaction.go @@ -26,6 +26,13 @@ func NewFileAppendTransaction() *FileAppendTransaction { return &transaction } +func fileAppendTransactionFromProtobuf(transactions map[TransactionID]map[AccountID]*proto.Transaction, pb *proto.TransactionBody) FileAppendTransaction { + return FileAppendTransaction{ + Transaction: transactionFromProtobuf(transactions, pb), + pb: pb.GetFileAppend(), + } +} + // SetFileID sets the FileID of the file to which the bytes are appended to. func (transaction *FileAppendTransaction) SetFileID(ID FileID) *FileAppendTransaction { transaction.requireNotFrozen() diff --git a/file_create_transaction.go b/file_create_transaction.go index 10fff639a..b323f1aa6 100644 --- a/file_create_transaction.go +++ b/file_create_transaction.go @@ -35,6 +35,13 @@ func NewFileCreateTransaction() *FileCreateTransaction { return &transaction } +func fileCreateTransactionFromProtobuf(transactions map[TransactionID]map[AccountID]*proto.Transaction, pb *proto.TransactionBody) FileCreateTransaction { + return FileCreateTransaction{ + Transaction: transactionFromProtobuf(transactions, pb), + pb: pb.GetFileCreate(), + } +} + // AddKey adds a key to the internal list of keys associated with the file. All of the keys on the list must sign to // create or modify a file, but only one of them needs to sign in order to delete the file. Each of those "keys" may // itself be threshold key containing other keys (including other threshold keys). In other words, the behavior is an diff --git a/file_delete_transaction.go b/file_delete_transaction.go index ae41cf0ee..2da9713af 100644 --- a/file_delete_transaction.go +++ b/file_delete_transaction.go @@ -21,6 +21,13 @@ func NewFileDeleteTransaction() *FileDeleteTransaction { return &transaction } +func fileDeleteTransactionFromProtobuf(transactions map[TransactionID]map[AccountID]*proto.Transaction, pb *proto.TransactionBody) FileDeleteTransaction { + return FileDeleteTransaction{ + Transaction: transactionFromProtobuf(transactions, pb), + pb: pb.GetFileDelete(), + } +} + func (transaction *FileDeleteTransaction) SetFileID(fileID FileID) *FileDeleteTransaction { transaction.requireNotFrozen() transaction.pb.FileID = fileID.toProtobuf() diff --git a/file_update_transaction.go b/file_update_transaction.go index aba90d622..6ad235a17 100644 --- a/file_update_transaction.go +++ b/file_update_transaction.go @@ -22,6 +22,13 @@ func NewFileUpdateTransaction() *FileUpdateTransaction { return &transaction } +func fileUpdateTransactionFromProtobuf(transactions map[TransactionID]map[AccountID]*proto.Transaction, pb *proto.TransactionBody) FileUpdateTransaction { + return FileUpdateTransaction{ + Transaction: transactionFromProtobuf(transactions, pb), + pb: pb.GetFileUpdate(), + } +} + func (transaction *FileUpdateTransaction) SetFileID(ID FileID) *FileUpdateTransaction { transaction.requireNotFrozen() transaction.pb.FileID = ID.toProtobuf() diff --git a/freeze_transaction.go b/freeze_transaction.go index 35fd9239a..b5843165a 100644 --- a/freeze_transaction.go +++ b/freeze_transaction.go @@ -21,6 +21,13 @@ func NewFreezeTransaction() *FreezeTransaction { return &transaction } +func freezeTransactionFromProtobuf(transactions map[TransactionID]map[AccountID]*proto.Transaction, pb *proto.TransactionBody) FreezeTransaction { + return FreezeTransaction{ + Transaction: transactionFromProtobuf(transactions, pb), + pb: pb.GetFreeze(), + } +} + func (transaction *FreezeTransaction) SetStartTime(startTime time.Time) *FreezeTransaction { transaction.requireNotFrozen() transaction.pb.StartHour = int32(startTime.Hour()) diff --git a/live_hash_add_transaction.go b/live_hash_add_transaction.go index 2aed9211d..b2180d412 100644 --- a/live_hash_add_transaction.go +++ b/live_hash_add_transaction.go @@ -20,6 +20,13 @@ func NewLiveHashAddTransaction() *LiveHashAddTransaction { return &transaction } +func liveHashAddTransactionFromProtobuf(transactions map[TransactionID]map[AccountID]*proto.Transaction, pb *proto.TransactionBody) LiveHashAddTransaction { + return LiveHashAddTransaction{ + Transaction: transactionFromProtobuf(transactions, pb), + pb: pb.GetCryptoAddLiveHash(), + } +} + func (transaction *LiveHashAddTransaction) SetHash(hash []byte) *LiveHashAddTransaction { transaction.requireNotFrozen() transaction.pb.LiveHash.Hash = hash diff --git a/live_hash_delete_transaction.go b/live_hash_delete_transaction.go index 0310ef632..136b2c761 100644 --- a/live_hash_delete_transaction.go +++ b/live_hash_delete_transaction.go @@ -20,6 +20,13 @@ func NewLiveHashDeleteTransaction() *LiveHashDeleteTransaction { return &transaction } +func liveHashDeleteTransactionFromProtobuf(transactions map[TransactionID]map[AccountID]*proto.Transaction, pb *proto.TransactionBody) LiveHashDeleteTransaction { + return LiveHashDeleteTransaction{ + Transaction: transactionFromProtobuf(transactions, pb), + pb: pb.GetCryptoDeleteLiveHash(), + } +} + func (transaction *LiveHashDeleteTransaction) SetHash(hash []byte) *LiveHashDeleteTransaction { transaction.requireNotFrozen() transaction.pb.LiveHashToDelete = hash diff --git a/single_topic_message_submit_transaction.go b/single_topic_message_submit_transaction.go index 19eb9b69d..6f78b3e2a 100644 --- a/single_topic_message_submit_transaction.go +++ b/single_topic_message_submit_transaction.go @@ -26,7 +26,13 @@ func newSingleTopicMessageSubmitTransaction( pb: pb, } } +func singleTopicMessageSubmitTransactionFromProtobuf(transactions map[TransactionID]map[AccountID]*proto.Transaction, pb *proto.TransactionBody) singleTopicMessageSubmitTransaction { + return singleTopicMessageSubmitTransaction{ + Transaction: transactionFromProtobuf(transactions, pb), + pb: pb.GetConsensusSubmitMessage(), + } +} // // The following methods must be copy-pasted/overriden at the bottom of **every** _transaction.go file // We override the embedded fluent setter methods to return the outer type diff --git a/system_delete_transaction.go b/system_delete_transaction.go index a106ab7ed..f0784faa6 100644 --- a/system_delete_transaction.go +++ b/system_delete_transaction.go @@ -22,6 +22,13 @@ func NewSystemDeleteTransaction() *SystemDeleteTransaction { return &transaction } +func systemDeleteTransactionFromProtobuf(transactions map[TransactionID]map[AccountID]*proto.Transaction, pb *proto.TransactionBody) SystemDeleteTransaction { + return SystemDeleteTransaction{ + Transaction: transactionFromProtobuf(transactions, pb), + pb: pb.GetSystemDelete(), + } +} + func (transaction *SystemDeleteTransaction) SetExpirationTime(expiration time.Time) *SystemDeleteTransaction { transaction.requireNotFrozen() transaction.pb.ExpirationTime = &proto.TimestampSeconds{ diff --git a/system_undelete_transaction.go b/system_undelete_transaction.go index 54f43dd7e..25532998c 100644 --- a/system_undelete_transaction.go +++ b/system_undelete_transaction.go @@ -21,6 +21,13 @@ func NewSystemUndeleteTransaction() *SystemUndeleteTransaction { return &transaction } +func systemUndeleteTransactionFromProtobuf(transactions map[TransactionID]map[AccountID]*proto.Transaction, pb *proto.TransactionBody) SystemUndeleteTransaction { + return SystemUndeleteTransaction{ + Transaction: transactionFromProtobuf(transactions, pb), + pb: pb.GetSystemUndelete(), + } +} + func (transaction *SystemUndeleteTransaction) SetContractID(contractID ContractID) *SystemUndeleteTransaction { transaction.requireNotFrozen() transaction.pb.Id = &proto.SystemUndeleteTransactionBody_ContractID{ContractID: contractID.toProtobuf()} diff --git a/token_associate_transaction.go b/token_associate_transaction.go index 773ea7bee..2cd97b940 100644 --- a/token_associate_transaction.go +++ b/token_associate_transaction.go @@ -39,6 +39,13 @@ func NewTokenAssociateTransaction() *TokenAssociateTransaction { return &transaction } +func tokenAssociateTransactionFromProtobuf(transactions map[TransactionID]map[AccountID]*proto.Transaction, pb *proto.TransactionBody) TokenAssociateTransaction { + return TokenAssociateTransaction{ + Transaction: transactionFromProtobuf(transactions, pb), + pb: pb.GetTokenAssociate(), + } +} + // The account to be associated with the provided tokens func (transaction *TokenAssociateTransaction) SetAccountID(accountID AccountID) *TokenAssociateTransaction { transaction.requireNotFrozen() diff --git a/token_burn_transaction.go b/token_burn_transaction.go index 7cde24e28..e33354f94 100644 --- a/token_burn_transaction.go +++ b/token_burn_transaction.go @@ -29,6 +29,13 @@ func NewTokenBurnTransaction() *TokenBurnTransaction { return &transaction } +func tokenBurnTransactionFromProtobuf(transactions map[TransactionID]map[AccountID]*proto.Transaction, pb *proto.TransactionBody) TokenBurnTransaction { + return TokenBurnTransaction{ + Transaction: transactionFromProtobuf(transactions, pb), + pb: pb.GetTokenBurn(), + } +} + // The token for which to burn tokens. If token does not exist, transaction results in // INVALID_TOKEN_ID func (transaction *TokenBurnTransaction) SetTokenID(tokenID TokenID) *TokenBurnTransaction { diff --git a/token_create_transaction.go b/token_create_transaction.go index 858d20faa..7a5dc5679 100644 --- a/token_create_transaction.go +++ b/token_create_transaction.go @@ -42,6 +42,13 @@ func NewTokenCreateTransaction() *TokenCreateTransaction { return &transaction } +func tokenCreateTransactionFromProtobuf(transactions map[TransactionID]map[AccountID]*proto.Transaction, pb *proto.TransactionBody) TokenCreateTransaction { + return TokenCreateTransaction{ + Transaction: transactionFromProtobuf(transactions, pb), + pb: pb.GetTokenCreation(), + } +} + // The publicly visible name of the token, specified as a string of only ASCII characters func (transaction *TokenCreateTransaction) SetTokenName(name string) *TokenCreateTransaction { transaction.requireNotFrozen() diff --git a/token_delete_transaction.go b/token_delete_transaction.go index f5e24d7bd..765c49618 100644 --- a/token_delete_transaction.go +++ b/token_delete_transaction.go @@ -26,6 +26,13 @@ func NewTokenDeleteTransaction() *TokenDeleteTransaction { return &transaction } +func tokenDeleteTransactionFromProtobuf(transactions map[TransactionID]map[AccountID]*proto.Transaction, pb *proto.TransactionBody) TokenDeleteTransaction { + return TokenDeleteTransaction{ + Transaction: transactionFromProtobuf(transactions, pb), + pb: pb.GetTokenDeletion(), + } +} + // The Token to be deleted func (transaction *TokenDeleteTransaction) SetTokenID(tokenID TokenID) *TokenDeleteTransaction { transaction.requireNotFrozen() diff --git a/token_dissociate_transaction.go b/token_dissociate_transaction.go index 293c974ca..12ec33c22 100644 --- a/token_dissociate_transaction.go +++ b/token_dissociate_transaction.go @@ -22,6 +22,13 @@ func NewTokenDissociateTransaction() *TokenDissociateTransaction { return &transaction } +func tokenDissociateTransactionFromProtobuf(transactions map[TransactionID]map[AccountID]*proto.Transaction, pb *proto.TransactionBody) TokenDissociateTransaction { + return TokenDissociateTransaction{ + Transaction: transactionFromProtobuf(transactions, pb), + pb: pb.GetTokenDissociate(), + } +} + // The account to be dissociated with the provided tokens func (transaction *TokenDissociateTransaction) SetAccountID(accountID AccountID) *TokenDissociateTransaction { transaction.requireNotFrozen() diff --git a/token_freeze_transaction.go b/token_freeze_transaction.go index 95589dc5e..3dc0f3b6e 100644 --- a/token_freeze_transaction.go +++ b/token_freeze_transaction.go @@ -32,6 +32,13 @@ func NewTokenFreezeTransaction() *TokenFreezeTransaction { return &transaction } +func tokenFreezeTransactionFromProtobuf(transactions map[TransactionID]map[AccountID]*proto.Transaction, pb *proto.TransactionBody) TokenFreezeTransaction { + return TokenFreezeTransaction{ + Transaction: transactionFromProtobuf(transactions, pb), + pb: pb.GetTokenFreeze(), + } +} + // The token for which this account will be frozen. If token does not exist, transaction results // in INVALID_TOKEN_ID func (transaction *TokenFreezeTransaction) SetTokenID(tokenID TokenID) *TokenFreezeTransaction { diff --git a/token_grant_kyc_transaction.go b/token_grant_kyc_transaction.go index 2616ea57a..9669eff52 100644 --- a/token_grant_kyc_transaction.go +++ b/token_grant_kyc_transaction.go @@ -31,6 +31,13 @@ func NewTokenGrantKycTransaction() *TokenGrantKycTransaction { return &transaction } +func tokenGrantKycTransactionFromProtobuf(transactions map[TransactionID]map[AccountID]*proto.Transaction, pb *proto.TransactionBody) TokenGrantKycTransaction { + return TokenGrantKycTransaction{ + Transaction: transactionFromProtobuf(transactions, pb), + pb: pb.GetTokenGrantKyc(), + } +} + // The token for which this account will be granted KYC. If token does not exist, transaction results in INVALID_TOKEN_ID func (transaction *TokenGrantKycTransaction) SetTokenID(tokenID TokenID) *TokenGrantKycTransaction { transaction.requireNotFrozen() diff --git a/token_mint_transaction.go b/token_mint_transaction.go index 6e6331c14..d2c5d20b3 100644 --- a/token_mint_transaction.go +++ b/token_mint_transaction.go @@ -29,6 +29,13 @@ func NewTokenMintTransaction() *TokenMintTransaction { return &transaction } +func tokenMintTransactionFromProtobuf(transactions map[TransactionID]map[AccountID]*proto.Transaction, pb *proto.TransactionBody) TokenMintTransaction { + return TokenMintTransaction{ + Transaction: transactionFromProtobuf(transactions, pb), + pb: pb.GetTokenMint(), + } +} + // The token for which to mint tokens. If token does not exist, transaction results in // INVALID_TOKEN_ID func (transaction *TokenMintTransaction) SetTokenID(tokenID TokenID) *TokenMintTransaction { diff --git a/token_revoke_kcy_transaction.go b/token_revoke_kcy_transaction.go index 3b2aa296c..f5fbc3517 100644 --- a/token_revoke_kcy_transaction.go +++ b/token_revoke_kcy_transaction.go @@ -31,6 +31,13 @@ func NewTokenRevokeKycTransaction() *TokenRevokeKycTransaction { return &transaction } +func tokenRevokeKycTransactionFromProtobuf(transactions map[TransactionID]map[AccountID]*proto.Transaction, pb *proto.TransactionBody) TokenRevokeKycTransaction { + return TokenRevokeKycTransaction{ + Transaction: transactionFromProtobuf(transactions, pb), + pb: pb.GetTokenRevokeKyc(), + } +} + // The token for which this account will get his KYC revoked. If token does not exist, transaction results in INVALID_TOKEN_ID func (transaction *TokenRevokeKycTransaction) SetTokenID(tokenID TokenID) *TokenRevokeKycTransaction { transaction.requireNotFrozen() diff --git a/token_unfreeze_transaction.go b/token_unfreeze_transaction.go index 80f354474..c34b00031 100644 --- a/token_unfreeze_transaction.go +++ b/token_unfreeze_transaction.go @@ -32,6 +32,13 @@ func NewTokenUnfreezeTransaction() *TokenUnfreezeTransaction { return &transaction } +func tokenUnfreezeTransactionFromProtobuf(transactions map[TransactionID]map[AccountID]*proto.Transaction, pb *proto.TransactionBody) TokenUnfreezeTransaction { + return TokenUnfreezeTransaction{ + Transaction: transactionFromProtobuf(transactions, pb), + pb: pb.GetTokenUnfreeze(), + } +} + // The token for which this account will be unfrozen. If token does not exist, transaction results in INVALID_TOKEN_ID func (transaction *TokenUnfreezeTransaction) SetTokenID(tokenID TokenID) *TokenUnfreezeTransaction { transaction.requireNotFrozen() diff --git a/token_update_transaction.go b/token_update_transaction.go index caefe4c9b..dbb3c2687 100644 --- a/token_update_transaction.go +++ b/token_update_transaction.go @@ -26,6 +26,13 @@ func NewTokenUpdateTransaction() *TokenUpdateTransaction { return &transaction } +func tokenUpdateTransactionFromProtobuf(transactions map[TransactionID]map[AccountID]*proto.Transaction, pb *proto.TransactionBody) TokenUpdateTransaction { + return TokenUpdateTransaction{ + Transaction: transactionFromProtobuf(transactions, pb), + pb: pb.GetTokenUpdate(), + } +} + // The Token to be updated func (transaction *TokenUpdateTransaction) SetTokenID(tokenID TokenID) *TokenUpdateTransaction { transaction.requireNotFrozen() diff --git a/token_wipe_transaction.go b/token_wipe_transaction.go index bc9e9675d..47984d64d 100644 --- a/token_wipe_transaction.go +++ b/token_wipe_transaction.go @@ -39,6 +39,13 @@ func NewTokenWipeTransaction() *TokenWipeTransaction { return &transaction } +func tokenWipeTransactionFromProtobuf(transactions map[TransactionID]map[AccountID]*proto.Transaction, pb *proto.TransactionBody) TokenWipeTransaction { + return TokenWipeTransaction{ + Transaction: transactionFromProtobuf(transactions, pb), + pb: pb.GetTokenWipe(), + } +} + // The token for which the account will be wiped. If token does not exist, transaction results in // INVALID_TOKEN_ID func (transaction *TokenWipeTransaction) SetTokenID(tokenID TokenID) *TokenWipeTransaction { diff --git a/topic_create_transaction.go b/topic_create_transaction.go index 0eac0e2a1..0d86d71a6 100644 --- a/topic_create_transaction.go +++ b/topic_create_transaction.go @@ -34,6 +34,13 @@ func NewTopicCreateTransaction() *TopicCreateTransaction { } +func topicCreateTransactionFromProtobuf(transactions map[TransactionID]map[AccountID]*proto.Transaction, pb *proto.TransactionBody) TopicCreateTransaction { + return TopicCreateTransaction{ + Transaction: transactionFromProtobuf(transactions, pb), + pb: pb.GetConsensusCreateTopic(), + } +} + // SetAdminKey sets the key required to update or delete the topic. If unspecified, anyone can increase the topic's // expirationTime. func (transaction *TopicCreateTransaction) SetAdminKey(publicKey Key) *TopicCreateTransaction { diff --git a/topic_delete_transaction.go b/topic_delete_transaction.go index bc24c47ff..c95dbb722 100644 --- a/topic_delete_transaction.go +++ b/topic_delete_transaction.go @@ -24,6 +24,13 @@ func NewTopicDeleteTransaction() *TopicDeleteTransaction { return &transaction } +func topicDeleteTransactionFromProtobuf(transactions map[TransactionID]map[AccountID]*proto.Transaction, pb *proto.TransactionBody) TopicDeleteTransaction { + return TopicDeleteTransaction{ + Transaction: transactionFromProtobuf(transactions, pb), + pb: pb.GetConsensusDeleteTopic(), + } +} + // SetTopicID sets the topic IDentifier. func (transaction *TopicDeleteTransaction) SetTopicID(ID TopicID) *TopicDeleteTransaction { transaction.requireNotFrozen() diff --git a/topic_message_submit_transaction.go b/topic_message_submit_transaction.go index 2b7d18e20..e48b2cd35 100644 --- a/topic_message_submit_transaction.go +++ b/topic_message_submit_transaction.go @@ -29,6 +29,25 @@ func NewTopicMessageSubmitTransaction() *TopicMessageSubmitTransaction { return &transaction } +func topicMessageSubmitTransactionFromProtobuf(transactions map[TransactionID]map[AccountID]*proto.Transaction, pb *proto.TransactionBody) TopicMessageSubmitTransaction { + tx := TopicMessageSubmitTransaction{ + Transaction: transactionFromProtobuf(transactions, pb), + pb: pb.GetConsensusSubmitMessage(), + maxChunks: 10, + message: make([]byte, 0), + chunkedTransactions: make([]*singleTopicMessageSubmitTransaction, 0), + } + + for transactionID, m := range transactions { + txs := make(map[TransactionID]map[AccountID]*proto.Transaction) + txs[transactionID] = m + singleTx := singleTopicMessageSubmitTransactionFromProtobuf(txs, pb) + tx.chunkedTransactions = append(tx.chunkedTransactions, &singleTx) + } + + return tx +} + func (transaction *TopicMessageSubmitTransaction) SetTopicID(ID TopicID) *TopicMessageSubmitTransaction { transaction.requireNotFrozen() transaction.pb.TopicID = ID.toProtobuf() diff --git a/topic_update_transaction.go b/topic_update_transaction.go index 7574a19b9..4667c7ae0 100644 --- a/topic_update_transaction.go +++ b/topic_update_transaction.go @@ -27,6 +27,13 @@ func NewTopicUpdateTransaction() *TopicUpdateTransaction { return &transaction } +func topicUpdateTransactionFromProtobuf(transactions map[TransactionID]map[AccountID]*proto.Transaction, pb *proto.TransactionBody) TopicUpdateTransaction { + return TopicUpdateTransaction{ + Transaction: transactionFromProtobuf(transactions, pb), + pb: pb.GetConsensusUpdateTopic(), + } +} + // SetTopicID sets the topic to be updated. func (transaction *TopicUpdateTransaction) SetTopicID(topicID TopicID) *TopicUpdateTransaction { transaction.requireNotFrozen() diff --git a/transaction.go b/transaction.go index 0594aa298..446d806bb 100644 --- a/transaction.go +++ b/transaction.go @@ -16,10 +16,6 @@ type Transaction struct { id TransactionID - // unfortunately; this is required to prevent setting the max TXFee if it is purposely set to 0 - // (for example, when .GetCost() is called) - noTXFee bool - nextTransactionIndex int transactions []*proto.Transaction @@ -33,7 +29,6 @@ func newTransaction() Transaction { TransactionValidDuration: durationToProtobuf(120 * time.Second), }, id: TransactionID{}, - noTXFee: false, nextTransactionIndex: 0, transactions: make([]*proto.Transaction, 0), signatures: make([]*proto.SignatureMap, 0), @@ -41,28 +36,135 @@ func newTransaction() Transaction { } } -// UnmarshalBinary implements the encoding.BinaryUnmarshaler interface. -func (transaction *Transaction) UnmarshalBinary(txBytes []byte) error { - transaction.transactions = make([]*proto.Transaction, 0) - transaction.transactions = append(transaction.transactions, &proto.Transaction{}) - if err := protobuf.Unmarshal(txBytes, transaction.transactions[0]); err != nil { - return err +func transactionFromProtobuf(transactions map[TransactionID]map[AccountID]*proto.Transaction, pb *proto.TransactionBody) Transaction { + tx := Transaction{ + pbBody: pb, + id: transactionIDFromProtobuf(pb.TransactionID), + nextTransactionIndex: 0, + transactions: make([]*proto.Transaction, 0), + signatures: make([]*proto.SignatureMap, 0), + nodeIDs: make([]AccountID, 0), } - var txBody proto.TransactionBody - if err := protobuf.Unmarshal(transaction.transactions[0].GetBodyBytes(), &txBody); err != nil { - return err + var protoTxs map[AccountID]*proto.Transaction + for _, m := range transactions { + protoTxs = m + break } - transaction.id = transactionIDFromProtobuf(txBody.TransactionID) + for nodeAccountID, protoTx := range protoTxs { + tx.nodeIDs = append(tx.nodeIDs, nodeAccountID) + tx.transactions = append(tx.transactions, protoTx) + tx.signatures = append(tx.signatures, protoTx.GetSigMap()) + } - return nil + return tx } -func TransactionFromBytes(bytes []byte) Transaction { - tx := Transaction{} - (&tx).UnmarshalBinary(bytes) - return tx +func TransactionFromBytes(bytes []byte) (interface{}, error) { + transactions := make(map[TransactionID]map[AccountID]*proto.Transaction) + buf := protobuf.NewBuffer(bytes) + var first *proto.TransactionBody = nil + + for { + tx := proto.Transaction{} + if err := buf.Unmarshal(&tx); err != nil { + break + } + + var txBody proto.TransactionBody + if err := protobuf.Unmarshal(tx.GetBodyBytes(), &txBody); err != nil { + return Transaction{}, err + } + + if first == nil { + first = &txBody + } + + transactionID := transactionIDFromProtobuf(txBody.TransactionID) + nodeAccountID := accountIDFromProtobuf(txBody.NodeAccountID) + + if _, ok := transactions[transactionID]; !ok { + transactions[transactionID] = make(map[AccountID]*proto.Transaction) + } + + transactions[transactionID][nodeAccountID] = &tx + } + + if first == nil { + return nil, errNoTransactionInBytes + } + + switch first.Data.(type) { + case *proto.TransactionBody_ContractCall: + return contractExecuteTransactionFromProtobuf(transactions, first), nil + case *proto.TransactionBody_ContractCreateInstance: + return contractCreateTransactionFromProtobuf(transactions, first), nil + case *proto.TransactionBody_ContractUpdateInstance: + return contractUpdateTransactionFromProtobuf(transactions, first), nil + case *proto.TransactionBody_ContractDeleteInstance: + return contractDeleteTransactionFromProtobuf(transactions, first), nil + case *proto.TransactionBody_CryptoAddLiveHash: + return liveHashAddTransactionFromProtobuf(transactions, first), nil + case *proto.TransactionBody_CryptoCreateAccount: + return accountCreateTransactionFromProtobuf(transactions, first), nil + case *proto.TransactionBody_CryptoDelete: + return accountDeleteTransactionFromProtobuf(transactions, first), nil + case *proto.TransactionBody_CryptoDeleteLiveHash: + return liveHashDeleteTransactionFromProtobuf(transactions, first), nil + case *proto.TransactionBody_CryptoTransfer: + return transferTransactionFromProtobuf(transactions, first), nil + case *proto.TransactionBody_CryptoUpdateAccount: + return accountUpdateTransactionFromProtobuf(transactions, first), nil + case *proto.TransactionBody_FileAppend: + return fileAppendTransactionFromProtobuf(transactions, first), nil + case *proto.TransactionBody_FileCreate: + return fileCreateTransactionFromProtobuf(transactions, first), nil + case *proto.TransactionBody_FileDelete: + return fileDeleteTransactionFromProtobuf(transactions, first), nil + case *proto.TransactionBody_FileUpdate: + return fileUpdateTransactionFromProtobuf(transactions, first), nil + case *proto.TransactionBody_SystemDelete: + return systemDeleteTransactionFromProtobuf(transactions, first), nil + case *proto.TransactionBody_SystemUndelete: + return systemUndeleteTransactionFromProtobuf(transactions, first), nil + case *proto.TransactionBody_Freeze: + return freezeTransactionFromProtobuf(transactions, first), nil + case *proto.TransactionBody_ConsensusCreateTopic: + return topicCreateTransactionFromProtobuf(transactions, first), nil + case *proto.TransactionBody_ConsensusUpdateTopic: + return topicUpdateTransactionFromProtobuf(transactions, first), nil + case *proto.TransactionBody_ConsensusDeleteTopic: + return topicDeleteTransactionFromProtobuf(transactions, first), nil + case *proto.TransactionBody_ConsensusSubmitMessage: + return topicMessageSubmitTransactionFromProtobuf(transactions, first), nil + case *proto.TransactionBody_TokenCreation: + return tokenCreateTransactionFromProtobuf(transactions, first), nil + case *proto.TransactionBody_TokenFreeze: + return tokenFreezeTransactionFromProtobuf(transactions, first), nil + case *proto.TransactionBody_TokenUnfreeze: + return tokenUnfreezeTransactionFromProtobuf(transactions, first), nil + case *proto.TransactionBody_TokenGrantKyc: + return tokenGrantKycTransactionFromProtobuf(transactions, first), nil + case *proto.TransactionBody_TokenRevokeKyc: + return tokenRevokeKycTransactionFromProtobuf(transactions, first), nil + case *proto.TransactionBody_TokenDeletion: + return tokenDeleteTransactionFromProtobuf(transactions, first), nil + case *proto.TransactionBody_TokenUpdate: + return tokenUpdateTransactionFromProtobuf(transactions, first), nil + case *proto.TransactionBody_TokenMint: + return tokenMintTransactionFromProtobuf(transactions, first), nil + case *proto.TransactionBody_TokenBurn: + return tokenBurnTransactionFromProtobuf(transactions, first), nil + case *proto.TransactionBody_TokenWipe: + return tokenWipeTransactionFromProtobuf(transactions, first), nil + case *proto.TransactionBody_TokenAssociate: + return tokenAssociateTransactionFromProtobuf(transactions, first), nil + case *proto.TransactionBody_TokenDissociate: + return tokenDissociateTransactionFromProtobuf(transactions, first), nil + default: + return Transaction{}, errFailedToDeserializeBytes + } } func (transaction *Transaction) GetTransactionHash() ([]byte, error) { diff --git a/transaction_test.go b/transaction_test.go index 5b5066d4c..bf0795c0c 100644 --- a/transaction_test.go +++ b/transaction_test.go @@ -13,12 +13,19 @@ func TestTransactionSerializationDeserialization(t *testing.T) { _, err = transaction.GetTransactionHash() assert.NoError(t, err) - txBytes, err := transaction.MarshalBinary() + txBytes, err := transaction.ToBytes() assert.NoError(t, err) - var deserializedTX Transaction - err = deserializedTX.UnmarshalBinary(txBytes) + deserializedTX, err := TransactionFromBytes(txBytes) assert.NoError(t, err) - assert.Equal(t, transaction.String(), deserializedTX.String()) + var deserializedTXTyped TransferTransaction + switch tx := deserializedTX.(type) { + case TransferTransaction: + deserializedTXTyped = tx + default: + panic("Transaction was not TransferTransaction") + } + + assert.Equal(t, transaction.String(), deserializedTXTyped.String()) } diff --git a/transfer_transaction.go b/transfer_transaction.go index 63ccf7370..93e8ae91c 100644 --- a/transfer_transaction.go +++ b/transfer_transaction.go @@ -28,6 +28,13 @@ func NewTransferTransaction() *TransferTransaction { return &transaction } +func transferTransactionFromProtobuf(transactions map[TransactionID]map[AccountID]*proto.Transaction, pb *proto.TransactionBody) TransferTransaction { + return TransferTransaction{ + Transaction: transactionFromProtobuf(transactions, pb), + pb: pb.GetCryptoTransfer(), + } +} + func (transaction *TransferTransaction) GetTokenTransfers() map[TokenID][]TokenTransfer { tokenTransferMap := make(map[TokenID][]TokenTransfer, len(transaction.pb.TokenTransfers)) for _, tokenTransfer := range transaction.pb.TokenTransfers { @@ -131,12 +138,9 @@ func (transaction *TransferTransaction) SignWith( for index := 0; index < len(transaction.transactions); index++ { signature := signer(transaction.transactions[index].GetBodyBytes()) - newSig := &proto.SignatureMap{SigPair: make([]*proto.SignaturePair, 0)} - newSig.SigPair = append(newSig.SigPair,publicKey.toSignaturePairProtobuf(signature)) - - transaction.signatures = append( - transaction.signatures, - newSig, + transaction.signatures[index].SigPair = append( + transaction.signatures[index].SigPair, + publicKey.toSignaturePairProtobuf(signature), ) } diff --git a/utilities_for_test.go b/utilities_for_test.go index 7e06a9996..838cb6c71 100644 --- a/utilities_for_test.go +++ b/utilities_for_test.go @@ -32,19 +32,11 @@ func newMockClient() (*Client, error) { func newMockTransaction() (Transaction, error) { privateKey, err := PrivateKeyFromString(mockPrivateKey) - if err != nil { return Transaction{}, err } client, err := newMockClient() - - if err != nil { - return Transaction{}, err - } - - nodeIDs := make([]AccountID, 1) - nodeIDs[0], err = AccountIDFromString("0.0.4") if err != nil { return Transaction{}, err } @@ -54,9 +46,8 @@ func newMockTransaction() (Transaction, error) { AddHbarTransfer(AccountID{Account: 3}, HbarFromTinybar(100)). SetMaxTransactionFee(HbarFrom(1, HbarUnits.Hbar)). SetTransactionID(testTransactionID). - SetNodeAccountIDs(nodeIDs). + SetNodeAccountIDs([]AccountID{AccountID{0, 0, 4}}). FreezeWith(client) - if err != nil { return Transaction{}, err }