2020-11-04 01:25:53 +00:00
|
|
|
package multisig
|
|
|
|
|
|
|
|
import (
|
2022-06-14 15:00:51 +00:00
|
|
|
cbg "github.com/whyrusleeping/cbor-gen"
|
|
|
|
|
2020-11-04 01:25:53 +00:00
|
|
|
"github.com/filecoin-project/go-address"
|
|
|
|
"github.com/filecoin-project/go-state-types/abi"
|
|
|
|
|
|
|
|
"github.com/filecoin-project/lotus/chain/actors/adt"
|
|
|
|
)
|
|
|
|
|
|
|
|
type PendingTransactionChanges struct {
|
|
|
|
Added []TransactionChange
|
|
|
|
Modified []TransactionModification
|
|
|
|
Removed []TransactionChange
|
|
|
|
}
|
|
|
|
|
|
|
|
type TransactionChange struct {
|
|
|
|
TxID int64
|
|
|
|
Tx Transaction
|
|
|
|
}
|
|
|
|
|
|
|
|
type TransactionModification struct {
|
|
|
|
TxID int64
|
|
|
|
From Transaction
|
|
|
|
To Transaction
|
|
|
|
}
|
|
|
|
|
|
|
|
func DiffPendingTransactions(pre, cur State) (*PendingTransactionChanges, error) {
|
|
|
|
results := new(PendingTransactionChanges)
|
|
|
|
if changed, err := pre.PendingTxnChanged(cur); err != nil {
|
|
|
|
return nil, err
|
|
|
|
} else if !changed { // if nothing has changed then return an empty result and bail.
|
|
|
|
return results, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
pret, err := pre.transactions()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
curt, err := cur.transactions()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := adt.DiffAdtMap(pret, curt, &transactionDiffer{results, pre, cur}); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return results, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
type transactionDiffer struct {
|
|
|
|
Results *PendingTransactionChanges
|
|
|
|
pre, after State
|
|
|
|
}
|
|
|
|
|
|
|
|
func (t *transactionDiffer) AsKey(key string) (abi.Keyer, error) {
|
|
|
|
txID, err := abi.ParseIntKey(key)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return abi.IntKey(txID), nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (t *transactionDiffer) Add(key string, val *cbg.Deferred) error {
|
|
|
|
txID, err := abi.ParseIntKey(key)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
tx, err := t.after.decodeTransaction(val)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
t.Results.Added = append(t.Results.Added, TransactionChange{
|
|
|
|
TxID: txID,
|
|
|
|
Tx: tx,
|
|
|
|
})
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (t *transactionDiffer) Modify(key string, from, to *cbg.Deferred) error {
|
|
|
|
txID, err := abi.ParseIntKey(key)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
txFrom, err := t.pre.decodeTransaction(from)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
txTo, err := t.after.decodeTransaction(to)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
if approvalsChanged(txFrom.Approved, txTo.Approved) {
|
|
|
|
t.Results.Modified = append(t.Results.Modified, TransactionModification{
|
|
|
|
TxID: txID,
|
|
|
|
From: txFrom,
|
|
|
|
To: txTo,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func approvalsChanged(from, to []address.Address) bool {
|
|
|
|
if len(from) != len(to) {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
for idx := range from {
|
|
|
|
if from[idx] != to[idx] {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
func (t *transactionDiffer) Remove(key string, val *cbg.Deferred) error {
|
|
|
|
txID, err := abi.ParseIntKey(key)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
tx, err := t.pre.decodeTransaction(val)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
t.Results.Removed = append(t.Results.Removed, TransactionChange{
|
|
|
|
TxID: txID,
|
|
|
|
Tx: tx,
|
|
|
|
})
|
|
|
|
return nil
|
|
|
|
}
|