@@ -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,43 @@ 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+ stateKey := bytes .NewBuffer (nil )
822+ stateKey .WriteByte (byte (ST_STATES ))
823+ serialization .WriteVarBytes (stateKey , su .Namespace )
824+ serialization .WriteVarBytes (stateKey , su .Key )
825+
826+ // verify tx signer public is in StateUpdater list.
827+ log .Tracef ("StateUpdate tx publickey: %x" , su .Updater )
828+
829+ stateUpdater , err := bd .GetStateUpdater ()
830+ if err != nil {
831+ return err
832+ }
833+
834+ findflag := false
835+ for k := 0 ; k < len (stateUpdater ); k ++ {
836+ log .Tracef ("StateUpdate updaterPublickey %d: %x %x" , k , stateUpdater [k ].X , stateUpdater [k ].Y )
837+
838+ if su .Updater .X .Cmp (stateUpdater [k ].X ) == 0 && su .Updater .Y .Cmp (stateUpdater [k ].Y ) == 0 {
839+ findflag = true
840+ break
841+ }
842+ }
843+
844+ if ! findflag {
845+ return errors .New (fmt .Sprintf ("[persist] stateUpdater publickey not found in store, reject. tx publickey: %x" , su .Updater ))
846+ }
847+
848+ // if not found in store, put value to the key.
849+ // if found in store, rewrite value.
850+ log .Tracef ("[persist] StateUpdate modify, key: %x, value:%x" , stateKey , su .Value )
851+ bd .st .BatchPut (stateKey .Bytes (), su .Value )
852+ }
853+
769854 for index := 0 ; index < len (b .Transactions [i ].Outputs ); index ++ {
770855 output := b .Transactions [i ].Outputs [index ]
771856 programHash := output .ProgramHash
@@ -1279,6 +1364,47 @@ func (bd *ChainStore) GetAccount(programHash Uint160) (*account.AccountState, er
12791364 return accountState , nil
12801365}
12811366
1367+ func (bd * ChainStore ) IsStateUpdaterVaild (Tx * tx.Transaction ) bool {
1368+ su := Tx .Payload .(* payload.StateUpdate )
1369+
1370+ stateUpdater , err := bd .GetStateUpdater ()
1371+ if err != nil {
1372+ return false
1373+ }
1374+
1375+ findflag := false
1376+ for k := 0 ; k < len (stateUpdater ); k ++ {
1377+ log .Tracef ("StateUpdate updaterPublickey %d: %x %x" , k , stateUpdater [k ].X , stateUpdater [k ].Y )
1378+
1379+ if su .Updater .X .Cmp (stateUpdater [k ].X ) == 0 && su .Updater .Y .Cmp (stateUpdater [k ].Y ) == 0 {
1380+ findflag = true
1381+ break
1382+ }
1383+ }
1384+
1385+ if ! findflag {
1386+ return false
1387+ }
1388+
1389+ return true
1390+ }
1391+
1392+ func (bd * ChainStore ) GetState (namespace []byte , key []byte ) ([]byte , error ) {
1393+
1394+ // stateKey
1395+ stateKey := bytes .NewBuffer (nil )
1396+ stateKey .WriteByte (byte (ST_STATES ))
1397+ serialization .WriteVarBytes (stateKey , namespace )
1398+ serialization .WriteVarBytes (stateKey , key )
1399+
1400+ stateValue , err := bd .st .Get (stateKey .Bytes ())
1401+ if err != nil {
1402+ return nil , err
1403+ }
1404+
1405+ return stateValue , nil
1406+ }
1407+
12821408func (bd * ChainStore ) GetUnspentFromProgramHash (programHash Uint160 , assetid Uint256 ) ([]* tx.UTXOUnspent , error ) {
12831409
12841410 prefix := []byte {byte (IX_Unspent_UTXO )}
0 commit comments