@@ -76,7 +76,7 @@ func NewChainStore(file string) (*ChainStore, error) {
7676 }, nil
7777}
7878
79- func (bd * ChainStore ) InitLedgerStoreWithGenesisBlock (genesisBlock * Block , defaultBookKeeper []* crypto.PubKey ) (uint32 , error ) {
79+ func (bd * ChainStore ) InitLedgerStoreWithGenesisBlock (genesisBlock * Block , defaultBookKeeper []* crypto.PubKey , defaultStateUpdater [] * crypto. PubKey ) (uint32 , error ) {
8080
8181 hash := genesisBlock .Hash ()
8282 bd .headerIndex [0 ] = hash
@@ -230,6 +230,24 @@ func (bd *ChainStore) InitLedgerStoreWithGenesisBlock(genesisBlock *Block, defau
230230 bd .st .Put (bkListKey .Bytes (), bkListValue .Bytes ())
231231 ///////////////////////////////////////////////////
232232
233+ ///////////////////////////////////////////////////
234+ // process defaultStateUpdater
235+ ///////////////////////////////////////////////////
236+ // StateUpdater key
237+ suKey := bytes .NewBuffer (nil )
238+ suKey .WriteByte (byte (CA_StateUpdater ))
239+
240+ // StateUpdater value
241+ suValue := bytes .NewBuffer (nil )
242+ serialization .WriteVarUint (suValue , uint64 (len (defaultStateUpdater )))
243+ for k := 0 ; k < len (defaultStateUpdater ); k ++ {
244+ defaultStateUpdater [k ].Serialize (suValue )
245+ }
246+
247+ // StateUpdater put value
248+ bd .st .Put (suKey .Bytes (), suValue .Bytes ())
249+ ///////////////////////////////////////////////////
250+
233251 // persist genesis block
234252 bd .persist (genesisBlock )
235253
@@ -652,6 +670,35 @@ func (self *ChainStore) GetBookKeeperList() ([]*crypto.PubKey, []*crypto.PubKey,
652670 return currBookKeeper , nextBookKeeper , nil
653671}
654672
673+ func (self * ChainStore ) GetStateUpdater () ([]* crypto.PubKey , error ) {
674+ prefix := []byte {byte (CA_StateUpdater )}
675+ suValue , err_get := self .st .Get (prefix )
676+ if err_get != nil {
677+ return nil , err_get
678+ }
679+
680+ r := bytes .NewReader (suValue )
681+
682+ // read length
683+ count , err := serialization .ReadVarUint (r , 0 )
684+ if err != nil {
685+ return nil , err
686+ }
687+
688+ var stateUpdater = make ([]* crypto.PubKey , count )
689+ for i := uint64 (0 ); i < count ; i ++ {
690+ bk := new (crypto.PubKey )
691+ err := bk .DeSerialize (r )
692+ if err != nil {
693+ return nil , err
694+ }
695+
696+ stateUpdater [i ] = bk
697+ }
698+
699+ return stateUpdater , nil
700+ }
701+
655702func (bd * ChainStore ) persist (b * Block ) error {
656703 utxoUnspents := make (map [Uint160 ]map [Uint256 ][]* tx.UTXOUnspent )
657704 unspents := make (map [Uint256 ][]uint16 )
@@ -738,6 +785,7 @@ func (bd *ChainStore) persist(b *Block) error {
738785 b .Transactions [i ].TxType == tx .IssueAsset ||
739786 b .Transactions [i ].TxType == tx .TransferAsset ||
740787 b .Transactions [i ].TxType == tx .Record ||
788+ b .Transactions [i ].TxType == tx .StateUpdate ||
741789 b .Transactions [i ].TxType == tx .BookKeeper ||
742790 b .Transactions [i ].TxType == tx .PrivacyPayload ||
743791 b .Transactions [i ].TxType == tx .BookKeeping ||
@@ -766,6 +814,48 @@ func (bd *ChainStore) persist(b *Block) error {
766814 }
767815 }
768816
817+ if b .Transactions [i ].TxType == tx .StateUpdate {
818+ su := b .Transactions [i ].Payload .(* payload.StateUpdate )
819+
820+ // stateKey
821+ statePrefix := []byte {byte (ST_STATES )}
822+ stateKey := append (statePrefix , su .Namespace ... )
823+ stateKey = append (stateKey , su .Key ... )
824+ //stateValueOld, err_get := bd.st.Get(stateKey)
825+
826+ // stateValue
827+ //stateValue := bytes.NewBuffer(nil)
828+ //serialization.WriteVarBytes(stateValue, su.Value)
829+
830+ // verify tx signer public is in StateUpdater list.
831+ //publicKey := b.Transactions[i].Programs[0].Parameter[1:34]
832+ log .Trace (fmt .Sprintf ("StateUpdate tx publickey: %x" , su .Updater ))
833+
834+ stateUpdater , err := bd .GetStateUpdater ()
835+ if err != nil {
836+ return err
837+ }
838+
839+ findflag := false
840+ for k := 0 ; k < len (stateUpdater ); k ++ {
841+ log .Trace (fmt .Sprintf ("StateUpdate updaterPublickey %d: %x %x" , k , stateUpdater [k ].X , stateUpdater [k ].Y ))
842+
843+ if su .Updater .X .Cmp (stateUpdater [k ].X ) == 0 && su .Updater .Y .Cmp (stateUpdater [k ].Y ) == 0 {
844+ findflag = true
845+ break
846+ }
847+ }
848+
849+ if ! findflag {
850+ return errors .New (fmt .Sprintf ("[persist] stateUpdater publickey not found in store, reject. tx publickey: %x" , su .Updater ))
851+ }
852+
853+ // if not found in store, put value to the key.
854+ // if found in store, rewrite value.
855+ log .Trace (fmt .Sprintf ("[persist] StateUpdate modify, key: %x, value:%x" , stateKey , su .Value ))
856+ bd .st .BatchPut (stateKey , su .Value )
857+ }
858+
769859 for index := 0 ; index < len (b .Transactions [i ].Outputs ); index ++ {
770860 output := b .Transactions [i ].Outputs [index ]
771861 programHash := output .ProgramHash
@@ -1279,6 +1369,45 @@ func (bd *ChainStore) GetAccount(programHash Uint160) (*account.AccountState, er
12791369 return accountState , nil
12801370}
12811371
1372+ func (bd * ChainStore ) IsStateUpdaterVaild (Tx * tx.Transaction ) bool {
1373+ su := Tx .Payload .(* payload.StateUpdate )
1374+
1375+ stateUpdater , err := bd .GetStateUpdater ()
1376+ if err != nil {
1377+ return false
1378+ }
1379+
1380+ findflag := false
1381+ for k := 0 ; k < len (stateUpdater ); k ++ {
1382+ log .Trace (fmt .Sprintf ("StateUpdate updaterPublickey %d: %x %x" , k , stateUpdater [k ].X , stateUpdater [k ].Y ))
1383+
1384+ if su .Updater .X .Cmp (stateUpdater [k ].X ) == 0 && su .Updater .Y .Cmp (stateUpdater [k ].Y ) == 0 {
1385+ findflag = true
1386+ break
1387+ }
1388+ }
1389+
1390+ if ! findflag {
1391+ return false
1392+ }
1393+
1394+ return true
1395+ }
1396+
1397+ func (bd * ChainStore ) GetState (namespace []byte , key []byte ) ([]byte , error ) {
1398+
1399+ // stateKey
1400+ statePrefix := []byte {byte (ST_STATES )}
1401+ stateKey := append (statePrefix , namespace ... )
1402+ stateKey = append (stateKey , key ... )
1403+ stateValue , err := bd .st .Get (stateKey )
1404+ if err != nil {
1405+ return nil , err
1406+ }
1407+
1408+ return stateValue , nil
1409+ }
1410+
12821411func (bd * ChainStore ) GetUnspentFromProgramHash (programHash Uint160 , assetid Uint256 ) ([]* tx.UTXOUnspent , error ) {
12831412
12841413 prefix := []byte {byte (IX_Unspent_UTXO )}
0 commit comments